diff --git a/game/server/basebludgeonweapon.cpp b/game/server/basebludgeonweapon.cpp index ff8df099..5d762683 100644 --- a/game/server/basebludgeonweapon.cpp +++ b/game/server/basebludgeonweapon.cpp @@ -306,7 +306,17 @@ void CBaseHLBludgeonWeapon::Swing( int bIsSecondary ) forward = pOwner->GetAutoaimVector( AUTOAIM_SCALE_DEFAULT, GetRange() ); Vector swingEnd = swingStart + forward * GetRange(); +#ifdef PORTAL + Ray_t rayPath; + CTraceFilterSkipTwoEntities m_filterBeams( pOwner, NULL, COLLISION_GROUP_NONE ); + rayPath.Init( swingStart, swingEnd ); + g_bBulletPortalTrace = true; // Why is this a global??? + UTIL_Portal_TraceRay( rayPath, MASK_SHOT_HULL, &m_filterBeams, &traceHit ); + g_bBulletPortalTrace = false; +#else UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit ); +#endif // PORTAL + Activity nHitActivity = ACT_VM_HITCENTER; // Like bullets, bludgeon traces have to trace against triggers. diff --git a/game/server/physgun.cpp b/game/server/physgun.cpp index 9864b20c..6e659d37 100644 --- a/game/server/physgun.cpp +++ b/game/server/physgun.cpp @@ -702,8 +702,7 @@ void CWeaponGravityGun::EffectUpdate( void ) #ifdef PORTAL Ray_t rayPath; - CTraceFilterSkipTwoEntities m_filterBeams( NULL, NULL, COLLISION_GROUP_NONE ); - m_filterBeams.SetPassEntity( pOwner ); + CTraceFilterSkipTwoEntities m_filterBeams( pOwner, NULL, COLLISION_GROUP_NONE ); rayPath.Init( start, end ); g_bBulletPortalTrace = true; // Why is this a global??? @@ -787,12 +786,12 @@ void CWeaponGravityGun::EffectUpdate( void ) #ifdef PORTAL Ray_t rayPath; - CTraceFilterSkipTwoEntities m_filterBeams( NULL, NULL, COLLISION_GROUP_NONE ); - m_filterBeams.SetPassEntity( pOwner ); + CTraceFilterSkipTwoEntities m_filterBeams( pOwner, NULL, COLLISION_GROUP_NONE ); rayPath.Init( start, awayfromPlayer ); g_bBulletPortalTrace = true; // Why is this a global??? UTIL_Portal_TraceRay(rayPath, MASK_SOLID, &m_filterBeams, &tr); + g_bBulletPortalTrace = false; #else UTIL_TraceLine( start, awayfromPlayer, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr ); #endif @@ -801,16 +800,18 @@ void CWeaponGravityGun::EffectUpdate( void ) #ifdef PORTAL rayPath.Init( awayfromPlayer, newPosition ); m_filterBeams.SetPassEntity( pObject ); + g_bBulletPortalTrace = true; // Why is this a global??? UTIL_Portal_TraceRay(rayPath, MASK_SOLID, &m_filterBeams, &tr); + g_bBulletPortalTrace = false; #else UTIL_TraceLine( awayfromPlayer, newPosition, MASK_SOLID, pObject, COLLISION_GROUP_NONE, &tr ); #endif Vector dir = tr.endpos - newPosition; - float distance = VectorNormalize(dir); + float distance = VectorNormalize(tr.endpos); float maxDist = m_gravCallback.m_maxVel * gpGlobals->frametime; - if ( distance > maxDist ) + if ( distance > maxDist ) { - newPosition += dir * maxDist; + newPosition += tr.endpos * maxDist; } else { @@ -821,7 +822,6 @@ void CWeaponGravityGun::EffectUpdate( void ) { newPosition = tr.endpos; } - g_bBulletPortalTrace = false; CreatePelletAttraction( phys_gunglueradius.GetFloat(), pObject ); @@ -1322,8 +1322,7 @@ void CWeaponGravityGun::SecondaryAttack( void ) trace_t tr; #ifdef PORTAL Ray_t rayPath; - CTraceFilterSkipTwoEntities m_filterBeams( NULL, NULL, COLLISION_GROUP_NONE ); - m_filterBeams.SetPassEntity( pOwner ); + CTraceFilterSkipTwoEntities m_filterBeams( pOwner, NULL, COLLISION_GROUP_NONE ); rayPath.Init( start, end ); g_bBulletPortalTrace = true; // Why is this a global??? diff --git a/game/server/portal/weapon_physcannon.cpp b/game/server/portal/weapon_physcannon.cpp index 215bb91b..86caac9f 100644 --- a/game/server/portal/weapon_physcannon.cpp +++ b/game/server/portal/weapon_physcannon.cpp @@ -221,24 +221,28 @@ protected: //----------------------------------------------------------------------------- void UTIL_PhyscannonTraceLine( const Vector &vecAbsStart, const Vector &vecAbsEnd, CBaseEntity *pTraceOwner, trace_t *pTrace ) { + Ray_t ray; // Default to HL2 vanilla if ( hl2_episodic.GetBool() == false ) { CTraceFilterNoOwnerTest filter( pTraceOwner, COLLISION_GROUP_NONE ); - UTIL_TraceLine( vecAbsStart, vecAbsEnd, (MASK_SHOT|CONTENTS_GRATE), &filter, pTrace ); + ray.Init( vecAbsStart, vecAbsEnd ); + UTIL_Portal_TraceRay(ray, (MASK_SHOT|CONTENTS_GRATE), &filter, pTrace); return; } // First, trace against entities CTraceFilterPhyscannon filter( pTraceOwner, COLLISION_GROUP_NONE ); - UTIL_TraceLine( vecAbsStart, vecAbsEnd, (MASK_SHOT|CONTENTS_GRATE), &filter, pTrace ); + ray.Init( vecAbsStart, vecAbsEnd ); + UTIL_Portal_TraceRay(ray, (MASK_SHOT|CONTENTS_GRATE), &filter, pTrace); // If we've hit something, test again to make sure no brushes block us if ( pTrace->m_pEnt != NULL ) { trace_t testTrace; CTraceFilterOnlyBrushes brushFilter( COLLISION_GROUP_NONE ); - UTIL_TraceLine( pTrace->startpos, pTrace->endpos, MASK_SHOT, &brushFilter, &testTrace ); + ray.Init( pTrace->startpos, pTrace->endpos ); + UTIL_Portal_TraceRay(ray, MASK_SHOT, &brushFilter, &testTrace); // If we hit a brush, replace the trace with that result if ( testTrace.fraction < 1.0f || testTrace.startsolid || testTrace.allsolid ) diff --git a/game/server/util.cpp b/game/server/util.cpp index 1c9d322f..2667109d 100644 --- a/game/server/util.cpp +++ b/game/server/util.cpp @@ -657,6 +657,44 @@ CBasePlayer *UTIL_GetListenServerHost( void ) return UTIL_PlayerByIndex( 1 ); } +// +// Returns nearest player. +// Control with boolean if line of sight is needed. +// Taken from https://developer.valvesoftware.com/wiki/GetLocalPlayer +CBasePlayer *UTIL_GetNearestPlayer(CBaseEntity *pLooker, bool bNeedsLOS) +{ + float flFinalDistance = 99999.0f; + CBasePlayer *pFinalPlayer = NULL; + + for (int i = 1; i < gpGlobals->maxClients; i++) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex(i); + + if (!pPlayer){ + continue; + } + + float flDistance = (pPlayer->GetAbsOrigin() - pLooker->GetAbsOrigin()).LengthSqr(); + + if (flDistance < flFinalDistance) + { + if (bNeedsLOS) + { + //Check if the player is visible to the entity (only brushes obstruct vision) + if (!pLooker->FVisible(pPlayer, MASK_SOLID_BRUSHONLY)) + { + continue; + } + } + + pFinalPlayer = pPlayer; + flFinalDistance = flDistance; + } + } + + return pFinalPlayer; +} + //-------------------------------------------------------------------------------------------------------------- /** diff --git a/game/server/util.h b/game/server/util.h index f8b82e0c..6eac25c0 100644 --- a/game/server/util.h +++ b/game/server/util.h @@ -231,6 +231,8 @@ CBasePlayer* UTIL_GetLocalPlayer( void ); // get the local player on a listen server CBasePlayer *UTIL_GetListenServerHost( void ); +CBasePlayer *UTIL_GetNearestPlayer(CBaseEntity *pLooker, bool needsLOS = false); + CBasePlayer* UTIL_PlayerByUserId( int userID ); CBasePlayer* UTIL_PlayerByName( const char *name ); // not case sensitive diff --git a/game/shared/portal/PortalSimulation.cpp b/game/shared/portal/PortalSimulation.cpp index 346591ac..da946897 100644 --- a/game/shared/portal/PortalSimulation.cpp +++ b/game/shared/portal/PortalSimulation.cpp @@ -104,7 +104,6 @@ static CPhysCollide *ConvertPolyhedronsToCollideable( CPolyhedron **pPolyhedrons #ifndef CLIENT_DLL static void UpdateShadowClonesPortalSimulationFlags( const CBaseEntity *pSourceEntity, unsigned int iFlags, int iSourceFlags ); -static bool g_bPlayerIsInSimulator = false; #endif static CUtlVector s_PortalSimulators; @@ -1099,11 +1098,6 @@ void CPortalSimulator::MarkAsOwned( CBaseEntity *pEntity ) m_InternalData.Simulation.Dynamic.EntFlags[iEntIndex] |= PSEF_OWNS_ENTITY; s_OwnedEntityMap[iEntIndex] = this; m_InternalData.Simulation.Dynamic.OwnedEntities.AddToTail( pEntity ); - - if ( pEntity->IsPlayer() ) - { - g_bPlayerIsInSimulator = true; - } } void CPortalSimulator::MarkAsReleased( CBaseEntity *pEntity ) @@ -1125,12 +1119,6 @@ void CPortalSimulator::MarkAsReleased( CBaseEntity *pEntity ) } } Assert( i >= 0 ); - - - if ( pEntity->IsPlayer() ) - { - g_bPlayerIsInSimulator = false; - } } @@ -2454,20 +2442,21 @@ void CPortalSimulator::PrePhysFrame( void ) } } +// Taken from portal 2. void CPortalSimulator::PostPhysFrame( void ) { - if ( g_bPlayerIsInSimulator ) + for( int i = 1; i <= gpGlobals->maxClients; ++i ) { - CPortal_Player* pPlayer = dynamic_cast( UTIL_GetLocalPlayer() ); - CProp_Portal* pTouchedPortal = pPlayer->m_hPortalEnvironment.Get(); - CPortalSimulator* pSim = GetSimulatorThatOwnsEntity( pPlayer ); - if ( pTouchedPortal && pSim && (pTouchedPortal->m_PortalSimulator.GetPortalSimulatorGUID() != pSim->GetPortalSimulatorGUID()) ) + CPortal_Player* pPlayer = (CPortal_Player *)UTIL_PlayerByIndex( i ); + if( pPlayer ) { - Warning ( "Player is simulated in a physics environment but isn't touching a portal! Can't teleport, but can fall through portal hole. Returning player to main environment.\n" ); - ADD_DEBUG_HISTORY( HISTORY_PLAYER_DAMAGE, UTIL_VarArgs( "Player in PortalSimulator but not touching a portal, removing from sim at : %f\n", gpGlobals->curtime ) ); - - if ( pSim ) + CProp_Portal* pTouchedPortal = pPlayer->m_hPortalEnvironment.Get(); + CPortalSimulator* pSim = GetSimulatorThatOwnsEntity( pPlayer ); + if ( pTouchedPortal && pSim && (pTouchedPortal->m_PortalSimulator.GetPortalSimulatorGUID() != pSim->GetPortalSimulatorGUID()) ) { + Warning ( "Player is simulated in a physics environment but isn't touching a portal! Can't teleport, but can fall through portal hole. Returning player to main environment.\n" ); + ADD_DEBUG_HISTORY( HISTORY_PLAYER_DAMAGE, UTIL_VarArgs( "Player in PortalSimulator but not touching a portal, removing from sim at : %f\n", gpGlobals->curtime ) ); + pSim->ReleaseOwnershipOfEntity( pPlayer, false ); } }