Added SecobMod multiplayer AI fixes and adjustments for HL2 play

This commit is contained in:
Blixibon 2020-12-23 14:22:35 -06:00
parent f62cf15db8
commit 25327099e0
123 changed files with 5148 additions and 422 deletions

View File

@ -82,7 +82,13 @@ void cc_cl_interp_all_changed( IConVar *pConVar, const char *pOldString, float f
static ConVar cl_extrapolate( "cl_extrapolate", "1", FCVAR_CHEAT, "Enable/disable extrapolation if interpolation history runs out." );
static ConVar cl_interp_npcs( "cl_interp_npcs", "0.0", FCVAR_USERINFO, "Interpolate NPC positions starting this many seconds in past (or cl_interp, if greater)" );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
static ConVar cl_interp_npcs( "cl_interp_npcs", "0.3", FCVAR_USERINFO, "Interpolate NPC positions starting this many seconds in past (or cl_interp, if greater)" );
#else
static ConVar cl_interp_npcs( "cl_interp_npcs", "0.0", FCVAR_USERINFO, "Interpolate NPC positions starting this many seconds in past (or cl_interp, if greater)" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
static ConVar cl_interp_all( "cl_interp_all", "0", 0, "Disable interpolation list optimizations.", 0, 0, 0, 0, cc_cl_interp_all_changed );
ConVar r_drawmodeldecals( "r_drawmodeldecals", "1" );
extern ConVar cl_showerror;

View File

@ -2233,6 +2233,12 @@ void OnRenderStart()
C_BaseAnimating::ThreadedBoneSetup();
#ifdef SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
//Tony; in multiplayer do some extra stuff. like re-calc the view if in a vehicle!
if ( engine->GetMaxClients() > 1 )
view->MP_PostSimulate();
#endif //SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
{
VPROF_("Client TempEnts", 0, VPROF_BUDGETGROUP_CLIENT_SIM, false, BUDGETFLAG_CLIENT);
// This creates things like temp entities.

View File

@ -400,11 +400,15 @@ void PlayImpactSound( CBaseEntity *pEntity, trace_t &tr, Vector &vecServerOrigin
else
{
CLocalPlayerFilter filter;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
C_BaseEntity::EmitSound( filter, NULL, pbulletImpactSoundName, /*pdata->soundhandles.bulletImpact,*/ &vecOrigin );
#else
C_BaseEntity::EmitSound( filter, NULL, pbulletImpactSoundName, pdata->soundhandles.bulletImpact, &vecOrigin );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI}
return;
}
}
#ifdef _DEBUG
Msg("***ERROR: PlayImpactSound() on a surface with 0 bulletImpactCount!\n");

View File

@ -67,6 +67,10 @@ public:
// Initialize view renderer
virtual void Init( void ) = 0;
#ifdef SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
virtual void MP_PostSimulate() = 0;
#endif //SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
// Clear any systems between levels
virtual void LevelInit( void ) = 0;
virtual void LevelShutdown( void ) = 0;

View File

@ -1366,3 +1366,59 @@ CON_COMMAND( getpos, "dump position and angles to the console" )
Warning( "%s %f %f %f\n", pCommand2, angles.x, angles.y, angles.z );
}
#ifdef SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
void CViewRender::MP_PostSimulate()
{
C_BasePlayer *pLocal = C_BasePlayer::GetLocalPlayer();
if ( !pLocal )
return;
//Tony; if the local player is in a vehicle, then we need to kill the bone cache, and re-calculate the view.
if ( !pLocal->IsInAVehicle() && !pLocal->GetVehicle())
return;
IClientVehicle *pVehicle = pLocal->GetVehicle();
Assert( pVehicle );
CBaseAnimating *pVehicleEntity =
(CBaseAnimating*)pVehicle->GetVehicleEnt();
Assert( pVehicleEntity );
int nRole = pVehicle->GetPassengerRole( pLocal );
//Tony; we have to invalidate the bone cache in order for the attachment lookups to be correct!
pVehicleEntity->InvalidateBoneCache();
pVehicle->GetVehicleViewPosition( nRole, &m_View.origin, &m_View.angles,
&m_View.fov );
//Tony; everything below is from SetupView - the things that should be recalculated.. are recalculated!
pLocal->CalcViewModelView( m_View.origin, m_View.angles );
// Compute the world->main camera transform
ComputeCameraVariables( m_View.origin, m_View.angles,
&g_vecVForward, &g_vecVRight, &g_vecVUp, &g_matCamInverse );
// set up the hearing origin...
AudioState_t audioState;
audioState.m_Origin = m_View.origin;
audioState.m_Angles = m_View.angles;
audioState.m_bIsUnderwater = pLocal && pLocal->AudioStateIsUnderwater(m_View.origin );
ToolFramework_SetupAudioState( audioState );
m_View.origin = audioState.m_Origin;
m_View.angles = audioState.m_Angles;
engine->SetAudioState( audioState );
g_vecPrevRenderOrigin = g_vecRenderOrigin;
g_vecPrevRenderAngles = g_vecRenderAngles;
g_vecRenderOrigin = m_View.origin;
g_vecRenderAngles = m_View.angles;
#ifdef _DEBUG
s_DbgSetupOrigin = m_View.origin;
s_DbgSetupAngles = m_View.angles;
#endif
}
#endif //SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER

View File

@ -317,6 +317,10 @@ public:
virtual void Init( void );
virtual void Shutdown( void );
#ifdef SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
virtual void MP_PostSimulate();
#endif //SecobMod__FIX_VEHICLE_PLAYER_CAMERA_JUDDER
const CViewSetup *GetPlayerViewSetup( ) const;
virtual void StartPitchDrift( void );

View File

@ -229,6 +229,7 @@ LINK_ENTITY_TO_CLASS( point_commentary_viewpoint, CCommentaryViewPosition );
//-----------------------------------------------------------------------------
CBasePlayer *GetCommentaryPlayer( void )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer;
if ( gpGlobals->maxClients <= 1 )
@ -242,6 +243,9 @@ CBasePlayer *GetCommentaryPlayer( void )
}
return pPlayer;
#else
return UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//===========================================================================================================

View File

@ -232,7 +232,12 @@ CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMat
// Necessary to cause it to do the appropriate death cleanup
if ( pTarget->m_lifeState == LIFE_ALIVE )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE );
pTarget->TakeDamage( ragdollInfo );
}
@ -347,7 +352,12 @@ void CEntityDissolve::DissolveThink( void )
// Necessary to cause it to do the appropriate death cleanup
// Yeah, the player may have nothing to do with it, but
// passing NULL to TakeDamage causes bad things to happen
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
int iNoPhysicsDamage = g_pGameRules->Damage_GetNoPhysicsForce();
CTakeDamageInfo info( pPlayer, pPlayer, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL | iNoPhysicsDamage );
pTarget->TakeDamage( info );

View File

@ -95,7 +95,11 @@ void CEnvHudHint::InputShowHudHint( inputdata_t &inputdata )
}
else
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if ( !pPlayer || !pPlayer->IsNetClient() )
@ -132,7 +136,11 @@ void CEnvHudHint::InputHideHudHint( inputdata_t &inputdata )
}
else
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if ( !pPlayer || !pPlayer->IsNetClient() )

View File

@ -228,12 +228,19 @@ void CCredits::RollOutroCredits()
{
sv_unlockedchapters.SetValue( "15" );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CRecipientFilter filter;
filter.AddAllPlayers();
filter.MakeReliable();
UserMessageBegin( filter, "CreditsMsg" );
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
UserMessageBegin( user, "CreditsMsg" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
WRITE_BYTE( 3 );
#ifdef MAPBASE
WRITE_STRING( STRING(m_iszCreditsFile) );
@ -253,14 +260,29 @@ void CCredits::InputRollOutroCredits( inputdata_t &inputdata )
void CCredits::InputShowLogo( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CRecipientFilter filter;
filter.AddAllPlayers();
filter.MakeReliable();
// Modification. Set to how old patched AI SDK had code.
//CSingleUserRecipientFilter user( pPlayer );
//user.MakeReliable();
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( m_flLogoLength )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UserMessageBegin( filter, "LogoTimeMsg" );
#else
UserMessageBegin( user, "LogoTimeMsg" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
WRITE_FLOAT( m_flLogoLength );
#ifdef MAPBASE
WRITE_STRING( STRING(m_iszCreditsFile) );
@ -269,7 +291,12 @@ void CCredits::InputShowLogo( inputdata_t &inputdata )
}
else
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UserMessageBegin( filter, "CreditsMsg" );
#else
UserMessageBegin( user, "CreditsMsg" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
WRITE_BYTE( 1 );
#ifdef MAPBASE
WRITE_STRING( STRING(m_iszCreditsFile) );
@ -285,12 +312,20 @@ void CCredits::InputSetLogoLength( inputdata_t &inputdata )
void CCredits::InputRollCredits( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CRecipientFilter filter;
filter.AddAllPlayers();
filter.MakeReliable();
UserMessageBegin( filter, "CreditsMsg" );
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
CSingleUserRecipientFilter user( pPlayer );
user.MakeReliable();
UserMessageBegin( user, "CreditsMsg" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
WRITE_BYTE( 2 );
#ifdef MAPBASE
WRITE_STRING( STRING(m_iszCreditsFile) );

View File

@ -87,6 +87,11 @@
#include "datacache/imdlcache.h"
#include "vstdlib/jobthread.h"
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
#include "ilagcompensationmanager.h"
#include "hl2mp_gamerules.h"
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef HL2_EPISODIC
#include "npc_alyx_episodic.h"
#endif
@ -264,10 +269,18 @@ int CAI_Manager::NumAIs()
//-------------------------------------
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
int CAI_Manager::AddAI( CAI_BaseNPC *pAI )
{
m_AIs.AddToTail( pAI );
return NumAIs()-1; // return the index it was added to
}
#else
void CAI_Manager::AddAI( CAI_BaseNPC *pAI )
{
m_AIs.AddToTail( pAI );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//-------------------------------------
@ -660,7 +673,23 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo
{
BaseClass::Ignite( flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner );
#ifdef HL2_EPISODIC
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef HL2_EPISODIC
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
if ( pPlayer->IRelationType( this ) != D_LI )
{
CNPC_Alyx *alyx = CNPC_Alyx::GetAlyx();
if ( alyx )
{
alyx->EnemyIgnited( this );
}
}
#endif //HL2_EPISODIC
#else
#ifdef HL2_EPISODIC
if ( AI_IsSinglePlayer() )
{
CBasePlayer *pPlayer = AI_GetSinglePlayer();
if ( pPlayer->IRelationType( this ) != D_LI )
{
@ -671,7 +700,9 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo
alyx->EnemyIgnited( this );
}
}
#endif
}
#endif //HL2_EPISODIC
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//-----------------------------------------------------------------------------
@ -1003,9 +1034,15 @@ int CAI_BaseNPC::OnTakeDamage_Alive( const CTakeDamageInfo &info )
#else
CAI_BaseNPC *pAttacker = dynamic_cast<CAI_BaseNPC *>( info.GetAttacker() );
#endif
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if( pAttacker && pAttacker->IsAlive() && UTIL_GetNearestPlayer(GetAbsOrigin()) )
#else
if( pAttacker && pAttacker->IsAlive() && pPlayer )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
if( pAttacker->GetSquad() != NULL && pAttacker->IsInPlayerSquad() )
{
@ -3512,8 +3549,12 @@ void CAI_BaseNPC::UpdateEfficiency( bool bInPVS )
}
//---------------------------------
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
static Vector vPlayerEyePosition;
static Vector vPlayerForward;
static int iPrevFrame = -1;
@ -3760,7 +3801,11 @@ void CAI_BaseNPC::UpdateSleepState( bool bInPVS )
#ifdef MAPBASE
#define Wake() Wake(pLocalPlayer)
#endif
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pLocalPlayer )
{
if ( gpGlobals->maxClients > 1 )
@ -3963,7 +4008,13 @@ void CAI_BaseNPC::RebalanceThinks()
int i;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Vector vPlayerForward;
Vector vPlayerEyePosition;
@ -4244,7 +4295,11 @@ void CAI_BaseNPC::SetPlayerAvoidState( void )
GetPlayerAvoidBounds( &vMins, &vMaxs );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pLocalPlayer )
{
@ -5340,6 +5395,25 @@ void CAI_BaseNPC::RunAI( void )
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if( ai_debug_loners.GetBool() && !IsInSquad() )
{
Vector right;
Vector vecPoint;
vecPoint = EyePosition() + Vector( 0, 0, 12 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_GetNearestPlayer(GetAbsOrigin())->GetVectors( NULL, &right, NULL );
#else
UTIL_GetLocalPlayer()->GetVectors( NULL, &right, NULL );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 64 ), 255, 0, 0, false , 0.1 );
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) + right * 32, 255, 0, 0, false , 0.1 );
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) - right * 32, 255, 0, 0, false , 0.1 );
}
#else
if( ai_debug_loners.GetBool() && !IsInSquad() && AI_IsSinglePlayer() )
{
Vector right;
@ -5347,12 +5421,18 @@ void CAI_BaseNPC::RunAI( void )
vecPoint = EyePosition() + Vector( 0, 0, 12 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_GetNearestPlayer(GetAbsOrigin())->GetVectors( NULL, &right, NULL );
#else
UTIL_GetLocalPlayer()->GetVectors( NULL, &right, NULL );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 64 ), 255, 0, 0, false , 0.1 );
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) + right * 32, 255, 0, 0, false , 0.1 );
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) - right * 32, 255, 0, 0, false , 0.1 );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef _DEBUG
m_bSelected = ( (m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) != 0 );
@ -9811,7 +9891,12 @@ void CAI_BaseNPC::DrawDebugGeometryOverlays(void)
info.SetDamage( m_iHealth );
info.SetAttacker( this );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
info.SetInflictor( (CBaseEntity *)this );
#else
info.SetInflictor( ( AI_IsSinglePlayer() ) ? (CBaseEntity *)AI_GetSinglePlayer() : (CBaseEntity *)this );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
info.SetDamageType( DMG_GENERIC );
m_debugOverlays &= ~OVERLAY_NPC_KILL_BIT;
@ -11043,7 +11128,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
{
if ( !stricmp( name, "!player" ))
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
return UTIL_GetNearestPlayer(GetAbsOrigin());
#else
return ( CBaseEntity * )AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else if ( !stricmp( name, "!enemy" ) )
{
@ -11058,7 +11147,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
{
// FIXME: look at CBaseEntity *CNPCSimpleTalker::FindNearestFriend(bool fPlayer)
// punt for now
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
return UTIL_GetNearestPlayer(GetAbsOrigin());
#else
return ( CBaseEntity * )AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else if (!stricmp( name, "self" ))
{
@ -11078,7 +11171,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
{
DevMsg( "ERROR: \"player\" is no longer used, use \"!player\" in vcd instead!\n" );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
return UTIL_GetNearestPlayer(GetAbsOrigin());
#else
return ( CBaseEntity * )AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else
{
@ -12733,7 +12830,12 @@ CAI_BaseNPC::CAI_BaseNPC(void)
m_interuptSchedule = NULL;
m_nDebugPauseIndex = 0;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
SetAIIndex( g_AI_Manager.AddAI( this ) );
lagcompensation->RemoveNpcData( GetAIIndex() ); // make sure we're not inheriting anyone else's data
#else
g_AI_Manager.AddAI( this );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( g_AI_Manager.NumAIs() == 1 )
{
@ -12763,6 +12865,11 @@ CAI_BaseNPC::~CAI_BaseNPC(void)
{
g_AI_Manager.RemoveAI( this );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// this should stop a crash occuring when our death immediately creates a new NPC (eg headcrab from zombie)
lagcompensation->RemoveNpcData( GetAIIndex() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
delete m_pLockedBestSound;
RemoveMemory();
@ -13336,7 +13443,11 @@ bool CAI_BaseNPC::CineCleanup()
{
SetLocalOrigin( origin );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
int drop = UTIL_DropToFloor( this, MASK_NPCSOLID, UTIL_GetNearestVisiblePlayer(this) );
#else
int drop = UTIL_DropToFloor( this, MASK_NPCSOLID, UTIL_GetLocalPlayer() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Origin in solid? Set to org at the end of the sequence
if ( ( drop < 0 ) || sv_test_scripted_sequences.GetBool() )
@ -13413,7 +13524,12 @@ void CAI_BaseNPC::Teleport( const Vector *newPosition, const QAngle *newAngles,
bool CAI_BaseNPC::FindSpotForNPCInRadius( Vector *pResult, const Vector &vStartPos, CAI_BaseNPC *pNPC, float radius, bool bOutOfPlayerViewcone )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(pNPC->GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
QAngle fan;
fan.x = 0;
@ -13965,11 +14081,17 @@ bool CAI_BaseNPC::IsPlayerAlly( CBasePlayer *pPlayer )
{
// in multiplayer mode we need a valid pPlayer
// or override this virtual function
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !AI_IsSinglePlayer() )
return false;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// NULL means single player mode
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
return ( !pPlayer || IRelationType( pPlayer ) == D_LI );
@ -14267,7 +14389,12 @@ bool CAI_BaseNPC::FindNearestValidGoalPos( const Vector &vTestPoint, Vector *pRe
if ( vCandidate != vec3_invalid )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
AI_Waypoint_t *pPathToPoint = GetPathfinder()->BuildRoute( GetAbsOrigin(), vCandidate, UTIL_GetNearestPlayer(GetAbsOrigin()), 5*12, NAV_NONE, true );
#else
AI_Waypoint_t *pPathToPoint = GetPathfinder()->BuildRoute( GetAbsOrigin(), vCandidate, AI_GetSinglePlayer(), 5*12, NAV_NONE, true );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPathToPoint )
{
GetPathfinder()->UnlockRouteNodes( pPathToPoint );
@ -15774,6 +15901,16 @@ void CAI_BaseNPC::PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot )
if ( pInteraction->iLoopBreakTriggerMethod & SNPCINT_LOOPBREAK_ON_FLASHLIGHT_ILLUM )
{
// Only do this in alyx darkness mode
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
// Can only break when we're in the action anim
if ( m_hCine->IsPlayingAction() )
{
m_hCine->StopActionLoop( true );
}
}
#else
if ( HL2GameRules()->IsAlyxInDarknessMode() )
{
// Can only break when we're in the action anim
@ -15782,6 +15919,7 @@ void CAI_BaseNPC::PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot )
m_hCine->StopActionLoop( true );
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
}
#endif

View File

@ -494,6 +494,10 @@ float ChangeDistance( float flInterval, float flGoalDistance, float flGoalVeloci
//
//=============================================================================
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
#define MAX_AIS 256
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
class CAI_Manager
{
public:
@ -502,16 +506,23 @@ public:
CAI_BaseNPC ** AccessAIs();
int NumAIs();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
int AddAI( CAI_BaseNPC *pAI );
#else
void AddAI( CAI_BaseNPC *pAI );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
void RemoveAI( CAI_BaseNPC *pAI );
bool FindAI( CAI_BaseNPC *pAI ) { return ( m_AIs.Find( pAI ) != m_AIs.InvalidIndex() ); }
private:
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
enum
{
MAX_AIS = 256
};
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
typedef CUtlVector<CAI_BaseNPC *> CAIArray;
@ -2345,7 +2356,16 @@ public:
void GetPlayerAvoidBounds( Vector *pMins, Vector *pMaxs );
void StartPingEffect( void ) { m_flTimePingEffect = gpGlobals->curtime + 2.0f; DispatchUpdateTransmitState(); }
};
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// used by lag compensation to be able to refer to & track specific NPCs, and detect changes in the AI list
void SetAIIndex(int i) { m_iAIIndex = i; }
int GetAIIndex() { return m_iAIIndex; }
private:
int m_iAIIndex;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
};
//-----------------------------------------------------------------------------

View File

@ -3409,7 +3409,11 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
case TASK_FACE_PLAYER:
{
// Get edict for one player
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
GetMotor()->SetIdealYawToTargetAndUpdate( pPlayer->GetAbsOrigin(), AI_KEEP_YAW_SPEED );
@ -3737,7 +3741,12 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
if( pHint )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Vector vecGoal = pHint->GetAbsOrigin();
if( vecGoal.DistToSqr(GetAbsOrigin()) < vecGoal.DistToSqr(pPlayer->GetAbsOrigin()) )

View File

@ -350,7 +350,12 @@ void CAI_FearBehavior::GatherConditions()
// -I haven't seen the player in 2 seconds
//
// Here's the distance check:
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer != NULL && GetAbsOrigin().DistToSqr(pPlayer->GetAbsOrigin()) >= Square( ai_fear_player_dist.GetFloat() * 1.5f ) )
{
SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
@ -492,7 +497,12 @@ CAI_Hint *CAI_FearBehavior::FindFearWithdrawalDest()
#ifdef MAPBASE
hintCriteria.SetFlag(bits_HINT_NODE_USE_GROUP);
#endif
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
hintCriteria.AddIncludePosition( UTIL_GetNearestPlayer(GetAbsOrigin())->GetAbsOrigin(), ( ai_fear_player_dist.GetFloat() ) );
#else
hintCriteria.AddIncludePosition( AI_GetSinglePlayer()->GetAbsOrigin(), ( ai_fear_player_dist.GetFloat() ) );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
pHint = CAI_HintManager::FindHint( pOuter, hintCriteria );

View File

@ -2157,6 +2157,19 @@ void CAI_FollowGoal::EnableGoal( CAI_BaseNPC *pAI )
return;
CBaseEntity *pGoalEntity = GetGoalEntity();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pGoalEntity )
{
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
if ( pAI->IRelationType(pPlayer) == D_LI )
{
pGoalEntity = pPlayer;
SetGoalEntity( pGoalEntity );
}
}
#else
if ( !pGoalEntity && AI_IsSinglePlayer() )
{
if ( pAI->IRelationType(UTIL_GetLocalPlayer()) == D_LI )
@ -2165,6 +2178,8 @@ void CAI_FollowGoal::EnableGoal( CAI_BaseNPC *pAI )
SetGoalEntity( pGoalEntity );
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pGoalEntity )
pBehavior->SetFollowGoal( this );

View File

@ -148,10 +148,18 @@ void CAI_LeadBehavior::LeadPlayer( const AI_LeadArgs_t &leadArgs, CAI_LeadBehavi
{
#ifndef CSTRIKE_DLL
CAI_PlayerAlly *pOuter = dynamic_cast<CAI_PlayerAlly*>(GetOuter());
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( pOuter )
{
pOuter->SetSpeechTarget( UTIL_GetNearestVisiblePlayer(pOuter) );
}
#else
if ( pOuter && AI_IsSinglePlayer() )
{
pOuter->SetSpeechTarget( UTIL_GetLocalPlayer() );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#endif
if( SetGoal( leadArgs ) )
@ -179,8 +187,10 @@ void CAI_LeadBehavior::StopLeading( void )
bool CAI_LeadBehavior::CanSelectSchedule()
{
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !AI_GetSinglePlayer() || AI_GetSinglePlayer()->IsDead() )
return false;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
bool fAttacked = ( HasCondition( COND_LIGHT_DAMAGE ) || HasCondition( COND_HEAVY_DAMAGE ) );
bool fNonCombat = ( GetNpcState() == NPC_STATE_IDLE || GetNpcState() == NPC_STATE_ALERT );
@ -192,7 +202,18 @@ bool CAI_LeadBehavior::CanSelectSchedule()
void CAI_LeadBehavior::BeginScheduleSelection()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(GetOuter());
if ( !pPlayer )
{
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
SetTarget( pPlayer );
}
#else
SetTarget( AI_GetSinglePlayer() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CAI_Expresser *pExpresser = GetOuter()->GetExpresser();
if ( pExpresser )
pExpresser->ClearSpokeConcept( TLK_LEAD_ARRIVAL );
@ -326,7 +347,11 @@ bool CAI_LeadBehavior::PlayerIsAheadOfMe( bool bForce )
m_bInitialAheadTest = false;
Vector vecClosestPoint;
if ( GetClosestPointOnRoute( AI_GetSinglePlayer()->GetAbsOrigin(), &vecClosestPoint ) )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( GetClosestPointOnRoute( UTIL_GetNearestPlayer(GetAbsOrigin())->GetAbsOrigin(), &vecClosestPoint ) )
#else
if ( GetClosestPointOnRoute( AI_GetSinglePlayer()->GetAbsOrigin(), &vecClosestPoint ) )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
// If the closest point is not right next to me, then
// the player is somewhere ahead of me on the route.
@ -353,7 +378,11 @@ void CAI_LeadBehavior::GatherConditions( void )
}
// We have to collect data about the person we're leading around.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pFollower = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pFollower = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pFollower )
{
@ -536,7 +565,12 @@ int CAI_LeadBehavior::SelectSchedule()
// Player's here, but does he have the weapon we want him to have?
if ( m_weaponname != NULL_STRING )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pFollower = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pFollower = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pFollower && !pFollower->Weapon_OwnsThisType( STRING(m_weaponname) ) )
{
// If the safety timeout has run out, just give the player the weapon
@ -569,7 +603,12 @@ int CAI_LeadBehavior::SelectSchedule()
else
{
// We have to collect data about the person we're leading around.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pFollower = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pFollower = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pFollower )
{
float flFollowerDist = ( WorldSpaceCenter() - pFollower->WorldSpaceCenter() ).Length();
@ -833,7 +872,12 @@ void CAI_LeadBehavior::StartTask( const Task_t *pTask )
case TASK_LEAD_RETRIEVE_WAIT:
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_MoveMonitor.SetMark( UTIL_GetNearestPlayer(GetAbsOrigin()), 24 );
#else
m_MoveMonitor.SetMark( AI_GetSinglePlayer(), 24 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
ChainStartTask( TASK_WAIT_INDEFINITE );
break;
}

View File

@ -720,7 +720,11 @@ Vector CAI_StandoffBehavior::GetStandoffGoalPosition()
}
else if( PlayerIsLeading() )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
return UTIL_GetNearestPlayer(GetAbsOrigin())->GetAbsOrigin();
#else
return UTIL_GetLocalPlayer()->GetAbsOrigin();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else
{
@ -772,7 +776,11 @@ void CAI_StandoffBehavior::UpdateBattleLines()
if ( m_params.fPlayerIsBattleline )
{
const float DIST_PLAYER_PLANE = 180;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
BattleLine_t playerLine;
@ -1003,7 +1011,12 @@ void CAI_StandoffBehavior::OnChangeTacticalConstraints()
bool CAI_StandoffBehavior::PlayerIsLeading()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return ( pPlayer && GetOuter()->IRelationType( pPlayer ) == D_LI );
}
@ -1011,7 +1024,12 @@ bool CAI_StandoffBehavior::PlayerIsLeading()
CBaseEntity *CAI_StandoffBehavior::GetPlayerLeader()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && GetOuter()->IRelationType( pPlayer ) == D_LI )
return pPlayer;
return NULL;

View File

@ -1409,7 +1409,14 @@ bool CAI_Hint::HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hint
if ( hintCriteria.HasFlag(bits_HINT_HAS_LOS_TO_PLAYER|bits_HAS_EYEPOSITION_LOS_TO_PLAYER) )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
if ( !pPlayer )
UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer != NULL )
{

View File

@ -351,7 +351,12 @@ void CAI_PlaneSolver::GenerateObstacleNpcs( const AILocalMoveGoal_t &goal, float
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(m_pNpc->GetAbsOrigin());
#else
CBaseEntity *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
Vector mins, maxs;

View File

@ -206,11 +206,19 @@ void CAI_Relationship::ApplyRelationship( CBaseEntity *pActivator, CBaseEntity *
// The player spawns slightly after the NPCs, meaning that if we don't wait, the
// player will miss any relationships placed on them.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( UTIL_GetLocalPlayer() )
{
SetThink( &CAI_Relationship::ApplyRelationshipThink );
SetNextThink( gpGlobals->curtime );
}
#else
if ( AI_IsSinglePlayer() && !UTIL_GetLocalPlayer() )
{
SetThink( &CAI_Relationship::ApplyRelationshipThink );
SetNextThink( gpGlobals->curtime );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( !m_bIsActive )
{

View File

@ -485,10 +485,14 @@ void CAI_ScriptConditions::EvaluationThink()
int iActorsDone = 0;
#ifdef HL2_DLL
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
//Do nothing.
#else
if( AI_GetSinglePlayer()->GetFlags() & FL_NOTARGET )
{
ScrCondDbgMsg( ("%s WARNING: Player is NOTARGET. This will affect all LOS conditiosn involving the player!\n", GetDebugName()) );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#endif

View File

@ -346,7 +346,12 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con
// Append local player criteria to set, but not if this is a player doing the talking
if ( !GetOuter()->IsPlayer() )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetOuter()->GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer )
pPlayer->ModifyOrAppendPlayerCriteria( set );
}
@ -1236,7 +1241,12 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C
set.AppendCriteria( "weapon", "none" );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(pSpeaker->GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
Vector distance = pPlayer->GetAbsOrigin() - pSpeaker->GetAbsOrigin();

View File

@ -23,10 +23,14 @@
inline CBasePlayer *AI_GetSinglePlayer()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
//Do nothing here.
#else
if ( gpGlobals->maxClients > 1 )
{
return NULL;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return UTIL_GetLocalPlayer();
}

View File

@ -73,6 +73,9 @@ public:
// This defaults to off.
void UseClientSideAnimation();
//SecobMod__Information: Set to match DutchMegas' Collaborate mod code.
void SetClientSideAnimation( bool val ) { m_bClientSideAnimation = val; };
// Tells whether or not we're using client-side animation. Used for controlling
// the transmission of animtime.
bool IsUsingClientSideAnimation() { return m_bClientSideAnimation; }

View File

@ -48,6 +48,9 @@
#include "hl2_gamerules.h"
#endif
//SecobMod.
#include "hl2mp_gamerules.h"
#ifdef PORTAL
#include "portal_util_shared.h"
#include "prop_portal_shared.h"
@ -1675,7 +1678,8 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
#ifdef HL2_EPISODIC
// Burning corpses are server-side in episodic, if we're in darkness mode
if ( IsOnFire() && HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod.
if (IsOnFire() && HL2MPRules()->IsAlyxInDarknessMode())
{
CBaseEntity *pRagdoll = CreateServerRagdoll( this, m_nForceBone, newinfo, COLLISION_GROUP_DEBRIS );
FixupBurningServerRagdoll( pRagdoll );
@ -1687,9 +1691,10 @@ bool CBaseCombatCharacter::BecomeRagdoll( const CTakeDamageInfo &info, const Vec
#ifdef HL2_DLL
bool bMegaPhyscannonActive = false;
#if !defined( HL2MP )
bMegaPhyscannonActive = HL2GameRules()->MegaPhyscannonActive();
#endif // !HL2MP
//SecobMod.
//#if !defined( HL2MP )
bMegaPhyscannonActive = HL2MPRules()->MegaPhyscannonActive();
//#endif // !HL2MP
// Mega physgun requires everything to be a server-side ragdoll
if ( m_bForceServerRagdoll == true || ( ( bMegaPhyscannonActive == true ) && !IsPlayer() && Classify() != CLASS_PLAYER_ALLY_VITAL && Classify() != CLASS_PLAYER_ALLY ) )
@ -3844,12 +3849,13 @@ void CBaseCombatCharacter::VPhysicsShadowCollision( int index, gamevcollisioneve
// which can occur owing to ordering issues it appears.
float flOtherAttackerTime = 0.0f;
#if defined( HL2_DLL ) && !defined( HL2MP )
if ( HL2GameRules()->MegaPhyscannonActive() == true )
//SecobMod.
//#if defined( HL2_DLL ) && !defined( HL2MP )
if ( HL2MPRules()->MegaPhyscannonActive() == true )
{
flOtherAttackerTime = 1.0f;
}
#endif // HL2_DLL && !HL2MP
//#endif // HL2_DLL && !HL2MP
if ( this == pOther->HasPhysicsAttacker( flOtherAttackerTime ) )
return;

View File

@ -965,12 +965,21 @@ void CBaseEntity::DrawDebugGeometryOverlays(void)
NDebugOverlay::EntityBounds(this, 255, 255, 255, 0, 0 );
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
if ( m_debugOverlays & OVERLAY_AUTOAIM_BIT && (GetFlags()&FL_AIMTARGET) && pPlayer != NULL )
#else
if ( m_debugOverlays & OVERLAY_AUTOAIM_BIT && (GetFlags()&FL_AIMTARGET) && AI_GetSinglePlayer() != NULL )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
// Crude, but it gets the point across.
Vector vecCenter = GetAutoAimCenter();
Vector vecRight, vecUp, vecDiag;
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
float radius = GetAutoAimRadius();
QAngle angles = pPlayer->EyeAngles();
@ -1675,9 +1684,23 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info )
unsigned short gameFlags = VPhysicsGetObject()->GetGameFlags();
if ( gameFlags & FVPHYSICS_PLAYER_HELD )
{
//SecobMod
// if the player is holding the object, use it's real mass (player holding reduced the mass)
CBasePlayer *pPlayer = NULL;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// See which MP player is holding the physics object and then use that player to get the real mass of the object.
// This is ugly but better than having linkage between an object and its "holding" player.
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i );
if ( tempPlayer && (tempPlayer->GetHeldObject() == this ) )
{
pPlayer = tempPlayer;
break;
}
}
#else
if ( AI_IsSinglePlayer() )
{
pPlayer = UTIL_GetLocalPlayer();
@ -1696,6 +1719,7 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info )
}
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
@ -9066,7 +9090,12 @@ void CBaseEntity::DispatchResponse( const char *conceptName )
ModifyOrAppendCriteria( set );
// Append local player criteria to set,too
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer )
pPlayer->ModifyOrAppendPlayerCriteria( set );
@ -9187,7 +9216,12 @@ void CBaseEntity::DumpResponseCriteria( void )
ModifyOrAppendCriteria( set );
// Append local player criteria to set,too
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
pPlayer->ModifyOrAppendPlayerCriteria( set );
@ -9676,7 +9710,11 @@ bool CBaseEntity::SUB_AllowedToFade( void )
// on Xbox, allow these to fade out
#ifndef _XBOX
CBasePlayer *pPlayer = ( AI_IsSinglePlayer() ) ? UTIL_GetLocalPlayer() : NULL;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = ( AI_IsSinglePlayer() ) ? UTIL_GetLocalPlayer() : NULL;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && pPlayer->FInViewCone( this ) )
return false;

View File

@ -1266,7 +1266,11 @@ bool CBaseFlex::ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoSc
// only check occasionally
else if (info->m_flNext <= gpGlobals->curtime)
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// if not in view, disable
info->m_bHasArrived = (pPlayer && !pPlayer->FInViewCone( this ) );
@ -2883,7 +2887,13 @@ void CFlexCycler::Think( void )
Vector forward, right, up;
GetVectors( &forward, &right, &up );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = (CBaseEntity *)UTIL_GetNearestVisiblePlayer(this);
#else
CBaseEntity *pPlayer = (CBaseEntity *)UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if (pPlayer)
{
if (pPlayer->GetSmoothedVelocity().Length() != 0 && DotProduct( forward, pPlayer->EyePosition() - EyePosition()) > 0.5)

View File

@ -162,7 +162,12 @@ void CColorCorrectionVolume::Spawn( void )
bool CColorCorrectionVolume::PassesTriggerFilters( CBaseEntity *pEntity )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if( pEntity->IsPlayer() )
#else
if( pEntity == UTIL_GetLocalPlayer() )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return true;
return false;

View File

@ -1142,7 +1142,12 @@ Vector CBlood::BloodPosition( CBaseEntity *pActivator )
}
else
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
player = UTIL_GetNearestVisiblePlayer(this);
#else
player = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if ( player )

View File

@ -82,7 +82,16 @@ float GetZoomOwnerDesiredFOV( CBaseEntity *pZoomOwner )
//-----------------------------------------------------------------------------
void CEnvZoom::InputZoom( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer;
if ( inputdata.pActivator && inputdata.pActivator->IsPlayer() )
pPlayer = ToBasePlayer( inputdata.pActivator );
else
pPlayer= UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
@ -113,7 +122,15 @@ void CEnvZoom::InputZoom( inputdata_t &inputdata )
//-----------------------------------------------------------------------------
void CEnvZoom::InputUnZoom( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer;
if ( inputdata.pActivator && inputdata.pActivator->IsPlayer() )
pPlayer = ToBasePlayer( inputdata.pActivator );
else
pPlayer= UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{

View File

@ -964,7 +964,12 @@ void CPropJeepEpisodic::UpdateRadar( bool forceUpdate )
//Msg("Server detected %d objects\n", m_iNumRadarContacts );
//SecobMod__Information: Fix pPlayer from sp to mp.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CSingleUserRecipientFilter filter(pPlayer);
UserMessageBegin( filter, "UpdateJalopyRadar" );
WRITE_BYTE( 0 ); // end marker
@ -1139,7 +1144,12 @@ CBaseEntity *CPropJeepEpisodic::OnFailedPhysGunPickup( Vector vPhysgunPos )
{
// Player's forward direction
Vector vecPlayerForward;
//SecobMod__Information: Fix pPlayer from sp to mp.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer == NULL )
return NULL;
@ -1320,6 +1330,14 @@ static void KillBlockingEnemyNPCs( CBasePlayer *pPlayer, CBaseEntity *pVehicleEn
CTakeDamageInfo dmgInfo( pVehicleEntity, pVehicleEntity, damageForce, contactList[i], 200.0f, DMG_CRUSH|DMG_VEHICLE );
npcList[i]->TakeDamage( dmgInfo );
//SecobMod__Information Occasionally on hitting an AI the game would crash, so fix the null error here.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
IPhysicsObject*physicsObj = npcList[i]->VPhysicsGetObject();
if (physicsObj == NULL)
return;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
pVehiclePhysics->ApplyForceOffset( vehicleForce, contactList[i] );
PhysCollisionSound( pVehicleEntity, npcList[i]->VPhysicsGetObject(), CHAN_BODY, pVehiclePhysics->GetMaterialIndex(), npcList[i]->VPhysicsGetObject()->GetMaterialIndex(), gpGlobals->frametime, 200.0f );
}
@ -1625,7 +1643,9 @@ int CPropJeepEpisodic::DrawDebugTextOverlays( void )
void CPropJeepEpisodic::InputOutsideTransition( inputdata_t &inputdata )
{
// Teleport into the new map
CBasePlayer *pPlayer = AI_GetSinglePlayer();
//SecobMod__Information: Fix pPlayer from sp to mp.
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
//CBasePlayer *pPlayer = AI_GetSinglePlayer();
Vector vecTeleportPos;
QAngle vecTeleportAngles;

View File

@ -1363,7 +1363,11 @@ void CServerGameDLL::Think( bool finalTick )
if ( m_fAutoSaveDangerousTime != 0.0f && m_fAutoSaveDangerousTime < gpGlobals->curtime )
{
// The safety timer for a dangerous auto save has expired
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && ( pPlayer->GetDeathTime() == 0.0f || pPlayer->GetDeathTime() > gpGlobals->curtime )
&& !pPlayer->IsSinglePlayerGameEnding()
@ -3352,7 +3356,12 @@ void CServerGameClients::GetBugReportInfo( char *buf, int buflen )
if ( gpGlobals->maxClients == 1 )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *ent = FindPickerEntity( UTIL_GetLocalPlayer() );
#else
CBaseEntity *ent = FindPickerEntity( UTIL_PlayerByIndex(1) );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( ent )
{
Q_snprintf( buf, buflen, "Picker %i/%s - ent %s model %s\n",

View File

@ -241,7 +241,12 @@ void CGameWeaponManager::Think()
if ( gpGlobals->maxClients == 1 )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(pCandidate);
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Nodraw serves as a flag that this weapon is already being removed since
// all we're really doing inside this loop is marking them for removal by
// the entity system. We don't want to count the same weapon as removed
@ -259,10 +264,12 @@ void CGameWeaponManager::Think()
fRemovedOne = true;
}
}
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
else
{
fRemovedOne = true;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( fRemovedOne )
{

View File

@ -622,7 +622,12 @@ void CFlextalkActor::ProcessSceneEvents( void )
}
else if (flex_talk.GetInt() == -4)
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
AddLookTarget( UTIL_GetNearestVisiblePlayer(this), 0.5, flex_looktime.GetFloat() );
#else
AddLookTarget( UTIL_PlayerByIndex( 1 ), 0.5, flex_looktime.GetFloat() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
flex_talk.SetValue( "0" );
}
else if (flex_talk.GetInt() == -5)

View File

@ -399,8 +399,11 @@ bool CGib::SUB_AllowedToFade( void )
if( VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD || GetEFlags() & EFL_IS_BEING_LIFTED_BY_BARNACLE )
return false;
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = ( AI_IsSinglePlayer() ) ? UTIL_GetLocalPlayer() : NULL;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && pPlayer->FInViewCone( this ) && m_bForceRemove == false )
{

View File

@ -124,6 +124,9 @@ void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics )
{
(*pTotal) = (*pMedics) = 0;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
//Do nothing here.
#else
if ( !AI_IsSinglePlayer() )
{
// @TODO (toml 10-22-04): no MP support right now
@ -131,6 +134,8 @@ void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics )
}
const Vector & vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CAI_BaseNPC ** ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
@ -147,15 +152,29 @@ void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics )
continue;
// They only count if I can use them.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if( ppAIs[i]->IRelationType( UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin()) ) != D_LI )
continue;
#else
if( ppAIs[i]->IRelationType( UTIL_GetLocalPlayer() ) != D_LI )
continue;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Skip distant NPCs
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
Vector vNearestPlayerPos = UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin())->GetAbsOrigin();
if ( !ppAIs[i]->IsInPlayerSquad() &&
!UTIL_FindClientInPVS( ppAIs[i]->edict() ) &&
( ( ppAIs[i]->GetAbsOrigin() - vNearestPlayerPos ).LengthSqr() > 150*12 ||
fabsf( ppAIs[i]->GetAbsOrigin().z - vNearestPlayerPos.z ) > 192 ) )
continue;
#else
if ( !ppAIs[i]->IsInPlayerSquad() &&
!UTIL_FindClientInPVS( ppAIs[i]->edict() ) &&
( ( ppAIs[i]->GetAbsOrigin() - vPlayerPos ).LengthSqr() > 150*12 ||
fabsf( ppAIs[i]->GetAbsOrigin().z - vPlayerPos.z ) > 192 ) )
continue;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( FClassnameIs( ppAIs[i], "npc_citizen" ) )
{

View File

@ -560,7 +560,11 @@ CAI_Hint *CAI_ActBusyBehavior::FindCombatActBusyHintNode()
{
Assert( IsCombatActBusy() );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( !pPlayer )
return NULL;
@ -605,7 +609,11 @@ CAI_Hint *CAI_ActBusyBehavior::FindCombatActBusyTeleportHintNode()
{
Assert( IsCombatActBusy() );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( !pPlayer )
return NULL;
@ -907,7 +915,11 @@ void CAI_ActBusyBehavior::GatherConditions( void )
ClearCondition( COND_SEE_ENEMY );
ClearCondition( COND_NEW_ENEMY );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer )
{
@ -1248,7 +1260,12 @@ int CAI_ActBusyBehavior::SelectScheduleWhileNotBusy( int iBase )
{
if( IsCombatActBusy() )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(GetOuter());
if ( m_hActBusyGoal->IsCombatActBusyTeleportAllowed() && m_iNumConsecutivePathFailures >= 2 && !pPlayer->FInViewCone(GetOuter()) )
#else
if ( m_hActBusyGoal->IsCombatActBusyTeleportAllowed() && m_iNumConsecutivePathFailures >= 2 && !AI_GetSinglePlayer()->FInViewCone(GetOuter()) )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
// Looks like I've tried several times to find a path to a valid hint node and
// haven't been able to. This means I'm on a patch of node graph that simply

View File

@ -1172,7 +1172,11 @@ void CAntlionTemplateMaker::FindNodesCloseToPlayer( void )
{
SetContextThink( &CAntlionTemplateMaker::FindNodesCloseToPlayer, gpGlobals->curtime + random->RandomFloat( 0.75, 1.75 ), s_pBlockedEffectsThinkContext );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); // dubious
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer == NULL )
return;
@ -1259,7 +1263,12 @@ void CAntlionTemplateMaker::BlockedCheckFunc( void )
if ( pNode )
{
Vector vHintPos;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pNode->GetPosition( UTIL_GetNearestPlayer(GetAbsOrigin()), &vHintPos );
#else
pNode->GetPosition( AI_GetSinglePlayer(), &vHintPos );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity* pList[20];
int count = UTIL_EntitiesInBox( pList, 20, vHintPos + NAI_Hull::Mins( HULL_MEDIUM ), vHintPos + NAI_Hull::Maxs( HULL_MEDIUM ), 0 );

View File

@ -952,7 +952,11 @@ void CEnvHeadcrabCanister::Detonate( )
// Shake the screen unless flagged otherwise
if ( !HasSpawnFlags( SF_NO_SHAKE ) )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// If the player is on foot, then do a more limited shake
float shakeRadius = ( pPlayer && pPlayer->IsInAVehicle() ) ? sk_env_headcrabcanister_shake_radius_vehicle.GetFloat() : sk_env_headcrabcanister_shake_radius.GetFloat();

View File

@ -915,6 +915,13 @@ void CFuncTank::Spawn( void )
AddSolidFlags( FSOLID_NOT_SOLID );
}
//SecobMod__Information: This is code added from DutchMegas' Collaborate source mod to fix func_tank for hl2mp usage.
CDynamicProp *pProp = dynamic_cast<CDynamicProp*>(GetParent());
if ( pProp )
{
pProp->SetClientSideAnimation( false );
}
/**/
m_hControlVolume = NULL;
if ( GetParent() && GetParent()->GetBaseAnimating() )
@ -1213,6 +1220,11 @@ bool CFuncTank::StartControl( CBaseCombatCharacter *pController )
m_hController->GetActiveWeapon()->Holster();
}
//SecobMod__Information: Here we add code from DutchMegas' Collaborate source mod.
if ( pController->IsPlayer() )
pController->SetNextAttack( gpGlobals->curtime + 1.0f );
/**/
// Set the controller's position to be the use position.
m_vecControllerUsePos = m_hController->GetLocalOrigin();
@ -1272,6 +1284,8 @@ void CFuncTank::StopControl()
{
CBasePlayer *pPlayer = static_cast<CBasePlayer*>( m_hController.Get() );
pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONSELECTION;
pPlayer->SwitchToNextBestWeapon(pPlayer->GetActiveWeapon());//SecobMod__Information: Restores to a weapon.
}
// Stop thinking.
@ -1765,7 +1779,13 @@ void CFuncTank::Think( void )
}
#ifdef FUNCTANK_AUTOUSE
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
bool bThinkFast = false;
if( pPlayer )
@ -2415,6 +2435,10 @@ void CFuncTank::DoMuzzleFlash( void )
data.m_nAttachmentIndex = m_nBarrelAttachment;
data.m_nEntIndex = pAnim->entindex();
//SecobMod__Information: Here we add code from DutchMegas' Collaborate source mode.
pAnim->GetAttachment( m_nBarrelAttachment, data.m_vOrigin );
/**/
// FIXME: Create a custom entry here!
DispatchEffect( "ChopperMuzzleFlash", data );
}
@ -2426,6 +2450,10 @@ void CFuncTank::DoMuzzleFlash( void )
data.m_flScale = 1.0f;
data.m_fFlags = MUZZLEFLASH_COMBINE;
//SecobMod__Information: Here we add code from DutchMegas' Collaborate source mode.
pAnim->GetAttachment( m_nBarrelAttachment, data.m_vOrigin );
/**/
DispatchEffect( "MuzzleFlash", data );
}
}
@ -2548,7 +2576,11 @@ void CFuncTank::Fire( int bulletCount, const Vector &barrelEnd, const Vector &fo
{
if ( IsX360() )
{
UTIL_PlayerByIndex(1)->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART | RUMBLE_FLAG_RANDOM_AMPLITUDE );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_GetNearestPlayer(GetAbsOrigin())->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART | RUMBLE_FLAG_RANDOM_AMPLITUDE );
#else
UTIL_PlayerByIndex(1)->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART | RUMBLE_FLAG_RANDOM_AMPLITUDE );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else
{
@ -2894,6 +2926,10 @@ bool CFuncTankGun::KeyValue( const char *szKeyName, const char *szValue )
//-----------------------------------------------------------------------------
void CFuncTankGun::Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread )
{
//SecobMod__Information: This is required so that tracers show up for mounted guns.
IPredictionSystem::SuppressHostEvents( NULL );
/**/
int i;
FireBulletsInfo_t info;
@ -3651,6 +3687,10 @@ void CFuncTankAirboatGun::DoMuzzleFlash( void )
data.m_nEntIndex = m_hAirboatGunModel->entindex();
data.m_nAttachmentIndex = m_nGunBarrelAttachment;
data.m_flScale = 1.0f;
//SecobMod__Information: Here we add code from DutchMegas' Collaborate source mode.
m_hAirboatGunModel->GetAttachment( m_nGunBarrelAttachment, data.m_vOrigin );
/**/
DispatchEffect( "AirboatMuzzleFlash", data );
}
}
@ -4244,7 +4284,12 @@ enum
void UTIL_VisualizeCurve( int type, int steps, float bias )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Vector vForward, vRight, vUp;
pPlayer->EyeVectors( &vForward, &vRight, &vUp );
@ -5039,7 +5084,19 @@ void CFuncTankCombineCannon::FuncTankPostThink()
AddSpawnFlags( SF_TANK_AIM_AT_POS );
Vector vecTargetPosition = GetTargetPosition();
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
////SecobMod__Information: Fixing null pointers on ep2_outland_09.
if (pPlayer == NULL)
{
CreateBeam();
return;
}
Vector vecToPlayer = pPlayer->WorldSpaceCenter() - GetAbsOrigin();
vecToPlayer.NormalizeInPlace();
@ -5048,15 +5105,28 @@ void CFuncTankCombineCannon::FuncTankPostThink()
if( flDot >= 0.9f && m_bShouldHarrass )
{
//SecobMod__Information: Harrassing doesn't appear to work for hl2mp, so we hack this to work. Basically we dont put any code here for harrass and instead place it in the else below.
// Original Code.
//Msg("%s Harrassing player\n", GetDebugName() );
vecTargetPosition = pPlayer->EyePosition();
bHarass = true;
//vecTargetPosition = pPlayer->EyePosition();
//bHarass = true;
}
else
{
//SecobMod__Information: We include our own form of harrassing the player here. Basically if a player isnt in sight, the code runs as normal shooting enemies. If a player comes in sight, then the guns start attacking them till they manage to hide.
// Original Code.
//Msg( "%s Bored\n", GetDebugName() );
// Just point off in the distance, more or less directly ahead of me.
vecTargetPosition = GetAbsOrigin() + m_vecTrueForward * 1900.0f;
//vecTargetPosition = GetAbsOrigin() + m_vecTrueForward * 1900.0f;
m_hBeam->SetColor( 0,0, 0 );
vecTargetPosition = pPlayer->EyePosition();
Vector vecForwardCurrent = vecToPlayer;
Vector vecBarrelCurrentEnd = WorldBarrelPosition();//SecobMod__MiscFixes Seco had added to the barrel position + 1.0f;
BaseClass::Fire( 1, vecBarrelCurrentEnd, vecForwardCurrent, pPlayer, false );
//m_flTimeBeamOn = gpGlobals->curtime + 0.2f;
//m_flTimeNextSweep = gpGlobals->curtime + random->RandomInt( 2.0f, 4.0f ); //When "harrassing" make sure we have a longer random wait time before the next shot. Otherwise things get quite hairy for players!
bHarass = true;
}
int i;
@ -5200,9 +5270,20 @@ void CFuncTankCombineCannon::Fire( int bulletCount, const Vector &barrelEnd, con
void CFuncTankCombineCannon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
// If the shot passed near the player, shake the screen.
//SecobMod__Information: Updated for multiplayer.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
if ( pPlayer == NULL)
{
return;
}
Vector vecPlayer = pPlayer->EyePosition();
#else
if( AI_IsSinglePlayer() )
{
Vector vecPlayer = AI_GetSinglePlayer()->EyePosition();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Vector vecNearestPoint = PointOnLineNearestPoint( vecTracerSrc, tr.endpos, vecPlayer );
@ -5213,7 +5294,9 @@ void CFuncTankCombineCannon::MakeTracer( const Vector &vecTracerSrc, const trace
// Don't shake the screen if we're hit (within 10 inches), but do shake if a shot otherwise comes within 10 feet.
UTIL_ScreenShake( vecNearestPoint, 10, 60, 0.3, 120.0f, SHAKE_START, false );
}
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Send the railgun effect
DispatchParticleEffect( "Weapon_Combine_Ion_Cannon", vecTracerSrc, tr.endpos, vec3_angle, NULL );

View File

@ -4625,7 +4625,8 @@ void CLogicPlayerProxy::Activate( void )
if ( m_hPlayer == NULL )
{
m_hPlayer = AI_GetSinglePlayer();
//SecobMod__MiscFixes
m_hPlayer = UTIL_GetLocalPlayer();
}
}

View File

@ -304,8 +304,15 @@ void CItem_DynamicResupply::InputKill( inputdata_t &data )
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::InputCalculateType( inputdata_t &data )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// spawn gear for the nearest player
CBasePlayer *pNearest = UTIL_GetNearestPlayer(GetAbsOrigin());
if ( pNearest != NULL )
SpawnDynamicItem( pNearest );
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
SpawnDynamicItem( pPlayer );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//-----------------------------------------------------------------------------

View File

@ -48,6 +48,9 @@
#include "ammodef.h"
#include "vehicle_base.h"
//SecobMod__MiscFixes: Here we include the hl2mp gamerules so that calls to darkness mode work and also in the file change darkness mode HL2GameRules to HL2MPRules.
#include "hl2mp_gamerules.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -977,8 +980,9 @@ int CNPC_BaseZombie::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo )
//-----------------------------------------------------------------------------
void CNPC_BaseZombie::MakeAISpookySound( float volume, float duration )
{
#ifdef HL2_EPISODIC
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
#ifdef HL2_EPISODIC
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
CSoundEnt::InsertSound( SOUND_COMBAT, EyePosition(), volume, duration, this, SOUNDENT_CHANNEL_SPOOKY_NOISE );
}
@ -1084,7 +1088,8 @@ bool CNPC_BaseZombie::ShouldIgniteZombieGib( void )
#ifdef HL2_EPISODIC
// If we're in darkness mode, don't ignite giblets, because we don't want to
// pay the perf cost of multiple dynamic lights per giblet.
return ( IsOnFire() && !HL2GameRules()->IsAlyxInDarknessMode() );
//SecobMod
return ( IsOnFire() && !HL2MPRules()->IsAlyxInDarknessMode() );
#else
return IsOnFire();
#endif
@ -1294,7 +1299,8 @@ void CNPC_BaseZombie::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize
BaseClass::Ignite( flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner );
#ifdef HL2_EPISODIC
if ( HL2GameRules()->IsAlyxInDarknessMode() == true && GetEffectEntity() != NULL )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() == true && GetEffectEntity() != NULL )
{
GetEffectEntity()->AddEffects( EF_DIMLIGHT );
}

View File

@ -964,7 +964,8 @@ void CNPC_Alyx::AnalyzeGunfireSound( CSound *pSound )
//-----------------------------------------------------------------------------
bool CNPC_Alyx::IsValidEnemy( CBaseEntity *pEnemy )
{
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
if ( !CanSeeEntityInDarkness( pEnemy ) )
return false;
@ -1266,7 +1267,8 @@ void CNPC_Alyx::DoCustomSpeechAI( void )
// Darkness mode speech
ClearCondition( COND_ALYX_IN_DARK );
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
// Even though the darkness light system will take flares into account when Alyx
// says she's lost the player in the darkness, players still think she's silly
@ -1448,7 +1450,8 @@ void CNPC_Alyx::DoCustomSpeechAI( void )
{
// If we've left darkness mode, or if the player has blinded me with
// the flashlight, don't bother speaking the found player line.
if ( !m_bIsFlashlightBlind && HL2GameRules()->IsAlyxInDarknessMode() && m_bDarknessSpeechAllowed )
//SecobMod
if ( !m_bIsFlashlightBlind && HL2MPRules()->IsAlyxInDarknessMode() && m_bDarknessSpeechAllowed )
{
if ( HasCondition(COND_SEE_PLAYER) && !HasCondition( COND_TALKER_PLAYER_DEAD ) )
{
@ -1597,7 +1600,8 @@ bool CNPC_Alyx::FInViewCone( CBaseEntity *pEntity )
}
// Else, fall through...
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
if ( CanSeeEntityInDarkness( pEntity ) )
return true;
@ -1636,7 +1640,8 @@ bool CNPC_Alyx::CanSeeEntityInDarkness( CBaseEntity *pEntity )
//-----------------------------------------------------------------------------
bool CNPC_Alyx::QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC)
{
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
if ( !CanSeeEntityInDarkness( pEntity ) )
return false;
@ -1760,7 +1765,8 @@ int CNPC_Alyx::SelectSchedule( void )
{
// If we're in darkness mode, and the player has the flashlight off, and we hear a zombie footstep,
// and the player isn't nearby, deliberately turn away from the zombie to let the zombie grab me.
if ( HL2GameRules()->IsAlyxInDarknessMode() && m_NPCState == NPC_STATE_ALERT )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() && m_NPCState == NPC_STATE_ALERT )
{
if ( HasCondition ( COND_HEAR_COMBAT ) && !HasCondition(COND_SEE_PLAYER) )
{
@ -1940,7 +1946,8 @@ int CNPC_Alyx::TranslateSchedule( int scheduleType )
case SCHED_HIDE_AND_RELOAD:
{
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() )
return SCHED_RELOAD;
// If I don't have a ranged attacker as an enemy, don't try to hide
@ -2346,7 +2353,8 @@ int CNPC_Alyx::OnTakeDamage_Alive( const CTakeDamageInfo &info )
int taken = BaseClass::OnTakeDamage_Alive(info);
if ( taken && HL2GameRules()->IsAlyxInDarknessMode() && !HasCondition( COND_TALKER_PLAYER_DEAD ) )
//SecobMod
if ( taken && HL2MPRules()->IsAlyxInDarknessMode() && !HasCondition( COND_TALKER_PLAYER_DEAD ) )
{
if ( !HasCondition(COND_SEE_ENEMY) && (info.GetDamageType() & (DMG_SLASH | DMG_CLUB) ) )
{
@ -2770,7 +2778,8 @@ bool CNPC_Alyx::PlayerFlashlightOnMyEyes( CBasePlayer *pPlayer )
float flDist = VectorNormalize( vecToEyes );
// We can be blinded in daylight, but only at close range
if ( HL2GameRules()->IsAlyxInDarknessMode() == false )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() == false )
{
if ( flDist > (8*12.0f) )
return false;

View File

@ -4115,12 +4115,23 @@ bool CNPC_Antlion::CorpseGib( const CTakeDamageInfo &info )
void CNPC_Antlion::Touch( CBaseEntity *pOther )
{
//See if the touching entity is a vehicle
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = ToBasePlayer( AI_GetSinglePlayer() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// FIXME: Technically we'll want to check to see if a vehicle has touched us with the player OR NPC driver
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer || !pPlayer->IsInAVehicle() )
continue;
#else
if ( pPlayer && pPlayer->IsInAVehicle() )
{
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
IServerVehicle *pVehicle = pPlayer->GetVehicle();
CBaseEntity *pVehicleEnt = pVehicle->GetVehicleEnt();
@ -4170,6 +4181,9 @@ void CNPC_Antlion::Touch( CBaseEntity *pOther )
}
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
break; // safe to assume will only be touched by 1 vehicle per frame
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
}

View File

@ -1619,8 +1619,13 @@ public:
//-----------------------------------------------------------------------------
void CNPC_AntlionGuard::Footstep( bool bHeavy )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
Assert( pPlayer != NULL );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer == NULL )
return;

View File

@ -5648,7 +5648,11 @@ void CGrenadeHelicopter::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t
bool CGrenadeHelicopter::IsThrownByPlayer()
{
// if player is the owner and we're set to explode on contact, then the player threw this grenade.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
return ( m_bExplodeOnContact );
#else
return ( ( GetOwnerEntity() == UTIL_GetLocalPlayer() ) && m_bExplodeOnContact );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//-----------------------------------------------------------------------------

View File

@ -1309,7 +1309,12 @@ void CNPC_BaseScanner::DiveBombSoundThink()
pPhysicsObject->GetPosition( &vecPosition, NULL );
pPhysicsObject->GetVelocity( &vecVelocity, NULL );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
Vector vecDelta;

View File

@ -394,7 +394,8 @@ BEGIN_DATADESC( CNPC_Citizen )
DEFINE_INPUTFUNC( FIELD_VOID, "SetAmmoResupplierOff", InputSetAmmoResupplierOff ),
DEFINE_INPUTFUNC( FIELD_VOID, "SpeakIdleResponse", InputSpeakIdleResponse ),
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
DEFINE_INPUTFUNC( FIELD_VOID, "ThrowHealthKit", InputForceHealthKitToss ),
#endif
@ -1324,7 +1325,8 @@ int CNPC_Citizen::SelectSchedulePriorityAction()
int CNPC_Citizen::SelectScheduleHeal()
{
// episodic medics may toss the healthkits rather than poke you with them
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
if ( CanHeal() )
{
@ -1707,7 +1709,8 @@ void CNPC_Citizen::StartTask( const Task_t *pTask )
break;
case TASK_CIT_HEAL:
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
case TASK_CIT_HEAL_TOSS:
#endif
if ( IsMedic() )
@ -1833,7 +1836,8 @@ void CNPC_Citizen::RunTask( const Task_t *pTask )
break;
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
case TASK_CIT_HEAL_TOSS:
if ( IsSequenceFinished() )
{
@ -4065,7 +4069,8 @@ void CNPC_Citizen::Heal()
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
//-----------------------------------------------------------------------------
// Like Heal(), but tosses a healthkit in front of the player rather than just juicing him up.
//-----------------------------------------------------------------------------
@ -4342,7 +4347,8 @@ AI_BEGIN_CUSTOM_NPC( npc_citizen, CNPC_Citizen )
DECLARE_TASK( TASK_CIT_SIT_ON_TRAIN )
DECLARE_TASK( TASK_CIT_LEAVE_TRAIN )
DECLARE_TASK( TASK_CIT_SPEAK_MOURNING )
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
DECLARE_TASK( TASK_CIT_HEAL_TOSS )
#endif
@ -4380,7 +4386,8 @@ AI_BEGIN_CUSTOM_NPC( npc_citizen, CNPC_Citizen )
" Interrupts"
)
#if HL2_EPISODIC
//SecobMod.
#ifdef HL2_EPISODIC
//=========================================================
// > SCHED_CITIZEN_HEAL_TOSS
// this is for the episodic behavior where the citizen hurls the medkit

View File

@ -237,14 +237,16 @@ public:
bool CanHeal();
bool ShouldHealTarget( CBaseEntity *pTarget, bool bActiveUse = false );
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
bool ShouldHealTossTarget( CBaseEntity *pTarget, bool bActiveUse = false );
#endif
void Heal();
bool ShouldLookForHealthItem();
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
void TossHealthKit( CBaseCombatCharacter *pThrowAt, const Vector &offset ); // create a healthkit and throw it at someone
void InputForceHealthKitToss( inputdata_t &inputdata );
#endif

View File

@ -927,7 +927,11 @@ void CNPC_Combine::StartTask( const Task_t *pTask )
case TASK_COMBINE_SIGNAL_BEST_SOUND:
if( IsInSquad() && GetSquad()->NumMembers() > 1 )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer && OccupyStrategySlot( SQUAD_SLOT_EXCLUSIVE_HANDSIGN ) && pPlayer->FInViewCone( this ) )
{

View File

@ -1609,7 +1609,12 @@ void CNPC_CombineDropship::UpdateRotorWashVolume( CSoundPatch *pRotorSound, floa
void CNPC_CombineDropship::UpdateRotorWashVolume()
{
float flNearFactor = 0.0f;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if (pPlayer)
{
float flDist = pPlayer->GetAbsOrigin().DistTo( GetAbsOrigin() );

View File

@ -2394,8 +2394,13 @@ void CNPC_CombineGunship::UpdateRotorSoundPitch( int iPitch )
// Apply the pitch to both sounds.
controller.SoundChangePitch( m_pAirExhaustSound, iPitch, 0.1 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
// FIXME: Doesn't work in multiplayer
CBaseEntity *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if (pPlayer)
{
Vector pos;

View File

@ -79,7 +79,8 @@ void CNPC_CombineS::Spawn( void )
BaseClass::Spawn();
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
if (m_iUseMarch && !HasSpawnFlags(SF_NPC_START_EFFICIENT))
{
Msg( "Soldier %s is set to use march anim, but is not an efficient AI. The blended march anim can only be used for dead-ahead walks!\n", GetDebugName() );
@ -255,7 +256,8 @@ void CNPC_CombineS::OnChangeActivity( Activity eNewActivity )
BaseClass::OnChangeActivity( eNewActivity );
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
// Give each trooper a varied look for his march. Done here because if you do it earlier (eg Spawn, StartTask), the
// pose param gets overwritten.
if (m_iUseMarch)
@ -425,7 +427,8 @@ bool CNPC_CombineS::IsHeavyDamage( const CTakeDamageInfo &info )
return BaseClass::IsHeavyDamage( info );
}
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
//-----------------------------------------------------------------------------
// Purpose: Translate base class activities into combot activites
//-----------------------------------------------------------------------------

View File

@ -18,7 +18,9 @@
class CNPC_CombineS : public CNPC_Combine
{
DECLARE_CLASS( CNPC_CombineS, CNPC_Combine );
#if HL2_EPISODIC
//SecobMod__IFDEF_Fixes
#ifdef HL2_EPISODIC
DECLARE_DATADESC();
#endif
@ -49,7 +51,8 @@ public:
private:
bool ShouldHitPlayer( const Vector &targetDir, float targetDist );
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
public:
Activity NPC_TranslateActivity( Activity eNewActivity );

View File

@ -340,7 +340,12 @@ void CNPC_Dog::SetPlayerAvoidState( void )
physfollower_t *pBone;
int i;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pLocalPlayer )
{
@ -832,7 +837,12 @@ void CNPC_Dog::ThrowObject( const char *pAttachmentName )
}
if ( m_hThrowTarget == NULL )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this);
#else
m_hThrowTarget = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Vector vThrowDirection;
@ -1385,7 +1395,11 @@ void CNPC_Dog::RunTask( const Task_t *pTask )
SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
float flDistanceToPlayer = flDistance;
@ -1519,7 +1533,12 @@ void CNPC_Dog::SetupThrowTarget( void )
{
if ( m_hThrowTarget == NULL )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this);
#else
m_hThrowTarget = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
SetTarget( m_hThrowTarget );
@ -1674,7 +1693,11 @@ void CNPC_Dog::StartTask( const Task_t *pTask )
m_flNextSwat = gpGlobals->curtime + pTask->flTaskData;
if ( m_hThrowTarget == NULL )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this);
#else
m_hThrowTarget = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
TaskComplete();
break;

View File

@ -352,9 +352,15 @@ void CNPC_EnemyFinder::StartNPC ( void )
// the ground just because it's not MOVETYPE_FLY
BaseClass::StartNPC();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( m_PlayerFreePass.GetParams().duration > 0.1 )
{
m_PlayerFreePass.SetPassTarget( UTIL_GetNearestPlayer(GetAbsOrigin()) );
#else
if ( AI_IsSinglePlayer() && m_PlayerFreePass.GetParams().duration > 0.1 )
{
m_PlayerFreePass.SetPassTarget( UTIL_PlayerByIndex(1) );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
AI_FreePassParams_t freePassParams = m_PlayerFreePass.GetParams();
@ -424,7 +430,12 @@ bool CNPC_EnemyFinder::ShouldAlwaysThink()
if ( BaseClass::ShouldAlwaysThink() )
return true;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef MAPBASE
if ( pPlayer && IRelationType( pPlayer ) <= D_FR )
#else

View File

@ -33,6 +33,9 @@
#include "hl2_gamerules.h"
#include "decals.h"
//SecobMod__MiscFixes: Here we include the hl2mp gamerules so that calls to darkness mode work.
#include "hl2mp_gamerules.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -1326,7 +1329,8 @@ void CBaseHeadcrab::JumpFromCanister()
void CBaseHeadcrab::DropFromCeiling( void )
{
#ifdef HL2_EPISODIC
if ( HL2GameRules()->IsAlyxInDarknessMode() )
//SecobMod__MiscFixes HL2MPRules as opposed to singleplayer HL2GameRules.
if ( HL2MPRules()->IsAlyxInDarknessMode() )
{
if ( IsHangingFromCeiling() )
{
@ -1342,7 +1346,11 @@ void CBaseHeadcrab::DropFromCeiling( void )
{
SetSchedule( SCHED_HEADCRAB_CEILING_DROP );
CBaseEntity *pPlayer = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
@ -1909,7 +1917,8 @@ int CBaseHeadcrab::SelectSchedule( void )
{
bool bIsAlyxInDarknessMode = false;
#ifdef HL2_EPISODIC
bIsAlyxInDarknessMode = HL2GameRules()->IsAlyxInDarknessMode();
//SecobMod
bIsAlyxInDarknessMode = HL2MPRules()->IsAlyxInDarknessMode();
#endif // HL2_EPISODIC
if ( bIsAlyxInDarknessMode == false && ( HasCondition( COND_CAN_RANGE_ATTACK1 ) || HasCondition( COND_NEW_ENEMY ) ) )
@ -2091,7 +2100,8 @@ void CBaseHeadcrab::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize,
if( !bWasOnFire )
{
#ifdef HL2_EPISODIC
if ( HL2GameRules()->IsAlyxInDarknessMode() == true )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() == true )
{
GetEffectEntity()->AddEffects( EF_DIMLIGHT );
}
@ -3383,8 +3393,8 @@ void CBlackHeadcrab::Panic( float flDuration )
m_bPanicState = true;
}
#if HL2_EPISODIC
//SecobMod
#ifdef HL2_EPISODIC
//-----------------------------------------------------------------------------
// Purpose: Black headcrabs have 360-degree vision when they are in the ambush
// schedule. This is because they ignore sounds when in ambush, and

View File

@ -272,7 +272,9 @@ public:
virtual void AlertSound( void );
virtual void ImpactSound( void );
virtual void TelegraphSound( void );
#if HL2_EPISODIC
//SecobMod__IFDEF_Fixes
#ifdef HL2_EPISODIC
virtual bool FInViewCone( CBaseEntity *pEntity );
#endif

View File

@ -551,7 +551,12 @@ void CNPC_MetroPolice::PrescheduleThink( void )
m_bPlayerIsNear = false;
if ( PlayerIsCriminal() == false )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && ( pPlayer->WorldSpaceCenter() - WorldSpaceCenter() ).LengthSqr() < (128*128) )
{
@ -4643,7 +4648,12 @@ void CNPC_MetroPolice::AnnounceHarrassment( void )
//-----------------------------------------------------------------------------
void CNPC_MetroPolice::IncrementPlayerCriminalStatus( void )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
@ -4695,8 +4705,10 @@ float CNPC_MetroPolice::GetIdealAccel( void ) const
//-----------------------------------------------------------------------------
void CNPC_MetroPolice::AdministerJustice( void )
{
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !AI_IsSinglePlayer() )
return;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// If we're allowed to chase the player, do so. Otherwise, just threaten.
if ( !IsInAScript() && (m_NPCState != NPC_STATE_SCRIPT) && HasSpawnFlags( SF_METROPOLICE_ALLOWED_TO_RESPOND ) )
@ -4709,7 +4721,14 @@ void CNPC_MetroPolice::AdministerJustice( void )
m_flChasePlayerTime = gpGlobals->curtime + RandomFloat( 3, 7 );
// Attack the target
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
if ( !pPlayer )
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
SetEnemy( pPlayer );
SetState( NPC_STATE_COMBAT );
UpdateEnemyMemory( pPlayer, pPlayer->GetAbsOrigin() );
@ -4733,7 +4752,13 @@ void CNPC_MetroPolice::AdministerJustice( void )
if ( pNPC->HasSpawnFlags( SF_METROPOLICE_ALLOWED_TO_RESPOND ) )
{
// Is he within site & range?
if ( FVisible(pNPC) && pNPC->FVisible( UTIL_PlayerByIndex(1) ) &&
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
if ( pPlayer && FVisible(pNPC) && pNPC->FVisible( pPlayer ) &&
#else
if ( FVisible(pNPC) && pNPC->FVisible( UTIL_PlayerByIndex(1) ) &&
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_DistApprox( WorldSpaceCenter(), pNPC->WorldSpaceCenter() ) < 512 )
{
pNPC->AdministerJustice();
@ -4750,7 +4775,13 @@ void CNPC_MetroPolice::AdministerJustice( void )
//-----------------------------------------------------------------------------
int CNPC_MetroPolice::SelectSchedule( void )
{
if ( !GetEnemy() && HasCondition( COND_IN_PVS ) && AI_GetSinglePlayer() && !AI_GetSinglePlayer()->IsAlive() )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
if ( !GetEnemy() && HasCondition( COND_IN_PVS ) && pPlayer && !pPlayer->IsAlive() )
#else
if ( !GetEnemy() && HasCondition( COND_IN_PVS ) && AI_GetSinglePlayer() && !AI_GetSinglePlayer()->IsAlive() )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
return SCHED_PATROL_WALK;
}
@ -5893,8 +5924,11 @@ void CNPC_MetroPolice::GatherConditions( void )
{
ClearCondition( COND_METROPOLICE_PLAYER_TOO_CLOSE );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// FIXME: Player can be NULL here during level transitions.
if ( !pPlayer )
@ -6031,7 +6065,11 @@ void CNPC_MetroPolice::VPhysicsCollision( int index, gamevcollisionevent_t *pEve
if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
{
CHL2_Player *pPlayer = dynamic_cast<CHL2_Player *>(UTIL_PlayerByIndex( 1 ));
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CHL2_Player *pPlayer = dynamic_cast<CHL2_Player *>(UTIL_GetNearestPlayer(pHitEntity->GetAbsOrigin()));
#else
CHL2_Player *pPlayer = dynamic_cast<CHL2_Player *>(UTIL_PlayerByIndex( 1 ));
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// See if it's being held by the player
if ( pPlayer != NULL && pPlayer->IsHoldingEntity( pHitEntity ) )

View File

@ -399,9 +399,17 @@ void CNPC_PlayerCompanion::GatherConditions()
{
BaseClass::GatherConditions();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
////SecobMod__Information: Null pointer fixed.
CBasePlayer *pPlayer = ToBasePlayer( GetFollowBehavior().GetFollowTarget() );//UTIL_GetNearestPlayer(GetAbsOrigin());
if ( pPlayer )
{
#else
if ( AI_IsSinglePlayer() )
{
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( Classify() == CLASS_PLAYER_ALLY_VITAL )
{
@ -573,7 +581,11 @@ void CNPC_PlayerCompanion::GatherConditions()
//-----------------------------------------------------------------------------
void CNPC_PlayerCompanion::DoCustomSpeechAI( void )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Don't allow this when we're getting in the car
#ifdef HL2_EPISODIC
@ -611,7 +623,12 @@ void CNPC_PlayerCompanion::DoCustomSpeechAI( void )
//-----------------------------------------------------------------------------
void CNPC_PlayerCompanion::PredictPlayerPush()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && pPlayer->GetSmoothedVelocity().LengthSqr() >= Square(140))
{
Vector predictedPosition = pPlayer->WorldSpaceCenter() + pPlayer->GetSmoothedVelocity() * .4;
@ -1128,7 +1145,11 @@ int CNPC_PlayerCompanion::TranslateSchedule( int scheduleType )
{
if ( AI_IsSinglePlayer() )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif
pWeapon = pPlayer->GetActiveWeapon();
if( pWeapon && pWeapon->UsesClipsForAmmo1() &&
pWeapon->Clip1() < ( pWeapon->GetMaxClip1() * .75 ) &&
@ -1416,10 +1437,15 @@ void CNPC_PlayerCompanion::RunTask( const Task_t *pTask )
case TASK_PC_GET_PATH_OFF_COMPANION:
{
if ( AI_IsSinglePlayer() )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
GetNavigator()->SetAllowBigStep( UTIL_GetNearestPlayer(GetAbsOrigin()) );
#else
if ( AI_IsSinglePlayer() )
{
GetNavigator()->SetAllowBigStep( UTIL_GetLocalPlayer() );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
ChainRunTask( TASK_MOVE_AWAY_PATH, 48 );
}
break;
@ -1844,7 +1870,12 @@ void CNPC_PlayerCompanion::Touch( CBaseEntity *pOther )
if ( m_afMemory & bits_MEMORY_PROVOKED )
return;
TestPlayerPushing( ( pOther->IsPlayer() ) ? pOther : AI_GetSinglePlayer() );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
TestPlayerPushing( ( pOther->IsPlayer() ) ? pOther : UTIL_GetNearestPlayer(GetAbsOrigin()) );
#else
TestPlayerPushing( ( pOther->IsPlayer() ) ? pOther : AI_GetSinglePlayer() );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
}
@ -2109,7 +2140,11 @@ void CNPC_PlayerCompanion::UpdateReadiness()
}
}
if( ai_debug_readiness.GetBool() && AI_IsSinglePlayer() )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if( ai_debug_readiness.GetBool() )
#else
if( ai_debug_readiness.GetBool() && AI_IsSinglePlayer() )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
// Draw the readiness-o-meter
Vector vecSpot;
@ -2118,7 +2153,11 @@ void CNPC_PlayerCompanion::UpdateReadiness()
const float GRADLENGTH = 4.0f;
Vector right;
UTIL_PlayerByIndex( 1 )->GetVectors( NULL, &right, NULL );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_GetNearestPlayer(GetAbsOrigin())->GetVectors( NULL, &right, NULL );
#else
UTIL_PlayerByIndex( 1 )->GetVectors( NULL, &right, NULL );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( IsInScriptedReadinessState() )
{
@ -2258,14 +2297,23 @@ bool CNPC_PlayerCompanion::PickTacticalLookTarget( AILookTargetArgs_t *pArgs )
}
flMaxLookTime = flMinLookTime + random->RandomFloat( 0.0f, 0.5f );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pArgs->flDuration = random->RandomFloat( flMinLookTime, flMaxLookTime );
#else
pArgs->flDuration = random->RandomFloat( flMinLookTime, flMaxLookTime );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( HasCondition(COND_SEE_PLAYER) && hl2_episodic.GetBool() )
{
// 1/3rd chance to authoritatively look at player
if( random->RandomInt( 0, 2 ) == 0 )
{
pArgs->hTarget = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pArgs->hTarget = UTIL_GetNearestVisiblePlayer(this);
#else
pArgs->hTarget = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return true;
}
}
@ -3253,7 +3301,12 @@ void CNPC_PlayerCompanion::OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CB
}
}
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && IsInPlayerSquad() && ( pPlayer->GetAbsOrigin().AsVector2D() - GetAbsOrigin().AsVector2D() ).LengthSqr() < Square( 25*12 ) && IsAllowedToSpeak( TLK_WATCHOUT ) )
{
if ( !pPlayer->FInViewCone( pAttacker ) )
@ -3494,12 +3547,21 @@ float CNPC_PlayerCompanion::GetIdealSpeed() const
float CNPC_PlayerCompanion::GetIdealAccel() const
{
float multiplier = 1.0;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( m_bMovingAwayFromPlayer && (UTIL_GetNearestPlayer(GetAbsOrigin())->GetAbsOrigin() - GetAbsOrigin()).Length2DSqr() < Square(3.0*12.0) )
multiplier = 2.0;
return BaseClass::GetIdealAccel() * multiplier;
#else
if ( AI_IsSinglePlayer() )
{
if ( m_bMovingAwayFromPlayer && (UTIL_PlayerByIndex(1)->GetAbsOrigin() - GetAbsOrigin()).Length2DSqr() < Square(3.0*12.0) )
multiplier = 2.0;
}
return BaseClass::GetIdealAccel() * multiplier;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//-----------------------------------------------------------------------------
@ -3561,8 +3623,10 @@ bool CNPC_PlayerCompanion::ShouldAlwaysTransition( void )
//-----------------------------------------------------------------------------
void CNPC_PlayerCompanion::InputOutsideTransition( inputdata_t &inputdata )
{
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !AI_IsSinglePlayer() )
return;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Must want to do this
if ( ShouldAlwaysTransition() == false )
@ -3572,7 +3636,12 @@ void CNPC_PlayerCompanion::InputOutsideTransition( inputdata_t &inputdata )
if ( IsInAVehicle() )
return;
CBaseEntity *pPlayer = UTIL_GetLocalPlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
const Vector &playerPos = pPlayer->GetAbsOrigin();
// Mark us as already having succeeded if we're vital or always meant to come with the player
@ -4326,9 +4395,21 @@ bool CNPC_PlayerCompanion::IsNavigationUrgent( void )
// could not see the player but the player could in fact see them. Now the NPC's facing is
// irrelevant and the player's viewcone is more authorative. -- jdw
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
if ( pPlayer->FInViewCone( EyePosition() ) )
return false;
}
#else
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
if ( pLocalPlayer->FInViewCone( EyePosition() ) )
return false;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return true;
}

View File

@ -330,7 +330,8 @@ public:
void InputSetReadinessMedium( inputdata_t &inputdata );
void InputSetReadinessHigh( inputdata_t &inputdata );
void InputLockReadiness( inputdata_t &inputdata );
#if HL2_EPISODIC
//SecobMod__IFDEF_Fixes
#ifdef HL2_EPISODIC
void InputClearAllOuputs( inputdata_t &inputdata ); ///< annihilate every output on this npc
#endif

View File

@ -1873,7 +1873,12 @@ float CNPC_RollerMine::GetAttackDamageScale( CBaseEntity *pVictim )
if ( pVictim->MyNPCPointer() )
{
// If we don't hate the player, we're immune
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && pVictim->MyNPCPointer()->IRelationType( pPlayer ) != D_HT )
return 0.0;
}

View File

@ -714,7 +714,12 @@ CBaseEntity* CNPC_CScanner::BestInspectTarget(void)
if ( m_bOnlyInspectPlayers )
{
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pPlayer )
return NULL;

View File

@ -670,7 +670,12 @@ void CNPC_Strider::PostNPCInit()
RemoveFlag( FL_FLY );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_PlayerFreePass.SetPassTarget( UTIL_GetNearestPlayer(GetAbsOrigin()) );
#else
m_PlayerFreePass.SetPassTarget( UTIL_PlayerByIndex(1) );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
AI_FreePassParams_t freePassParams =
{
@ -796,7 +801,11 @@ int CNPC_Strider::DrawDebugTextOverlays()
text_offset++;
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
if ( GetSenses()->ShouldSeeEntity( pPlayer ) && GetSenses()->CanSeeEntity( pPlayer ) )
@ -3177,7 +3186,12 @@ int CNPC_Strider::OnTakeDamage_Alive( const CTakeDamageInfo &info )
{
// See if the person that injured me is an NPC.
CAI_BaseNPC *pAttacker = dynamic_cast<CAI_BaseNPC *>( info.GetAttacker() );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pAttacker && pAttacker->IsAlive() && pPlayer )
{
@ -3399,7 +3413,12 @@ bool CNPC_Strider::BecomeRagdoll( const CTakeDamageInfo &info, const Vector &for
{
// Otherwise just keel over
CRagdollProp *pRagdoll = NULL;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && mat_dxlevel.GetInt() > 0 )
{
int dxlevel = mat_dxlevel.GetInt();

View File

@ -1942,7 +1942,12 @@ QAngle CNPC_FloorTurret::PreferredCarryAngles( void )
static QAngle g_prefAngles;
Vector vecUserForward;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer->EyeVectors( &vecUserForward );
// If we're looking up, then face directly forward

View File

@ -442,7 +442,12 @@ void CNPC_Vortigaunt::RunTask( const Task_t *pTask )
case TASK_VORTIGAUNT_WAIT_FOR_PLAYER:
{
// Wait for the player to get near (before starting the bugbait sequence)
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer != NULL )
{
GetMotor()->SetIdealYawToTargetAndUpdate( pPlayer->GetAbsOrigin(), AI_KEEP_YAW_SPEED );
@ -661,8 +666,12 @@ int CNPC_Vortigaunt::RangeAttack1Conditions( float flDot, float flDist )
// See if it's too close to me
if ( ( GetAbsOrigin() - GetEnemy()->GetAbsOrigin() ).LengthSqr() < Square( AntlionWorkerBurstRadius() ) )
return COND_TOO_CLOSE_TO_ATTACK;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetEnemy()->GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && ( pPlayer->GetAbsOrigin() - GetEnemy()->GetAbsOrigin() ).LengthSqr() < Square( AntlionWorkerBurstRadius() ) )
{
// Warn the player to get away!
@ -919,7 +928,12 @@ void CNPC_Vortigaunt::HandleAnimEvent( animevent_t *pEvent )
// HACK: If we've still failed, just spawn it on the player
if ( i == iNumAttempts )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
vecSpawnOrigin = pPlayer->WorldSpaceCenter();
@ -1708,7 +1722,12 @@ void CNPC_Vortigaunt::MaintainHealSchedule( void )
return;
// For now, we only heal the player
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer == NULL )
return;
@ -2365,7 +2384,12 @@ Disposition_t CNPC_Vortigaunt::IRelationType( CBaseEntity *pTarget )
bool CNPC_Vortigaunt::HealGestureHasLOS( void )
{
//For now the player is always our target
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pTargetEnt = UTIL_GetNearestVisiblePlayer(this);
#else
CBaseEntity *pTargetEnt = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pTargetEnt == NULL )
return false;

View File

@ -35,6 +35,9 @@
#include "ai_interactions.h"
//SecobMod__MiscFixes: Here we include the hl2mp gamerules so that calls to darkness mode work.
#include "hl2mp_gamerules.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -633,7 +636,8 @@ bool CNPC_Zombine::AllowedToSprint( void )
if ( pPlayer )
{
if ( HL2GameRules()->IsAlyxInDarknessMode() && pPlayer->FlashlightIsOn() == false )
//SecobMod
if ( HL2MPRules()->IsAlyxInDarknessMode() && pPlayer->FlashlightIsOn() == false )
{
iChance = SPRINT_CHANCE_VALUE_DARKNESS;
}

View File

@ -794,6 +794,8 @@ void CPropCombineBall::WhizSoundThink()
pPhysicsObject->GetPosition( &vecPosition, NULL );
pPhysicsObject->GetVelocity( &vecVelocity, NULL );
//SecobMod__MiscFixes
//if ( gpGlobals->maxClients == 1 )
// Multiplayer equivelent, loops through players and decides if it should go or not, like SP.
if ( gpGlobals->maxClients > 1 )
{
@ -849,7 +851,11 @@ void CPropCombineBall::WhizSoundThink()
}
else
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); //Slightly different location due to OLD/NEW sdk code differences. Unsure if needed.
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{

View File

@ -890,7 +890,11 @@ void CProtoSniper::PaintTarget( const Vector &vecTarget, float flPaintTime )
//-----------------------------------------------------------------------------
bool CProtoSniper::IsPlayerAllySniper()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBaseEntity *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return IRelationType( pPlayer ) == D_LI;
}
@ -1532,7 +1536,8 @@ int CProtoSniper::SelectSchedule ( void )
// Reload is absolute priority.
return SCHED_RELOAD;
}
//SecobMod__Information: The condition area below when used in mp caused the sniper to fail terribly. Removing it from working with the AI enabled really improves snipers.
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if( !AI_GetSinglePlayer()->IsAlive() && m_bKilledPlayer )
{
if( HasCondition(COND_IN_PVS) )
@ -1540,6 +1545,7 @@ int CProtoSniper::SelectSchedule ( void )
return SCHED_PSNIPER_PLAYER_DEAD;
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( HasCondition( COND_HEAR_DANGER ) )
{
@ -2787,11 +2793,19 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget )
CBaseEntity *CProtoSniper::PickDeadPlayerTarget()
{
const int iSearchSize = 32;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pTarget = UTIL_GetNearestVisiblePlayer(this);
CBaseEntity *pEntities[ iSearchSize ];
int iNumEntities = UTIL_EntitiesInSphere( pEntities, iSearchSize, pTarget->GetAbsOrigin(), 180.0f, 0 );
#else
CBaseEntity *pTarget = AI_GetSinglePlayer();
CBaseEntity *pEntities[ iSearchSize ];
int iNumEntities = UTIL_EntitiesInSphere( pEntities, iSearchSize, AI_GetSinglePlayer()->GetAbsOrigin(), 180.0f, 0 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Not very robust, but doesn't need to be. Randomly select a nearby object in the list that isn't an NPC.
if( iNumEntities > 0 )
{

View File

@ -248,7 +248,12 @@ void CScriptIntro::InputSetFOVBlendTime( inputdata_t &inputdata )
else
{
// If we weren't blending, then we need to construct a proper starting point from scratch
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = AI_GetSinglePlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
m_iStartFOV = ( m_iFOV ) ? m_iFOV : pPlayer->GetFOV();

View File

@ -852,7 +852,12 @@ void CPropCrane::InputUnlock( inputdata_t &inputdata )
//-----------------------------------------------------------------------------
void CPropCrane::InputForcePlayerIn( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer && !m_hPlayer )
{
GetServerVehicle()->HandlePassengerEntry( pPlayer, 0 );

View File

@ -595,8 +595,14 @@ void CPropVehiclePrisonerPod::InputEnterVehicle( inputdata_t &inputdata )
CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator );
if ( pPassenger == NULL )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// Activator was not a player, just grab the nearest player.
pPassenger = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
// Activator was not a player, just grab the singleplayer player.
pPassenger = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPassenger == NULL )
return;
}
@ -622,8 +628,14 @@ void CPropVehiclePrisonerPod::InputEnterVehicleImmediate( inputdata_t &inputdata
CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator );
if ( pPassenger == NULL )
{
// Activator was not a player, just grab the singleplayer player.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// Activator was not a player, just grab the nearest player.
pPassenger = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
// Activator was not a player, just grab the singleplayer player.
pPassenger = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPassenger == NULL )
return;
}

View File

@ -134,7 +134,12 @@ void CPropVehicleViewController::ExitVehicle( int nRole )
//-----------------------------------------------------------------------------
void CPropVehicleViewController::InputForcePlayerIn( inputdata_t &inputdata )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pPlayer )
return;

View File

@ -615,9 +615,19 @@ void CHL2MP_Player::NoteWeaponFired( void )
}
extern ConVar sv_maxunlag;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
bool CHL2MP_Player::WantsLagCompensationOnEntity( const CBaseEntity *pEntity, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const
{
// No need to lag compensate at all if we're not attacking in this command and
// we haven't attacked recently.
if ( !( pCmd->buttons & IN_ATTACK ) && (pCmd->command_number - m_iLastWeaponFireUsercmd > 5) )
return false;
bool CHL2MP_Player::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const
{
return BaseClass::WantsLagCompensationOnEntity( pEntity, pCmd, pEntityTransmitBits );
}
#else
bool CHL2MP_Player::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const
{
// No need to lag compensate at all if we're not attacking in this command and
// we haven't attacked recently.
if ( !( pCmd->buttons & IN_ATTACK ) && (pCmd->command_number - m_iLastWeaponFireUsercmd > 5) )
@ -650,7 +660,8 @@ bool CHL2MP_Player::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, co
return false;
return true;
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
Activity CHL2MP_Player::TranslateTeamActivity( Activity ActToTranslate )
{
@ -1380,13 +1391,104 @@ CBaseEntity* CHL2MP_Player::EntSelectSpawnPoint( void )
goto ReturnSpot;
}
if ( !pSpot )
{
pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start" );
if ( !pSpot )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
char szMapName[256];
Q_strncpy(szMapName, STRING(gpGlobals->mapname), sizeof(szMapName) );
Q_strlower(szMapName);
if ( pSpot )
//SecobMod__Information: Although we don't support official maps for gaming, they are useful for testing and these maps for whatever reason spawn you in the wrong location. As such this
// code is here to force players to spawn at the beginning of the selected maps. Custom maps won't require this as they will have deathmatch/class based player starts.
if( !Q_strnicmp( szMapName, "d1_canals_01a", 13 )
|| !Q_strnicmp( szMapName, "d1_canals_03", 12 )
|| !Q_strnicmp( szMapName, "d1_canals_13", 12 )
|| !Q_strnicmp( szMapName, "d1_town_01", 10 )
|| !Q_strnicmp( szMapName, "d1_town_01a", 11 )
|| !Q_strnicmp( szMapName, "d1_town_02", 10 )
|| !Q_strnicmp( szMapName, "d1_town_02a", 11 )
|| !Q_strnicmp( szMapName, "d1_town_03", 10 )
|| !Q_strnicmp( szMapName, "d1_town_04", 10 )
|| !Q_strnicmp( szMapName, "d1_town_05", 10 )
|| !Q_strnicmp( szMapName, "d2_coast_03", 11)
|| !Q_strnicmp( szMapName, "d2_coast_08", 11 )
|| !Q_strnicmp( szMapName, "d2_coast_11", 11 )
|| !Q_strnicmp( szMapName, "d2_prison_01", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_02", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_03", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_04", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_05", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_06", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_07", 12 )
|| !Q_strnicmp( szMapName, "d2_prison_08", 12 )
|| !Q_strnicmp( szMapName, "d3_c17_08", 9 )
|| !Q_strnicmp( szMapName, "d3_citadel_01", 13 )
|| !Q_strnicmp( szMapName, "d3_citadel_02", 13 )
|| !Q_strnicmp( szMapName, "d3_citadel_03", 13 )
|| !Q_strnicmp( szMapName, "d3_citadel_04", 13 )
|| !Q_strnicmp( szMapName, "d3_citadel_05", 13 )
|| !Q_strnicmp( szMapName, "d3_breen_01", 11 )
|| !Q_strnicmp( szMapName, "ep1_c17_00", 10 )
|| !Q_strnicmp( szMapName, "ep1_c17_00a", 11 )
|| !Q_strnicmp( szMapName, "ep1_c17_02b", 11 )
|| !Q_strnicmp( szMapName, "ep1_c17_05", 10 )
|| !Q_strnicmp( szMapName, "ep2_outland_01a", 15 )
|| !Q_strnicmp( szMapName, "ep2_outland_03", 14 )
|| !Q_strnicmp( szMapName, "ep2_outland_08", 14 )
|| !Q_strnicmp( szMapName, "ep2_outland_06", 14 )
)
{
CBaseEntity *pEntity = NULL;
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
Vector vecOrigin = pPlayer->GetAbsOrigin();
pEntity = gEntList.FindEntityByClassnameNearest( "item_suit", vecOrigin, 0);
if (pEntity != NULL)
{
vecOrigin = pEntity->GetAbsOrigin();
pEntity = gEntList.FindEntityByClassnameNearest( "info_player_start", vecOrigin, 0);
pSpot = pEntity;
pSpawnpointName = "info_player_start";
goto ReturnSpot;
}
else
{
pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start");
}
}
else if( !Q_strnicmp( szMapName, "d1_trainstation_05", 18 ) )
{
CBaseEntity *pEntity = NULL;
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
Vector vecOrigin = pPlayer->GetAbsOrigin();
pEntity = gEntList.FindEntityByClassnameNearest( "npc_alyx", vecOrigin, 0);
if (pEntity != NULL)
{
vecOrigin = pEntity->GetAbsOrigin();
pEntity = gEntList.FindEntityByClassnameNearest( "info_player_start", vecOrigin, 0);
pSpot = pEntity;
pSpawnpointName = "info_player_start";
goto ReturnSpot;
}
else
{
pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start");
}
}
else
{
pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start");
}
#else
pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start");
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if (pSpot)
{
goto ReturnSpot; //return pSpot;*/
}
ReturnSpot:
@ -1450,7 +1552,6 @@ CON_COMMAND( timeleft, "prints the time remaining in the match" )
}
}
void CHL2MP_Player::Reset()
{
ResetDeathCount();
@ -1627,3 +1728,24 @@ bool CHL2MP_Player::CanHearAndReadChatFrom( CBasePlayer *pPlayer )
return true;
}
void CHL2MP_Player::SetArmorValue( int value )
{
BaseClass::SetArmorValue(value);
m_iArmor = value;
}
// Armour Settings.
void CHL2MP_Player::SetMaxArmorValue( int MaxArmorValue )
{
m_iMaxArmor = MaxArmorValue;
}
//-----------------------------------------------------------------------------
void CHL2MP_Player::IncrementArmorValue( int nCount, int nMaxValue )
{
nMaxValue = m_iMaxArmor;
BaseClass::IncrementArmorValue(nCount, nMaxValue );
}

View File

@ -64,7 +64,13 @@ public:
virtual bool BecomeRagdollOnClient( const Vector &force );
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
virtual bool WantsLagCompensationOnEntity( const CBaseEntity *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
#else
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
virtual void FireBullets ( const FireBulletsInfo_t &info );
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0);
virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon );
@ -137,6 +143,13 @@ public:
virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer );
// Armor Ints.
int m_iArmor;
int m_iMaxArmor;
void IncrementArmorValue( int nCount, int nMaxValue = -1 );
void SetArmorValue( int value );
void SetMaxArmorValue( int MaxArmorValue );
private:

View File

@ -24,6 +24,9 @@ public:
virtual void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) = 0;
virtual void FinishLagCompensation( CBasePlayer *player ) = 0;
virtual bool IsCurrentlyDoingLagCompensation() const = 0;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
virtual void RemoveNpcData(int index) = 0;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
};
extern ILagCompensationManager *lagcompensation;

View File

@ -3310,7 +3310,11 @@ void CLogicAutosave::InputSaveDangerous( inputdata_t &inputdata )
}
#endif
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( g_ServerGameDLL.m_fAutoSaveDangerousTime != 0.0f && g_ServerGameDLL.m_fAutoSaveDangerousTime >= gpGlobals->curtime )
{
@ -3359,8 +3363,13 @@ class CLogicActiveAutosave : public CLogicAutosave
void SaveThink()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( pPlayer && gpGlobals->maxClients == 1 )
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( pPlayer )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
if ( m_flStartTime < 0 )
{

View File

@ -134,7 +134,11 @@ void CMessageEntity::Think( void )
SetNextThink( gpGlobals->curtime + 0.1f );
// check for player distance
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pPlayer || ( pPlayer->GetFlags() & FL_NOTARGET ) )
return;

View File

@ -664,6 +664,10 @@ CNPCSpawnDestination *CTemplateNPCMaker::FindSpawnDestination()
bool fValid = true;
Vector vecTest = pDestination->GetAbsOrigin();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(vecTest);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( m_CriterionVisibility != TS_YN_DONT_CARE )
{
// Right now View Cone check is omitted intentionally.
@ -730,6 +734,11 @@ CNPCSpawnDestination *CTemplateNPCMaker::FindSpawnDestination()
for( int i = 0 ; i < count ; i++ )
{
Vector vecTest = pDestinations[ i ]->GetAbsOrigin();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(vecTest);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
float flDist = ( vecTest - pPlayer->GetAbsOrigin() ).Length();
if ( m_iMinSpawnDistance != 0 && m_iMinSpawnDistance > flDist )

View File

@ -228,6 +228,17 @@ void CNPCSimpleTalker::RunTask( const Task_t *pTask )
case TASK_TALKER_CLIENT_STARE:
case TASK_TALKER_LOOK_AT_CLIENT:
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( pTask->iTask == TASK_TALKER_CLIENT_STARE )
{
// Get edict for one player
//CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
//Assert( pPlayer );
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
// fail out if the player looks away or moves away.
if ( !pPlayer || ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST )
#else
if ( pTask->iTask == TASK_TALKER_CLIENT_STARE && AI_IsSinglePlayer() )
{
// Get edict for one player
@ -236,6 +247,8 @@ void CNPCSimpleTalker::RunTask( const Task_t *pTask )
// fail out if the player looks away or moves away.
if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
// player moved away.
TaskFail("Player moved away");
@ -826,10 +839,16 @@ int CNPCSimpleTalker::SelectNonCombatSpeechSchedule()
}
// failed to speak, so look at the player if he's around
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( GetExpresser()->CanSpeak() && HasCondition ( COND_SEE_PLAYER ) && random->RandomInt( 0, 6 ) == 0 )
{
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
if ( AI_IsSinglePlayer() && GetExpresser()->CanSpeak() && HasCondition ( COND_SEE_PLAYER ) && random->RandomInt( 0, 6 ) == 0 )
{
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
Assert( pPlayer );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{

View File

@ -297,7 +297,14 @@ IMotionEvent::simresult_e CPhysicsNPCSolver::Simulate( IPhysicsMotionController
if ( pObject->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
Vector origin;
pObject->GetPosition(&origin,NULL);
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(origin);
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer )
{
pPlayer->ForceDropOfCarriedPhysObjects( m_hEntity );

View File

@ -206,7 +206,11 @@ ConVar player_use_visibility_cache( "player_use_visibility_cache", "0", FCVAR_NO
void CC_GiveCurrentAmmo( void )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetCommandClient();
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if( pPlayer )
{
@ -852,7 +856,35 @@ int CBasePlayer::ShouldTransmit( const CCheckTransmitInfo *pInfo )
return BaseClass::ShouldTransmit( pInfo );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
bool CBasePlayer::WantsLagCompensationOnEntity( const CBaseEntity *pEntity, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const
{
//Tony; only check teams in teamplay
if ( gpGlobals->teamplay )
{
// Team members shouldn't be adjusted unless friendly fire is on.
if ( !friendlyfire.GetInt() && pEntity->GetTeamNumber() == GetTeamNumber() )
return false;
}
// If this entity hasn't been transmitted to us and acked, then don't bother lag compensating it.
if ( pEntityTransmitBits && !pEntityTransmitBits->Get( pEntity->entindex() ) )
return false;
const Vector &vMyOrigin = GetAbsOrigin();
const Vector &vHisOrigin = pEntity->GetAbsOrigin();
// get max distance player could have moved within max lag compensation time,
// multiply by 1.5 to to avoid "dead zones" (sqrt(2) would be the exact value)
//float maxDistance = 1.5 * pPlayer->MaxSpeed() * sv_maxunlag.GetFloat();
float maxspeed;
CBasePlayer *pPlayer = ToBasePlayer((CBaseEntity*)pEntity);
if ( pPlayer )
maxspeed = pPlayer->MaxSpeed();
else
maxspeed = 600;
float maxDistance = 1.5 * maxspeed * sv_maxunlag.GetFloat();
#else
bool CBasePlayer::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const
{
//Tony; only check teams in teamplay
@ -873,6 +905,7 @@ bool CBasePlayer::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, cons
// get max distance player could have moved within max lag compensation time,
// multiply by 1.5 to to avoid "dead zones" (sqrt(2) would be the exact value)
float maxDistance = 1.5 * pPlayer->MaxSpeed() * sv_maxunlag.GetFloat();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// If the player is within this distance, lag compensate them in case they're running past us.
if ( vHisOrigin.DistTo( vMyOrigin ) < maxDistance )
@ -8071,7 +8104,18 @@ void CStripWeapons::StripWeapons(inputdata_t &data, bool stripSuit)
}
else if ( !g_pGameRules->IsDeathmatch() )
{
pPlayer = UTIL_GetLocalPlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( pPlayer )
{
pPlayer->RemoveAllItems( stripSuit );
}
}
#else
pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if ( pPlayer )
@ -8166,8 +8210,12 @@ void CRevertSaved::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
UTIL_ScreenFadeAll( m_clrRender, Duration(), HoldTime(), FFADE_OUT );
SetNextThink( gpGlobals->curtime + LoadTime() );
SetThink( &CRevertSaved::LoadThink );
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
if ( pPlayer )
{
@ -8179,6 +8227,21 @@ void CRevertSaved::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
g_ServerGameDLL.m_fAutoSaveDangerousTime = 0.0f;
g_ServerGameDLL.m_fAutoSaveDangerousMinHealthToCommit = 0.0f;
}
}
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( pPlayer )
{
//Adrian: Setting this flag so we can't move or save a game.
pPlayer->pl.deadflag = true;
pPlayer->AddFlag( (FL_NOTARGET|FL_FROZEN) );
// clear any pending autosavedangerous
g_ServerGameDLL.m_fAutoSaveDangerousTime = 0.0f;
g_ServerGameDLL.m_fAutoSaveDangerousMinHealthToCommit = 0.0f;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
void CRevertSaved::InputReload( inputdata_t &inputdata )
@ -8229,6 +8292,16 @@ void CRevertSaved::LoadThink( void )
{
engine->ServerCommand("reload\n");
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
//SecobMod__Information: Here we change level to the map we're already on if a vital ally such as Alyx is killed etc etc etc.
else
{
char *szDefaultMapName = new char[32];
Q_strncpy( szDefaultMapName, STRING(gpGlobals->mapname), 32 );
engine->ChangeLevel( szDefaultMapName, NULL );
return;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
#define SF_SPEED_MOD_SUPPRESS_WEAPONS (1<<0) // Take away weapons
@ -8335,7 +8408,11 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
}
else if ( !g_pGameRules->IsDeathmatch() )
{
pPlayer = UTIL_GetLocalPlayer();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
if ( pPlayer )

View File

@ -287,7 +287,11 @@ public:
// Returns true if this player wants pPlayer to be moved back in time when this player runs usercmds.
// Saves a lot of overhead on the server if we can cull out entities that don't need to lag compensate
// (like team members, entities out of our PVS, etc).
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
virtual bool WantsLagCompensationOnEntity( const CBaseEntity *pEntity, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
#else
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
virtual void Spawn( void );
virtual void Activate( void );

View File

@ -12,6 +12,11 @@
#include "inetchannelinfo.h"
#include "utllinkedlist.h"
#include "BaseAnimatingOverlay.h"
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
#include "ai_basenpc.h"
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#include "tier0/vprof.h"
// memdbgon must be the last include file in a .cpp file!!!
@ -162,7 +167,48 @@ static void RestorePlayerTo( CBasePlayer *pPlayer, const Vector &vWantedPos )
UTIL_SetOrigin( pPlayer, tr.endpos, true );
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
static void RestoreEntityTo( CAI_BaseNPC *pEntity, const Vector &vWantedPos )
{
// Try to move to the wanted position from our current position.
trace_t tr;
VPROF_BUDGET( "RestoreEntityTo", "CLagCompensationManager" );
UTIL_TraceEntity( pEntity, vWantedPos, vWantedPos, MASK_NPCSOLID, pEntity, COLLISION_GROUP_NPC, &tr );
if ( tr.startsolid || tr.allsolid )
{
if ( sv_unlag_debug.GetBool() )
{
DevMsg( "RestorepEntityTo() could not restore entity position for %s ( %.1f %.1f %.1f )\n",
pEntity->GetClassname(), vWantedPos.x, vWantedPos.y, vWantedPos.z );
}
UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), vWantedPos, MASK_NPCSOLID, pEntity, COLLISION_GROUP_NPC, &tr );
if ( tr.startsolid || tr.allsolid )
{
// In this case, the guy got stuck back wherever we lag compensated him to. Nasty.
if ( sv_unlag_debug.GetBool() )
DevMsg( " restore failed entirely\n" );
}
else
{
// We can get to a valid place, but not all the way back to where we were.
Vector vPos;
VectorLerp( pEntity->GetLocalOrigin(), vWantedPos, tr.fraction * g_flFractionScale, vPos );
UTIL_SetOrigin( pEntity, vPos, true );
if ( sv_unlag_debug.GetBool() )
DevMsg( " restore got most of the way\n" );
}
}
else
{
// Cool, the entity can go back to whence he came.
UTIL_SetOrigin( pEntity, tr.endpos, true );
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//-----------------------------------------------------------------------------
// Purpose:
@ -173,6 +219,9 @@ public:
CLagCompensationManager( char const *name ) : CAutoGameSystemPerFrame( name ), m_flTeleportDistanceSqr( 64 *64 )
{
m_isCurrentlyDoingCompensation = false;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
m_bNeedsAIUpdate = true;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
// IServerSystem stuff
@ -194,31 +243,66 @@ public:
// Called during player movement to set up/restore after lag compensation
void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd );
void FinishLagCompensation( CBasePlayer *player );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void RemoveNpcData(int index) // clear specific NPC's history
{
CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[index];
track->Purge();
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
bool IsCurrentlyDoingLagCompensation() const OVERRIDE { return m_isCurrentlyDoingCompensation; }
private:
void BacktrackPlayer( CBasePlayer *player, float flTargetTime );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void BacktrackEntity( CAI_BaseNPC *entity, float flTargetTime );
#endif //#SecobMod__Enable_Fixed_Multiplayer_AI
void ClearHistory()
{
for ( int i=0; i<MAX_PLAYERS; i++ )
m_PlayerTrack[i].Purge();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for ( int j=0; j<MAX_AIS; j++ )
m_EntityTrack[j].Purge();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void UpdateAIIndexes();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// keep a list of lag records for each player
CUtlFixedLinkedList< LagRecord > m_PlayerTrack[ MAX_PLAYERS ];
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CUtlFixedLinkedList< LagRecord > m_EntityTrack[ MAX_AIS ];
#endif SecobMod__Enable_Fixed_Multiplayer_AI
// Scratchpad for determining what needs to be restored
CBitVec<MAX_PLAYERS> m_RestorePlayer;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBitVec<MAX_AIS> m_RestoreEntity;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
bool m_bNeedToRestore;
LagRecord m_RestoreData[ MAX_PLAYERS ]; // player data before we moved him back
LagRecord m_ChangeData[ MAX_PLAYERS ]; // player data where we moved him back
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
LagRecord m_EntityRestoreData[ MAX_AIS ];
LagRecord m_EntityChangeData[ MAX_AIS ];
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *m_pCurrentPlayer; // The player we are doing lag compensation for
float m_flTeleportDistanceSqr;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
bool m_bNeedsAIUpdate;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
bool m_isCurrentlyDoingCompensation; // Sentinel to prevent calling StartLagCompensation a second time before a Finish.
};
@ -232,6 +316,13 @@ ILagCompensationManager *lagcompensation = &g_LagCompensationManager;
//-----------------------------------------------------------------------------
void CLagCompensationManager::FrameUpdatePostEntityThink()
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( m_bNeedsAIUpdate )
UpdateAIIndexes(); // only bother if we haven't had one yet
else // setting this true here ensures that the update happens at the start of the next frame
m_bNeedsAIUpdate = true;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( (gpGlobals->maxClients <= 1) || !sv_unlag.GetBool() )
{
ClearHistory();
@ -319,11 +410,129 @@ void CLagCompensationManager::FrameUpdatePostEntityThink()
record.m_masterSequence = pPlayer->GetSequence();
record.m_masterCycle = pPlayer->GetCycle();
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// Iterate all active NPCs
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for ( int i = 0; i < nAIs; i++ )
{
CAI_BaseNPC *pNPC = ppAIs[i];
CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[i];
if ( !pNPC )
{
track->RemoveAll();
continue;
}
Assert( track->Count() < 1000 ); // insanity check
// remove tail records that are too old
int tailIndex = track->Tail();
while ( track->IsValidIndex( tailIndex ) )
{
LagRecord &tail = track->Element( tailIndex );
// if tail is within limits, stop
if ( tail.m_flSimulationTime >= flDeadtime )
break;
// remove tail, get new tail
track->Remove( tailIndex );
tailIndex = track->Tail();
}
// check if head has same simulation time
if ( track->Count() > 0 )
{
LagRecord &head = track->Element( track->Head() );
// check if entity changed simulation time since last time updated
if ( &head && head.m_flSimulationTime >= pNPC->GetSimulationTime() )
continue; // don't add new entry for same or older time
// Simulation Time is set when an entity moves or rotates ...
// this error occurs when whatever entity it is that breaks it moves or rotates then, presumably?
}
// add new record to track
LagRecord &record = track->Element( track->AddToHead() );
record.m_fFlags = 0;
if ( pNPC->IsAlive() )
{
record.m_fFlags |= LC_ALIVE;
}
record.m_flSimulationTime = pNPC->GetSimulationTime();
record.m_vecAngles = pNPC->GetLocalAngles();
record.m_vecOrigin = pNPC->GetLocalOrigin();
record.m_vecMaxsPreScaled = pNPC->WorldAlignMaxs();
record.m_vecMinsPreScaled = pNPC->WorldAlignMins();
int layerCount = pNPC->GetNumAnimOverlays();
for( int layerIndex = 0; layerIndex < layerCount; ++layerIndex )
{
CAnimationLayer *currentLayer = pNPC->GetAnimOverlay(layerIndex);
if( currentLayer )
{
record.m_layerRecords[layerIndex].m_cycle = currentLayer->m_flCycle;
record.m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder;
record.m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence;
record.m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight;
}
}
record.m_masterSequence = pNPC->GetSequence();
record.m_masterCycle = pNPC->GetCycle();
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//Clear the current player.
m_pCurrentPlayer = NULL;
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void CLagCompensationManager::UpdateAIIndexes()
{
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for ( int i = 0; i < nAIs; i++ )
{
CAI_BaseNPC *pNPC = ppAIs[i];
if ( pNPC && pNPC->GetAIIndex() != i ) // index of NPC has changed
{// move their data to their new index, probably wanting to delete the old track record
int oldIndex = pNPC->GetAIIndex();
int newIndex = i;
//Msg("Lag compensation record adjusting, moving from index %i to %i\n",oldIndex,newIndex);
CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[ oldIndex ];
CUtlFixedLinkedList< LagRecord > *oldTrack = &m_EntityTrack[ newIndex ];
m_EntityTrack[oldIndex] = *oldTrack;
m_EntityTrack[newIndex] = *track;
if ( oldTrack->Count() > 0 ) // there's data in the auld yin, probably from someone newly dead,
{// but if not we'll swap them round so that the old one can then fix their AI index
//Msg("Index %i already contains data!\n",newIndex);
for ( int j=0; j<nAIs; j++ )
{
CAI_BaseNPC *pConflictingNPC = ppAIs[j];
if ( pConflictingNPC && pConflictingNPC->GetAIIndex() == newIndex )
{// found the conflicting NPC, swap them into the old index
pConflictingNPC->SetAIIndex(oldIndex); // presumably they'll fix themselves further down the loop
Warning("Lag compensation adjusting entity index, swapping with an existing entity! (%i & %i)\n",oldIndex,newIndex);
break;
}
}
}
pNPC->SetAIIndex(newIndex);
}
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Called during player movement to set up/restore after lag compensation
void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCmd *cmd )
{
@ -338,8 +547,22 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm
return;
}
// Assume no players need to be restored
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// sort out any changes to the AI indexing
if ( m_bNeedsAIUpdate ) // to be called once per frame... must happen BEFORE lag compensation -
{// if that happens, that is. if not its called at the end of the frame
m_bNeedsAIUpdate = false;
UpdateAIIndexes();
}
// Assume no players or entities need to be restored
m_RestorePlayer.ClearAll();
m_RestoreEntity.ClearAll();
#else
// Assume no players need to be restored
m_RestorePlayer.ClearAll();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
m_bNeedToRestore = false;
m_pCurrentPlayer = player;
@ -356,6 +579,10 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm
VPROF_BUDGET( "StartLagCompensation", VPROF_BUDGETGROUP_OTHER_NETWORKING );
Q_memset( m_RestoreData, 0, sizeof( m_RestoreData ) );
Q_memset( m_ChangeData, 0, sizeof( m_ChangeData ) );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
Q_memset( m_EntityRestoreData, 0, sizeof( m_EntityRestoreData ) );
Q_memset( m_EntityChangeData, 0, sizeof( m_EntityChangeData ) );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
m_isCurrentlyDoingCompensation = true;
@ -399,8 +626,11 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( !pPlayer || player == pPlayer )
continue;
#else
if ( !pPlayer )
{
continue;
}
@ -410,6 +640,7 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm
{
continue;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Custom checks for if things should lag compensate (based on things like what team the player is on).
if ( !player->WantsLagCompensationOnEntity( pPlayer, cmd, pEntityTransmitBits ) )
@ -418,6 +649,23 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer *player, CUserCm
// Move other player back in time
BacktrackPlayer( pPlayer, TICKS_TO_TIME( targettick ) );
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// also iterate all monsters
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for ( int i = 0; i < nAIs; i++ )
{
CAI_BaseNPC *pNPC = ppAIs[i];
// Custom checks for if things should lag compensate
if ( !pNPC || !player->WantsLagCompensationOnEntity( pNPC, cmd, pEntityTransmitBits ) )
continue;
// Move NPC back in time
BacktrackEntity( pNPC, TICKS_TO_TIME( targettick ) );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, float flTargetTime )
@ -553,6 +801,40 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, float flTar
m_RestorePlayer.Clear( pl_index );
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
else
{
CAI_BaseNPC *pHitEntity = dynamic_cast<CAI_BaseNPC *>( tr.m_pEnt );
if ( pHitEntity )
{
CAI_BaseNPC *pNPC = NULL;
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for ( int i = 0; i < nAIs; i++ ) // we'll have to find this entity's index though :(
{
pNPC = ppAIs[i];
if ( pNPC == pHitEntity )
break;
}
// If we haven't backtracked this player, do it now
// this deliberately ignores WantsLagCompensationOnEntity.
if ( pNPC && !m_RestoreEntity.Get( pNPC->GetAIIndex() ) )
{
// prevent recursion - save a copy of m_RestoreEntity,
// pretend that this player is off-limits
// Temp turn this flag on
m_RestoreEntity.Set( pNPC->GetAIIndex() );
BacktrackEntity( pHitEntity, flTargetTime );
// Remove the temp flag
m_RestoreEntity.Clear( pNPC->GetAIIndex() );
}
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// now trace us back as far as we can go
UTIL_TraceEntity( pPlayer, pPlayer->GetLocalOrigin(), org, MASK_PLAYERSOLID, &tr );
@ -734,6 +1016,349 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, float flTar
pPlayer->DrawServerHitboxes(4, true);
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void CLagCompensationManager::BacktrackEntity( CAI_BaseNPC *pEntity, float flTargetTime )
{
Vector org, mins, maxs;
QAngle ang;
VPROF_BUDGET( "BacktrackEntity", "CLagCompensationManager" );
// get track history of this entity
int index = pEntity->GetAIIndex();
CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[ index ];
// check if we have at leat one entry
if ( track->Count() <= 0 )
return;
int curr = track->Head();
LagRecord *prevRecord = NULL;
LagRecord *record = NULL;
Vector prevOrg = pEntity->GetLocalOrigin();
// Walk context looking for any invalidating event
while( track->IsValidIndex(curr) )
{
// remember last record
prevRecord = record;
// get next record
record = &track->Element( curr );
if ( !(record->m_fFlags & LC_ALIVE) )
{
// entity must be alive, lost track
return;
}
Vector delta = record->m_vecOrigin - prevOrg;
if ( delta.LengthSqr() > LAG_COMPENSATION_EPS_SQR )
{
// lost track, moved too far (may have teleported)
return;
}
// did we find a context smaller than target time ?
if ( record->m_flSimulationTime <= flTargetTime )
break; // hurra, stop
prevOrg = record->m_vecOrigin;
// go one step back in time
curr = track->Next( curr );
}
Assert( record );
if ( !record )
{
if ( sv_unlag_debug.GetBool() )
{
DevMsg( "No valid positions in history for BacktrackEntity ( %s )\n", pEntity->GetClassname() );
}
return; // that should never happen
}
float frac = 0.0f;
if ( prevRecord &&
(record->m_flSimulationTime < flTargetTime) &&
(record->m_flSimulationTime < prevRecord->m_flSimulationTime) )
{
// we didn't find the exact time but have a valid previous record
// so interpolate between these two records;
Assert( prevRecord->m_flSimulationTime > record->m_flSimulationTime );
Assert( flTargetTime < prevRecord->m_flSimulationTime );
// calc fraction between both records
frac = ( flTargetTime - record->m_flSimulationTime ) /
( prevRecord->m_flSimulationTime - record->m_flSimulationTime );
Assert( frac > 0 && frac < 1 ); // should never extrapolate
ang = Lerp( frac, record->m_vecAngles, prevRecord->m_vecAngles );
org = Lerp( frac, record->m_vecOrigin, prevRecord->m_vecOrigin );
mins = Lerp( frac, record->m_vecMinsPreScaled, prevRecord->m_vecMinsPreScaled );
maxs = Lerp( frac, record->m_vecMaxsPreScaled, prevRecord->m_vecMaxsPreScaled );
}
else
{
// we found the exact record or no other record to interpolate with
// just copy these values since they are the best we have
ang = record->m_vecAngles;
org = record->m_vecOrigin;
mins = record->m_vecMinsPreScaled;
maxs = record->m_vecMaxsPreScaled;
}
// See if this is still a valid position for us to teleport to
if ( sv_unlag_fixstuck.GetBool() )
{
// Try to move to the wanted position from our current position.
trace_t tr;
UTIL_TraceEntity( pEntity, org, org, MASK_NPCSOLID, &tr );
if ( tr.startsolid || tr.allsolid )
{
if ( sv_unlag_debug.GetBool() )
DevMsg( "WARNING: BackupEntity trying to back entity into a bad position - %s\n", pEntity->GetClassname() );
CBasePlayer *pHitPlayer = dynamic_cast<CBasePlayer *>( tr.m_pEnt );
// don't lag compensate the current player
if ( pHitPlayer && ( pHitPlayer != m_pCurrentPlayer ) )
{
// If we haven't backtracked this player, do it now
// this deliberately ignores WantsLagCompensationOnEntity.
if ( !m_RestorePlayer.Get( pHitPlayer->entindex() - 1 ) )
{
// prevent recursion - save a copy of m_RestorePlayer,
// pretend that this player is off-limits
int pl_index = pEntity->entindex() - 1;
// Temp turn this flag on
m_RestorePlayer.Set( pl_index );
BacktrackPlayer( pHitPlayer, flTargetTime );
// Remove the temp flag
m_RestorePlayer.Clear( pl_index );
}
}
else
{
CAI_BaseNPC *pHitEntity = dynamic_cast<CAI_BaseNPC *>( tr.m_pEnt );
if ( pHitEntity )
{
CAI_BaseNPC *pNPC = NULL;
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for ( int i = 0; i < nAIs; i++ ) // we'll have to find this entity's index though :(
{
pNPC = ppAIs[i];
if ( pNPC == pHitEntity )
break;
}
// If we haven't backtracked this player, do it now
// this deliberately ignores WantsLagCompensationOnEntity.
if ( pNPC && !m_RestoreEntity.Get( pNPC->GetAIIndex() ) )
{
// prevent recursion - save a copy of m_RestoreEntity,
// pretend that this player is off-limits
// Temp turn this flag on
m_RestoreEntity.Set( pNPC->GetAIIndex() );
BacktrackEntity( pHitEntity, flTargetTime );
// Remove the temp flag
m_RestoreEntity.Clear( pNPC->GetAIIndex() );
}
}
}
// now trace us back as far as we can go
UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), org, MASK_NPCSOLID, &tr );
if ( tr.startsolid || tr.allsolid )
{
// Our starting position is bogus
if ( sv_unlag_debug.GetBool() )
DevMsg( "Backtrack failed completely, bad starting position\n" );
}
else
{
// We can get to a valid place, but not all the way to the target
Vector vPos;
VectorLerp( pEntity->GetLocalOrigin(), org, tr.fraction * g_flFractionScale, vPos );
// This is as close as we're going to get
org = vPos;
if ( sv_unlag_debug.GetBool() )
DevMsg( "Backtrack got most of the way\n" );
}
}
}
// See if this represents a change for the entity
int flags = 0;
LagRecord *restore = &m_EntityRestoreData[ index ];
LagRecord *change = &m_EntityChangeData[ index ];
QAngle angdiff = pEntity->GetLocalAngles() - ang;
Vector orgdiff = pEntity->GetLocalOrigin() - org;
// Always remember the pristine simulation time in case we need to restore it.
restore->m_flSimulationTime = pEntity->GetSimulationTime();
if ( angdiff.LengthSqr() > LAG_COMPENSATION_EPS_SQR )
{
flags |= LC_ANGLES_CHANGED;
restore->m_vecAngles = pEntity->GetLocalAngles();
pEntity->SetLocalAngles( ang );
change->m_vecAngles = ang;
}
// Use absolute equality here
if ( ( mins != pEntity->WorldAlignMins() ) ||
( maxs != pEntity->WorldAlignMaxs() ) )
{
flags |= LC_SIZE_CHANGED;
restore->m_vecMinsPreScaled = pEntity->WorldAlignMins() ;
restore->m_vecMaxsPreScaled = pEntity->WorldAlignMaxs();
pEntity->SetSize( mins, maxs );
change->m_vecMinsPreScaled = mins;
change->m_vecMaxsPreScaled = maxs;
}
// Note, do origin at end since it causes a relink into the k/d tree
if ( orgdiff.LengthSqr() > LAG_COMPENSATION_EPS_SQR )
{
flags |= LC_ORIGIN_CHANGED;
restore->m_vecOrigin = pEntity->GetLocalOrigin();
pEntity->SetLocalOrigin( org );
change->m_vecOrigin = org;
}
// Sorry for the loss of the optimization for the case of people
// standing still, but you breathe even on the server.
// This is quicker than actually comparing all bazillion floats.
flags |= LC_ANIMATION_CHANGED;
restore->m_masterSequence = pEntity->GetSequence();
restore->m_masterCycle = pEntity->GetCycle();
bool interpolationAllowed = false;
if( prevRecord && (record->m_masterSequence == prevRecord->m_masterSequence) )
{
// If the master state changes, all layers will be invalid too, so don't interp (ya know, interp barely ever happens anyway)
interpolationAllowed = true;
}
////////////////////////
// First do the master settings
bool interpolatedMasters = false;
if( frac > 0.0f && interpolationAllowed )
{
interpolatedMasters = true;
pEntity->SetSequence( Lerp( frac, record->m_masterSequence, prevRecord->m_masterSequence ) );
pEntity->SetCycle( Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle ) );
if( record->m_masterCycle > prevRecord->m_masterCycle )
{
// the older record is higher in frame than the newer, it must have wrapped around from 1 back to 0
// add one to the newer so it is lerping from .9 to 1.1 instead of .9 to .1, for example.
float newCycle = Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle + 1 );
pEntity->SetCycle(newCycle < 1 ? newCycle : newCycle - 1 );// and make sure .9 to 1.2 does not end up 1.05
}
else
{
pEntity->SetCycle( Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle ) );
}
}
if( !interpolatedMasters )
{
pEntity->SetSequence(record->m_masterSequence);
pEntity->SetCycle(record->m_masterCycle);
}
////////////////////////
// Now do all the layers
int layerCount = pEntity->GetNumAnimOverlays();
for( int layerIndex = 0; layerIndex < layerCount; ++layerIndex )
{
CAnimationLayer *currentLayer = pEntity->GetAnimOverlay(layerIndex);
if( currentLayer )
{
restore->m_layerRecords[layerIndex].m_cycle = currentLayer->m_flCycle;
restore->m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder;
restore->m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence;
restore->m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight;
bool interpolated = false;
if( (frac > 0.0f) && interpolationAllowed )
{
LayerRecord &recordsLayerRecord = record->m_layerRecords[layerIndex];
LayerRecord &prevRecordsLayerRecord = prevRecord->m_layerRecords[layerIndex];
if( (recordsLayerRecord.m_order == prevRecordsLayerRecord.m_order)
&& (recordsLayerRecord.m_sequence == prevRecordsLayerRecord.m_sequence)
)
{
// We can't interpolate across a sequence or order change
interpolated = true;
if( recordsLayerRecord.m_cycle > prevRecordsLayerRecord.m_cycle )
{
// the older record is higher in frame than the newer, it must have wrapped around from 1 back to 0
// add one to the newer so it is lerping from .9 to 1.1 instead of .9 to .1, for example.
float newCycle = Lerp( frac, recordsLayerRecord.m_cycle, prevRecordsLayerRecord.m_cycle + 1 );
currentLayer->m_flCycle = newCycle < 1 ? newCycle : newCycle - 1;// and make sure .9 to 1.2 does not end up 1.05
}
else
{
currentLayer->m_flCycle = Lerp( frac, recordsLayerRecord.m_cycle, prevRecordsLayerRecord.m_cycle );
}
currentLayer->m_nOrder = recordsLayerRecord.m_order;
currentLayer->m_nSequence = recordsLayerRecord.m_sequence;
currentLayer->m_flWeight = Lerp( frac, recordsLayerRecord.m_weight, prevRecordsLayerRecord.m_weight );
}
}
if( !interpolated )
{
//Either no interp, or interp failed. Just use record.
currentLayer->m_flCycle = record->m_layerRecords[layerIndex].m_cycle;
currentLayer->m_nOrder = record->m_layerRecords[layerIndex].m_order;
currentLayer->m_nSequence = record->m_layerRecords[layerIndex].m_sequence;
currentLayer->m_flWeight = record->m_layerRecords[layerIndex].m_weight;
}
}
}
if ( !flags )
return; // we didn't change anything
if ( sv_lagflushbonecache.GetBool() )
pEntity->InvalidateBoneCache();
/*char text[256]; Q_snprintf( text, sizeof(text), "time %.2f", flTargetTime );
pEntity->DrawServerHitboxes( 10 );
NDebugOverlay::Text( org, text, false, 10 );
NDebugOverlay::EntityBounds( pEntity, 255, 0, 0, 32, 10 ); */
m_RestoreEntity.Set( index ); //remember that we changed this entity
m_bNeedToRestore = true; // we changed at least one player / entity
restore->m_fFlags = flags; // we need to restore these flags
change->m_fFlags = flags; // we have changed these flags
if( sv_showlagcompensation.GetInt() == 1 )
{
pEntity->DrawServerHitboxes(4, true);
}
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player )
@ -782,12 +1407,12 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player )
// Restore it
pPlayer->SetSize( restore->m_vecMinsPreScaled, restore->m_vecMaxsPreScaled );
}
#ifdef STAGING_ONLY
#ifdef STAGING_ONLY
else
{
Warning( "Should we really not restore the size?\n" );
}
#endif
#endif
}
if ( restore->m_fFlags & LC_ANGLES_CHANGED )
@ -841,6 +1466,91 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player )
}
}
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// also iterate all monsters
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
int nAIs = g_AI_Manager.NumAIs();
for (int i = 0; i < nAIs; i++)
{
CAI_BaseNPC *pNPC = ppAIs[i];
if (!m_RestoreEntity.Get(i))
{
// entity wasn't changed by lag compensation
continue;
}
LagRecord *restore = &m_EntityRestoreData[i];
LagRecord *change = &m_EntityChangeData[i];
bool restoreSimulationTime = false;
if (restore->m_fFlags & LC_SIZE_CHANGED)
{
restoreSimulationTime = true;
// see if simulation made any changes, if no, then do the restore, otherwise,
// leave new values in
if (pNPC->WorldAlignMins() == change->m_vecMinsPreScaled &&
pNPC->WorldAlignMaxs() == change->m_vecMaxsPreScaled)
{
// Restore it
pNPC->SetSize(restore->m_vecMinsPreScaled, restore->m_vecMaxsPreScaled);
}
}
if (restore->m_fFlags & LC_ANGLES_CHANGED)
{
restoreSimulationTime = true;
if (pNPC->GetLocalAngles() == change->m_vecAngles)
{
pNPC->SetLocalAngles(restore->m_vecAngles);
}
}
if (restore->m_fFlags & LC_ORIGIN_CHANGED)
{
restoreSimulationTime = true;
// Okay, let's see if we can do something reasonable with the change
Vector delta = pNPC->GetLocalOrigin() - change->m_vecOrigin;
// If it moved really far, just leave the player in the new spot!!!
if (delta.LengthSqr() < LAG_COMPENSATION_EPS_SQR)
{
RestoreEntityTo(pNPC, restore->m_vecOrigin + delta);
}
}
if (restore->m_fFlags & LC_ANIMATION_CHANGED)
{
restoreSimulationTime = true;
pNPC->SetSequence(restore->m_masterSequence);
pNPC->SetCycle(restore->m_masterCycle);
int layerCount = pNPC->GetNumAnimOverlays();
for (int layerIndex = 0; layerIndex < layerCount; ++layerIndex)
{
CAnimationLayer *currentLayer = pNPC->GetAnimOverlay(layerIndex);
if (currentLayer)
{
currentLayer->m_flCycle = restore->m_layerRecords[layerIndex].m_cycle;
currentLayer->m_nOrder = restore->m_layerRecords[layerIndex].m_order;
currentLayer->m_nSequence = restore->m_layerRecords[layerIndex].m_sequence;
currentLayer->m_flWeight = restore->m_layerRecords[layerIndex].m_weight;
}
}
}
if (restoreSimulationTime)
{
pNPC->SetSimulationTime(restore->m_flSimulationTime);
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
m_isCurrentlyDoingCompensation = false;
}

View File

@ -24,7 +24,12 @@ void Pickup_ForcePlayerToDropThisObject( CBaseEntity *pTarget )
if ( pPhysics->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(pTarget->GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
pPlayer->ForceDropOfCarriedPhysObjects( pTarget );
}
}

View File

@ -4080,7 +4080,11 @@ CBaseEntity *CSceneEntity::FindNamedEntity( const char *name, CBaseEntity *pActo
if ( !stricmp( name, "Player" ) || !stricmp( name, "!player" ))
{
entity = ( gpGlobals->maxClients == 1 ) ? ( CBaseEntity * )UTIL_GetLocalPlayer() : NULL;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
entity = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
entity = ( gpGlobals->maxClients == 1 ) ? ( CBaseEntity * )UTIL_GetLocalPlayer() : NULL;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
else if ( !stricmp( name, "!target1" ) )
{
@ -4273,7 +4277,11 @@ CBaseEntity *CSceneEntity::FindNamedEntityClosest( const char *name, CBaseEntity
}
else if ( !stricmp( name, "Player" ) || !stricmp( name, "!player" ))
{
entity = ( gpGlobals->maxClients == 1 ) ? ( CBaseEntity * )UTIL_GetLocalPlayer() : NULL;
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
entity = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
entity = ( gpGlobals->maxClients == 1 ) ? ( CBaseEntity * )UTIL_GetLocalPlayer() : NULL;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return entity;
}
else if ( !stricmp( name, "!target1" ) )

View File

@ -26,6 +26,9 @@ CBaseEntity* MoveToRandomSpot( CBaseEntity *pEnt )
{
if ( pEnt )
{
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
UTIL_SetOrigin( pEnt, GetRandomSpot() );
#else
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
if ( pLocalPlayer )
{
@ -34,6 +37,7 @@ CBaseEntity* MoveToRandomSpot( CBaseEntity *pEnt )
UTIL_SetOrigin( pEnt, GetRandomSpot() );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
return pEnt;

View File

@ -2832,7 +2832,11 @@ void CTriggerSave::Touch( CBaseEntity *pOther )
if ( g_ServerGameDLL.m_fAutoSaveDangerousTime != 0.0f && g_ServerGameDLL.m_fAutoSaveDangerousTime >= gpGlobals->curtime )
{
// A previous dangerous auto save was waiting to become safe
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( pPlayer->GetDeathTime() == 0.0f || pPlayer->GetDeathTime() > gpGlobals->curtime )
{
@ -2852,7 +2856,12 @@ void CTriggerSave::Touch( CBaseEntity *pOther )
if ( m_fDangerousTimer != 0.0f )
{
// There's a dangerous timer. Save if we have enough hitpoints.
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if (pPlayer && pPlayer->GetHealth() >= m_minHitPoints)
{
@ -3900,7 +3909,9 @@ static void PlayCDTrack( int iTrack )
// manually find the single player.
pClient = engine->PEntityOfEntIndex( 1 );
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
Assert(gpGlobals->maxClients == 1);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Can't play if the client is not connected!
if ( !pClient )

View File

@ -686,6 +686,101 @@ CBasePlayer* UTIL_PlayerByUserId( int userID )
// Return the local player.
// If this is a multiplayer game, return NULL.
//
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *UTIL_GetLocalPlayer( void )
{
// first try getting the host, failing that, get *ANY* player
CBasePlayer *pHost = UTIL_GetListenServerHost();
if ( pHost )
return pHost;
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( pPlayer )
return pPlayer;
}
return NULL;
}
//SecobMod__Information: This is a new function designed to get the nearest player to a player that called the command, this is used for our respawn where killed code to try and respawn at a near-by player.
CBasePlayer *UTIL_GetOtherNearestPlayer( const Vector &origin )
{
// End of copied and pasted code. //SecobMod__Information: See the following Null Pointer line.
float distToOtherNearest = 128.0f; //SecobMod__Information: We don't want the OtherNearest player to be the player that called this function.
CBasePlayer *pOtherNearest = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
float flDist = (pPlayer->GetAbsOrigin() - origin).LengthSqr();
if ( flDist >= distToOtherNearest )
{
pOtherNearest = pPlayer;
distToOtherNearest = flDist;
}
}
return pOtherNearest;
}
CBasePlayer *UTIL_GetNearestPlayer( const Vector &origin )
{
float distToNearest = 99999999999999999999999999999999999999.0f;
CBasePlayer *pNearest = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
float flDist = (pPlayer->GetAbsOrigin() - origin).LengthSqr();
if ( flDist < distToNearest )
{
pNearest = pPlayer;
distToNearest = flDist;
}
}
return pNearest;
}
CBasePlayer *UTIL_GetNearestVisiblePlayer( CBaseEntity *pLooker, int mask )
{
float distToNearest = 99999999999999999999999999999999999999.0f;
CBasePlayer *pNearest = NULL;
for (int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
float flDist = (pPlayer->GetAbsOrigin() - pLooker->GetAbsOrigin()).LengthSqr();
if ( flDist < distToNearest && pLooker->FVisible( pPlayer, mask ) )
{
pNearest = pPlayer;
distToNearest = flDist;
}
}
return pNearest;
}
#else
CBasePlayer *UTIL_GetLocalPlayer( void )
{
if ( gpGlobals->maxClients > 1 )
@ -704,6 +799,7 @@ CBasePlayer *UTIL_GetLocalPlayer( void )
return UTIL_PlayerByIndex( 1 );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//
// Get the local player on a listen server - this is for multiplayer use only
@ -713,8 +809,11 @@ CBasePlayer *UTIL_GetListenServerHost( void )
// no "local player" if this is a dedicated server or a single player game
if (engine->IsDedicatedServer())
{
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
Assert( !"UTIL_GetListenServerHost" );
Warning( "UTIL_GetListenServerHost() called from a dedicated server or single-player game.\n" );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return NULL;
}

View File

@ -235,6 +235,16 @@ CBasePlayer *UTIL_PlayerBySteamID( const CSteamID &steamID );
// not useable in multiplayer - see UTIL_GetListenServerHost()
CBasePlayer* UTIL_GetLocalPlayer( void );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
// helper functions added for replacing the above
CBasePlayer *UTIL_GetNearestPlayer( const Vector &origin );
CBasePlayer *UTIL_GetNearestVisiblePlayer(CBaseEntity *pLooker, int mask = MASK_SOLID_BRUSHONLY);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//SecobMod__Information: Helper function for player usage.
CBasePlayer *UTIL_GetOtherNearestPlayer( const Vector &origin );
// get the local player on a listen server
CBasePlayer *UTIL_GetListenServerHost( void );

View File

@ -126,12 +126,23 @@ protected:
{
CBaseEntity *pThrower = pGrenade->GetThrower();
CBaseEntity *pOriginalThrower = pGrenade->GetOriginalThrower();
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// check if player was most recent thrower, but the victim was the original thrower
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( pThrower->IsPlayer() && ( pOriginalThrower == pVictim ) )
{
IncrementCount();
}
#else
if ( ( pPlayer == pThrower ) && ( pOriginalThrower == pVictim ) )
{
IncrementCount();
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
}
};

View File

@ -1175,7 +1175,12 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration )
sequence = SelectWeightedSequence( ACT_VM_IDLE );
//Adrian: Oh man again...
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ))
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ) || defined( SDK_DLL ) )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( GetOwner()->IsPlayer() )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
SetModel( GetViewModel() );
#endif

View File

@ -1644,9 +1644,10 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info )
bool bDoServerEffects = true;
#if defined( HL2MP ) && defined( GAME_DLL )
//SecobMod__Information: This is a fix which is meant to allow tracers from mounted guns to display once more in-game, by always making sure it returns true.
/*#if defined( HL2MP ) && defined( GAME_DLL )
bDoServerEffects = false;
#endif
#endif*/
#if defined( GAME_DLL )
if( IsPlayer() )
@ -2094,7 +2095,11 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info )
bool CBaseEntity::ShouldDrawUnderwaterBulletBubbles()
{
#if defined( HL2_DLL ) && defined( GAME_DLL )
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pPlayer = UTIL_GetNearestVisiblePlayer(this);
#else
CBaseEntity *pPlayer = ( gpGlobals->maxClients == 1 ) ? UTIL_GetLocalPlayer() : NULL;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
return pPlayer && (pPlayer->GetWaterLevel() == 3);
#else
return false;
@ -2600,10 +2605,22 @@ ConVar sv_alternateticks( "sv_alternateticks", ( IsX360() ) ? "1" : "0", FCVAR_S
//-----------------------------------------------------------------------------
bool CBaseEntity::IsSimulatingOnAlternateTicks()
{
//.Kave's fix for slow motion single player problems.
#ifdef SecobMod__ENABLED_FIXED_MULTIPLAYER_AI
if( gpGlobals->maxClients > 1 )
{
sv_alternateticks.SetValue( 1 );
}
else if( gpGlobals->maxClients == 1 )
{
sv_alternateticks.SetValue( 0 );
}
#else
if ( gpGlobals->maxClients != 1 )
{
return false;
}
#endif
return sv_alternateticks.GetBool();
}

View File

@ -1834,7 +1834,11 @@ void CGameMovement::Accelerate( Vector& wishdir, float wishspeed, float accel )
return;
// See if we are changing direction a bit
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
currentspeed = sqrt( DotProduct(mv->m_vecVelocity, mv->m_vecVelocity) );
#else
currentspeed = mv->m_vecVelocity.Dot(wishdir);
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Reduce wishspeed by the amount of veer.
addspeed = wishspeed - currentspeed;

View File

@ -875,7 +875,11 @@ float CGameRules::GetAmmoDamage( CBaseEntity *pAttacker, CBaseEntity *pVictim, i
float flDamage = 0;
CAmmoDef *pAmmoDef = GetAmmoDef();
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
if ( pAttacker && pAttacker->IsPlayer() )
#else
if ( pAttacker->IsPlayer() )
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
{
flDamage = pAmmoDef->PlrDamage( nAmmoType );
}

View File

@ -32,9 +32,13 @@ REGISTER_GAMERULES_CLASS( CHalfLife2 );
BEGIN_NETWORK_TABLE_NOBASE( CHalfLife2, DT_HL2GameRules )
#ifdef CLIENT_DLL
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
RecvPropBool( RECVINFO( m_bMegaPhysgun ) ),
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#else
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
SendPropBool( SENDINFO( m_bMegaPhysgun ) ),
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#endif
END_NETWORK_TABLE()
@ -275,7 +279,9 @@ void CHalfLife2Proxy::UpdateOnRemove()
END_SEND_TABLE()
#endif
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
ConVar physcannon_mega_enabled( "physcannon_mega_enabled", "0", FCVAR_CHEAT | FCVAR_REPLICATED );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
// Controls the application of the robus radius damage model.
ConVar sv_robust_explosions( "sv_robust_explosions","1", FCVAR_REPLICATED );
@ -430,9 +436,12 @@ bool CHalfLife2::Damage_IsTimeBased( int iDmgType )
#ifdef CLIENT_DLL
#else
#ifdef HL2_EPISODIC
ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REPLICATED );
#endif // HL2_EPISODIC
//SecobMod__MiscFixes Here we disable this as it's been moved to hl2mp_gamerules so that calls to darkness mode work.
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef HL2_EPISODIC
ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REPLICATED );
#endif // HL2_EPISODIC
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#endif // CLIENT_DLL
@ -464,7 +473,9 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP
//-----------------------------------------------------------------------------
CHalfLife2::CHalfLife2()
{
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
m_bMegaPhysgun = false;
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
m_flLastHealthDropTime = 0.0f;
m_flLastGrenadeDropTime = 0.0f;
@ -1554,7 +1565,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP
void CHalfLife2::Think( void )
{
BaseClass::Think();
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
if( physcannon_mega_enabled.GetBool() == true )
{
m_bMegaPhysgun = true;
@ -1564,6 +1575,7 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP
// FIXME: Is there a better place for this?
m_bMegaPhysgun = ( GlobalEntity_GetState("super_phys_gun") == GLOBAL_ON );
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
}
//-----------------------------------------------------------------------------
@ -1622,19 +1634,27 @@ ConVar alyx_darkness_force( "alyx_darkness_force", "0", FCVAR_CHEAT | FCVAR_REP
#ifndef CLIENT_DLL
if( (info.GetDamageType() & DMG_CRUSH) && info.GetInflictor() && pVictim->MyNPCPointer() )
{
if( pVictim->MyNPCPointer()->IsPlayerAlly() )
{
// A physics object has struck a player ally. Don't allow damage if it
// came from the player's physcannon.
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
#ifdef MAPBASE
// Friendly fire needs to be handled here.
if ( pPlayer && !pVictim->MyNPCPointer()->FriendlyFireEnabled() )
if( pVictim->MyNPCPointer()->IsPlayerAlly() && !pVictim->MyNPCPointer()->FriendlyFireEnabled())
#else
if( pPlayer )
if( pVictim->MyNPCPointer()->IsPlayerAlly() )
#endif
{
// A physics object has struck a player ally. Don't allow damage if it
// came from any player's physcannon.
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
for (int i = 1; i <= gpGlobals->maxClients; i++ )//
//AI Patch Removal: CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )//AI Patch Removal
continue;
#else
CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
if( pPlayer )
{
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
CBaseEntity *pWeapon = pPlayer->HasNamedPlayerItem("weapon_physcannon");
if( pWeapon )
@ -1752,12 +1772,14 @@ bool CHalfLife2::ShouldCollide( int collisionGroup0, int collisionGroup1 )
collisionGroup1 = COLLISION_GROUP_NPC;
}
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
// This is only for the super physcannon
if ( m_bMegaPhysgun )
{
if ( collisionGroup0 == COLLISION_GROUP_INTERACTIVE_DEBRIS && collisionGroup1 == COLLISION_GROUP_PLAYER )
return false;
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
if ( collisionGroup0 == HL2COLLISION_GROUP_COMBINE_BALL )
{
@ -1972,6 +1994,8 @@ void CHalfLife2::LevelInitPreEntity()
BaseClass::LevelInitPreEntity();
}
//SecobMod__MiscFixes Here we disable this as it's been moved to hl2mp_gamerules so that calls to darkness mode work.
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
//-----------------------------------------------------------------------------
// Returns whether or not Alyx cares about light levels in order to see.
//-----------------------------------------------------------------------------
@ -2000,6 +2024,7 @@ bool CHalfLife2::ShouldBurningPropsEmitLight()
return false;
#endif // HL2_EPISODIC
}
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef MAPBASE

View File

@ -86,8 +86,10 @@ public:
#endif
private:
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
// Rules change for the mega physgun
CNetworkVar( bool, m_bMegaPhysgun );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef CLIENT_DLL
@ -113,7 +115,11 @@ private:
virtual void PlayerThink( CBasePlayer *pPlayer );
virtual float GetAmmoDamage( CBaseEntity *pAttacker, CBaseEntity *pVictim, int nAmmoType );
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
/SecobMod__MiscFixes Here we disable this as it's been moved to hl2mp_gamerules so that calls to darkness mode work.
virtual bool ShouldBurningPropsEmitLight();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
public:
bool AllowDamage( CBaseEntity *pVictim, const CTakeDamageInfo &info );
@ -122,9 +128,15 @@ public:
bool NPC_ShouldDropHealth( CBasePlayer *pRecipient );
void NPC_DroppedHealth( void );
void NPC_DroppedGrenade( void );
bool MegaPhyscannonActive( void ) { return m_bMegaPhysgun; }
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
bool MegaPhyscannonActive( void ) { return m_bMegaPhysgun; }
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
//SecobMod__MiscFixes: Here we disable this as it's been moved to hl2mp_gamerules so that calls to darkness mode work.
#ifndef SecobMod__Enable_Fixed_Multiplayer_AI
virtual bool IsAlyxInDarknessMode();
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#ifdef MAPBASE
int GetDefaultCitizenType();

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,10 @@
#include "hl2mp_player.h"
#endif
#ifdef MAPBASE_MP
#define SecobMod__ALLOW_SUPER_GRAVITY_GUN 1
#endif
#define VEC_CROUCH_TRACE_MIN HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMin
#define VEC_CROUCH_TRACE_MAX HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMax
@ -84,6 +88,10 @@ class CHL2MPRules : public CTeamplayRules
public:
DECLARE_CLASS( CHL2MPRules, CTeamplayRules );
#ifdef SecobMod__ALLOW_SUPER_GRAVITY_GUN
bool MegaPhyscannonActive( void ) { return m_bMegaPhysgun; }
#endif //SecobMod__ALLOW_SUPER_GRAVITY_GUN
#ifdef CLIENT_DLL
DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
@ -91,6 +99,12 @@ public:
#else
DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
//SecobMod__MiscFixes: Here we add darkness mode so that it now works.
virtual bool IsAlyxInDarknessMode();
virtual bool ShouldBurningPropsEmitLight();
#endif
CHL2MPRules();
@ -134,6 +148,10 @@ public:
void CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg );
const char *GetChatFormat( bool bTeamOnly, CBasePlayer *pPlayer );
#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
void InitDefaultAIRelationships( void );
#endif //SecobMod__Enable_Fixed_Multiplayer_AI
#endif
virtual void ClientDisconnected( edict_t *pClient );
@ -159,6 +177,12 @@ private:
bool m_bAwaitingReadyRestart;
bool m_bHeardAllPlayersReady;
#ifdef SecobMod__ALLOW_SUPER_GRAVITY_GUN
//SecobMod__Information: Super grav gun stuff.
// Rules change for the mega physgun
CNetworkVar( bool, m_bMegaPhysgun );
#endif //SecobMod__ALLOW_SUPER_GRAVITY_GUN
#ifndef CLIENT_DLL
bool m_bChangelevelDone;
#endif

Some files were not shown because too many files have changed in this diff Show More