Thread: CollisionHook
View Single Post
VoiDeD
AlliedModders Donor
Join Date: Mar 2009
Location: Illinois, USA
Old 10-08-2012 , 13:12   Re: CollisionHook
Reply With Quote #3

Quote:
Originally Posted by GoD-Tony View Post
Using this code for example:
PHP Code:
public Action:CH_PassFilterent1ent2, &bool:result )
{
    
// No client-client collisions
    
if (<= ent1 <= MaxClients && <= 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.
Interesting, in TF2 that code works as expected. The original purpose of the extension was to support a plugin I'm working on that controls precise player-player collision.

I haven't tested CS:S so I'm not sure why that would crash, but I'll check it out and see if anything can be salvaged.

Quote:
Originally Posted by GoD-Tony View Post
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.
That's a pretty good idea! I may rework the extension hook that function instead, as the extra info during collision checking would definitely be useful. Hooking that function also has the added benefit of handling any checks done in StandardFilterRules as well.

Also I'd make the assumption that most mods won't be touching CTraceFilterSimple, so the offsets to the members would likely be safe to get at.
__________________
VoiDeD is offline