Skip to content

Commit 737f579

Browse files
committed
add mp support to ai_basenpcs and behavior
1 parent 6f28f15 commit 737f579

File tree

7 files changed

+251
-47
lines changed

7 files changed

+251
-47
lines changed

src/game/server/ai_basenpc.cpp

Lines changed: 139 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@
8787
#include "datacache/imdlcache.h"
8888
#include "vstdlib/jobthread.h"
8989

90+
#ifdef BDSBASE
91+
#include "ilagcompensationmanager.h"
92+
93+
//TDT - Information: Here we include the hl2mp gamerules.
94+
#include "hl2mp_gamerules.h"
95+
#endif //BDSBASE
96+
9097
#ifdef HL2_EPISODIC
9198
#include "npc_alyx_episodic.h"
9299
#endif
@@ -254,10 +261,18 @@ int CAI_Manager::NumAIs()
254261

255262
//-------------------------------------
256263

257-
void CAI_Manager::AddAI( CAI_BaseNPC *pAI )
264+
#ifdef BDSBASE
265+
int CAI_Manager::AddAI(CAI_BaseNPC* pAI)
258266
{
259-
m_AIs.AddToTail( pAI );
267+
m_AIs.AddToTail(pAI);
268+
return NumAIs() - 1; // return the index it was added to
260269
}
270+
#else
271+
void CAI_Manager::AddAI(CAI_BaseNPC* pAI)
272+
{
273+
m_AIs.AddToTail(pAI);
274+
}
275+
#endif //BDSBASE
261276

262277
//-------------------------------------
263278

@@ -642,18 +657,39 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo
642657
{
643658
BaseClass::Ignite( flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner );
644659

660+
#ifdef BDSBASE
661+
/*#ifdef HL2_EPISODIC
662+
if ( AI_IsSinglePlayer() )
663+
{
664+
CBasePlayer *pPlayer = AI_GetSinglePlayer();
665+
if ( pPlayer->IRelationType( this ) != D_LI )
666+
{
667+
CNPC_Alyx *alyx = CNPC_Alyx::GetAlyx();
668+
669+
if ( alyx )
670+
{
671+
alyx->EnemyIgnited( this );
672+
}
673+
}
674+
}
675+
#endif*/
676+
#else
645677
#ifdef HL2_EPISODIC
646-
CBasePlayer *pPlayer = AI_GetSinglePlayer();
647-
if ( pPlayer->IRelationType( this ) != D_LI )
678+
if (AI_IsSinglePlayer())
648679
{
649-
CNPC_Alyx *alyx = CNPC_Alyx::GetAlyx();
650-
651-
if ( alyx )
680+
CBasePlayer* pPlayer = AI_GetSinglePlayer();
681+
if (pPlayer->IRelationType(this) != D_LI)
652682
{
653-
alyx->EnemyIgnited( this );
683+
CNPC_Alyx* alyx = CNPC_Alyx::GetAlyx();
684+
685+
if (alyx)
686+
{
687+
alyx->EnemyIgnited(this);
688+
}
654689
}
655690
}
656691
#endif
692+
#endif //BDSBASE
657693
}
658694

659695
//-----------------------------------------------------------------------------
@@ -777,9 +813,15 @@ int CAI_BaseNPC::OnTakeDamage_Alive( const CTakeDamageInfo &info )
777813
{
778814
// See if the person that injured me is an NPC.
779815
CAI_BaseNPC *pAttacker = dynamic_cast<CAI_BaseNPC *>( info.GetAttacker() );
780-
CBasePlayer *pPlayer = AI_GetSinglePlayer();
816+
#ifndef BDSBASE
817+
CBasePlayer* pPlayer = AI_GetSinglePlayer();
818+
#endif //BDSBASE
781819

782-
if( pAttacker && pAttacker->IsAlive() && pPlayer )
820+
#ifdef BDSBASE
821+
if (pAttacker && pAttacker->IsAlive() && UTIL_GetNearestPlayer(GetAbsOrigin()))
822+
#else
823+
if (pAttacker && pAttacker->IsAlive() && pPlayer)
824+
#endif //BDSBASE
783825
{
784826
if( pAttacker->GetSquad() != NULL && pAttacker->IsInPlayerSquad() )
785827
{
@@ -3110,7 +3152,11 @@ void CAI_BaseNPC::UpdateEfficiency( bool bInPVS )
31103152

31113153
//---------------------------------
31123154

3113-
CBasePlayer *pPlayer = AI_GetSinglePlayer();
3155+
#ifdef BDSBASE
3156+
CBasePlayer* pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
3157+
#else
3158+
CBasePlayer* pPlayer = AI_GetSinglePlayer();
3159+
#endif //BDSBASE
31143160
static Vector vPlayerEyePosition;
31153161
static Vector vPlayerForward;
31163162
static int iPrevFrame = -1;
@@ -3361,7 +3407,11 @@ void CAI_BaseNPC::UpdateSleepState( bool bInPVS )
33613407
{
33623408
if ( GetSleepState() > AISS_AWAKE )
33633409
{
3364-
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
3410+
#ifdef BDSBASE
3411+
CBasePlayer* pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
3412+
#else
3413+
CBasePlayer* pLocalPlayer = AI_GetSinglePlayer();
3414+
#endif //BDSBASE
33653415
if ( !pLocalPlayer )
33663416
{
33673417
if ( gpGlobals->maxClients > 1 )
@@ -3568,7 +3618,11 @@ void CAI_BaseNPC::RebalanceThinks()
35683618

35693619
int i;
35703620

3571-
CBasePlayer *pPlayer = AI_GetSinglePlayer();
3621+
#ifdef BDSBASE
3622+
CBasePlayer* pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
3623+
#else
3624+
CBasePlayer* pPlayer = AI_GetSinglePlayer();
3625+
#endif //BDSBASE
35723626
Vector vPlayerForward;
35733627
Vector vPlayerEyePosition;
35743628

@@ -3849,7 +3903,11 @@ void CAI_BaseNPC::SetPlayerAvoidState( void )
38493903

38503904
GetPlayerAvoidBounds( &vMins, &vMaxs );
38513905

3852-
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
3906+
#ifdef BDSBASE
3907+
CBasePlayer* pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
3908+
#else
3909+
CBasePlayer* pLocalPlayer = AI_GetSinglePlayer();
3910+
#endif //BDSBASE
38533911

38543912
if ( pLocalPlayer )
38553913
{
@@ -4824,14 +4882,22 @@ void CAI_BaseNPC::RunAI( void )
48244882
}
48254883
}
48264884

4827-
if( ai_debug_loners.GetBool() && !IsInSquad() && AI_IsSinglePlayer() )
4885+
#ifdef BDSBASE
4886+
if (ai_debug_loners.GetBool() && !IsInSquad())
4887+
#else
4888+
if (ai_debug_loners.GetBool() && !IsInSquad() && AI_IsSinglePlayer())
4889+
#endif //BDSBASE
48284890
{
48294891
Vector right;
48304892
Vector vecPoint;
48314893

48324894
vecPoint = EyePosition() + Vector( 0, 0, 12 );
48334895

4834-
UTIL_GetLocalPlayer()->GetVectors( NULL, &right, NULL );
4896+
#ifdef BDSBASE
4897+
UTIL_GetNearestPlayer(GetAbsOrigin())->GetVectors(NULL, &right, NULL);
4898+
#else
4899+
UTIL_GetLocalPlayer()->GetVectors(NULL, &right, NULL);
4900+
#endif //BDSBASE
48354901

48364902
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 64 ), 255, 0, 0, false , 0.1 );
48374903
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) + right * 32, 255, 0, 0, false , 0.1 );
@@ -8691,7 +8757,11 @@ void CAI_BaseNPC::DrawDebugGeometryOverlays(void)
86918757

86928758
info.SetDamage( m_iHealth );
86938759
info.SetAttacker( this );
8694-
info.SetInflictor( ( AI_IsSinglePlayer() ) ? (CBaseEntity *)AI_GetSinglePlayer() : (CBaseEntity *)this );
8760+
#ifdef BDSBASE
8761+
info.SetInflictor((CBaseEntity*)this);
8762+
#else
8763+
info.SetInflictor((AI_IsSinglePlayer()) ? (CBaseEntity*)AI_GetSinglePlayer() : (CBaseEntity*)this);
8764+
#endif //BDSBASE
86958765
info.SetDamageType( DMG_GENERIC );
86968766

86978767
m_debugOverlays &= ~OVERLAY_NPC_KILL_BIT;
@@ -9922,7 +9992,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
99229992
{
99239993
if ( !stricmp( name, "!player" ))
99249994
{
9925-
return ( CBaseEntity * )AI_GetSinglePlayer();
9995+
#ifdef BDSBASE
9996+
return UTIL_GetNearestPlayer(GetAbsOrigin());
9997+
#else
9998+
return (CBaseEntity*)AI_GetSinglePlayer();
9999+
#endif //BDSBASE
992610000
}
992710001
else if ( !stricmp( name, "!enemy" ) )
992810002
{
@@ -9937,7 +10011,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
993710011
{
993810012
// FIXME: look at CBaseEntity *CNPCSimpleTalker::FindNearestFriend(bool fPlayer)
993910013
// punt for now
9940-
return ( CBaseEntity * )AI_GetSinglePlayer();
10014+
#ifdef BDSBASE
10015+
return UTIL_GetNearestPlayer(GetAbsOrigin());
10016+
#else
10017+
return (CBaseEntity*)AI_GetSinglePlayer();
10018+
#endif //BDSBASE
994110019
}
994210020
else if (!stricmp( name, "self" ))
994310021
{
@@ -9957,7 +10035,11 @@ CBaseEntity *CAI_BaseNPC::FindNamedEntity( const char *name, IEntityFindFilter *
995710035
{
995810036
DevMsg( "ERROR: \"player\" is no longer used, use \"!player\" in vcd instead!\n" );
995910037
}
9960-
return ( CBaseEntity * )AI_GetSinglePlayer();
10038+
#ifdef BDSBASE
10039+
return UTIL_GetNearestPlayer(GetAbsOrigin());
10040+
#else
10041+
return (CBaseEntity*)AI_GetSinglePlayer();
10042+
#endif //BDSBASE
996110043
}
996210044
else
996310045
{
@@ -11386,7 +11468,12 @@ CAI_BaseNPC::CAI_BaseNPC(void)
1138611468
m_interuptSchedule = NULL;
1138711469
m_nDebugPauseIndex = 0;
1138811470

11389-
g_AI_Manager.AddAI( this );
11471+
#ifdef BDSBASE
11472+
SetAIIndex(g_AI_Manager.AddAI(this));
11473+
lagcompensation->RemoveNpcData(GetAIIndex()); // make sure we're not inheriting anyone else's data
11474+
#else
11475+
g_AI_Manager.AddAI(this);
11476+
#endif //BDSBASE
1139011477

1139111478
if ( g_AI_Manager.NumAIs() == 1 )
1139211479
{
@@ -11410,6 +11497,10 @@ CAI_BaseNPC::CAI_BaseNPC(void)
1141011497
CAI_BaseNPC::~CAI_BaseNPC(void)
1141111498
{
1141211499
g_AI_Manager.RemoveAI( this );
11500+
#ifdef BDSBASE
11501+
// this should stop a crash occuring when our death immediately creates a new NPC (eg headcrab from zombie)
11502+
lagcompensation->RemoveNpcData(GetAIIndex());
11503+
#endif //BDSBASE
1141311504

1141411505
delete m_pLockedBestSound;
1141511506

@@ -11930,7 +12021,11 @@ bool CAI_BaseNPC::CineCleanup()
1193012021
{
1193112022
SetLocalOrigin( origin );
1193212023

11933-
int drop = UTIL_DropToFloor( this, MASK_NPCSOLID, UTIL_GetLocalPlayer() );
12024+
#ifdef BDSBASE
12025+
int drop = UTIL_DropToFloor(this, MASK_NPCSOLID, UTIL_GetNearestVisiblePlayer(this));
12026+
#else
12027+
int drop = UTIL_DropToFloor(this, MASK_NPCSOLID, UTIL_GetLocalPlayer());
12028+
#endif //BDSBASE
1193412029

1193512030
// Origin in solid? Set to org at the end of the sequence
1193612031
if ( ( drop < 0 ) || sv_test_scripted_sequences.GetBool() )
@@ -12007,7 +12102,11 @@ void CAI_BaseNPC::Teleport( const Vector *newPosition, const QAngle *newAngles,
1200712102

1200812103
bool CAI_BaseNPC::FindSpotForNPCInRadius( Vector *pResult, const Vector &vStartPos, CAI_BaseNPC *pNPC, float radius, bool bOutOfPlayerViewcone )
1200912104
{
12010-
CBasePlayer *pPlayer = AI_GetSinglePlayer();
12105+
#ifdef BDSBASE
12106+
CBasePlayer* pPlayer = UTIL_GetNearestPlayer(pNPC->GetAbsOrigin());
12107+
#else
12108+
CBasePlayer* pPlayer = AI_GetSinglePlayer();
12109+
#endif //BDSBASE
1201112110
QAngle fan;
1201212111

1201312112
fan.x = 0;
@@ -12541,13 +12640,17 @@ bool CAI_BaseNPC::IsPlayerAlly( CBasePlayer *pPlayer )
1254112640
{
1254212641
if ( pPlayer == NULL )
1254312642
{
12544-
// in multiplayer mode we need a valid pPlayer
12545-
// or override this virtual function
12546-
if ( !AI_IsSinglePlayer() )
12643+
#ifndef BDSBASE
12644+
if (!AI_IsSinglePlayer())
1254712645
return false;
12646+
#endif //BDSBASE
1254812647

1254912648
// NULL means single player mode
12649+
#ifdef BDSBASE
12650+
pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin());
12651+
#else
1255012652
pPlayer = UTIL_GetLocalPlayer();
12653+
#endif //BDSBASE
1255112654
}
1255212655

1255312656
return ( !pPlayer || IRelationType( pPlayer ) == D_LI );
@@ -12841,7 +12944,11 @@ bool CAI_BaseNPC::FindNearestValidGoalPos( const Vector &vTestPoint, Vector *pRe
1284112944

1284212945
if ( vCandidate != vec3_invalid )
1284312946
{
12844-
AI_Waypoint_t *pPathToPoint = GetPathfinder()->BuildRoute( GetAbsOrigin(), vCandidate, AI_GetSinglePlayer(), 5*12, NAV_NONE, true );
12947+
#ifdef BDSBASE
12948+
AI_Waypoint_t* pPathToPoint = GetPathfinder()->BuildRoute(GetAbsOrigin(), vCandidate, UTIL_GetNearestPlayer(GetAbsOrigin()), 5 * 12, NAV_NONE, true);
12949+
#else
12950+
AI_Waypoint_t* pPathToPoint = GetPathfinder()->BuildRoute(GetAbsOrigin(), vCandidate, AI_GetSinglePlayer(), 5 * 12, NAV_NONE, true);
12951+
#endif //BDSBASE
1284512952
if ( pPathToPoint )
1284612953
{
1284712954
GetPathfinder()->UnlockRouteNodes( pPathToPoint );
@@ -13981,7 +14088,11 @@ void CAI_BaseNPC::PlayerHasIlluminatedNPC( CBasePlayer *pPlayer, float flDot )
1398114088
if ( pInteraction->iLoopBreakTriggerMethod & SNPCINT_LOOPBREAK_ON_FLASHLIGHT_ILLUM )
1398214089
{
1398314090
// Only do this in alyx darkness mode
13984-
if ( HL2GameRules()->IsAlyxInDarknessMode() )
14091+
#ifdef BDSBASE
14092+
if (HL2MPRules()->IsAlyxInDarknessMode())
14093+
#else
14094+
if (HL2GameRules()->IsAlyxInDarknessMode())
14095+
#endif //BDSBASE
1398514096
{
1398614097
// Can only break when we're in the action anim
1398714098
if ( m_hCine->IsPlayingAction() )

src/game/server/ai_basenpc.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ float ChangeDistance( float flInterval, float flGoalDistance, float flGoalVeloci
446446
//
447447
//=============================================================================
448448

449+
#ifdef BDSBASE
450+
#define MAX_AIS 256
451+
#endif //BDSBASE
452+
449453
class CAI_Manager
450454
{
451455
public:
@@ -454,16 +458,22 @@ class CAI_Manager
454458
CAI_BaseNPC ** AccessAIs();
455459
int NumAIs();
456460

457-
void AddAI( CAI_BaseNPC *pAI );
461+
#ifdef BDSBASE
462+
int AddAI(CAI_BaseNPC* pAI);
463+
#else
464+
void AddAI(CAI_BaseNPC* pAI);
465+
#endif //BDSBASE
458466
void RemoveAI( CAI_BaseNPC *pAI );
459467

460468
bool FindAI( CAI_BaseNPC *pAI ) { return ( m_AIs.Find( pAI ) != m_AIs.InvalidIndex() ); }
461469

462470
private:
471+
#ifndef BDSBASE
463472
enum
464473
{
465474
MAX_AIS = 256
466475
};
476+
#endif // !BDSBASE
467477

468478
typedef CUtlVector<CAI_BaseNPC *> CAIArray;
469479

@@ -2122,6 +2132,13 @@ class CAI_BaseNPC : public CBaseCombatCharacter,
21222132
void GetPlayerAvoidBounds( Vector *pMins, Vector *pMaxs );
21232133

21242134
void StartPingEffect( void ) { m_flTimePingEffect = gpGlobals->curtime + 2.0f; DispatchUpdateTransmitState(); }
2135+
#ifdef BDSBASE
2136+
// used by lag compensation to be able to refer to & track specific NPCs, and detect changes in the AI list
2137+
void SetAIIndex(int i) { m_iAIIndex = i; }
2138+
int GetAIIndex() { return m_iAIIndex; }
2139+
private:
2140+
int m_iAIIndex;
2141+
#endif //BDSBASE
21252142
};
21262143

21272144

0 commit comments

Comments
 (0)