From 56936b8e02734182ee8522ae304e342739a26348 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Sat, 13 Dec 2025 20:25:33 +0200 Subject: [PATCH 01/19] Spectator fixes When a player join spectators: - Fired ForceDropOfCarriedPhysObjects input to fix stucked in air physics objects and controlled func_tank like entities. - Called RemoveAllItems() for cases if they're not removed (somehow). --- scripting/include/srccoop/playerpatch.inc | 36 +++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 27052ec..714b06d 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -711,11 +711,19 @@ public MRESReturn Hook_PlayerChangeTeam(int iClient, DHookParam hParams) { // Allow next ForceRespawn() call after a team change g_bUnblockRespawn[iClient] = true; - + + int iTeam = hParams.Get(1); + if (!CMultiplayRules.IsTeamplay()) + { + if(iTeam == TEAM_SPECTATOR) + { + PlayerJoinedSpectators(iClient); + } + return MRES_Ignored; + } - int iTeam = hParams.Get(1); if (iTeam == TEAM_UNASSIGNED || iTeam > TEAM_SPECTATOR) { int iEnforcedTeam = CoopManager.GetEnforcedTeam(); @@ -731,10 +739,34 @@ public MRESReturn Hook_PlayerChangeTeam(int iClient, DHookParam hParams) return MRES_ChangedHandled; } } + + if(iTeam == TEAM_SPECTATOR) + { + PlayerJoinedSpectators(iClient); + } } return MRES_Ignored; } +//------------------------------------------------------ +// Function called from Hook_PlayerChangeTeam when player join spectators to fix some stuff +//------------------------------------------------------ +public void PlayerJoinedSpectators(int iClient) +{ + CBasePlayer pPlayer = CBasePlayer(iClient); + CBaseEntity pCarriedObject = pPlayer.GetUseEntity(); + + //if joined spectators, force player to drop the carried phys object or dismount used tank entity + if (pCarriedObject != NULL_CBASEENTITY) + { + pPlayer.ForceDropOfCarriedPhysObjects(); + } + + //POWER SALO said that sometimes orig code doesn't remove items itself, so I added this line + pPlayer.RemoveAllItems(); +} + + public MRESReturn Hook_PlayerChangeTeamPost(int iClient, DHookParam hParams) { if (CoopManager.IsCoopModeEnabled()) From 0f0aa7d786772179a848ffb8263514a1e5b8b316 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:35:07 +0200 Subject: [PATCH 02/19] env_screenoverlay path Added: - Input hooks for custom logic. - New inputs "StartOverlaysForEveryone" and "StopOverlaysForEveryone". - Globals to control overlay values for each player. - Enable/disable an env_screenoverlay on cllient connect/disconnect (NOT TESTED). - New methods in CBaseEntity methodmap: getter and setter to response context, getter and setter for texture frame index. - Added new methodmap CEnvScreenOverlay. --- scripting/include/srccoop/entitypatch.inc | 361 ++++++++++++++++++ scripting/include/srccoop/globals.inc | 9 + scripting/include/srccoop/playerpatch.inc | 15 + scripting/include/srccoop_api/classdef.inc | 1 + .../classdef/common/CBaseEntity.inc | 16 + .../classdef/common/CEnvScreenOverlay.inc | 181 +++++++++ scripting/srccoop.sp | 13 + 7 files changed, 596 insertions(+) create mode 100644 scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc diff --git a/scripting/include/srccoop/entitypatch.inc b/scripting/include/srccoop/entitypatch.inc index a5adf24..0d1d60e 100644 --- a/scripting/include/srccoop/entitypatch.inc +++ b/scripting/include/srccoop/entitypatch.inc @@ -876,6 +876,367 @@ public void Timer_EnvSpritePostSpawn(Handle timer, CBaseEntity pEntity) } } +#if defined ENTPATCH_ENV_SCREENOVERLAY +//------------------------------------------------------ +// CEnvScreenOverlay - env_screenoverlay +// Inputs hook for custom logic. +//------------------------------------------------------ +public MRESReturn Hook_EnvScreenoverlayAcceptInput(int _this, DHookReturn hReturn, DHookParam hParams) +{ + //skip in case if input name is nullprt + if (DHookIsNullParam(hParams, 1)) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //get input name + char szInputName[MAX_FORMAT]; + DHookGetParamString(hParams, 1, szInputName, sizeof(szInputName)); + + //StartOverlays input + if (strcmp(szInputName, "StartOverlays", false) == 0) + { + //we don't have rights to override global overlay entity, ignore this input + if(g_iActiveScreenOverlayEntity[0] != 0) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //don't do anything in case if player is nullprt for some reason + if (DHookIsNullParam(hParams, 2)) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + CBasePlayer pPlayer = DHookGetParam(hParams, 2); + CEnvScreenOverlay pScreenOverlay = CEnvScreenOverlay(_this); + + //don't active me if i'm already active for this player + if(pScreenOverlay.GetActiveStoredOverlay(pPlayer) == pScreenOverlay.entindex) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + int iTextureIndex = pScreenOverlay.GetTextureFrameIndex(); //HACK! Use this UNUSED field to define index we want to start overlay from on server + + //get material that we will apply for screen by getting it from starting overlay + char szOverlayName[MAX_FORMAT]; + pScreenOverlay.GetOverlayName(iTextureIndex, szOverlayName, sizeof(szOverlayName)); + + //print warning and do nothing if the first overlay keyvalue is empty, just like in source sdk + //(https://github.com/ValveSoftware/source-sdk-2013/blob/2d3a6efb50bba856a44e73d4f0098ed4a726699c/src/game/server/env_screenoverlay.cpp#L134C12-L134C62) + if (szOverlayName[0] == '\0') + { + //don't use this code unless debugging or you just want to have a very heavy spam in server console + /* + //note: added entindex so we can define "invalid" entity by index if no targetname for it + char szTargetname[MAX_FORMAT]; + pScreenOverlay.GetTargetname(szTargetname, sizeof(szTargetname)); + PrintToServer("WARNING: env_screenoverlay (%d) with targetname \"%s\" has no overlays to display.\n", pScreenOverlay.entindex, szTargetname); + */ + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //if other local screenoverlay is active - stop overlay for it before we use this entity + if(pScreenOverlay.GetActiveStoredOverlay(pPlayer) != 0) + { + AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlays"); + } + + //send command to apply screen overlay + char szPlayerCommand[MAX_FORMAT]; + Format(szPlayerCommand, sizeof(szPlayerCommand), "r_screenoverlay %s", szOverlayName); + pPlayer.SendCommand(szPlayerCommand); //apply overlay + + pScreenOverlay.SetActiveStoredOverlay(pScreenOverlay.entindex, pPlayer); //store active overlay entindex for this player + + pScreenOverlay.SetNextOverlay(iTextureIndex + 1, pPlayer); //set next overlay we want to play + + float flOverlayDuration = pScreenOverlay.GetOverlayTimes(0); + + //don't do anything anymore if used infinite time for the first overlay + if(flOverlayDuration < 0) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + pScreenOverlay.SetNextOverlayStartTime(GetTickedTime() + flOverlayDuration, pPlayer); + + //don't create more timers if already active + if(pScreenOverlay.GetActiveState() == false) + { + pScreenOverlay.SetActiveState(true); + + //Think() does seem to work on this entity at all, use timer + CreateTimer(0.01, Timer_EnvScreenOverlayThink, pScreenOverlay, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); + } + + //prevent orig code + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //StopOverlays input, needs !activator or param to work + if (strcmp(szInputName, "StopOverlays", false) == 0) + { + CBasePlayer pPlayer = NULL_CBASEENTITY; + + //param 4 is empty, check if param 2 isn't nullprt + if (!DHookIsNullParam(hParams, 2)) + { + pPlayer = DHookGetParam(hParams, 2); + } + else + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + CEnvScreenOverlay pScreenOverlay = CEnvScreenOverlay(_this); + + //don't if player's active overlay isn't me + if(pScreenOverlay.GetActiveStoredOverlay(pPlayer) != pScreenOverlay.entindex) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + pPlayer.SendCommand("r_screenoverlay off"); //used by source source sdk code as disabled overlay val + + pScreenOverlay.SetActiveStoredOverlay(0, pPlayer); //mark that this player has no active ent overlays + pScreenOverlay.SetActiveState(false); + + //prevent orig code + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //StartOverlaysForEveryone input (CUSTOM INPUT), starts overlays for all players + if (strcmp(szInputName, "StartOverlaysForEveryone", false) == 0) + { + g_iActiveScreenOverlayEntity[0] = _this; //mark that global overlay entity is active + CEnvScreenOverlay pScreenOverlay = CEnvScreenOverlay(_this); + int iTextureIndex = pScreenOverlay.GetTextureFrameIndex(); + char szOverlayName[MAX_FORMAT]; + pScreenOverlay.GetOverlayName(iTextureIndex, szOverlayName, sizeof(szOverlayName)); + + // If the first overlay is empty, do nothing for all + if (szOverlayName[0] == '\0') + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + float flOverlayDuration = pScreenOverlay.GetOverlayTimes(0); + + for (int i = 1; i <= MaxClients; i++) + { + CBasePlayer pPlayer = CBasePlayer(i); + //if (!pPlayer.IsValid() || !IsClientInGame(i) || IsFakeClient(i) || !IsValidEntity(i)) + if (!pPlayer.IsValid() || !IsClientInGame(i) || !IsValidEntity(i)) + continue; + + // Don't activate if already active for this player + if (pScreenOverlay.GetActiveStoredOverlay(pPlayer) == pScreenOverlay.entindex) + continue; + + // If another overlay is active, stop it first + if (pScreenOverlay.GetActiveStoredOverlay(pPlayer) != 0) + { + AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlaysForEveryone"); + } + + // Send overlay command + char szPlayerCommand[MAX_FORMAT]; + Format(szPlayerCommand, sizeof(szPlayerCommand), "r_screenoverlay %s", szOverlayName); + pPlayer.SendCommand(szPlayerCommand); + + pScreenOverlay.SetActiveStoredOverlay(pScreenOverlay.entindex, pPlayer); + pScreenOverlay.SetNextOverlay(iTextureIndex + 1, pPlayer); + + // Only set timer if overlay is not infinite + if (flOverlayDuration >= 0) + { + pScreenOverlay.SetNextOverlayStartTime(GetTickedTime() + flOverlayDuration, pPlayer); + } + } + + // Only create timer if not already active + if (pScreenOverlay.GetActiveState() == false && flOverlayDuration >= 0) + { + pScreenOverlay.SetActiveState(true); + CreateTimer(0.01, Timer_EnvScreenOverlayThink, pScreenOverlay, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); + } + + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //StopOverlaysForEveryone input (CUSTOM INPUT), stops overlays for all players + if (strcmp(szInputName, "StopOverlaysForEveryone", false) == 0) + { + g_iActiveScreenOverlayEntity[0] = 0; //mark that no global overlay entity is active + CEnvScreenOverlay pScreenOverlay = CEnvScreenOverlay(_this); + for(int i = 1; i <= MaxClients; i++) + { + CBasePlayer pPlayer = CBasePlayer(i); + int entidx = pPlayer.entindex; + if (entidx > 0 && entidx <= MAX_PLAYERS && IsClientInGame(i) && IsValidEntity(i)) + //if (entidx > 0 && entidx <= MAX_PLAYERS && IsClientInGame(i) && !IsFakeClient(i) && IsValidEntity(i)) + { + if(pScreenOverlay.GetActiveStoredOverlay(pPlayer) == pScreenOverlay.entindex) + { + pPlayer.SendCommand("r_screenoverlay off"); + pScreenOverlay.SetActiveStoredOverlay(0, pPlayer); + pScreenOverlay.SetNextOverlayStartTime(0.0, pPlayer); + pScreenOverlay.SetNextOverlay(0, pPlayer); + } + } + } + pScreenOverlay.SetActiveState(false); + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //SwitchOverlay input + if (strcmp(szInputName, "SwitchOverlay", false) == 0) + { + CEnvScreenOverlay pScreenOverlay = CEnvScreenOverlay(_this); + + //get input param to define the texture overlay entity will start from + char szParam[MAX_FORMAT]; + DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, szParam, sizeof(szParam)); + TrimString(szParam); + + //-1 is also in orig code, cuz for Hammer user everything counts from 1 to 10, while 0 to 9 for programmers + int iSwitchOverlayVal = StringToInt(szParam) - 1; + + //following 2 if() mimics orig code behavior + if (iSwitchOverlayVal < 0) + { + iSwitchOverlayVal = -iSwitchOverlayVal; + } + + if(iSwitchOverlayVal > 9) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + pScreenOverlay.SetTextureFrameIndex(iSwitchOverlayVal); //set new starting overlay texture num + + //prevent orig code + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + //Kill input, fixes overlay not stopped after entity killed + if (strcmp(szInputName, "Kill", false) == 0) + { + AcceptEntityInput(_this, "StopOverlaysForEveryone"); + return MRES_Ignored; + } + + + return MRES_Ignored; //ignore if the input is not one of those we should override +} + +//------------------------------------------------------ +// CEnvScreenOverlay - env_screenoverlay +// Implementation of think for env_screenoverlay entity when it is enabled. +//------------------------------------------------------ +public Action Timer_EnvScreenOverlayThink(Handle timer, CEnvScreenOverlay pScreenOverlay) +{ + if(!IsValidEntity(pScreenOverlay.entindex) || pScreenOverlay.GetActiveState() == false) + { + if (timer != null) + { + return Plugin_Stop; //stop timer if entity is not valid anymore + } + return Plugin_Continue; + } + + float flTickedTime = GetTickedTime(); //store ingame time in this var so we don't call func every time + + int iNextOverlayIndex = -1; + int iNextOverlay[MAX_PLAYERS + 1] = {-1}; //store next overlays to set for certain players + float flNextOverlayStartTime[MAX_PLAYERS + 1] = {-1.0}; + + for(int i = 1; i <= MaxClients; i++) + { + CBasePlayer pPlayer = CBasePlayer(i); + int entidx = pPlayer.entindex; + // Only proceed if entidx is in valid range (1..MAX_PLAYERS) + if (entidx > 0 && entidx <= MAX_PLAYERS && IsClientInGame(i) && IsValidEntity(i)) + //if (entidx > 0 && entidx <= MAX_PLAYERS && IsClientInGame(i) && !IsFakeClient(i) && IsValidEntity(i)) + { + if (pScreenOverlay.GetActiveStoredOverlay(pPlayer) == pScreenOverlay.entindex) + { + iNextOverlayIndex = pScreenOverlay.GetNextOverlay(pPlayer); + if(iNextOverlayIndex <= 9 && iNextOverlayIndex >= 0) + { + iNextOverlay[i] = pScreenOverlay.GetNextOverlay(pPlayer); + } + else + { + iNextOverlay[i] = -1; + } + + flNextOverlayStartTime[i] = pScreenOverlay.GetNextOverlayStartTime(pPlayer); + continue; + } + } + iNextOverlay[i] = -1; + flNextOverlayStartTime[i] = -1.0; + } + + for(int i = 1; i <= MaxClients; i++) + { + CBasePlayer pPlayer = CBasePlayer(i); + if(!pPlayer.IsValid()) + continue; + + // Only switch overlay if the delay has finished + if(flNextOverlayStartTime[i] <= flTickedTime && iNextOverlay[i] != -1) + { + //PrintToChatAll("iNextOverlay[%d] == %d", i, iNextOverlay[i]); + + //get material that we will apply for screen + char szOverlayName[MAX_FORMAT]; + pScreenOverlay.GetOverlayName(iNextOverlay[i], szOverlayName, sizeof(szOverlayName)); + + //print warning and do nothing if the first overlay keyvalue is empty, just like in source sdk + if (szOverlayName[0] == '\0') + { + continue; + } + + //send command to apply screen overlay + char szPlayerCommand[MAX_FORMAT]; + Format(szPlayerCommand, sizeof(szPlayerCommand), "r_screenoverlay %s", szOverlayName); + pPlayer.SendCommand(szPlayerCommand); + + // If at last overlay (9), do not increment further, but still set timer for this overlay + if(iNextOverlayIndex <= 9 && iNextOverlayIndex >= 0) + { + pScreenOverlay.SetNextOverlay(iNextOverlay[i] + 1, pPlayer); + float flOverlayDuration = pScreenOverlay.GetOverlayTimes(iNextOverlay[i]); + pScreenOverlay.SetNextOverlayStartTime(flTickedTime + flOverlayDuration, pPlayer); + } + } + } + + return Plugin_Continue; + +} +#endif + //------------------------------------------------------ // CAI_GoalEntity - ai_goal_* // set goal entity to nearest player diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index a2a6a76..90fd346 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -243,6 +243,15 @@ CBaseEntity g_pLocalPlayerEntity[32] = {NULL_CBASEENTITY, ...}; int g_iLocalPlayerStackSkips[sizeof(g_pLocalPlayerEntity)]; int g_iLocalPlayerStackPointer; +//stores active env_screenoverlay for certain player, the first element of the array is for global overlays +int g_iActiveScreenOverlayEntity[MAX_PLAYERS+1]; + +//stores next overlay will be played by env_screenoverlay for certain player +int g_iNextScreenOverlayIndex[MAX_PLAYERS+1]; + +//stores time value for every player to check if we want to start next overlay for certain player +float g_flNextOverlayTime[MAX_PLAYERS+1]; + // ---------------------------- // Plugin API // ---------------------------- diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 714b06d..6c920ad 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -402,6 +402,14 @@ public void PlayerPatch_OnClientPutInServer(const int iClient) g_bSetJumpModuleActive[iClient] = false; #endif + #if defined ENTPATCH_ENV_SCREENOVERLAY + //if global overlay is active - start it for this client + if(g_iActiveScreenOverlayEntity[0] != 0) + { + AcceptEntityInput(g_iActiveScreenOverlayEntity[0], "StartOverlays", iClient); + } + #endif + SendClientConvars(iClient, false); } @@ -636,6 +644,13 @@ public void PlayerPatch_OnClientDisconnect(CBasePlayer pPlayer) pRagdoll.Kill(); } #endif // SRCCOOP_HL2DM && PLAYERPATCH_SERVERSIDE_RAGDOLLS + + #if defined ENTPATCH_ENV_SCREENOVERLAY + //disable screenoverlay for this client + g_iActiveScreenOverlayEntity[client] = 0; + g_iNextScreenOverlayIndex[client] = 0; + g_flNextOverlayTime[client] = 0.0; + #endif } } diff --git a/scripting/include/srccoop_api/classdef.inc b/scripting/include/srccoop_api/classdef.inc index b1f4d0d..5f85568 100644 --- a/scripting/include/srccoop_api/classdef.inc +++ b/scripting/include/srccoop_api/classdef.inc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/scripting/include/srccoop_api/classdef/common/CBaseEntity.inc b/scripting/include/srccoop_api/classdef/common/CBaseEntity.inc index 3b30548..53d2b88 100644 --- a/scripting/include/srccoop_api/classdef/common/CBaseEntity.inc +++ b/scripting/include/srccoop_api/classdef/common/CBaseEntity.inc @@ -214,6 +214,14 @@ methodmap CBaseEntity { return SetEntPropString(this.entindex, Prop_Data, "m_iName", szTargetname); } + public bool GetResponseContext(char[] szBuffer, const int iMaxLength) + { + return GetEntPropString(this.entindex, Prop_Data, "m_iszResponseContext", szBuffer, iMaxLength) != 0; + } + public int SetResponseContext(const char[] szResponseContext) + { + return SetEntPropString(this.entindex, Prop_Data, "m_iszResponseContext", szResponseContext); + } public bool GetTarget(char[] szBuffer, const int iMaxLength) { return GetEntPropString(this.entindex, Prop_Data, "m_target", szBuffer, iMaxLength) != 0; @@ -637,6 +645,14 @@ methodmap CBaseEntity { SetEntProp(this.entindex, Prop_Data, "m_iMaxHealth", iMaxHealth); } + public int GetTextureFrameIndex() + { + return GetEntProp(this.entindex, Prop_Data, "m_iTextureFrameIndex"); + } + public void SetTextureFrameIndex(const int iTextureFrameIndex) + { + SetEntProp(this.entindex, Prop_Data, "m_iTextureFrameIndex", iTextureFrameIndex); + } public bool FVisibleEntity(const CBaseEntity pEntity, int iTraceMask = MASK_BLOCKLOS, CBaseEntity& pBlocker = NULL_CBASEENTITY) { if (pEntity.m_fFlags & FL_NOTARGET) diff --git a/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc new file mode 100644 index 0000000..c21bf2e --- /dev/null +++ b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc @@ -0,0 +1,181 @@ +#pragma newdecls required +#pragma semicolon 1 + +methodmap CEnvScreenOverlay < CBaseEntity +{ + public CEnvScreenOverlay(const int iEntIndex = -1) + { + return view_as(CBaseEntity(iEntIndex)); + } + + //Create new env_screenoverlay entity. + public static CEnvScreenOverlay Create() + { + return CEnvScreenOverlay(CreateEntityByName("env_screenoverlay")); + } + + //Get overlay material texture that will be used when screenoverlay is active. Integer paramater is value from 0 to 9. + public bool GetOverlayName(int iOverlayNumber, char[] szBuffer, const int iMaxLength) + { + if(iOverlayNumber < 0) + iOverlayNumber = 0; + + if(iOverlayNumber > 9) + iOverlayNumber = 9; + + return GetEntPropString(this.entindex, Prop_Send, "m_iszOverlayNames", szBuffer, iMaxLength, iOverlayNumber) != 0; + } + + //Set overlay material texture that will be used when screenoverlay is active. Integer paramater is value from 0 to 9. + public void SetOverlayName(int iOverlayNumber, char[] szBuffer) + { + if(iOverlayNumber < 0) + iOverlayNumber = 0; + + if(iOverlayNumber > 9) + iOverlayNumber = 9; + + SetEntPropString(this.entindex, Prop_Send, "m_iszOverlayNames", szBuffer, iOverlayNumber); + } + + //Get overlay times, from 0 to 9. + public float GetOverlayTimes(int iOverlayNumber) + { + if(iOverlayNumber < 0) + iOverlayNumber = 0; + + if(iOverlayNumber > 9) + iOverlayNumber = 9; + + return GetEntPropFloat(this.entindex, Prop_Send, "m_flOverlayTimes", iOverlayNumber); + } + + //Set overlay times, from 0 to 9. + public void SetOverlayTimes(int iOverlayNumber, const float flDuration) + { + if(iOverlayNumber < 0) + iOverlayNumber = 0; + + if(iOverlayNumber > 9) + iOverlayNumber = 9; + + SetEntPropFloat(this.entindex, Prop_Send, "m_flOverlayTimes", flDuration, iOverlayNumber); + } + + //Set next overlay start time for certain player. + public void SetNextOverlayStartTime(const float flNextOverlayTime, const CBasePlayer pPlayer) + { + g_flNextOverlayTime[pPlayer.entindex] = flNextOverlayTime; + } + + //Get next overlay start time for certain player. + public float GetNextOverlayStartTime(const CBasePlayer pPlayer) + { + return g_flNextOverlayTime[pPlayer.entindex]; + } + + //Get desired overlay. + public int GetDesiredOverlay() + { + return GetEntProp(this.entindex, Prop_Data, "m_iDesiredOverlay"); + } + + //Set desired overlay. + public void SetDesiredOverlay(int iDesiredOverlay) + { + if(iDesiredOverlay < 0) + iDesiredOverlay = 0; + + if(iDesiredOverlay > 9) + iDesiredOverlay = 9; + + SetEntProp(this.entindex, Prop_Data, "m_iDesiredOverlay", iDesiredOverlay); + } + + //Get next overlay will be played. + public int GetNextOverlay(const CBasePlayer pPlayer) + { + return g_iNextScreenOverlayIndex[pPlayer.entindex]; + } + + //Set next overlay will be played. + public void SetNextOverlay(int iNextOverlay, const CBasePlayer pPlayer) + { + if(iNextOverlay < 0) + iNextOverlay = 0; + + if(iNextOverlay > 9) + iNextOverlay = 9; + + g_iNextScreenOverlayIndex[pPlayer.entindex] = iNextOverlay; + } + + //Returns false if this screenoverlay marked as disabled or true if this screenoverlay marked as enabled. + public bool GetActiveState() + { + //HACK! Use UNUSED field to store active state + if(GetEntProp(this.entindex, Prop_Data, "m_iHealth") != 1) + { + return false; + } + else + { + return true; + } + } + + //True to mark this screenoverlay as enabled, false to mark this screenoverlay as disabled. + public void SetActiveState(const bool bIsActive) + { + //HACK! Use UNUSED field to store active state + if(bIsActive) + { + SetEntProp(this.entindex, Prop_Data, "m_iHealth", 1); + } + else + { + SetEntProp(this.entindex, Prop_Data, "m_iHealth", 0); + } + } + + public int GetActiveStoredOverlay(const CBasePlayer pPlayer) + { + return g_iActiveScreenOverlayEntity[pPlayer.entindex]; + } + + public void SetActiveStoredOverlay(const int iEntIndex, const CBasePlayer pPlayer) + { + g_iActiveScreenOverlayEntity[pPlayer.entindex] = iEntIndex; //store active screenoverlay for this player + } + + //Fire StartOverlays input. + public void StartOverlays(const CBasePlayer pPlayer) + { + AcceptEntityInput(this.entindex, "StartOverlays", pPlayer.entindex); + } + + //Fire StopOverlays input. + public void StopOverlays(const CBasePlayer pPlayer) + { + AcceptEntityInput(this.entindex, "StopOverlays", pPlayer.entindex); + } + + //Fire StartOverlaysForEveryone input. + public void StartOverlaysForEveryone(const CBasePlayer pPlayer) + { + AcceptEntityInput(this.entindex, "StartOverlaysForEveryone", pPlayer.entindex); + } + + //Fire StopOverlaysForEveryone input. + public void StopOverlaysForEveryone(const CBasePlayer pPlayer) + { + AcceptEntityInput(this.entindex, "StopOverlaysForEveryone", pPlayer.entindex); + } + + //Fire SwitchOverlay input, defined by number from 1 to 10. + public void SwitchOverlay(const char[] szOverlayNumber) + { + SetVariantString(szOverlayNumber); + AcceptEntityInput(this.entindex, "SwitchOverlay"); + } +} \ No newline at end of file diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index d0bbce5..6907bdb 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -1224,6 +1224,19 @@ public MRESReturn Hook_RestoreWorld(DHookReturn hReturn) { if (CoopManager.IsCoopModeEnabled()) { + //NOTE: In case if SourceCoop will use restore world - uncomment this part of code. + /* + g_iActiveScreenOverlayEntity[0] = 0; //mark that no global overlay entity is active + //stop overlay for active env_screenoverlays + for (int i = 1; i <= MaxClients; i++) + { + if(g_iActiveScreenOverlayEntity[i] != 0) + { + AcceptEntityInput(g_iActiveScreenOverlayEntity[i], "StopOverlaysForEveryone"); + } + } + */ + // disable gamerules resetting the world on 'round start', this caused crashes DHookSetReturn(hReturn, 0); return MRES_Supercede; From 6f39ad3a66e1c511c8b1ac2ad182c3a979a1b262 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:38:54 +0200 Subject: [PATCH 03/19] Added MAX_PLAYERS macro Needs to be used for every array with MAXPLAYERS. --- scripting/include/srccoop/globals.inc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index 90fd346..26f41e9 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -212,16 +212,22 @@ ArrayList g_pCoopModeMemPatchList; // ---------------------------- // Plugin variables // ---------------------------- +#if defined SRCCOOP_BLACKMESA +#define MAX_PLAYERS 33 //max players for bms +#else +#define MAX_PLAYERS 101 //max players for hl2dm +#endif + char g_szMapName[MAX_MAPNAME]; char g_szPrevMapName[MAX_MAPNAME]; char g_szEntityString[ENTITYSTRING_LENGTH]; -char g_szSteamIds[MAXPLAYERS+1][32]; +char g_szSteamIds[MAX_PLAYERS+1][32]; bool g_bTempDontHookEnts; public bool g_bMapStarted; int g_iPlayerCount; -bool g_bPostTeamSelect[MAXPLAYERS+1]; -int g_iAddButtons[MAXPLAYERS+1]; -int g_bUnblockRespawn[MAXPLAYERS+1]; +bool g_bPostTeamSelect[MAX_PLAYERS+1]; +int g_iAddButtons[MAX_PLAYERS+1]; +int g_bUnblockRespawn[MAX_PLAYERS+1]; SpawnOptions g_pSpawnOptions; OperatingSystem g_serverOS; FeatureMap g_pFeatureMap; From de355e80e6ee60ac3ae9bdb2a41a27e5dfc209cf Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:40:33 +0200 Subject: [PATCH 04/19] Update srccoop.inc --- scripting/include/srccoop.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index ee02b8a..e3dcac3 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -153,12 +153,12 @@ #include #include +#include #include #include #include #include #include -#include #include #include #include From 629921eda84dc1f6328464127e01e25c7f5eacc3 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:43:30 +0200 Subject: [PATCH 05/19] playing with this, still not sure how to fix --- scripting/include/srccoop.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index e3dcac3..a4f4775 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -153,8 +153,8 @@ #include #include -#include #include +#include #include #include #include From da24888aba6e5afded10bec7ed2de0bbfc31736c Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:45:29 +0200 Subject: [PATCH 06/19] Update srccoop.inc --- scripting/include/srccoop.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index a4f4775..ff31dc2 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -150,11 +150,12 @@ #include #include +#include + #include #include #include -#include #include #include #include From 1ccdbea376983889141793f3e868531470a8ef17 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:49:05 +0200 Subject: [PATCH 07/19] attempt to fix compile issue by replacing macro with num --- scripting/include/srccoop.inc | 3 +-- scripting/include/srccoop/globals.inc | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index ff31dc2..ee02b8a 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -150,8 +150,6 @@ #include #include -#include - #include #include @@ -160,6 +158,7 @@ #include #include #include +#include #include #include #include diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index 26f41e9..1c97c46 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -218,9 +218,9 @@ ArrayList g_pCoopModeMemPatchList; #define MAX_PLAYERS 101 //max players for hl2dm #endif -char g_szMapName[MAX_MAPNAME]; -char g_szPrevMapName[MAX_MAPNAME]; -char g_szEntityString[ENTITYSTRING_LENGTH]; +char g_szMapName[64]; +char g_szPrevMapName[64]; +char g_szEntityString[4096]; char g_szSteamIds[MAX_PLAYERS+1][32]; bool g_bTempDontHookEnts; public bool g_bMapStarted; From d39a4569f815895fff79904f573b7f48ca842b1b Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:50:43 +0200 Subject: [PATCH 08/19] Update srccoop.inc --- scripting/include/srccoop.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index ee02b8a..e3dcac3 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -153,12 +153,12 @@ #include #include +#include #include #include #include #include #include -#include #include #include #include From 2184bd7c1e4cb12bef9228e31b3dd85203e92636 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:53:52 +0200 Subject: [PATCH 09/19] Update globals.inc --- scripting/include/srccoop/globals.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index 1c97c46..3838abd 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -218,9 +218,9 @@ ArrayList g_pCoopModeMemPatchList; #define MAX_PLAYERS 101 //max players for hl2dm #endif -char g_szMapName[64]; -char g_szPrevMapName[64]; -char g_szEntityString[4096]; +char g_szMapName[32]; +char g_szPrevMapName[32]; +char g_szEntityString[2097152]; char g_szSteamIds[MAX_PLAYERS+1][32]; bool g_bTempDontHookEnts; public bool g_bMapStarted; From 717a6857f29994dc82a62f36665a49293b32bec7 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 21:58:59 +0200 Subject: [PATCH 10/19] moved new globals to CEnvScreenOverlay.inc --- scripting/include/srccoop/globals.inc | 9 --------- .../srccoop_api/classdef/common/CEnvScreenOverlay.inc | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index 3838abd..91febb6 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -249,15 +249,6 @@ CBaseEntity g_pLocalPlayerEntity[32] = {NULL_CBASEENTITY, ...}; int g_iLocalPlayerStackSkips[sizeof(g_pLocalPlayerEntity)]; int g_iLocalPlayerStackPointer; -//stores active env_screenoverlay for certain player, the first element of the array is for global overlays -int g_iActiveScreenOverlayEntity[MAX_PLAYERS+1]; - -//stores next overlay will be played by env_screenoverlay for certain player -int g_iNextScreenOverlayIndex[MAX_PLAYERS+1]; - -//stores time value for every player to check if we want to start next overlay for certain player -float g_flNextOverlayTime[MAX_PLAYERS+1]; - // ---------------------------- // Plugin API // ---------------------------- diff --git a/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc index c21bf2e..eb1ff3a 100644 --- a/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc +++ b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc @@ -1,6 +1,15 @@ #pragma newdecls required #pragma semicolon 1 +//stores active env_screenoverlay for certain player, the first element of the array is for global overlays +int g_iActiveScreenOverlayEntity[MAX_PLAYERS+1]; + +//stores next overlay will be played by env_screenoverlay for certain player +int g_iNextScreenOverlayIndex[MAX_PLAYERS+1]; + +//stores time value for every player to check if we want to start next overlay for certain player +float g_flNextOverlayTime[MAX_PLAYERS+1]; + methodmap CEnvScreenOverlay < CBaseEntity { public CEnvScreenOverlay(const int iEntIndex = -1) From e205aea64b8143eb146e03e048bb37e3a657ff95 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:02:52 +0200 Subject: [PATCH 11/19] Update CEnvScreenOverlay.inc --- .../classdef/common/CEnvScreenOverlay.inc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc index eb1ff3a..12dd972 100644 --- a/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc +++ b/scripting/include/srccoop_api/classdef/common/CEnvScreenOverlay.inc @@ -1,14 +1,17 @@ #pragma newdecls required #pragma semicolon 1 -//stores active env_screenoverlay for certain player, the first element of the array is for global overlays -int g_iActiveScreenOverlayEntity[MAX_PLAYERS+1]; - -//stores next overlay will be played by env_screenoverlay for certain player -int g_iNextScreenOverlayIndex[MAX_PLAYERS+1]; - -//stores time value for every player to check if we want to start next overlay for certain player -float g_flNextOverlayTime[MAX_PLAYERS+1]; +#if defined SRCCOOP_BLACKMESA +int g_iActiveScreenOverlayEntity[33+1]; //stores active env_screenoverlay for certain player + //the first element of the array is for global overlays + +int g_iNextScreenOverlayIndex[33+1]; //stores next overlay will be played by env_screenoverlay for certain player +float g_flNextOverlayTime[33+1]; //stores time value for every player to check if we want to start next overlay for certain player +#else +int g_iActiveScreenOverlayEntity[101+1]; +int g_iNextScreenOverlayIndex[101+1]; +float g_flNextOverlayTime[101+1]; +#endif methodmap CEnvScreenOverlay < CBaseEntity { From 3af8f9370dedaabcbe1c850a022343e521360316 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:22:24 +0200 Subject: [PATCH 12/19] Update srccoop.inc --- scripting/include/srccoop.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index e3dcac3..9dc9673 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -24,6 +24,7 @@ #define ENTPATCH_POINT_SERVERCOMMAND_CHANGELEVEL #define ENTPATCH_ENV_ZOOM #define ENTPATCH_ENV_CREDITS + #define ENTPATCH_ENV_SCREENOVERLAY #define ENTPATCH_ENV_SPRITE #define ENTPATCH_AI_SCRIPT_CONDITIONS #define ENTPATCH_FUNC_ROTATING From cb78202ba7499bb224f7d5d6312a26608175d01d Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:22:52 +0200 Subject: [PATCH 13/19] Update srccoop.inc --- scripting/include/srccoop.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index 9dc9673..d5dcaa5 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -75,6 +75,7 @@ #define ENTPATCH_ENV_ZOOM #define ENTPATCH_ENV_CREDITS #define ENTPATCH_ENV_INTROCREDITS + #define ENTPATCH_ENV_SCREENOVERLAY #define ENTPATCH_ENV_SPRITE #define ENTPATCH_AI_SCRIPT_CONDITIONS #define ENTPATCH_LAGCOMP_POSE_PARAMS From 1447bbf610b6fad81b78296fc9e2b52a6121b513 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:24:22 +0200 Subject: [PATCH 14/19] Update playerpatch.inc --- scripting/include/srccoop/playerpatch.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 6c920ad..01069dc 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -647,9 +647,9 @@ public void PlayerPatch_OnClientDisconnect(CBasePlayer pPlayer) #if defined ENTPATCH_ENV_SCREENOVERLAY //disable screenoverlay for this client - g_iActiveScreenOverlayEntity[client] = 0; - g_iNextScreenOverlayIndex[client] = 0; - g_flNextOverlayTime[client] = 0.0; + g_iActiveScreenOverlayEntity[pPlayer.entindex] = 0; + g_iNextScreenOverlayIndex[pPlayer.entindex] = 0; + g_flNextOverlayTime[pPlayer.entindex] = 0.0; #endif } } From 6981ca4133a1abbb6dd1c615fecaa264ab919e4a Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:39:54 +0200 Subject: [PATCH 15/19] Update entitypatch.inc --- scripting/include/srccoop/entitypatch.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripting/include/srccoop/entitypatch.inc b/scripting/include/srccoop/entitypatch.inc index 0d1d60e..c5c2d05 100644 --- a/scripting/include/srccoop/entitypatch.inc +++ b/scripting/include/srccoop/entitypatch.inc @@ -945,7 +945,7 @@ public MRESReturn Hook_EnvScreenoverlayAcceptInput(int _this, DHookReturn hRetur //if other local screenoverlay is active - stop overlay for it before we use this entity if(pScreenOverlay.GetActiveStoredOverlay(pPlayer) != 0) { - AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlays"); + AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlays", pPlayer.entindex); } //send command to apply screen overlay @@ -1049,7 +1049,7 @@ public MRESReturn Hook_EnvScreenoverlayAcceptInput(int _this, DHookReturn hRetur // If another overlay is active, stop it first if (pScreenOverlay.GetActiveStoredOverlay(pPlayer) != 0) { - AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlaysForEveryone"); + AcceptEntityInput(pScreenOverlay.GetActiveStoredOverlay(pPlayer), "StopOverlaysForEveryone", pPlayer.entindex); } // Send overlay command From 1a12129d1d6258b91acec33ba7a9abf260618023 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:10:00 +0200 Subject: [PATCH 16/19] Replaced MAXPLAYERS with MAX_PLAYERS in playerpatch.inc --- scripting/include/srccoop/playerpatch.inc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 01069dc..69ee0a1 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -1,11 +1,11 @@ #pragma newdecls required #pragma semicolon 1 -static float g_vec3PlayerShootPosition[MAXPLAYERS + 1][3]; -static float g_flPlayerMaxSpeed[MAXPLAYERS + 1]; +static float g_vec3PlayerShootPosition[MAX_PLAYERS + 1][3]; +static float g_flPlayerMaxSpeed[MAX_PLAYERS + 1]; #if defined PLAYERPATCH_BM_CLIENT_PREDICTION -static bool g_bSetJumpModuleActive[MAXPLAYERS + 1]; +static bool g_bSetJumpModuleActive[MAX_PLAYERS + 1]; #endif //------------------------------------------------------ @@ -102,7 +102,7 @@ public void Hook_PlayerPreThinkPost(int iClient) CBlackMesaBaseCombatWeapon pWeapon = view_as(pPlayer.GetActiveWeapon()); if (pWeapon != NULL_CBASEENTITY) { - static bool g_bDisableAttack[MAXPLAYERS + 1]; + static bool g_bDisableAttack[MAX_PLAYERS + 1]; // Fixes prediction errors with weapons. bool bIsZooming = pPlayer.IsZooming(); @@ -305,10 +305,10 @@ public Action PlayerCommandListener(int client, const char[] command, int argc) //------------------------------------------------------ #if defined PLAYERPATCH_SUIT_SOUNDS -char szLastSuitSound[MAXPLAYERS+1][PLATFORM_MAX_PATH]; +char szLastSuitSound[MAX_PLAYERS+1][PLATFORM_MAX_PATH]; #endif -public Action PlayerSoundListener(int iClients[MAXPLAYERS], int& iNumClients, char szSample[PLATFORM_MAX_PATH], int& iEntIndex, int& iChannel, float& flVolume, int& iLevel, int& iPitch, int& iFlags, char szSoundEntry[PLATFORM_MAX_PATH], int& iSeed) +public Action PlayerSoundListener(int iClients[MAX_PLAYERS], int& iNumClients, char szSample[PLATFORM_MAX_PATH], int& iEntIndex, int& iChannel, float& flVolume, int& iLevel, int& iPitch, int& iFlags, char szSoundEntry[PLATFORM_MAX_PATH], int& iSeed) { #if defined PLAYERPATCH_SUIT_SOUNDS if (strncmp(szSample, "!HEV_", 5) == 0) @@ -532,7 +532,7 @@ public MRESReturn Hook_PlayerSpawnPost(int iClient, DHookReturn hReturn, DHookPa // - Force serverside ragdolls //------------------------------------------------------ #if defined PLAYERPATCH_SERVERSIDE_RAGDOLLS -bool g_bServerRagdoll[MAXPLAYERS + 1]; +bool g_bServerRagdoll[MAX_PLAYERS + 1]; #endif public MRESReturn Hook_PlayerKilled(int _this, DHookParam hParams) @@ -965,7 +965,7 @@ public void Movement_FindLadder(CBasePlayer pPlayer) // Detaches and stores player's equipped items. // Makes it possible to re-equip the player on potential revives. //------------------------------------------------------ -CCoopEquipment g_pPackedEquipment[MAXPLAYERS + 1]; +CCoopEquipment g_pPackedEquipment[MAX_PLAYERS + 1]; bool HasPackedItems(CBasePlayer pPlayer) { @@ -1156,7 +1156,7 @@ static void ClearNpcMemoryForPlayer(const CBasePlayer pPlayer) // If removing the player index was successful, this function returns `true`, modifies the array and adjusts `iNumClients`. // -stock bool RemovePlayerFromSoundListener(const int iClientIndex, int iClients[MAXPLAYERS], int& iNumClients) +stock bool RemovePlayerFromSoundListener(const int iClientIndex, int iClients[MAX_PLAYERS], int& iNumClients) { for (int i = 0; i < iNumClients; ++i) { From b080283c933c7d77c071e3ff31c7186039c47fbb Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:13:21 +0200 Subject: [PATCH 17/19] Update playerpatch.inc --- scripting/include/srccoop/playerpatch.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 69ee0a1..538dd50 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -308,7 +308,7 @@ public Action PlayerCommandListener(int client, const char[] command, int argc) char szLastSuitSound[MAX_PLAYERS+1][PLATFORM_MAX_PATH]; #endif -public Action PlayerSoundListener(int iClients[MAX_PLAYERS], int& iNumClients, char szSample[PLATFORM_MAX_PATH], int& iEntIndex, int& iChannel, float& flVolume, int& iLevel, int& iPitch, int& iFlags, char szSoundEntry[PLATFORM_MAX_PATH], int& iSeed) +public Action PlayerSoundListener(int iClients[MAXPLAYERS], int& iNumClients, char szSample[PLATFORM_MAX_PATH], int& iEntIndex, int& iChannel, float& flVolume, int& iLevel, int& iPitch, int& iFlags, char szSoundEntry[PLATFORM_MAX_PATH], int& iSeed) { #if defined PLAYERPATCH_SUIT_SOUNDS if (strncmp(szSample, "!HEV_", 5) == 0) From 6fe33dba50fcfedb7598be4be4d67e3e3870ad80 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:21:29 +0200 Subject: [PATCH 18/19] Update playerpatch.inc --- scripting/include/srccoop/playerpatch.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/include/srccoop/playerpatch.inc b/scripting/include/srccoop/playerpatch.inc index 538dd50..46d6b96 100644 --- a/scripting/include/srccoop/playerpatch.inc +++ b/scripting/include/srccoop/playerpatch.inc @@ -1156,7 +1156,7 @@ static void ClearNpcMemoryForPlayer(const CBasePlayer pPlayer) // If removing the player index was successful, this function returns `true`, modifies the array and adjusts `iNumClients`. // -stock bool RemovePlayerFromSoundListener(const int iClientIndex, int iClients[MAX_PLAYERS], int& iNumClients) +stock bool RemovePlayerFromSoundListener(const int iClientIndex, int iClients[MAXPLAYERS], int& iNumClients) { for (int i = 0; i < iNumClients; ++i) { From 7712d3f90c806c4602bd6763236578af285c5808 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Wed, 17 Dec 2025 19:24:24 +0200 Subject: [PATCH 19/19] Update entitypatch.inc Replaced MAXPLAYERS with MAX_PLAYERS --- scripting/include/srccoop/bms/entitypatch.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripting/include/srccoop/bms/entitypatch.inc b/scripting/include/srccoop/bms/entitypatch.inc index 078e1ac..695e7d4 100644 --- a/scripting/include/srccoop/bms/entitypatch.inc +++ b/scripting/include/srccoop/bms/entitypatch.inc @@ -3,7 +3,7 @@ // Patches for Black Mesa -static bool g_pPlayerIronsightClassic[MAXPLAYERS + 1]; +static bool g_pPlayerIronsightClassic[MAX_PLAYERS + 1]; //------------------------------------------------------ // CNPC_PlayerCompanion - npc_human_scientist*, npc_human_security @@ -353,7 +353,7 @@ public void Hook_XenTurretSpawnPost(int iEntIndex) // CMiscMarionettist - misc_marionettist // Prevent a crash due to reactivation before finishing or when used by multiple players at once //------------------------------------------------------ -CBaseEntity g_pActiveMarionettist[MAXPLAYERS+1] = {view_as(-1), ...}; +CBaseEntity g_pActiveMarionettist[MAX_PLAYERS+1] = {view_as(-1), ...}; public MRESReturn Hook_MarionettistAcceptInput(int _this, DHookReturn hReturn, DHookParam hParams) {