From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/trigger_portal.cpp | 684 +++++++++++++++++----------------- 1 file changed, 342 insertions(+), 342 deletions(-) (limited to 'mp/src/game/server/trigger_portal.cpp') diff --git a/mp/src/game/server/trigger_portal.cpp b/mp/src/game/server/trigger_portal.cpp index 5e7eb911..17508047 100644 --- a/mp/src/game/server/trigger_portal.cpp +++ b/mp/src/game/server/trigger_portal.cpp @@ -1,343 +1,343 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Entity which teleports touched entities and reorients their physics -// -//=============================================================================// - -#include "cbase.h" -#include "baseentity.h" -#include "triggers.h" -#include "modelentities.h" -#include "saverestore_utlvector.h" -#include "player_pickup.h" -#include "vphysics/friction.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define TRIGGER_DISABLED_THINK "PortalDisabledThink" - -ConVar portal_debug( "portal_debug", "0", FCVAR_CHEAT, "Turn on debugging for portal connections." ); - -////////////////////////////////////////////////////////////////////////// -// CTriggerPortal -// Moves touched entity to a target location, changing the model's orientation -// to match the exit target. It differs from CTriggerTeleport in that it -// reorients physics and has inputs to enable/disable its function. -////////////////////////////////////////////////////////////////////////// -class CTriggerPortal : public CBaseTrigger -{ -public: - DECLARE_DATADESC(); - DECLARE_CLASS( CTriggerPortal, CBaseTrigger ); - DECLARE_SERVERCLASS(); - - virtual void Spawn( void ); - virtual void Activate(); - - void Touch( CBaseEntity *pOther ); - void EndTouch(CBaseEntity *pOther); - void DisableForIncomingEntity( CBaseEntity *pEntity ); - bool IsTouchingPortal( CBaseEntity *pEntity ); - - void DisabledThink( void ); - - // TEMP: Since brushes have no directionality, give this wall a forward face specified in hammer - QAngle m_qFaceAngles; - -private: - string_t m_strRemotePortal; - CNetworkHandle( CTriggerPortal, m_hRemotePortal ); - CUtlVector m_hDisabledForEntities; - - // Input for setting remote portal entity (for teleporting to it) - void SetRemotePortal ( const char* strRemotePortalName ); - void InputSetRemotePortal ( inputdata_t &inputdata ); - -}; - -LINK_ENTITY_TO_CLASS( trigger_portal, CTriggerPortal ); - -BEGIN_DATADESC( CTriggerPortal ) - DEFINE_KEYFIELD( m_strRemotePortal, FIELD_STRING, "RemotePortal" ), - - DEFINE_FIELD( m_hRemotePortal, FIELD_EHANDLE ), - DEFINE_UTLVECTOR( m_hDisabledForEntities, FIELD_EHANDLE ), - - // TEMP: Only keep this field while portals are still brushes - DEFINE_FIELD( m_qFaceAngles, FIELD_VECTOR ), - - DEFINE_THINKFUNC( DisabledThink ), - - DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), - DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), - DEFINE_INPUTFUNC( FIELD_STRING, "SetRemotePortal", InputSetRemotePortal ), -END_DATADESC() - -IMPLEMENT_SERVERCLASS_ST( CTriggerPortal, DT_TriggerPortal ) - SendPropEHandle(SENDINFO(m_hRemotePortal)), -END_SEND_TABLE() - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTriggerPortal::Spawn( void ) -{ - BaseClass::Spawn(); - - InitTrigger(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : - -//----------------------------------------------------------------------------- -void CTriggerPortal::Activate() -{ - BaseClass::Activate(); - - m_qFaceAngles = this->GetAbsAngles(); - - // keep the remote portal's pointer at activate time to avoid redundant FindEntity calls - if ( m_strRemotePortal != NULL_STRING ) - { - SetRemotePortal( STRING(m_strRemotePortal) ); - m_strRemotePortal = NULL_STRING; - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : &inputdata - -//----------------------------------------------------------------------------- -void CTriggerPortal::InputSetRemotePortal(inputdata_t &inputdata ) -{ - SetRemotePortal( inputdata.value.String() ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : strRemotePortalName - -//----------------------------------------------------------------------------- -void CTriggerPortal::SetRemotePortal(const char *strRemotePortalName ) -{ - m_hRemotePortal = dynamic_cast (gEntList.FindEntityByName( NULL, strRemotePortalName, NULL, NULL, NULL )); - if ( m_hRemotePortal == NULL ) - { - Warning ( "trigger_portal: Cannot find remote portal entity named %s\n", strRemotePortalName ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pOther - -//----------------------------------------------------------------------------- -void CTriggerPortal::EndTouch(CBaseEntity *pOther) -{ - BaseClass::EndTouch(pOther); - - if ( portal_debug.GetBool() ) - { - Msg("%s ENDTOUCH: for %s\n", GetDebugName(), pOther->GetDebugName() ); - } - - EHANDLE hHandle; - hHandle = pOther; - m_hDisabledForEntities.FindAndRemove( hHandle ); -} - -//----------------------------------------------------------------------------- -// Purpose: Upon touching a non-filtered entity, CTriggerPortal teleports them to it's -// remote portal location. -// Input : *pOther - -//----------------------------------------------------------------------------- -void CTriggerPortal::Touch( CBaseEntity *pOther ) -{ - // If we are enabled, and allowed to react to the touched entity - if ( PassesTriggerFilters(pOther) ) - { - // If we somehow lost our pointer to the remote portal, get a new one - if ( m_hRemotePortal == NULL ) - { - Disable(); - return; - } - - bool bDebug = portal_debug.GetBool(); - if ( bDebug ) - { - Msg("%s TOUCH: for %s\n", GetDebugName(), pOther->GetDebugName() ); - } - - // Don't touch entities that came through us and haven't left us yet. - EHANDLE hHandle; - hHandle = pOther; - if ( m_hDisabledForEntities.Find(hHandle) != m_hDisabledForEntities.InvalidIndex() ) - { - Msg(" IGNORED\n", GetDebugName(), pOther->GetDebugName() ); - return; - } - - Pickup_ForcePlayerToDropThisObject( pOther ); - - // de-ground this entity - pOther->SetGroundEntity( NULL ); - - // Build a this --> remote transformation - VMatrix matMyModelToWorld, matMyInverse; - matMyModelToWorld = this->EntityToWorldTransform(); - MatrixInverseGeneral ( matMyModelToWorld, matMyInverse ); - - // Teleport our object - VMatrix matRemotePortalTransform = m_hRemotePortal->EntityToWorldTransform(); - Vector ptNewOrigin, vLook, vRight, vUp, vNewLook; - pOther->GetVectors( &vLook, &vRight, &vUp ); - - // Move origin - ptNewOrigin = matMyInverse * pOther->GetAbsOrigin(); - ptNewOrigin = matRemotePortalTransform * Vector( ptNewOrigin.x, -ptNewOrigin.y, ptNewOrigin.z ); - - // Re-aim camera - vNewLook = matMyInverse.ApplyRotation( vLook ); - vNewLook = matRemotePortalTransform.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z ) ); - - // Reorient the physics - Vector vVelocity, vOldVelocity; - pOther->GetVelocity( &vOldVelocity ); - vVelocity = matMyInverse.ApplyRotation( vOldVelocity ); - vVelocity = matRemotePortalTransform.ApplyRotation( Vector( -vVelocity.x, -vVelocity.y, vVelocity.z ) ); - - QAngle qNewAngles; - VectorAngles( vNewLook, qNewAngles ); - - if ( pOther->IsPlayer() ) - { - ((CBasePlayer*)pOther)->SnapEyeAngles(qNewAngles); - } - - Vector vecOldPos = pOther->WorldSpaceCenter(); - if ( bDebug ) - { - NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 255,0,0, 8, 20 ); - NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); - } - - // place player at the new destination - CTriggerPortal *pPortal = m_hRemotePortal.Get(); - pPortal->DisableForIncomingEntity( pOther ); - pOther->Teleport( &ptNewOrigin, &qNewAngles, &vVelocity ); - - if ( bDebug ) - { - NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 0,255,0, 8, 20 ); - NDebugOverlay::Line( vecOldPos, pOther->WorldSpaceCenter(), 0,255,0, true, 20 ); - NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); - - Msg("%s TELEPORTED: %s\n", GetDebugName(), pOther->GetDebugName() ); - } - - // test collision on the new teleport location - Vector vMin, vMax, vCenter; - pOther->CollisionProp()->WorldSpaceAABB( &vMin, &vMax ); - vCenter = (vMin + vMax) * 0.5f; - vMin -= vCenter; - vMax -= vCenter; - - Vector vStart, vEnd; - vStart = ptNewOrigin; - vEnd = ptNewOrigin; - - Ray_t ray; - ray.Init( vStart, vEnd, vMin, vMax ); - trace_t tr; - pPortal->TestCollision( ray, pOther->PhysicsSolidMaskForEntity(), tr ); - - // Teleportation caused us to hit something, deal with it. - if ( tr.DidHit() ) - { - - } - - - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTriggerPortal::DisableForIncomingEntity( CBaseEntity *pEntity ) -{ - EHANDLE hHandle; - hHandle = pEntity; - Assert( m_hDisabledForEntities.Find(hHandle) == m_hDisabledForEntities.InvalidIndex() ); - m_hDisabledForEntities.AddToTail( hHandle ); - - // Start thinking, and remove the other as soon as it's not touching me. - // Needs to be done in addition to EndTouch, because entities may move fast - // enough through the portal to come out not touching the other portal. - SetContextThink( DisabledThink, gpGlobals->curtime + 0.1, TRIGGER_DISABLED_THINK ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CTriggerPortal::DisabledThink( void ) -{ - // If we've got no disabled entities left, we're done - if ( !m_hDisabledForEntities.Count() ) - { - SetContextThink( NULL, gpGlobals->curtime, TRIGGER_DISABLED_THINK ); - return; - } - - for ( int i = m_hDisabledForEntities.Count()-1; i >= 0; i-- ) - { - CBaseEntity *pEntity = m_hDisabledForEntities[i]; - if ( !pEntity || !IsTouchingPortal(pEntity) ) - { - m_hDisabledForEntities.Remove(i); - } - } - - SetContextThink( DisabledThink, gpGlobals->curtime + 0.1, TRIGGER_DISABLED_THINK ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -bool CTriggerPortal::IsTouchingPortal( CBaseEntity *pEntity ) -{ - // First, check the touchlinks. This will find non-vphysics entities touching us - touchlink_t *root = ( touchlink_t * )GetDataObject( TOUCHLINK ); - if ( root ) - { - for ( touchlink_t *link = root->nextLink; link != root; link = link->nextLink ) - { - CBaseEntity *pTouch = link->entityTouched; - if ( pTouch == pEntity ) - return true; - } - } - - // Then check the friction snapshot. This will find vphysics objects touching us. - IPhysicsObject *pPhysics = VPhysicsGetObject(); - if ( !pPhysics ) - return false; - - IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot(); - bool bFound = false; - while ( pSnapshot->IsValid() ) - { - IPhysicsObject *pOther = pSnapshot->GetObject( 1 ); - if ( ((CBaseEntity *)pOther->GetGameData()) == pEntity ) - { - bFound = true; - break; - } - - pSnapshot->NextFrictionData(); - } - pPhysics->DestroyFrictionSnapshot( pSnapshot ); - - return bFound; +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Entity which teleports touched entities and reorients their physics +// +//=============================================================================// + +#include "cbase.h" +#include "baseentity.h" +#include "triggers.h" +#include "modelentities.h" +#include "saverestore_utlvector.h" +#include "player_pickup.h" +#include "vphysics/friction.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define TRIGGER_DISABLED_THINK "PortalDisabledThink" + +ConVar portal_debug( "portal_debug", "0", FCVAR_CHEAT, "Turn on debugging for portal connections." ); + +////////////////////////////////////////////////////////////////////////// +// CTriggerPortal +// Moves touched entity to a target location, changing the model's orientation +// to match the exit target. It differs from CTriggerTeleport in that it +// reorients physics and has inputs to enable/disable its function. +////////////////////////////////////////////////////////////////////////// +class CTriggerPortal : public CBaseTrigger +{ +public: + DECLARE_DATADESC(); + DECLARE_CLASS( CTriggerPortal, CBaseTrigger ); + DECLARE_SERVERCLASS(); + + virtual void Spawn( void ); + virtual void Activate(); + + void Touch( CBaseEntity *pOther ); + void EndTouch(CBaseEntity *pOther); + void DisableForIncomingEntity( CBaseEntity *pEntity ); + bool IsTouchingPortal( CBaseEntity *pEntity ); + + void DisabledThink( void ); + + // TEMP: Since brushes have no directionality, give this wall a forward face specified in hammer + QAngle m_qFaceAngles; + +private: + string_t m_strRemotePortal; + CNetworkHandle( CTriggerPortal, m_hRemotePortal ); + CUtlVector m_hDisabledForEntities; + + // Input for setting remote portal entity (for teleporting to it) + void SetRemotePortal ( const char* strRemotePortalName ); + void InputSetRemotePortal ( inputdata_t &inputdata ); + +}; + +LINK_ENTITY_TO_CLASS( trigger_portal, CTriggerPortal ); + +BEGIN_DATADESC( CTriggerPortal ) + DEFINE_KEYFIELD( m_strRemotePortal, FIELD_STRING, "RemotePortal" ), + + DEFINE_FIELD( m_hRemotePortal, FIELD_EHANDLE ), + DEFINE_UTLVECTOR( m_hDisabledForEntities, FIELD_EHANDLE ), + + // TEMP: Only keep this field while portals are still brushes + DEFINE_FIELD( m_qFaceAngles, FIELD_VECTOR ), + + DEFINE_THINKFUNC( DisabledThink ), + + DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ), + DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ), + DEFINE_INPUTFUNC( FIELD_STRING, "SetRemotePortal", InputSetRemotePortal ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CTriggerPortal, DT_TriggerPortal ) + SendPropEHandle(SENDINFO(m_hRemotePortal)), +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTriggerPortal::Spawn( void ) +{ + BaseClass::Spawn(); + + InitTrigger(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : - +//----------------------------------------------------------------------------- +void CTriggerPortal::Activate() +{ + BaseClass::Activate(); + + m_qFaceAngles = this->GetAbsAngles(); + + // keep the remote portal's pointer at activate time to avoid redundant FindEntity calls + if ( m_strRemotePortal != NULL_STRING ) + { + SetRemotePortal( STRING(m_strRemotePortal) ); + m_strRemotePortal = NULL_STRING; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &inputdata - +//----------------------------------------------------------------------------- +void CTriggerPortal::InputSetRemotePortal(inputdata_t &inputdata ) +{ + SetRemotePortal( inputdata.value.String() ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : strRemotePortalName - +//----------------------------------------------------------------------------- +void CTriggerPortal::SetRemotePortal(const char *strRemotePortalName ) +{ + m_hRemotePortal = dynamic_cast (gEntList.FindEntityByName( NULL, strRemotePortalName, NULL, NULL, NULL )); + if ( m_hRemotePortal == NULL ) + { + Warning ( "trigger_portal: Cannot find remote portal entity named %s\n", strRemotePortalName ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pOther - +//----------------------------------------------------------------------------- +void CTriggerPortal::EndTouch(CBaseEntity *pOther) +{ + BaseClass::EndTouch(pOther); + + if ( portal_debug.GetBool() ) + { + Msg("%s ENDTOUCH: for %s\n", GetDebugName(), pOther->GetDebugName() ); + } + + EHANDLE hHandle; + hHandle = pOther; + m_hDisabledForEntities.FindAndRemove( hHandle ); +} + +//----------------------------------------------------------------------------- +// Purpose: Upon touching a non-filtered entity, CTriggerPortal teleports them to it's +// remote portal location. +// Input : *pOther - +//----------------------------------------------------------------------------- +void CTriggerPortal::Touch( CBaseEntity *pOther ) +{ + // If we are enabled, and allowed to react to the touched entity + if ( PassesTriggerFilters(pOther) ) + { + // If we somehow lost our pointer to the remote portal, get a new one + if ( m_hRemotePortal == NULL ) + { + Disable(); + return; + } + + bool bDebug = portal_debug.GetBool(); + if ( bDebug ) + { + Msg("%s TOUCH: for %s\n", GetDebugName(), pOther->GetDebugName() ); + } + + // Don't touch entities that came through us and haven't left us yet. + EHANDLE hHandle; + hHandle = pOther; + if ( m_hDisabledForEntities.Find(hHandle) != m_hDisabledForEntities.InvalidIndex() ) + { + Msg(" IGNORED\n", GetDebugName(), pOther->GetDebugName() ); + return; + } + + Pickup_ForcePlayerToDropThisObject( pOther ); + + // de-ground this entity + pOther->SetGroundEntity( NULL ); + + // Build a this --> remote transformation + VMatrix matMyModelToWorld, matMyInverse; + matMyModelToWorld = this->EntityToWorldTransform(); + MatrixInverseGeneral ( matMyModelToWorld, matMyInverse ); + + // Teleport our object + VMatrix matRemotePortalTransform = m_hRemotePortal->EntityToWorldTransform(); + Vector ptNewOrigin, vLook, vRight, vUp, vNewLook; + pOther->GetVectors( &vLook, &vRight, &vUp ); + + // Move origin + ptNewOrigin = matMyInverse * pOther->GetAbsOrigin(); + ptNewOrigin = matRemotePortalTransform * Vector( ptNewOrigin.x, -ptNewOrigin.y, ptNewOrigin.z ); + + // Re-aim camera + vNewLook = matMyInverse.ApplyRotation( vLook ); + vNewLook = matRemotePortalTransform.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z ) ); + + // Reorient the physics + Vector vVelocity, vOldVelocity; + pOther->GetVelocity( &vOldVelocity ); + vVelocity = matMyInverse.ApplyRotation( vOldVelocity ); + vVelocity = matRemotePortalTransform.ApplyRotation( Vector( -vVelocity.x, -vVelocity.y, vVelocity.z ) ); + + QAngle qNewAngles; + VectorAngles( vNewLook, qNewAngles ); + + if ( pOther->IsPlayer() ) + { + ((CBasePlayer*)pOther)->SnapEyeAngles(qNewAngles); + } + + Vector vecOldPos = pOther->WorldSpaceCenter(); + if ( bDebug ) + { + NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 255,0,0, 8, 20 ); + NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); + } + + // place player at the new destination + CTriggerPortal *pPortal = m_hRemotePortal.Get(); + pPortal->DisableForIncomingEntity( pOther ); + pOther->Teleport( &ptNewOrigin, &qNewAngles, &vVelocity ); + + if ( bDebug ) + { + NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 0,255,0, 8, 20 ); + NDebugOverlay::Line( vecOldPos, pOther->WorldSpaceCenter(), 0,255,0, true, 20 ); + NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); + + Msg("%s TELEPORTED: %s\n", GetDebugName(), pOther->GetDebugName() ); + } + + // test collision on the new teleport location + Vector vMin, vMax, vCenter; + pOther->CollisionProp()->WorldSpaceAABB( &vMin, &vMax ); + vCenter = (vMin + vMax) * 0.5f; + vMin -= vCenter; + vMax -= vCenter; + + Vector vStart, vEnd; + vStart = ptNewOrigin; + vEnd = ptNewOrigin; + + Ray_t ray; + ray.Init( vStart, vEnd, vMin, vMax ); + trace_t tr; + pPortal->TestCollision( ray, pOther->PhysicsSolidMaskForEntity(), tr ); + + // Teleportation caused us to hit something, deal with it. + if ( tr.DidHit() ) + { + + } + + + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTriggerPortal::DisableForIncomingEntity( CBaseEntity *pEntity ) +{ + EHANDLE hHandle; + hHandle = pEntity; + Assert( m_hDisabledForEntities.Find(hHandle) == m_hDisabledForEntities.InvalidIndex() ); + m_hDisabledForEntities.AddToTail( hHandle ); + + // Start thinking, and remove the other as soon as it's not touching me. + // Needs to be done in addition to EndTouch, because entities may move fast + // enough through the portal to come out not touching the other portal. + SetContextThink( DisabledThink, gpGlobals->curtime + 0.1, TRIGGER_DISABLED_THINK ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTriggerPortal::DisabledThink( void ) +{ + // If we've got no disabled entities left, we're done + if ( !m_hDisabledForEntities.Count() ) + { + SetContextThink( NULL, gpGlobals->curtime, TRIGGER_DISABLED_THINK ); + return; + } + + for ( int i = m_hDisabledForEntities.Count()-1; i >= 0; i-- ) + { + CBaseEntity *pEntity = m_hDisabledForEntities[i]; + if ( !pEntity || !IsTouchingPortal(pEntity) ) + { + m_hDisabledForEntities.Remove(i); + } + } + + SetContextThink( DisabledThink, gpGlobals->curtime + 0.1, TRIGGER_DISABLED_THINK ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTriggerPortal::IsTouchingPortal( CBaseEntity *pEntity ) +{ + // First, check the touchlinks. This will find non-vphysics entities touching us + touchlink_t *root = ( touchlink_t * )GetDataObject( TOUCHLINK ); + if ( root ) + { + for ( touchlink_t *link = root->nextLink; link != root; link = link->nextLink ) + { + CBaseEntity *pTouch = link->entityTouched; + if ( pTouch == pEntity ) + return true; + } + } + + // Then check the friction snapshot. This will find vphysics objects touching us. + IPhysicsObject *pPhysics = VPhysicsGetObject(); + if ( !pPhysics ) + return false; + + IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot(); + bool bFound = false; + while ( pSnapshot->IsValid() ) + { + IPhysicsObject *pOther = pSnapshot->GetObject( 1 ); + if ( ((CBaseEntity *)pOther->GetGameData()) == pEntity ) + { + bFound = true; + break; + } + + pSnapshot->NextFrictionData(); + } + pPhysics->DestroyFrictionSnapshot( pSnapshot ); + + return bFound; } \ No newline at end of file -- cgit v1.2.3