Skip to content

Commit 648c8eb

Browse files
committed
Integrate SecobMod multiplayer HL2 NPC and logic entity support
1 parent f29550e commit 648c8eb

75 files changed

Lines changed: 972 additions & 13 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ including radial fog, rope code, and treesway)
7070
- https://github.com/entropy-zero/source-sdk-2013 (skill_changed game event)
7171
- https://github.com/Nbc66/source-sdk-2013-ce/tree/v142 (Base for VS2019 toolset support)
7272

73+
Mapbase also contains parts of Source Engine Co-Operative Base Modification (SecobMod), mainly the multiplayer NPC support by Winston.
74+
- https://developer.valvesoftware.com/wiki/Co-Operative_Base_(Mod)
75+
7376
//-------------------------------------------------------------------------------------------------------------------------
7477

7578
Valve Developer Community (VDC) sources:

src/game/client/c_baseentity.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ void cc_cl_interp_all_changed( IConVar *pConVar, const char *pOldString, float f
8686

8787

8888
static ConVar cl_extrapolate( "cl_extrapolate", "1", FCVAR_CHEAT, "Enable/disable extrapolation if interpolation history runs out." );
89+
#ifdef MAPBASE_MP // From SecobMod
90+
static ConVar cl_interp_npcs( "cl_interp_npcs", "0.25", FCVAR_USERINFO, "Interpolate NPC positions starting this many seconds in past (or cl_interp, if greater)" );
91+
#else
8992
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)" );
93+
#endif
9094
static ConVar cl_interp_all( "cl_interp_all", "0", 0, "Disable interpolation list optimizations.", 0, 0, 0, 0, cc_cl_interp_all_changed );
9195
ConVar r_drawmodeldecals( "r_drawmodeldecals", "1", FCVAR_ALLOWED_IN_COMPETITIVE );
9296
extern ConVar cl_showerror;

src/game/server/EntityDissolve.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,11 @@ CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMat
232232
// Necessary to cause it to do the appropriate death cleanup
233233
if ( pTarget->m_lifeState == LIFE_ALIVE )
234234
{
235+
#ifdef MAPBASE_MP // From SecobMod
236+
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
237+
#else
235238
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
239+
#endif
236240
CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE );
237241
pTarget->TakeDamage( ragdollInfo );
238242
}
@@ -347,7 +351,11 @@ void CEntityDissolve::DissolveThink( void )
347351
// Necessary to cause it to do the appropriate death cleanup
348352
// Yeah, the player may have nothing to do with it, but
349353
// passing NULL to TakeDamage causes bad things to happen
354+
#ifdef MAPBASE_MP // From SecobMod
355+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
356+
#else
350357
CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 );
358+
#endif
351359
int iNoPhysicsDamage = g_pGameRules->Damage_GetNoPhysicsForce();
352360
CTakeDamageInfo info( pPlayer, pPlayer, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL | iNoPhysicsDamage );
353361
pTarget->TakeDamage( info );

src/game/server/EnvHudHint.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ void CEnvHudHint::InputShowHudHint( inputdata_t &inputdata )
9595
}
9696
else
9797
{
98+
#ifdef MAPBASE_MP // From SecobMod
99+
pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
100+
#else
98101
pPlayer = UTIL_GetLocalPlayer();
102+
#endif
99103
}
100104

101105
if ( !pPlayer || !pPlayer->IsNetClient() )
@@ -132,7 +136,11 @@ void CEnvHudHint::InputHideHudHint( inputdata_t &inputdata )
132136
}
133137
else
134138
{
139+
#ifdef MAPBASE_MP // From SecobMod
140+
pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
141+
#else
135142
pPlayer = UTIL_GetLocalPlayer();
143+
#endif
136144
}
137145

138146
if ( !pPlayer || !pPlayer->IsNetClient() )

src/game/server/EnvMessage.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,16 @@ void CCredits::RollOutroCredits()
267267
if (Mapbase_GetChapterCount() <= 0 && sv_unlockedchapters.GetInt() < 15)
268268
#endif
269269
sv_unlockedchapters.SetValue( "15" );
270-
270+
271+
#ifdef MAPBASE_MP // From SecobMod
272+
CRecipientFilter user;
273+
user.AddAllPlayers();
274+
#else
271275
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
272276

273277
CSingleUserRecipientFilter user( pPlayer );
274278
user.MakeReliable();
279+
#endif
275280

276281
UserMessageBegin( user, "CreditsMsg" );
277282
WRITE_BYTE( 3 );
@@ -293,10 +298,15 @@ void CCredits::InputRollOutroCredits( inputdata_t &inputdata )
293298

294299
void CCredits::InputShowLogo( inputdata_t &inputdata )
295300
{
301+
#ifdef MAPBASE_MP // From SecobMod
302+
CRecipientFilter user;
303+
user.AddAllPlayers();
304+
#else
296305
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
297306

298307
CSingleUserRecipientFilter user( pPlayer );
299308
user.MakeReliable();
309+
#endif
300310

301311
if ( m_flLogoLength )
302312
{
@@ -325,10 +335,15 @@ void CCredits::InputSetLogoLength( inputdata_t &inputdata )
325335

326336
void CCredits::InputRollCredits( inputdata_t &inputdata )
327337
{
338+
#ifdef MAPBASE_MP // From SecobMod
339+
CRecipientFilter user;
340+
user.AddAllPlayers();
341+
#else
328342
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
329343

330344
CSingleUserRecipientFilter user( pPlayer );
331345
user.MakeReliable();
346+
#endif
332347

333348
UserMessageBegin( user, "CreditsMsg" );
334349
WRITE_BYTE( 2 );

src/game/server/ai_basenpc.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,11 @@ void CAI_BaseNPC::Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bo
689689
#endif
690690

691691
#ifdef HL2_EPISODIC
692+
#ifdef MAPBASE_MP // From SecobMod
693+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
694+
#else
692695
CBasePlayer *pPlayer = AI_GetSinglePlayer();
696+
#endif
693697
if ( pPlayer && pPlayer->IRelationType( this ) != D_LI )
694698
{
695699
CNPC_Alyx *alyx = CNPC_Alyx::GetAlyx();
@@ -1200,7 +1204,11 @@ int CAI_BaseNPC::OnTakeDamage_Alive( const CTakeDamageInfo &info )
12001204
{
12011205
// See if the person that injured me is an NPC.
12021206
CAI_BaseNPC *pAttacker = info.GetAttacker()->MyNPCPointer();
1207+
#ifdef MAPBASE_MP // From SecobMod
1208+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
1209+
#else
12031210
CBasePlayer *pPlayer = AI_GetSinglePlayer();
1211+
#endif
12041212

12051213
if( pAttacker && pAttacker->IsAlive() && pPlayer )
12061214
{
@@ -3738,7 +3746,11 @@ void CAI_BaseNPC::UpdateEfficiency( bool bInPVS )
37383746

37393747
//---------------------------------
37403748

3749+
#ifdef MAPBASE_MP // From SecobMod
3750+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
3751+
#else
37413752
CBasePlayer *pPlayer = AI_GetSinglePlayer();
3753+
#endif
37423754
static Vector vPlayerEyePosition;
37433755
static Vector vPlayerForward;
37443756
static int iPrevFrame = -1;
@@ -3985,7 +3997,11 @@ void CAI_BaseNPC::UpdateSleepState( bool bInPVS )
39853997
#ifdef MAPBASE
39863998
#define Wake() Wake(pLocalPlayer)
39873999
#endif
4000+
#ifdef MAPBASE_MP
4001+
CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
4002+
#else
39884003
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
4004+
#endif
39894005
if ( !pLocalPlayer )
39904006
{
39914007
if ( gpGlobals->maxClients > 1 )
@@ -4188,7 +4204,11 @@ void CAI_BaseNPC::RebalanceThinks()
41884204

41894205
int i;
41904206

4207+
#ifdef MAPBASE_MP
4208+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
4209+
#else
41914210
CBasePlayer *pPlayer = AI_GetSinglePlayer();
4211+
#endif
41924212
Vector vPlayerForward;
41934213
Vector vPlayerEyePosition;
41944214

@@ -4469,7 +4489,11 @@ void CAI_BaseNPC::SetPlayerAvoidState( void )
44694489

44704490
GetPlayerAvoidBounds( &vMins, &vMaxs );
44714491

4492+
#ifdef MAPBASE_MP
4493+
CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
4494+
#else
44724495
CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
4496+
#endif
44734497

44744498
if ( pLocalPlayer )
44754499
{
@@ -5571,14 +5595,22 @@ void CAI_BaseNPC::RunAI( void )
55715595
}
55725596
}
55735597

5598+
#ifdef MAPBASE_MP // From SecobMod
5599+
if( ai_debug_loners.GetBool() && !IsInSquad() )
5600+
#else
55745601
if( ai_debug_loners.GetBool() && !IsInSquad() && AI_IsSinglePlayer() )
5602+
#endif
55755603
{
55765604
Vector right;
55775605
Vector vecPoint;
55785606

55795607
vecPoint = EyePosition() + Vector( 0, 0, 12 );
55805608

5609+
#ifdef MAPBASE_MP // From SecobMod
5610+
UTIL_GetNearestPlayer( GetAbsOrigin() )->GetVectors( NULL, &right, NULL );
5611+
#else
55815612
UTIL_GetLocalPlayer()->GetVectors( NULL, &right, NULL );
5613+
#endif
55825614

55835615
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 64 ), 255, 0, 0, false , 0.1 );
55845616
NDebugOverlay::Line( vecPoint, vecPoint + Vector( 0, 0, 32 ) + right * 32, 255, 0, 0, false , 0.1 );
@@ -10325,7 +10357,11 @@ void CAI_BaseNPC::DrawDebugGeometryOverlays(void)
1032510357

1032610358
info.SetDamage( m_iHealth );
1032710359
info.SetAttacker( this );
10360+
#ifdef MAPBASE_MP // From SecobMod
10361+
info.SetInflictor( (CBaseEntity *)this );
10362+
#else
1032810363
info.SetInflictor( ( AI_IsSinglePlayer() ) ? (CBaseEntity *)AI_GetSinglePlayer() : (CBaseEntity *)this );
10364+
#endif
1032910365
info.SetDamageType( DMG_GENERIC );
1033010366

1033110367
m_debugOverlays &= ~OVERLAY_NPC_KILL_BIT;
@@ -13970,7 +14006,11 @@ bool CAI_BaseNPC::CineCleanup()
1397014006
{
1397114007
SetLocalOrigin( origin );
1397214008

14009+
#ifdef MAPBASE_MP // From SecobMod
14010+
int drop = UTIL_DropToFloor( this, MASK_NPCSOLID, UTIL_GetNearestVisiblePlayer( this ) );
14011+
#else
1397314012
int drop = UTIL_DropToFloor( this, MASK_NPCSOLID, UTIL_GetLocalPlayer() );
14013+
#endif
1397414014

1397514015
// Origin in solid? Set to org at the end of the sequence
1397614016
if ( ( drop < 0 ) || sv_test_scripted_sequences.GetBool() )
@@ -14051,7 +14091,11 @@ void CAI_BaseNPC::Teleport( const Vector *newPosition, const QAngle *newAngles,
1405114091

1405214092
bool CAI_BaseNPC::FindSpotForNPCInRadius( Vector *pResult, const Vector &vStartPos, CAI_BaseNPC *pNPC, float radius, bool bOutOfPlayerViewcone )
1405314093
{
14094+
#ifdef MAPBASE_MP // From SecobMod
14095+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( pNPC->GetAbsOrigin() );
14096+
#else
1405414097
CBasePlayer *pPlayer = AI_GetSinglePlayer();
14098+
#endif
1405514099
QAngle fan;
1405614100

1405714101
fan.x = 0;
@@ -14644,13 +14688,17 @@ bool CAI_BaseNPC::IsPlayerAlly( CBasePlayer *pPlayer )
1464414688
{
1464514689
if ( pPlayer == NULL )
1464614690
{
14691+
#ifdef MAPBASE_MP // From SecobMod
14692+
pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
14693+
#else
1464714694
// in multiplayer mode we need a valid pPlayer
1464814695
// or override this virtual function
1464914696
if ( !AI_IsSinglePlayer() )
1465014697
return false;
1465114698

1465214699
// NULL means single player mode
1465314700
pPlayer = UTIL_GetLocalPlayer();
14701+
#endif
1465414702
}
1465514703

1465614704
return ( !pPlayer || IRelationType( pPlayer ) == D_LI );
@@ -14948,7 +14996,11 @@ bool CAI_BaseNPC::FindNearestValidGoalPos( const Vector &vTestPoint, Vector *pRe
1494814996

1494914997
if ( vCandidate != vec3_invalid )
1495014998
{
14999+
#ifdef MAPBASE_MP // From SecobMod
15000+
AI_Waypoint_t *pPathToPoint = GetPathfinder()->BuildRoute( GetAbsOrigin(), vCandidate, UTIL_GetNearestPlayer( GetAbsOrigin() ), 5 * 12, NAV_NONE, true );
15001+
#else
1495115002
AI_Waypoint_t *pPathToPoint = GetPathfinder()->BuildRoute( GetAbsOrigin(), vCandidate, AI_GetSinglePlayer(), 5*12, NAV_NONE, true );
15003+
#endif
1495215004
if ( pPathToPoint )
1495315005
{
1495415006
GetPathfinder()->UnlockRouteNodes( pPathToPoint );

src/game/server/ai_basenpc_schedule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,7 +3532,11 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
35323532
case TASK_FACE_PLAYER:
35333533
{
35343534
// Get edict for one player
3535+
#ifdef MAPBASE_MP // From SecobMod
3536+
CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer( this );
3537+
#else
35353538
CBasePlayer *pPlayer = AI_GetSinglePlayer();
3539+
#endif
35363540
if ( pPlayer )
35373541
{
35383542
GetMotor()->SetIdealYawToTargetAndUpdate( pPlayer->GetAbsOrigin(), AI_KEEP_YAW_SPEED );
@@ -3866,7 +3870,11 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
38663870

38673871
if( pHint )
38683872
{
3873+
#ifdef MAPBASE_MP // From SecobMod
3874+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
3875+
#else
38693876
CBasePlayer *pPlayer = AI_GetSinglePlayer();
3877+
#endif
38703878
Vector vecGoal = pHint->GetAbsOrigin();
38713879

38723880
if( vecGoal.DistToSqr(GetAbsOrigin()) < vecGoal.DistToSqr(pPlayer->GetAbsOrigin()) )

src/game/server/ai_behavior_fear.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,11 @@ void CAI_FearBehavior::GatherConditions()
350350
// -I haven't seen the player in 2 seconds
351351
//
352352
// Here's the distance check:
353+
#ifdef MAPBASE_MP // From SecobMod
354+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
355+
#else
353356
CBasePlayer *pPlayer = AI_GetSinglePlayer();
357+
#endif
354358
if( pPlayer != NULL && GetAbsOrigin().DistToSqr(pPlayer->GetAbsOrigin()) >= Square( ai_fear_player_dist.GetFloat() * 1.5f ) )
355359
{
356360
SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
@@ -492,7 +496,12 @@ CAI_Hint *CAI_FearBehavior::FindFearWithdrawalDest()
492496
#ifdef MAPBASE
493497
hintCriteria.SetFlag(bits_HINT_NODE_USE_GROUP);
494498
#endif
499+
500+
#ifdef MAPBASE_MP // From SecobMod
501+
hintCriteria.AddIncludePosition( UTIL_GetNearestPlayer( GetAbsOrigin() )->GetAbsOrigin(), (ai_fear_player_dist.GetFloat()) );
502+
#else
495503
hintCriteria.AddIncludePosition( AI_GetSinglePlayer()->GetAbsOrigin(), ( ai_fear_player_dist.GetFloat() ) );
504+
#endif
496505

497506
pHint = CAI_HintManager::FindHint( pOuter, hintCriteria );
498507

src/game/server/ai_behavior_follow.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,11 +2163,20 @@ void CAI_FollowGoal::EnableGoal( CAI_BaseNPC *pAI )
21632163
CBaseEntity *pGoalEntity = GetGoalEntity();
21642164
if ( !pGoalEntity && AI_IsSinglePlayer() )
21652165
{
2166+
#ifdef MAPBASE_MP // From SecobMod
2167+
CBasePlayer *pPlayer = UTIL_GetNearestPlayer( GetAbsOrigin() );
2168+
if ( pAI->IRelationType( pPlayer ) == D_LI )
2169+
{
2170+
pGoalEntity = pPlayer;
2171+
SetGoalEntity( pGoalEntity );
2172+
}
2173+
#else
21662174
if ( pAI->IRelationType(UTIL_GetLocalPlayer()) == D_LI )
21672175
{
21682176
pGoalEntity = UTIL_GetLocalPlayer();
21692177
SetGoalEntity( pGoalEntity );
21702178
}
2179+
#endif
21712180
}
21722181

21732182
if ( pGoalEntity )

0 commit comments

Comments
 (0)