This is a neat idea! I tried something like this myself a while ago and ran into a few issues with a
PassServerEntityFilter detour.
Using this code for example:
PHP Code:
public Action:CH_PassFilter( ent1, ent2, &bool:result )
{
// No client-client collisions
if (1 <= ent1 <= MaxClients && 1 <= ent2 <= MaxClients)
{
result = false;
return Plugin_Handled;
}
return Plugin_Continue;
}
This is all on CS:S, and the code above seems to crash when shooting a player.
Normally it would prevent trace weapons from hitting any player target, because the player firing is passed as
pPass. So in order to differentiate player collision traces from the rest, I detoured
CTraceFilterSimple::ShouldHitEntity instead which provided
collisionGroup and
contentsMask.
Mine ended up looking like this:
(unreleased because I thought it was an ugly workaround)
Code:
DETOUR_DECL_MEMBER2(ShouldHitEntity, bool, IHandleEntity *, pHandleEntity, int, contentsMask)
{
IHandleEntity *m_pPassEnt = *(IHandleEntity **)((intptr_t)this + g_iPassEntOffs);
int m_collisionGroup = *(int *)((intptr_t)this + g_iCollisionOffs);
cell_t result = DETOUR_MEMBER_CALL(ShouldHitEntity)(pHandleEntity, contentsMask);
if (!pHandleEntity || !m_pPassEnt || pHandleEntity == m_pPassEnt)
return (result != 0);
cell_t touchEnt = gamehelpers->EntityToBCompatRef((CBaseEntity *)pHandleEntity);
cell_t passEnt = gamehelpers->EntityToBCompatRef((CBaseEntity *)m_pPassEnt);
g_pOnShouldCollide->PushCell(touchEnt);
g_pOnShouldCollide->PushCell(passEnt);
g_pOnShouldCollide->PushCell(m_collisionGroup);
g_pOnShouldCollide->PushCell(contentsMask);
g_pOnShouldCollide->PushCellByRef(&result);
g_pOnShouldCollide->Execute(NULL);
return (result != 0);
}
Then in the plugin if you only wanted to work with player collisions, you could check if contentsMask == MASK_PLAYERSOLID.
__________________