From 399c16a6f37b38e43a8ea86b0df17ec47e64b8e6 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:57:16 +0200 Subject: [PATCH 1/7] added snark team reset if mp_teamplay == 1 --- scripting/include/srccoop.inc | 1 + scripting/include/srccoop/bms/entitypatch.inc | 14 ++++++++++++++ scripting/srccoop.sp | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index b4988e92..7b8f3412 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -101,6 +101,7 @@ #define ENTPATCH_BM_GARGANTUA #define ENTPATCH_BM_PUFFBALLFUNGUS #define ENTPATCH_BM_MEDIC + #define ENTPATCH_BM_SNARK #define ENTPATCH_BM_LAV #define ENTPATCH_BM_TRIPMINE_COLORS #define ENTPATCH_BM_PROP_CHARGERS diff --git a/scripting/include/srccoop/bms/entitypatch.inc b/scripting/include/srccoop/bms/entitypatch.inc index 078e1ac8..e54664b0 100644 --- a/scripting/include/srccoop/bms/entitypatch.inc +++ b/scripting/include/srccoop/bms/entitypatch.inc @@ -187,6 +187,20 @@ public MRESReturn Hook_HumanMedicKilled(int _this, DHookParam hParams) return MRES_Ignored; } +//------------------------------------------------------ +// npc_snark +// Make snark aggressive to all players with mp_teamplay 1. +//------------------------------------------------------ +public void Hook_SnarkSpawnPost(const int iEntIndex) +{ + //let map-placed snarks to have any team the mapper want for mapper's goals + if (CoopManager.IsCoopModeEnabled() && CBaseEntity(iEntIndex).GetHammerID() == 0) + { + SetEntProp(iEntIndex, Prop_Data, "m_iInitialTeamNum", TEAM_ANY); + SetEntProp(iEntIndex, Prop_Data, "m_iTeamNum", TEAM_ANY); + } +} + //------------------------------------------------------ // CPropRadiationCharger - prop_radiation_charger // diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index b6064ba6..e61f8e84 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -720,6 +720,14 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) return; } #endif + + #if defined ENTPATCH_BM_SNARK + if (strcmp(szClassname, "npc_snark") == 0 && CMultiplayRules.IsTeamplay()) + { + SDKHook(iEntIndex, SDKHook_SpawnPost, Hook_SnarkSpawnPost); + return; + } + #endif } else // !isNPC { From 39e00463cba8ebf0b3a1049fb19c19a5ec1791fd Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:04:29 +0200 Subject: [PATCH 2/7] fixed (tested) --- scripting/include/srccoop/bms/entitypatch.inc | 6 +++--- scripting/srccoop.sp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripting/include/srccoop/bms/entitypatch.inc b/scripting/include/srccoop/bms/entitypatch.inc index e54664b0..03f2b3c4 100644 --- a/scripting/include/srccoop/bms/entitypatch.inc +++ b/scripting/include/srccoop/bms/entitypatch.inc @@ -191,10 +191,10 @@ public MRESReturn Hook_HumanMedicKilled(int _this, DHookParam hParams) // npc_snark // Make snark aggressive to all players with mp_teamplay 1. //------------------------------------------------------ -public void Hook_SnarkSpawnPost(const int iEntIndex) +public void Hook_Snark_OnCreated(const int iEntIndex) { - //let map-placed snarks to have any team the mapper want for mapper's goals - if (CoopManager.IsCoopModeEnabled() && CBaseEntity(iEntIndex).GetHammerID() == 0) + //NOTE: We let map-placed snarks to have any team the mapper want for mapper's goals + if (CBaseEntity(iEntIndex).GetHammerID() == 0) { SetEntProp(iEntIndex, Prop_Data, "m_iInitialTeamNum", TEAM_ANY); SetEntProp(iEntIndex, Prop_Data, "m_iTeamNum", TEAM_ANY); diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index e61f8e84..f270cbd3 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -722,9 +722,9 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) #endif #if defined ENTPATCH_BM_SNARK - if (strcmp(szClassname, "npc_snark") == 0 && CMultiplayRules.IsTeamplay()) + if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled() && CMultiplayRules.IsTeamplay()) { - SDKHook(iEntIndex, SDKHook_SpawnPost, Hook_SnarkSpawnPost); + RequestFrame(Hook_Snark_OnCreated, iEntIndex); return; } #endif From d72eadf65087ca2be0821ac9d6698e81bf2a4d01 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 24 Feb 2026 02:01:39 +0200 Subject: [PATCH 3/7] rework - Added hook for IsValidEnemy on snark to filter ally NPC and teammates. - Added IsPlayerAlly method for CAI_BaseNPC methodmap. - Added CNpc_Snark methodmap from necro_multipatch. --- gamedata/srccoop.games.txt | 19 +++++++ scripting/include/srccoop/bms/entitypatch.inc | 53 ++++++++++++++++--- scripting/include/srccoop/globals.inc | 4 ++ scripting/include/srccoop_api/classdef.inc | 1 + .../srccoop_api/classdef/bms/CNpc_Snark.inc | 34 ++++++++++++ .../classdef/common/CAI_BaseNPC.inc | 16 ++++++ scripting/srccoop.sp | 5 ++ 7 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 scripting/include/srccoop_api/classdef/bms/CNpc_Snark.inc diff --git a/gamedata/srccoop.games.txt b/gamedata/srccoop.games.txt index be2f8afa..dff401ae 100644 --- a/gamedata/srccoop.games.txt +++ b/gamedata/srccoop.games.txt @@ -174,6 +174,20 @@ } } } + "CAI_BaseNPC::IsValidEnemy" //bool CAI_BaseNPC::IsValidEnemy( CBaseEntity *pEnemy ) + { + "offset" "CAI_BaseNPC::IsValidEnemy" + "hooktype" "entity" + "return" "bool" + "this" "entity" + "arguments" + { + "pEnemy" + { + "type" "cbaseentity" + } + } + } "CAI_BaseNPC::IsNavigationUrgent" { "offset" "CAI_BaseNPC::IsNavigationUrgent" @@ -1357,6 +1371,11 @@ "windows" "445" "linux" "446" } + "CAI_BaseNPC::IsValidEnemy" // CAI_BaseNPC::IsValidEnemy(CBaseEntity*) + { + "windows" "434" + "linux" "435" + } "CAI_BaseNPC::IsNavigationUrgent" // CAI_BaseNPC::IsNavigationUrgent() { "windows" "482" diff --git a/scripting/include/srccoop/bms/entitypatch.inc b/scripting/include/srccoop/bms/entitypatch.inc index 03f2b3c4..f687e76a 100644 --- a/scripting/include/srccoop/bms/entitypatch.inc +++ b/scripting/include/srccoop/bms/entitypatch.inc @@ -189,16 +189,55 @@ public MRESReturn Hook_HumanMedicKilled(int _this, DHookParam hParams) //------------------------------------------------------ // npc_snark -// Make snark aggressive to all players with mp_teamplay 1. +// Set snark's team to make it evil or peaceful to the players. //------------------------------------------------------ public void Hook_Snark_OnCreated(const int iEntIndex) { - //NOTE: We let map-placed snarks to have any team the mapper want for mapper's goals - if (CBaseEntity(iEntIndex).GetHammerID() == 0) - { - SetEntProp(iEntIndex, Prop_Data, "m_iInitialTeamNum", TEAM_ANY); - SetEntProp(iEntIndex, Prop_Data, "m_iTeamNum", TEAM_ANY); - } + if (CBaseEntity(iEntIndex).GetHammerID() != 0) //don't for map-placed + return; + + CBasePlayer pPlayer = CBasePlayer(CNpc_Snark(iEntIndex).GetSnarkOwner()); + + //don't if i don't have any owner + if (!pPlayer.IsValid()) + return; + + int iTeam = (mp_friendlyfire.BoolValue) ? TEAM_ANY : pPlayer.GetTeam(); + SetEntProp(iEntIndex, Prop_Data, "m_iInitialTeamNum", iTeam); + SetEntProp(iEntIndex, Prop_Data, "m_iTeamNum", iTeam); +} + +//------------------------------------------------------ +// npc_snark +// Make snark owned by a player peaceful with mp_friendlyfire, filter players (by teamnum) and ally to owner NPCs +//------------------------------------------------------ +public MRESReturn Hook_SnarkIsValidEnemy(int _this, DHookReturn hReturn, DHookParam hParams) +{ + if (DHookIsNullParam(hParams, 1) || mp_friendlyfire.BoolValue) + return MRES_Ignored; + + + CBasePlayer pOwner = CBasePlayer(CNpc_Snark(_this).GetSnarkOwner()); + + //check if i have owner + if (!pOwner.IsValid()) + return MRES_Ignored; + + CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1)); + + //check if the targer plr/npc is valid for me + if (!pEnemy.IsValid()) + return MRES_Ignored; + + //check if in my owner's team or if is owner's ally + if (pEnemy.GetTeam() == pOwner.GetTeam() || pEnemy.IsPlayerAlly(pOwner)) + { + //not valid enemy + DHookSetReturn(hReturn, false); + return MRES_Supercede; + } + + return MRES_Ignored; } //------------------------------------------------------ diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index a2a6a762..c38da5d9 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -204,6 +204,10 @@ DynamicDetour hkTestGroundMove; DynamicDetour hkStartLagCompensation; #endif +#if defined ENTPATCH_BM_SNARK +DynamicHook hkIsBaseNPCIsValidEnemy; +#endif + // ---------------------------- // MemPatches // ---------------------------- diff --git a/scripting/include/srccoop_api/classdef.inc b/scripting/include/srccoop_api/classdef.inc index 5f855689..8d67181a 100644 --- a/scripting/include/srccoop_api/classdef.inc +++ b/scripting/include/srccoop_api/classdef.inc @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include diff --git a/scripting/include/srccoop_api/classdef/bms/CNpc_Snark.inc b/scripting/include/srccoop_api/classdef/bms/CNpc_Snark.inc new file mode 100644 index 00000000..87465696 --- /dev/null +++ b/scripting/include/srccoop_api/classdef/bms/CNpc_Snark.inc @@ -0,0 +1,34 @@ +#pragma newdecls required +#pragma semicolon 1 + +methodmap CNpc_Snark < CBaseCombatCharacter +{ + public CNpc_Snark(const int iEntIndex = -1) + { + return view_as(CBaseEntity(iEntIndex)); + } + public static CNpc_Snark Create() + { + return CNpc_Snark(CreateEntityByName("npc_snark")); + } + + public float GetLifeTime() + { + return GetEntPropFloat(this.entindex, Prop_Data, "m_fLifeTime"); + } + + public void SetLifeTime(const float flLifeTime) + { + SetEntPropFloat(this.entindex, Prop_Data, "m_fLifeTime", flLifeTime); + } + + public int GetSnarkOwner() + { + return GetEntPropEnt(this.entindex, Prop_Data, "m_hOwner"); + } + + public void SetSnarkOwner(int iEntIndex) + { + SetEntPropEnt(this.entindex, Prop_Data, "m_hOwner", iEntIndex); + } +} \ No newline at end of file diff --git a/scripting/include/srccoop_api/classdef/common/CAI_BaseNPC.inc b/scripting/include/srccoop_api/classdef/common/CAI_BaseNPC.inc index 4f928730..bd40a846 100644 --- a/scripting/include/srccoop_api/classdef/common/CAI_BaseNPC.inc +++ b/scripting/include/srccoop_api/classdef/common/CAI_BaseNPC.inc @@ -6,6 +6,7 @@ static Handle g_pGetSoundInterests; static Handle g_pHearingSensitivity; static Handle g_pUpdateEnemyMemory; static Handle g_pShouldPlayerAvoid; +static Handle g_pIsPlayerAlly; enum CAI_BaseNPC_SpawnFlags { @@ -100,6 +101,17 @@ methodmap CAI_BaseNPC < CBaseCombatCharacter PrepSDKCall_SetReturnInfo(SDKType_Bool, SDKPass_Plain); if (!(g_pShouldPlayerAvoid = EndPrepSDKCall())) SetFailState("Could not prep SDK call %s", szShouldPlayerAvoid); } + + char szIsPlayerAlly[] = "CAI_BaseNPC::IsPlayerAlly"; + StartPrepSDKCall(SDKCall_Entity); + if (!PrepSDKCall_SetFromConf(hGameConfig, SDKConf_Virtual, szIsPlayerAlly)) + LogMessage("Could not obtain gamedata offset %s", szIsPlayerAlly); + else + { + PrepSDKCall_SetReturnInfo(SDKType_Bool, SDKPass_Plain); + PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer); + if (!(g_pIsPlayerAlly = EndPrepSDKCall())) SetFailState("Could not prep SDK call %s", szIsPlayerAlly); + } } public CAI_BaseNPC(const int iEntIndex = -1) { @@ -136,6 +148,10 @@ methodmap CAI_BaseNPC < CBaseCombatCharacter { return GetEntProp(this.entindex, Prop_Data, "m_bInAScript") != 0; } + public bool IsPlayerAlly(const CBasePlayer pPlayer) + { + return SDKCall(g_pIsPlayerAlly, this, pPlayer); + } public bool IsSoundVisible(CSound pSound) { float vec3SoundReactOrigin[3]; diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index f270cbd3..4c2f1cbe 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -128,6 +128,10 @@ void LoadGameData() g_iUserCmdOffset = pGameConfig.GetOffset("CBasePlayer::GetCurrentUserCommand"); #endif + #if defined ENTPATCH_BM_SNARK + LoadDHookVirtual(pGameConfig_Srccoop, hkIsBaseNPCIsValidEnemy, "CAI_BaseNPC::IsValidEnemy"); + #endif + #if defined PLAYERPATCH_SUIT_SOUNDS LoadDHookDetour(pGameConfig, hkSetSuitUpdate, "CBasePlayer::SetSuitUpdate", Hook_SetSuitUpdate, Hook_SetSuitUpdatePost); #endif @@ -725,6 +729,7 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled() && CMultiplayRules.IsTeamplay()) { RequestFrame(Hook_Snark_OnCreated, iEntIndex); + DHookEntity(hkIsBaseNPCIsValidEnemy, false, iEntIndex, _, Hook_SnarkIsValidEnemy); return; } #endif From 1abaf5c0bceaccfe456138e06aee0a50f0e82f7d Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 24 Feb 2026 02:03:08 +0200 Subject: [PATCH 4/7] comp fix --- scripting/srccoop.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index 4c2f1cbe..60a97d27 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -129,7 +129,7 @@ void LoadGameData() #endif #if defined ENTPATCH_BM_SNARK - LoadDHookVirtual(pGameConfig_Srccoop, hkIsBaseNPCIsValidEnemy, "CAI_BaseNPC::IsValidEnemy"); + LoadDHookVirtual(pGameConfig, hkIsBaseNPCIsValidEnemy, "CAI_BaseNPC::IsValidEnemy"); #endif #if defined PLAYERPATCH_SUIT_SOUNDS From dcced24d01e59666a4efd5f084ff646e048cb993 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Tue, 24 Feb 2026 21:48:32 +0200 Subject: [PATCH 5/7] Update srccoop.sp --- scripting/srccoop.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index 60a97d27..a21d1f2d 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -726,7 +726,7 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) #endif #if defined ENTPATCH_BM_SNARK - if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled() && CMultiplayRules.IsTeamplay()) + if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled()) { RequestFrame(Hook_Snark_OnCreated, iEntIndex); DHookEntity(hkIsBaseNPCIsValidEnemy, false, iEntIndex, _, Hook_SnarkIsValidEnemy); From d47ae6fa2e9ab50021c8c57f43e2cd25e7c05759 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:57:27 +0200 Subject: [PATCH 6/7] now ally npcs will not attack snarks but security still asks for help due to how it's done in the code, i tried using SetReletationship input on snarks, but i still have to idea why it says that the syntax is incorrect --- scripting/include/srccoop/bms/entitypatch.inc | 104 +++++++++++++++--- scripting/include/srccoop/globals.inc | 2 +- scripting/srccoop.sp | 23 +--- 3 files changed, 97 insertions(+), 32 deletions(-) diff --git a/scripting/include/srccoop/bms/entitypatch.inc b/scripting/include/srccoop/bms/entitypatch.inc index f687e76a..163f30b3 100644 --- a/scripting/include/srccoop/bms/entitypatch.inc +++ b/scripting/include/srccoop/bms/entitypatch.inc @@ -48,6 +48,41 @@ public MRESReturn Hook_IsNavigationUrgent(int _this, DHookReturn hReturn, DHookP return MRES_Supercede; } +//------------------------------------------------------ +// CNPC_PlayerCompanion +// Ignore player's snarks without mp_friendlyfire unless this player is not my friend +//------------------------------------------------------ +public MRESReturn Hook_PlayerCompanionIsValidEnemy(int _this, DHookReturn hReturn, DHookParam hParams) +{ + if (DHookIsNullParam(hParams, 1) || mp_friendlyfire.BoolValue) + return MRES_Ignored; + + CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1)); + + //not valid target + if (!pEnemy.IsValid()) + return MRES_Ignored; + + char szClassname[MAX_CLASSNAME]; + pEnemy.GetClassname(szClassname, sizeof(szClassname)); + + if (strcmp(szClassname, "npc_snark") == 0) + { + CBasePlayer pOwner = CBasePlayer(CNpc_Snark(pEnemy.entindex).GetSnarkOwner()); + CAI_BaseNPC pThis = CAI_BaseNPC(_this); + + //not valid OR owner is not player (f. e. npc_maker) OR i don't like the player OR not player's snark + if (!pOwner.IsValid() || !pOwner.IsPlayer() || (pThis.m_afMemory & bits_MEMORY_PROVOKED || + pThis.IRelationType(pOwner) == D_HT) || pEnemy.GetTeam() != pOwner.GetTeam()) + return MRES_Ignored; + + DHookSetReturn(hReturn, false); + return MRES_Supercede; + } + + return MRES_Ignored; +} + //------------------------------------------------------ // CAI_BaseNPC - npc_lav // fixes the client crash seen in bm_c2a5g related to LAV npc @@ -209,30 +244,39 @@ public void Hook_Snark_OnCreated(const int iEntIndex) //------------------------------------------------------ // npc_snark -// Make snark owned by a player peaceful with mp_friendlyfire, filter players (by teamnum) and ally to owner NPCs +// Make snark owned by a player peaceful without mp_friendlyfire, filter players (by teamnum) and ally to owner NPCs //------------------------------------------------------ public MRESReturn Hook_SnarkIsValidEnemy(int _this, DHookReturn hReturn, DHookParam hParams) { - if (DHookIsNullParam(hParams, 1) || mp_friendlyfire.BoolValue) + if (DHookIsNullParam(hParams, 1) || mp_friendlyfire.BoolValue) + return MRES_Ignored; + + CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1)); + if (!pEnemy.IsValid()) return MRES_Ignored; - CBasePlayer pOwner = CBasePlayer(CNpc_Snark(_this).GetSnarkOwner()); - - //check if i have owner + + //not valid target if (!pOwner.IsValid()) return MRES_Ignored; - - CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1)); - - //check if the targer plr/npc is valid for me - if (!pEnemy.IsValid()) + + //guard is PROVOKED + if (HasEntProp(pEnemy.entindex, Prop_Data, "m_afMemory") && pEnemy.m_afMemory & bits_MEMORY_PROVOKED) + return MRES_Ignored; + + //target hates my owner + if (pEnemy.IRelationType(pOwner) == D_HT) return MRES_Ignored; + + //Is it owner's friend player ? + bool bIsAllyPlayer = (pEnemy.IsPlayer()) ? (pEnemy.GetTeam() == pOwner.GetTeam()) : false; + + //Does it targets my owner ? + bool bMyOwnerIsTargetEnemy = (HasEntProp(pEnemy.entindex, Prop_Data, "m_hEnemy")) ? (pEnemy.GetEnemy() == pOwner) : false; - //check if in my owner's team or if is owner's ally - if (pEnemy.GetTeam() == pOwner.GetTeam() || pEnemy.IsPlayerAlly(pOwner)) - { - //not valid enemy + if (bIsAllyPlayer || pEnemy.IsPlayerAlly(pOwner) || !bMyOwnerIsTargetEnemy) + { DHookSetReturn(hReturn, false); return MRES_Supercede; } @@ -240,6 +284,38 @@ public MRESReturn Hook_SnarkIsValidEnemy(int _this, DHookReturn hReturn, DHookPa return MRES_Ignored; } +//------------------------------------------------------ +// npc_snark +// Make everyone think i'm ally under certain conditions. +// TODO: Make sure it doesn't break anything. +//------------------------------------------------------ +public MRESReturn Hook_SnarkIsPlayerAlly(int _this, DHookReturn hReturn, DHookParam hParams) +{ + if (mp_friendlyfire.BoolValue || hParams.IsNull(1)) + return MRES_Ignored; + + CBlackMesaPlayer pPlayer = CBlackMesaPlayer(DHookGetParam(hParams, 1)); + + //not valid player + if (!pPlayer.IsValid()) + return MRES_Ignored; + + CBlackMesaPlayer pOwner = CBlackMesaPlayer(CNpc_Snark(_this).GetSnarkOwner()); + + //no valid owner + if (!pOwner.IsValid()) + return MRES_Ignored; + + //i'm ally if this player is my owner + if (pPlayer == pOwner) + { + DHookSetReturn(hReturn, true); + return MRES_Supercede; + } + + return MRES_Ignored; +} + //------------------------------------------------------ // CPropRadiationCharger - prop_radiation_charger // diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index c38da5d9..05faf4ee 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -205,7 +205,7 @@ DynamicDetour hkStartLagCompensation; #endif #if defined ENTPATCH_BM_SNARK -DynamicHook hkIsBaseNPCIsValidEnemy; +DynamicHook hkIsValidEnemy; #endif // ---------------------------- diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index a21d1f2d..e0d5b584 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -129,7 +129,7 @@ void LoadGameData() #endif #if defined ENTPATCH_BM_SNARK - LoadDHookVirtual(pGameConfig, hkIsBaseNPCIsValidEnemy, "CAI_BaseNPC::IsValidEnemy"); + LoadDHookVirtual(pGameConfig, hkIsValidEnemy, "CAI_BaseNPC::IsValidEnemy"); #endif #if defined PLAYERPATCH_SUIT_SOUNDS @@ -644,8 +644,8 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) #endif #if defined SRCCOOP_BLACKMESA - - if (strncmp(szClassname, "npc_human_scientist", 19) == 0) + if (strncmp(szClassname, "npc_human_scientist", 19) == 0 || strcmp(szClassname, "npc_human_security") == 0 || + strcmp(szClassname, "npc_human_eli") == 0 || strcmp(szClassname, "npc_human_kleiner") == 0 || strcmp(szClassname, "npc_gman") == 0) { #if defined ENTPATCH_PLAYER_ALLY DHookEntity(hkIsPlayerAlly, false, iEntIndex, _, Hook_IsPlayerAlly); @@ -655,24 +655,12 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) DHookEntity(hkIsNavigationUrgent, false, iEntIndex, _, Hook_IsNavigationUrgent); #endif - return; - } - - #if defined ENTPATCH_PLAYER_ALLY - if (strcmp(szClassname, "npc_human_security") == 0) - { - #if defined ENTPATCH_PLAYER_ALLY - DHookEntity(hkIsPlayerAlly, false, iEntIndex, _, Hook_IsPlayerAlly); - #endif - - #if defined ENTPATCH_NAVIGATION_URGENT - DHookEntity(hkIsNavigationUrgent, false, iEntIndex, _, Hook_IsNavigationUrgent); + #if defined ENTPATCH_BM_SNARK + DHookEntity(hkIsValidEnemy, false, iEntIndex, _, Hook_PlayerCompanionIsValidEnemy); #endif return; } - #endif - #endif // SRCCOOP_BLACKMESA #if defined ENTPATCH_BM_XENTURRET @@ -730,6 +718,7 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) { RequestFrame(Hook_Snark_OnCreated, iEntIndex); DHookEntity(hkIsBaseNPCIsValidEnemy, false, iEntIndex, _, Hook_SnarkIsValidEnemy); + DHookEntity(hkIsPlayerAlly, false, iEntIndex, _, Hook_SnarkIsPlayerAlly); return; } #endif From 3d8d5b2a82cc4bd678630d0606bd2e6ae68b0667 Mon Sep 17 00:00:00 2001 From: "MyGamepedia (Sorry For My English)" <103366204+MyGamepedia@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:58:29 +0200 Subject: [PATCH 7/7] Update srccoop.sp --- scripting/srccoop.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index e0d5b584..1a30c5a1 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -717,7 +717,7 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname) if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled()) { RequestFrame(Hook_Snark_OnCreated, iEntIndex); - DHookEntity(hkIsBaseNPCIsValidEnemy, false, iEntIndex, _, Hook_SnarkIsValidEnemy); + DHookEntity(hkIsValidEnemy, false, iEntIndex, _, Hook_SnarkIsValidEnemy); DHookEntity(hkIsPlayerAlly, false, iEntIndex, _, Hook_SnarkIsPlayerAlly); return; }