mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-07-16 22:35:09 +00:00
fix(multiplayer): Fix a crash when player gets near a portal in multiplayer.
fix(crowbar): Fix crowbar not hitting through portals. chore(util): Added UTIL_GetNearestPlayer function from valve developer wiki. Made this a month ago and didn't really test anything now. A lot of useless portal ray traces.
This commit is contained in:
parent
398645a181
commit
cd2241af21
@ -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.
|
||||
|
||||
@ -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???
|
||||
|
||||
@ -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 )
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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<CPortalSimulator *> 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<CPortal_Player*>( 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 );
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user