Skip to content

Snarks enemy selection rework#358

Open
MyGamepedia wants to merge 16 commits intoampreeT:masterfrom
MyGamepedia:snark-team-fix
Open

Snarks enemy selection rework#358
MyGamepedia wants to merge 16 commits intoampreeT:masterfrom
MyGamepedia:snark-team-fix

Conversation

@MyGamepedia
Copy link
Copy Markdown
Contributor

Fixes #300
Replaces teamnum value to make IsValidEnemy() pass players even if mp_teamplay is enabled to make snarks aggressive to all players, just like in sp/dm. Filtered map-placed snarks for certain reasons.
Includes ENTPATCH_BM_SNARK macro.

@MyGamepedia
Copy link
Copy Markdown
Contributor Author

okay, this doesn't work somehow, i'll rework it.

@MyGamepedia
Copy link
Copy Markdown
Contributor Author

Turns out this needs to be done with a delay.

@ampreeT
Copy link
Copy Markdown
Owner

ampreeT commented Feb 22, 2026

Hey I don't think that implementing snark aggression against players is a good idea as it would be easier to grief (spawn, throw snarks, suicide, repeat). In fact, it may be better for snarks to ignore players/friendly npcs regardless of mp_teamplay and to instead use mp_friendlyfire to dictate snark aggression. @Alienmario wdyt?

@Alienmario
Copy link
Copy Markdown
Collaborator

Yeah, mp_friendlyfire makes sense here.

@MyGamepedia
Copy link
Copy Markdown
Contributor Author

Hey I don't think that implementing snark aggression against players is a good idea as it would be easier to grief (spawn, throw snarks, suicide, repeat). In fact, it may be better for snarks to ignore players/friendly npcs regardless of mp_teamplay and to instead use mp_friendlyfire to dictate snark aggression. @Alienmario wdyt?

good idea.

@MyGamepedia MyGamepedia changed the title Snarks not aggressive to players path for teamplay Snarks enemy selection rework Feb 23, 2026
- 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.
@MyGamepedia
Copy link
Copy Markdown
Contributor Author

Hey I don't think that implementing snark aggression against players is a good idea as it would be easier to grief (spawn, throw snarks, suicide, repeat). In fact, it may be better for snarks to ignore players/friendly npcs regardless of mp_teamplay and to instead use mp_friendlyfire to dictate snark aggression. @Alienmario wdyt?

Done in the way as described here. Guard and scientists still aren't happy to see player's snarks, but I guess it's fine ?

@MyGamepedia
Copy link
Copy Markdown
Contributor Author

I have working filter for ally NPCs now, the only issue is that they still can ask for help.

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
@MyGamepedia
Copy link
Copy Markdown
Contributor Author

No ally agro on snarks now, 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.

Copy link
Copy Markdown
Owner

@ampreeT ampreeT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on Linux Dedicated server. Implementation is working as described and looks good to me. Did you test on a Windows server?

Fix up the syntax/styling issues and we can get this merged in. Thanks!

CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1));

//not valid target
if (!pEnemy.IsValid())
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this line to if (pEnemy == NULL_CBASEENTITY)


if (strcmp(szClassname, "npc_snark") == 0)
{
CBasePlayer pOwner = CBasePlayer(CNpc_Snark(pEnemy.entindex).GetSnarkOwner());
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Methodmap function GetSnarkOwner currently returns int. It should return CBaseEntity. When that is fixed, change this line to:

CNpc_Snark pSnark = view_as<CNpc_Snark>(pEnemy);
CBaseEntity pOwner = pSnark.GetSnarkOwner();
... // cast to player if it is still needed after checking entity is valid player

//------------------------------------------------------
public void Hook_Snark_OnCreated(const int iEntIndex)
{
if (CBaseEntity(iEntIndex).GetHammerID() != 0) //don't for map-placed
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to:

CNpc_Snark pSnark = CNpc_Snark(iEntIndex);
if (pSnark.GetHammerID() != 0) //don't for map-placed

if (CBaseEntity(iEntIndex).GetHammerID() != 0) //don't for map-placed
return;

CBasePlayer pPlayer = CBasePlayer(CNpc_Snark(iEntIndex).GetSnarkOwner());
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to:

CBaseEntity pOwner = pSnark.GetSnarkOwner();
if (pOwner == NULL_CBASEENTITY || !pOwner.IsPlayer())
    return;
CBasePlayer pPlayer = view_as<CBasePlayer>(pOwner);

return;

int iTeam = (mp_friendlyfire.BoolValue) ? TEAM_ANY : pPlayer.GetTeam();
SetEntProp(iEntIndex, Prop_Data, "m_iInitialTeamNum", iTeam);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to:

pSnark.SetInitialTeam(iTeam);
pSnark.SetTeam(iTeam);

return MRES_Ignored;

CAI_BaseNPC pEnemy = CAI_BaseNPC(DHookGetParam(hParams, 1));
if (!pEnemy.IsValid())
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to:

if (pEnemy == NULL_CBASEENTITY)

return MRES_Ignored;

//guard is PROVOKED
if (HasEntProp(pEnemy.entindex, Prop_Data, "m_afMemory") && pEnemy.m_afMemory & bits_MEMORY_PROVOKED)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not familar with this implementation. What is the point of checking if the entity has the netprop m_afMemory?

SetEntPropFloat(this.entindex, Prop_Data, "m_fLifeTime", flLifeTime);
}

public int GetSnarkOwner()
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this so it returns CBaseEntity:

public CBaseEntity GetSnarkOwner()
{
	return CBaseEntity(GetEntPropEnt(this.entindex, Prop_Data, "m_hOwner"));
}

return GetEntPropEnt(this.entindex, Prop_Data, "m_hOwner");
}

public void SetSnarkOwner(int iEntIndex)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this:

public void SetSnarkOwner(const CBaseEntity pOwner)
{
	SetEntPropEnt(this.entindex, Prop_Data, "m_hOwner", pOwner.entindex);
}

Comment thread scripting/srccoop.sp
#if defined ENTPATCH_BM_SNARK
if (strcmp(szClassname, "npc_snark") == 0 && CoopManager.IsCoopModeEnabled())
{
RequestFrame(Hook_Snark_OnCreated, iEntIndex);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using RequestFrame, try using a post spawn hook here using SDKhooks

@MyGamepedia
Copy link
Copy Markdown
Contributor Author

Tested on Linux Dedicated server. Implementation is working as described and looks good to me. Did you test on a Windows server?

Fix up the syntax/styling issues and we can get this merged in. Thanks!

I gonna try to fix sec guard issue first once I can dedicate the time again, i have an idea.

It was tested with listening servers on Windows.

@MyGamepedia MyGamepedia requested a review from ampreeT March 29, 2026 09:12
@MyGamepedia
Copy link
Copy Markdown
Contributor Author

Found few issues.

@MyGamepedia MyGamepedia marked this pull request as draft March 30, 2026 12:19
- now friend players checked early by team
- not npc ents ignored
- added method description in gamedata
@MyGamepedia MyGamepedia marked this pull request as ready for review April 20, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reset npc_snark's teamnum via OnSpawnPost

3 participants