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/shared/obstacle_pushaway.cpp | 670 +++++++++++++++---------------- 1 file changed, 335 insertions(+), 335 deletions(-) (limited to 'mp/src/game/shared/obstacle_pushaway.cpp') diff --git a/mp/src/game/shared/obstacle_pushaway.cpp b/mp/src/game/shared/obstacle_pushaway.cpp index 043c1773..35fef4ad 100644 --- a/mp/src/game/shared/obstacle_pushaway.cpp +++ b/mp/src/game/shared/obstacle_pushaway.cpp @@ -1,335 +1,335 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "cbase.h" -#include "obstacle_pushaway.h" -#include "props_shared.h" - -#if defined( CSTRIKE_DLL ) -#define SV_PUSH_CONVAR_FLAGS (FCVAR_REPLICATED) -#else -#define SV_PUSH_CONVAR_FLAGS (FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY) -#endif // CSTRIKE_DLL - -//----------------------------------------------------------------------------------------------------- -ConVar sv_pushaway_force( "sv_pushaway_force", "30000", SV_PUSH_CONVAR_FLAGS, "How hard physics objects are pushed away from the players on the server." ); -ConVar sv_pushaway_min_player_speed( "sv_pushaway_min_player_speed", "75", SV_PUSH_CONVAR_FLAGS, "If a player is moving slower than this, don't push away physics objects (enables ducking behind things)." ); -ConVar sv_pushaway_max_force( "sv_pushaway_max_force", "1000", SV_PUSH_CONVAR_FLAGS, "Maximum amount of force applied to physics objects by players." ); -ConVar sv_pushaway_clientside( "sv_pushaway_clientside", "0", SV_PUSH_CONVAR_FLAGS, "Clientside physics push away (0=off, 1=only localplayer, 1=all players)" ); - -ConVar sv_pushaway_player_force( "sv_pushaway_player_force", "200000", SV_PUSH_CONVAR_FLAGS | FCVAR_CHEAT, "How hard the player is pushed away from physics objects (falls off with inverse square of distance)." ); -ConVar sv_pushaway_max_player_force( "sv_pushaway_max_player_force", "10000", SV_PUSH_CONVAR_FLAGS | FCVAR_CHEAT, "Maximum of how hard the player is pushed away from physics objects." ); - -#ifdef CLIENT_DLL -ConVar sv_turbophysics( "sv_turbophysics", "0", FCVAR_REPLICATED, "Turns on turbo physics" ); -#else -extern ConVar sv_turbophysics; -#endif - -//----------------------------------------------------------------------------------------------------- -bool IsPushAwayEntity( CBaseEntity *pEnt ) -{ - if ( pEnt == NULL ) - return false; - - if ( pEnt->GetCollisionGroup() != COLLISION_GROUP_PUSHAWAY ) - { - // Try backing away from doors that are currently rotating, to prevent blocking them -#ifndef CLIENT_DLL - if ( FClassnameIs( pEnt, "func_door_rotating" ) ) - { - CBaseDoor *door = dynamic_cast(pEnt); - if ( !door ) - { - return false; - } - - if ( door->m_toggle_state != TS_GOING_UP && door->m_toggle_state != TS_GOING_DOWN ) - { - return false; - } - } - else if ( FClassnameIs( pEnt, "prop_door_rotating" ) ) - { - CBasePropDoor *door = dynamic_cast(pEnt); - if ( !door ) - { - return false; - } - - if ( !door->IsDoorOpening() && !door->IsDoorClosing() ) - { - return false; - } - } - else -#endif // !CLIENT_DLL - { - return false; - } - } - - return true; -} - -//----------------------------------------------------------------------------------------------------- -bool IsPushableEntity( CBaseEntity *pEnt ) -{ - if ( pEnt == NULL ) - return false; - - if ( sv_turbophysics.GetBool() ) - { - if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_NONE ) - { -#ifdef CLIENT_DLL - if ( FClassnameIs( pEnt, "class CPhysicsPropMultiplayer" ) ) -#else - if ( FClassnameIs( pEnt, "prop_physics_multiplayer" ) ) -#endif // CLIENT_DLL - { - return true; - } - } - } - - return false; -} - -//----------------------------------------------------------------------------------------------------- -#ifndef CLIENT_DLL -bool IsBreakableEntity( CBaseEntity *pEnt ) -{ - if ( pEnt == NULL ) - return false; - - // If we won't be able to break it, don't try - if ( pEnt->m_takedamage != DAMAGE_YES ) - return false; - - if ( pEnt->GetCollisionGroup() != COLLISION_GROUP_PUSHAWAY && pEnt->GetCollisionGroup() != COLLISION_GROUP_BREAKABLE_GLASS && pEnt->GetCollisionGroup() != COLLISION_GROUP_NONE ) - return false; - - if ( pEnt->m_iHealth > 200 ) - return false; - - IMultiplayerPhysics *pPhysicsInterface = dynamic_cast< IMultiplayerPhysics * >( pEnt ); - if ( pPhysicsInterface ) - { - if ( pPhysicsInterface->GetMultiplayerPhysicsMode() != PHYSICS_MULTIPLAYER_SOLID ) - return false; - } - else - { - if ((FClassnameIs( pEnt, "func_breakable" ) || FClassnameIs( pEnt, "func_breakable_surf" ))) - { - if (FClassnameIs( pEnt, "func_breakable_surf" )) - { - // don't try to break it if it has already been broken - CBreakableSurface *surf = static_cast< CBreakableSurface * >( pEnt ); - - if ( surf->m_bIsBroken ) - return false; - } - } - else if ( pEnt->PhysicsSolidMaskForEntity() & CONTENTS_PLAYERCLIP ) - { - // hostages and players use CONTENTS_PLAYERCLIP, so we can use it to ignore them - return false; - } - } - - IBreakableWithPropData *pBreakableInterface = dynamic_cast< IBreakableWithPropData * >( pEnt ); - if ( pBreakableInterface ) - { - // Bullets don't damage it - ignore - if ( pBreakableInterface->GetDmgModBullet() <= 0.0f ) - { - return false; - } - } - - CBreakableProp *pProp = dynamic_cast< CBreakableProp * >( pEnt ); - if ( pProp ) - { - // It takes a large amount of damage to even scratch it - ignore - if ( pProp->m_iMinHealthDmg >= 50 ) - { - return false; - } - } - - return true; -} -#endif // !CLIENT_DLL - -//----------------------------------------------------------------------------------------------------- -int GetPushawayEnts( CBaseCombatCharacter *pPushingEntity, CBaseEntity **ents, int nMaxEnts, float flPlayerExpand, int PartitionMask, CPushAwayEnumerator *enumerator ) -{ - - Vector vExpand( flPlayerExpand, flPlayerExpand, flPlayerExpand ); - - Ray_t ray; - ray.Init( pPushingEntity->GetAbsOrigin(), pPushingEntity->GetAbsOrigin(), pPushingEntity->GetCollideable()->OBBMins() - vExpand, pPushingEntity->GetCollideable()->OBBMaxs() + vExpand ); - - CPushAwayEnumerator *physPropEnum = NULL; - if ( !enumerator ) - { - physPropEnum = new CPushAwayEnumerator( ents, nMaxEnts ); - enumerator = physPropEnum; - } - - partition->EnumerateElementsAlongRay( PartitionMask, ray, false, enumerator ); - - int numHit = enumerator->m_nAlreadyHit; - - if ( physPropEnum ) - delete physPropEnum; - - return numHit; -} - -void AvoidPushawayProps( CBaseCombatCharacter *pPlayer, CUserCmd *pCmd ) -{ - // Figure out what direction we're moving and the extents of the box we're going to sweep - // against physics objects. - Vector currentdir; - Vector rightdir; - AngleVectors( pCmd->viewangles, ¤tdir, &rightdir, NULL ); - - CBaseEntity *props[512]; -#ifdef CLIENT_DLL - int nEnts = GetPushawayEnts( pPlayer, props, ARRAYSIZE( props ), 0.0f, PARTITION_CLIENT_SOLID_EDICTS, NULL ); -#else - int nEnts = GetPushawayEnts( pPlayer, props, ARRAYSIZE( props ), 0.0f, PARTITION_ENGINE_SOLID_EDICTS, NULL ); -#endif - - const Vector & ourCenter = pPlayer->WorldSpaceCenter(); - Vector nearestPropPoint; - Vector nearestPlayerPoint; - - for ( int i=0; i < nEnts; i++ ) - { - // Don't respond to this entity on the client unless it has PHYSICS_MULTIPLAYER_FULL set. - IMultiplayerPhysics *pInterface = dynamic_cast( props[i] ); - if ( pInterface && pInterface->GetMultiplayerPhysicsMode() != PHYSICS_MULTIPLAYER_SOLID ) - continue; - - const float minMass = 10.0f; // minimum mass that can push a player back - const float maxMass = 30.0f; // cap at a decently large value - float mass = maxMass; - if ( pInterface ) - { - mass = pInterface->GetMass(); - } - mass = clamp( mass, minMass, maxMass ); - - mass = MAX( mass, 0 ); - mass /= maxMass; // bring into a 0..1 range - - // Push away from the collision point. The closer our center is to the collision point, - // the harder we push away. - props[i]->CollisionProp()->CalcNearestPoint( ourCenter, &nearestPropPoint ); - pPlayer->CollisionProp()->CalcNearestPoint( nearestPropPoint, &nearestPlayerPoint ); - Vector vPushAway = (nearestPlayerPoint - nearestPropPoint); - float flDist = VectorNormalize( vPushAway ); - - const float MaxPushawayDistance = 5.0f; - if ( flDist > MaxPushawayDistance && !pPlayer->CollisionProp()->IsPointInBounds( nearestPropPoint ) ) - { - continue; - } - - // If we're not pushing, try from our center to the nearest edge of the prop - if ( vPushAway.IsZero() ) - { - vPushAway = (ourCenter - nearestPropPoint); - flDist = VectorNormalize( vPushAway ); - } - - // If we're still not pushing, try from our center to the center of the prop - if ( vPushAway.IsZero() ) - { - vPushAway = (ourCenter - props[i]->WorldSpaceCenter()); - flDist = VectorNormalize( vPushAway ); - } - - flDist = MAX( flDist, 1 ); - - float flForce = sv_pushaway_player_force.GetFloat() / flDist * mass; - flForce = MIN( flForce, sv_pushaway_max_player_force.GetFloat() ); - -#ifndef CLIENT_DLL - pPlayer->PushawayTouch( props[i] ); - - // We can get right up next to rotating doors before they start to move, so scale back our force so we don't go flying - if ( FClassnameIs( props[i], "func_door_rotating" ) || FClassnameIs( props[i], "prop_door_rotating" ) ) -#endif - { - flForce *= 0.25f; - } - - vPushAway *= flForce; - - pCmd->forwardmove += vPushAway.Dot( currentdir ); - pCmd->sidemove += vPushAway.Dot( rightdir ); - } -} - -//----------------------------------------------------------------------------------------------------- -void PerformObstaclePushaway( CBaseCombatCharacter *pPushingEntity ) -{ - if ( pPushingEntity->m_lifeState != LIFE_ALIVE ) - return; - - // Give a push to any barrels that we're touching. - // The client handles adjusting our usercmd to push us away. - CBaseEntity *props[256]; - -#ifdef CLIENT_DLL - // if sv_pushaway_clientside is disabled, clientside phys objects don't bounce away - if ( sv_pushaway_clientside.GetInt() == 0 ) - return; - - // if sv_pushaway_clientside is 1, only local player can push them - CBasePlayer *pPlayer = pPushingEntity->IsPlayer() ? (dynamic_cast< CBasePlayer * >(pPushingEntity)) : NULL; - if ( (sv_pushaway_clientside.GetInt() == 1) && (!pPlayer || !pPlayer->IsLocalPlayer()) ) - return; - - int nEnts = GetPushawayEnts( pPushingEntity, props, ARRAYSIZE( props ), 3.0f, PARTITION_CLIENT_RESPONSIVE_EDICTS, NULL ); -#else - int nEnts = GetPushawayEnts( pPushingEntity, props, ARRAYSIZE( props ), 3.0f, PARTITION_ENGINE_SOLID_EDICTS, NULL ); -#endif - - for ( int i=0; i < nEnts; i++ ) - { - // If this entity uas PHYSICS_MULTIPLAYER_FULL set (ie: it's not just debris), and we're moving too slow, don't push it away. - // Instead, let the client bounce off it. This allows players to get close to and duck behind things without knocking them over. - IMultiplayerPhysics *pInterface = dynamic_cast( props[i] ); - - if ( pInterface && pInterface->GetMultiplayerPhysicsMode() == PHYSICS_MULTIPLAYER_SOLID ) - { - if ( pPushingEntity->GetAbsVelocity().Length2D() < sv_pushaway_min_player_speed.GetFloat() ) - continue; - } - - IPhysicsObject *pObj = props[i]->VPhysicsGetObject(); - - if ( pObj ) - { - Vector vPushAway = (props[i]->WorldSpaceCenter() - pPushingEntity->WorldSpaceCenter()); - vPushAway.z = 0; - - float flDist = VectorNormalize( vPushAway ); - flDist = MAX( flDist, 1 ); - - float flForce = sv_pushaway_force.GetFloat() / flDist; - flForce = MIN( flForce, sv_pushaway_max_force.GetFloat() ); - - pObj->ApplyForceOffset( vPushAway * flForce, pPushingEntity->WorldSpaceCenter() ); - } - } -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "obstacle_pushaway.h" +#include "props_shared.h" + +#if defined( CSTRIKE_DLL ) +#define SV_PUSH_CONVAR_FLAGS (FCVAR_REPLICATED) +#else +#define SV_PUSH_CONVAR_FLAGS (FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY) +#endif // CSTRIKE_DLL + +//----------------------------------------------------------------------------------------------------- +ConVar sv_pushaway_force( "sv_pushaway_force", "30000", SV_PUSH_CONVAR_FLAGS, "How hard physics objects are pushed away from the players on the server." ); +ConVar sv_pushaway_min_player_speed( "sv_pushaway_min_player_speed", "75", SV_PUSH_CONVAR_FLAGS, "If a player is moving slower than this, don't push away physics objects (enables ducking behind things)." ); +ConVar sv_pushaway_max_force( "sv_pushaway_max_force", "1000", SV_PUSH_CONVAR_FLAGS, "Maximum amount of force applied to physics objects by players." ); +ConVar sv_pushaway_clientside( "sv_pushaway_clientside", "0", SV_PUSH_CONVAR_FLAGS, "Clientside physics push away (0=off, 1=only localplayer, 1=all players)" ); + +ConVar sv_pushaway_player_force( "sv_pushaway_player_force", "200000", SV_PUSH_CONVAR_FLAGS | FCVAR_CHEAT, "How hard the player is pushed away from physics objects (falls off with inverse square of distance)." ); +ConVar sv_pushaway_max_player_force( "sv_pushaway_max_player_force", "10000", SV_PUSH_CONVAR_FLAGS | FCVAR_CHEAT, "Maximum of how hard the player is pushed away from physics objects." ); + +#ifdef CLIENT_DLL +ConVar sv_turbophysics( "sv_turbophysics", "0", FCVAR_REPLICATED, "Turns on turbo physics" ); +#else +extern ConVar sv_turbophysics; +#endif + +//----------------------------------------------------------------------------------------------------- +bool IsPushAwayEntity( CBaseEntity *pEnt ) +{ + if ( pEnt == NULL ) + return false; + + if ( pEnt->GetCollisionGroup() != COLLISION_GROUP_PUSHAWAY ) + { + // Try backing away from doors that are currently rotating, to prevent blocking them +#ifndef CLIENT_DLL + if ( FClassnameIs( pEnt, "func_door_rotating" ) ) + { + CBaseDoor *door = dynamic_cast(pEnt); + if ( !door ) + { + return false; + } + + if ( door->m_toggle_state != TS_GOING_UP && door->m_toggle_state != TS_GOING_DOWN ) + { + return false; + } + } + else if ( FClassnameIs( pEnt, "prop_door_rotating" ) ) + { + CBasePropDoor *door = dynamic_cast(pEnt); + if ( !door ) + { + return false; + } + + if ( !door->IsDoorOpening() && !door->IsDoorClosing() ) + { + return false; + } + } + else +#endif // !CLIENT_DLL + { + return false; + } + } + + return true; +} + +//----------------------------------------------------------------------------------------------------- +bool IsPushableEntity( CBaseEntity *pEnt ) +{ + if ( pEnt == NULL ) + return false; + + if ( sv_turbophysics.GetBool() ) + { + if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_NONE ) + { +#ifdef CLIENT_DLL + if ( FClassnameIs( pEnt, "class CPhysicsPropMultiplayer" ) ) +#else + if ( FClassnameIs( pEnt, "prop_physics_multiplayer" ) ) +#endif // CLIENT_DLL + { + return true; + } + } + } + + return false; +} + +//----------------------------------------------------------------------------------------------------- +#ifndef CLIENT_DLL +bool IsBreakableEntity( CBaseEntity *pEnt ) +{ + if ( pEnt == NULL ) + return false; + + // If we won't be able to break it, don't try + if ( pEnt->m_takedamage != DAMAGE_YES ) + return false; + + if ( pEnt->GetCollisionGroup() != COLLISION_GROUP_PUSHAWAY && pEnt->GetCollisionGroup() != COLLISION_GROUP_BREAKABLE_GLASS && pEnt->GetCollisionGroup() != COLLISION_GROUP_NONE ) + return false; + + if ( pEnt->m_iHealth > 200 ) + return false; + + IMultiplayerPhysics *pPhysicsInterface = dynamic_cast< IMultiplayerPhysics * >( pEnt ); + if ( pPhysicsInterface ) + { + if ( pPhysicsInterface->GetMultiplayerPhysicsMode() != PHYSICS_MULTIPLAYER_SOLID ) + return false; + } + else + { + if ((FClassnameIs( pEnt, "func_breakable" ) || FClassnameIs( pEnt, "func_breakable_surf" ))) + { + if (FClassnameIs( pEnt, "func_breakable_surf" )) + { + // don't try to break it if it has already been broken + CBreakableSurface *surf = static_cast< CBreakableSurface * >( pEnt ); + + if ( surf->m_bIsBroken ) + return false; + } + } + else if ( pEnt->PhysicsSolidMaskForEntity() & CONTENTS_PLAYERCLIP ) + { + // hostages and players use CONTENTS_PLAYERCLIP, so we can use it to ignore them + return false; + } + } + + IBreakableWithPropData *pBreakableInterface = dynamic_cast< IBreakableWithPropData * >( pEnt ); + if ( pBreakableInterface ) + { + // Bullets don't damage it - ignore + if ( pBreakableInterface->GetDmgModBullet() <= 0.0f ) + { + return false; + } + } + + CBreakableProp *pProp = dynamic_cast< CBreakableProp * >( pEnt ); + if ( pProp ) + { + // It takes a large amount of damage to even scratch it - ignore + if ( pProp->m_iMinHealthDmg >= 50 ) + { + return false; + } + } + + return true; +} +#endif // !CLIENT_DLL + +//----------------------------------------------------------------------------------------------------- +int GetPushawayEnts( CBaseCombatCharacter *pPushingEntity, CBaseEntity **ents, int nMaxEnts, float flPlayerExpand, int PartitionMask, CPushAwayEnumerator *enumerator ) +{ + + Vector vExpand( flPlayerExpand, flPlayerExpand, flPlayerExpand ); + + Ray_t ray; + ray.Init( pPushingEntity->GetAbsOrigin(), pPushingEntity->GetAbsOrigin(), pPushingEntity->GetCollideable()->OBBMins() - vExpand, pPushingEntity->GetCollideable()->OBBMaxs() + vExpand ); + + CPushAwayEnumerator *physPropEnum = NULL; + if ( !enumerator ) + { + physPropEnum = new CPushAwayEnumerator( ents, nMaxEnts ); + enumerator = physPropEnum; + } + + partition->EnumerateElementsAlongRay( PartitionMask, ray, false, enumerator ); + + int numHit = enumerator->m_nAlreadyHit; + + if ( physPropEnum ) + delete physPropEnum; + + return numHit; +} + +void AvoidPushawayProps( CBaseCombatCharacter *pPlayer, CUserCmd *pCmd ) +{ + // Figure out what direction we're moving and the extents of the box we're going to sweep + // against physics objects. + Vector currentdir; + Vector rightdir; + AngleVectors( pCmd->viewangles, ¤tdir, &rightdir, NULL ); + + CBaseEntity *props[512]; +#ifdef CLIENT_DLL + int nEnts = GetPushawayEnts( pPlayer, props, ARRAYSIZE( props ), 0.0f, PARTITION_CLIENT_SOLID_EDICTS, NULL ); +#else + int nEnts = GetPushawayEnts( pPlayer, props, ARRAYSIZE( props ), 0.0f, PARTITION_ENGINE_SOLID_EDICTS, NULL ); +#endif + + const Vector & ourCenter = pPlayer->WorldSpaceCenter(); + Vector nearestPropPoint; + Vector nearestPlayerPoint; + + for ( int i=0; i < nEnts; i++ ) + { + // Don't respond to this entity on the client unless it has PHYSICS_MULTIPLAYER_FULL set. + IMultiplayerPhysics *pInterface = dynamic_cast( props[i] ); + if ( pInterface && pInterface->GetMultiplayerPhysicsMode() != PHYSICS_MULTIPLAYER_SOLID ) + continue; + + const float minMass = 10.0f; // minimum mass that can push a player back + const float maxMass = 30.0f; // cap at a decently large value + float mass = maxMass; + if ( pInterface ) + { + mass = pInterface->GetMass(); + } + mass = clamp( mass, minMass, maxMass ); + + mass = MAX( mass, 0 ); + mass /= maxMass; // bring into a 0..1 range + + // Push away from the collision point. The closer our center is to the collision point, + // the harder we push away. + props[i]->CollisionProp()->CalcNearestPoint( ourCenter, &nearestPropPoint ); + pPlayer->CollisionProp()->CalcNearestPoint( nearestPropPoint, &nearestPlayerPoint ); + Vector vPushAway = (nearestPlayerPoint - nearestPropPoint); + float flDist = VectorNormalize( vPushAway ); + + const float MaxPushawayDistance = 5.0f; + if ( flDist > MaxPushawayDistance && !pPlayer->CollisionProp()->IsPointInBounds( nearestPropPoint ) ) + { + continue; + } + + // If we're not pushing, try from our center to the nearest edge of the prop + if ( vPushAway.IsZero() ) + { + vPushAway = (ourCenter - nearestPropPoint); + flDist = VectorNormalize( vPushAway ); + } + + // If we're still not pushing, try from our center to the center of the prop + if ( vPushAway.IsZero() ) + { + vPushAway = (ourCenter - props[i]->WorldSpaceCenter()); + flDist = VectorNormalize( vPushAway ); + } + + flDist = MAX( flDist, 1 ); + + float flForce = sv_pushaway_player_force.GetFloat() / flDist * mass; + flForce = MIN( flForce, sv_pushaway_max_player_force.GetFloat() ); + +#ifndef CLIENT_DLL + pPlayer->PushawayTouch( props[i] ); + + // We can get right up next to rotating doors before they start to move, so scale back our force so we don't go flying + if ( FClassnameIs( props[i], "func_door_rotating" ) || FClassnameIs( props[i], "prop_door_rotating" ) ) +#endif + { + flForce *= 0.25f; + } + + vPushAway *= flForce; + + pCmd->forwardmove += vPushAway.Dot( currentdir ); + pCmd->sidemove += vPushAway.Dot( rightdir ); + } +} + +//----------------------------------------------------------------------------------------------------- +void PerformObstaclePushaway( CBaseCombatCharacter *pPushingEntity ) +{ + if ( pPushingEntity->m_lifeState != LIFE_ALIVE ) + return; + + // Give a push to any barrels that we're touching. + // The client handles adjusting our usercmd to push us away. + CBaseEntity *props[256]; + +#ifdef CLIENT_DLL + // if sv_pushaway_clientside is disabled, clientside phys objects don't bounce away + if ( sv_pushaway_clientside.GetInt() == 0 ) + return; + + // if sv_pushaway_clientside is 1, only local player can push them + CBasePlayer *pPlayer = pPushingEntity->IsPlayer() ? (dynamic_cast< CBasePlayer * >(pPushingEntity)) : NULL; + if ( (sv_pushaway_clientside.GetInt() == 1) && (!pPlayer || !pPlayer->IsLocalPlayer()) ) + return; + + int nEnts = GetPushawayEnts( pPushingEntity, props, ARRAYSIZE( props ), 3.0f, PARTITION_CLIENT_RESPONSIVE_EDICTS, NULL ); +#else + int nEnts = GetPushawayEnts( pPushingEntity, props, ARRAYSIZE( props ), 3.0f, PARTITION_ENGINE_SOLID_EDICTS, NULL ); +#endif + + for ( int i=0; i < nEnts; i++ ) + { + // If this entity uas PHYSICS_MULTIPLAYER_FULL set (ie: it's not just debris), and we're moving too slow, don't push it away. + // Instead, let the client bounce off it. This allows players to get close to and duck behind things without knocking them over. + IMultiplayerPhysics *pInterface = dynamic_cast( props[i] ); + + if ( pInterface && pInterface->GetMultiplayerPhysicsMode() == PHYSICS_MULTIPLAYER_SOLID ) + { + if ( pPushingEntity->GetAbsVelocity().Length2D() < sv_pushaway_min_player_speed.GetFloat() ) + continue; + } + + IPhysicsObject *pObj = props[i]->VPhysicsGetObject(); + + if ( pObj ) + { + Vector vPushAway = (props[i]->WorldSpaceCenter() - pPushingEntity->WorldSpaceCenter()); + vPushAway.z = 0; + + float flDist = VectorNormalize( vPushAway ); + flDist = MAX( flDist, 1 ); + + float flForce = sv_pushaway_force.GetFloat() / flDist; + flForce = MIN( flForce, sv_pushaway_max_force.GetFloat() ); + + pObj->ApplyForceOffset( vPushAway * flForce, pPushingEntity->WorldSpaceCenter() ); + } + } +} -- cgit v1.2.3