Skip to content

Commit 07c78af

Browse files
committed
Add NPC, clientside activity, and Mapbase param support to HL2MP weapons
1 parent 648c8eb commit 07c78af

36 files changed

+4844
-465
lines changed

src/game/client/c_basecombatcharacter.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,25 @@ void C_BaseCombatCharacter::DoMuzzleFlash()
109109
}
110110
}
111111

112+
#ifdef MAPBASE
113+
// UNDONE: Should these operate on a list of weapon/items
114+
Activity C_BaseCombatCharacter::Weapon_TranslateActivity( Activity baseAct, bool *pRequired )
115+
{
116+
Activity translated = baseAct;
117+
118+
if ( m_hActiveWeapon )
119+
{
120+
translated = m_hActiveWeapon->ActivityOverride( baseAct, pRequired );
121+
}
122+
else if (pRequired)
123+
{
124+
*pRequired = false;
125+
}
126+
127+
return translated;
128+
}
129+
#endif
130+
112131
#ifdef GLOWS_ENABLE
113132
//-----------------------------------------------------------------------------
114133
// Purpose:

src/game/client/c_basecombatcharacter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ class C_BaseCombatCharacter : public C_BaseFlex
116116
HSCRIPT ScriptGetWeapon( int i );
117117
#endif
118118

119+
#ifdef MAPBASE
120+
virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired );
121+
virtual Activity Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired = false, C_BaseCombatWeapon *pSpecificWeapon = NULL );
122+
#endif
123+
119124
public:
120125

121126
float m_flNextAttack;

src/game/client/c_baseplayer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
131131
virtual Vector Weapon_ShootPosition();
132132
virtual void Weapon_DropPrimary( void ) {}
133133

134+
#ifdef MAPBASE
135+
virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL );
136+
#endif
137+
134138
virtual Vector GetAutoaimVector( float flScale );
135139
void SetSuitUpdate(const char *name, int fgroup, int iNoRepeat);
136140

src/game/server/basecombatcharacter.cpp

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,76 +2800,6 @@ bool CBaseCombatCharacter::Weapon_CanUse( CBaseCombatWeapon *pWeapon )
28002800
return true;
28012801
}
28022802

2803-
#ifdef MAPBASE
2804-
2805-
//-----------------------------------------------------------------------------
2806-
// Purpose:
2807-
//-----------------------------------------------------------------------------
2808-
static Activity Weapon_BackupActivityFromList( CBaseCombatCharacter *pBCC, acttable_t *pTable, int actCount, Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pWeapon )
2809-
{
2810-
int i = 0;
2811-
for ( ; i < actCount; i++, pTable++ )
2812-
{
2813-
if ( activity == pTable->baseAct )
2814-
{
2815-
// Don't pick backup activities we don't actually have an animation for.
2816-
if (!pBCC->GetModelPtr()->HaveSequenceForActivity(pTable->weaponAct))
2817-
break;
2818-
2819-
return (Activity)pTable->weaponAct;
2820-
}
2821-
}
2822-
2823-
// We didn't succeed in finding an activity. See if we can recurse
2824-
acttable_t *pBackupTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pTable - i, actCount );
2825-
if (pBackupTable)
2826-
{
2827-
return Weapon_BackupActivityFromList( pBCC, pBackupTable, actCount, activity, weaponTranslationWasRequired, pWeapon );
2828-
}
2829-
2830-
return activity;
2831-
}
2832-
2833-
//-----------------------------------------------------------------------------
2834-
// Purpose: Uses an activity from a different weapon when the activity we were originally looking for does not exist on this character.
2835-
// This gives NPCs and players the ability to use weapons they are otherwise unable to use.
2836-
//-----------------------------------------------------------------------------
2837-
Activity CBaseCombatCharacter::Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pSpecificWeapon )
2838-
{
2839-
CBaseCombatWeapon *pWeapon = pSpecificWeapon ? pSpecificWeapon : GetActiveWeapon();
2840-
if (!pWeapon)
2841-
return activity;
2842-
2843-
// Make sure the weapon allows this activity to have a backup.
2844-
if (!pWeapon->SupportsBackupActivity(activity))
2845-
return activity;
2846-
2847-
// UNDONE: Sometimes, a NPC is supposed to use the default activity. Return that if the weapon translation was "not required" and we have an original activity.
2848-
/*
2849-
if (!weaponTranslationWasRequired && GetModelPtr()->HaveSequenceForActivity(activity) && !IsPlayer())
2850-
{
2851-
return activity;
2852-
}
2853-
*/
2854-
2855-
acttable_t *pTable = pWeapon->GetBackupActivityList();
2856-
int actCount = pWeapon->GetBackupActivityListCount();
2857-
if (!pTable)
2858-
{
2859-
// Look for a default list
2860-
acttable_t *pTable = pWeapon->ActivityList( actCount );
2861-
pTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pTable, actCount );
2862-
}
2863-
2864-
if (pTable && GetModelPtr())
2865-
{
2866-
return Weapon_BackupActivityFromList( this, pTable, actCount, activity, weaponTranslationWasRequired, pWeapon );
2867-
}
2868-
2869-
return activity;
2870-
}
2871-
#endif
2872-
28732803
//-----------------------------------------------------------------------------
28742804
// Purpose:
28752805
// Input :

src/game/server/player.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8149,33 +8149,6 @@ void CBasePlayer::Weapon_Equip( CBaseCombatWeapon *pWeapon )
81498149
}
81508150
}
81518151

8152-
#ifdef MAPBASE
8153-
//-----------------------------------------------------------------------------
8154-
// Purpose:
8155-
//-----------------------------------------------------------------------------
8156-
Activity CBasePlayer::Weapon_TranslateActivity( Activity baseAct, bool *pRequired )
8157-
{
8158-
Activity weaponTranslation = BaseClass::Weapon_TranslateActivity( baseAct, pRequired );
8159-
8160-
if ( GetActiveWeapon() && !GetActiveWeapon()->IsWeaponVisible() && baseAct != ACT_ARM )
8161-
{
8162-
// Our weapon is holstered. Use the base activity.
8163-
return baseAct;
8164-
}
8165-
if ( GetModelPtr() && (!GetModelPtr()->HaveSequenceForActivity(weaponTranslation) || baseAct == weaponTranslation) )
8166-
{
8167-
// This is used so players can fall back to backup activities in the same way NPCs in Mapbase can
8168-
Activity backupActivity = Weapon_BackupActivity(baseAct, pRequired ? *pRequired : false);
8169-
if ( baseAct != backupActivity && GetModelPtr()->HaveSequenceForActivity(backupActivity) )
8170-
return backupActivity;
8171-
8172-
return baseAct;
8173-
}
8174-
8175-
return weaponTranslation;
8176-
}
8177-
#endif
8178-
81798152

81808153
//=========================================================
81818154
// HasNamedPlayerItem Does the player already have this item?

src/game/server/soundent.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include "soundent.h"
1010
#include "game.h"
1111
#include "world.h"
12+
#ifdef MAPBASE_MP
13+
#include "ai_basenpc.h"
14+
#endif
1215

1316
// memdbgon must be the last include file in a .cpp file!!!
1417
#include "tier0/memdbgon.h"
@@ -459,6 +462,35 @@ void CSoundEnt::InsertSound ( int iType, const Vector &vecOrigin, int iVolume, f
459462
if ( !g_pSoundEnt )
460463
return;
461464

465+
#if defined(MAPBASE_MP) && defined(HL2MP)
466+
// Mapbase adds AI sounds to HL2DM weapons, but this fills up the list very quickly and isn't needed when NPCs aren't actually being used
467+
// Ignore weapon sounds when we're reasonably certain they wouldn't be useful
468+
if ( soundChannelIndex == SOUNDENT_CHANNEL_WEAPON )
469+
{
470+
bool bHasNPCNearby = false;
471+
CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
472+
for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )
473+
{
474+
CAI_BaseNPC *pNPC = ppAIs[i];
475+
476+
if ( !pNPC->IsAlive() || pNPC == pOwner )
477+
continue;
478+
479+
// Is there any chance this NPC would hear me?
480+
Vector vecDistSqr = vecOrigin - pNPC->EarPosition();
481+
if (vecDistSqr.LengthSqr() > Square(iVolume))
482+
continue;
483+
484+
bHasNPCNearby = true;
485+
break;
486+
}
487+
488+
// Just don't if there's no NPC nearby
489+
if (!bHasNPCNearby)
490+
return;
491+
}
492+
#endif
493+
462494
if( soundChannelIndex == SOUNDENT_CHANNEL_UNSPECIFIED )
463495
{
464496
// No sound channel specified. So just make a new sound.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//========= Copyright Valve Corporation, All rights reserved. ============//
2+
//
3+
// Purpose:
4+
//
5+
// $NoKeywords: $
6+
//=============================================================================//
7+
8+
#ifndef AI_BASENPC_SHARED_H
9+
#define AI_BASENPC_SHARED_H
10+
11+
#ifdef CLIENT_DLL
12+
#include "c_ai_basenpc.h"
13+
#else
14+
#include "ai_basenpc.h"
15+
#endif
16+
17+
#ifdef CLIENT_DLL
18+
#define CAI_BaseNPC C_AI_BaseNPC
19+
#endif
20+
21+
#endif // AI_BASENPC_SHARED_H

src/game/shared/basecombatcharacter_shared.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,75 @@ void CBaseCombatCharacter::InputSetBloodColor( inputdata_t &inputdata )
237237
}
238238
#endif
239239

240+
#ifdef MAPBASE
241+
//-----------------------------------------------------------------------------
242+
// Purpose:
243+
//-----------------------------------------------------------------------------
244+
static Activity Weapon_BackupActivityFromList( CBaseCombatCharacter *pBCC, acttable_t *pTable, int actCount, Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pWeapon )
245+
{
246+
int i = 0;
247+
for ( ; i < actCount; i++, pTable++ )
248+
{
249+
if ( activity == pTable->baseAct )
250+
{
251+
// Don't pick backup activities we don't actually have an animation for.
252+
if (!pBCC->GetModelPtr()->HaveSequenceForActivity(pTable->weaponAct))
253+
break;
254+
255+
return (Activity)pTable->weaponAct;
256+
}
257+
}
258+
259+
// We didn't succeed in finding an activity. See if we can recurse
260+
acttable_t *pBackupTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pTable - i, actCount );
261+
if (pBackupTable)
262+
{
263+
return Weapon_BackupActivityFromList( pBCC, pBackupTable, actCount, activity, weaponTranslationWasRequired, pWeapon );
264+
}
265+
266+
return activity;
267+
}
268+
269+
//-----------------------------------------------------------------------------
270+
// Purpose: Uses an activity from a different weapon when the activity we were originally looking for does not exist on this character.
271+
// This gives NPCs and players the ability to use weapons they are otherwise unable to use.
272+
//-----------------------------------------------------------------------------
273+
Activity CBaseCombatCharacter::Weapon_BackupActivity( Activity activity, bool weaponTranslationWasRequired, CBaseCombatWeapon *pSpecificWeapon )
274+
{
275+
CBaseCombatWeapon *pWeapon = pSpecificWeapon ? pSpecificWeapon : GetActiveWeapon();
276+
if (!pWeapon)
277+
return activity;
278+
279+
// Make sure the weapon allows this activity to have a backup.
280+
if (!pWeapon->SupportsBackupActivity(activity))
281+
return activity;
282+
283+
// UNDONE: Sometimes, a NPC is supposed to use the default activity. Return that if the weapon translation was "not required" and we have an original activity.
284+
/*
285+
if (!weaponTranslationWasRequired && GetModelPtr()->HaveSequenceForActivity(activity) && !IsPlayer())
286+
{
287+
return activity;
288+
}
289+
*/
290+
291+
acttable_t *pTable = pWeapon->GetBackupActivityList();
292+
int actCount = pWeapon->GetBackupActivityListCount();
293+
if (!pTable)
294+
{
295+
// Look for a default list
296+
acttable_t *pDefaultTable = pWeapon->ActivityList( actCount );
297+
pTable = CBaseCombatWeapon::GetDefaultBackupActivityList( pDefaultTable, actCount );
298+
}
299+
300+
if (pTable && GetModelPtr())
301+
{
302+
return Weapon_BackupActivityFromList( this, pTable, actCount, activity, weaponTranslationWasRequired, pWeapon );
303+
}
304+
305+
return activity;
306+
}
307+
#endif
308+
240309
//-----------------------------------------------------------------------------
241310
/**
242311
The main visibility check. Checks all the entity specific reasons that could

src/game/shared/basecombatweapon_shared.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ WeaponClass_t CBaseCombatWeapon::WeaponClassFromString(const char *str)
11581158
return WEPCLASS_INVALID;
11591159
}
11601160

1161-
#ifdef HL2_DLL
1161+
#if defined(HL2_DLL) || defined(HL2MP) // HL2MP is effectively used here as "present on client in MP"
11621162
extern acttable_t *GetSMG1Acttable();
11631163
extern int GetSMG1ActtableCount();
11641164

@@ -1206,7 +1206,7 @@ int CBaseCombatWeapon::GetBackupActivityListCount()
12061206
//-----------------------------------------------------------------------------
12071207
acttable_t *CBaseCombatWeapon::GetDefaultBackupActivityList( acttable_t *pTable, int &actCount )
12081208
{
1209-
#ifdef HL2_DLL
1209+
#if defined(HL2_DLL) || defined(HL2MP) // HL2MP is effectively used here as "present on client in MP"
12101210
// Ensure this isn't already a default backup activity list
12111211
if (pTable == GetSMG1Acttable() || pTable == GetPistolActtable())
12121212
return NULL;
@@ -1318,6 +1318,9 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration )
13181318
{
13191319
//Adrian: Oh man...
13201320
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ))
1321+
#ifdef MAPBASE_MP
1322+
if ( GetOwner() && GetOwner()->IsPlayer() )
1323+
#endif
13211324
SetModel( GetWorldModel() );
13221325
#endif
13231326

@@ -1329,6 +1332,9 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration )
13291332

13301333
//Adrian: Oh man again...
13311334
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ))
1335+
#ifdef MAPBASE_MP
1336+
if ( GetOwner() && GetOwner()->IsPlayer() )
1337+
#endif
13321338
SetModel( GetViewModel() );
13331339
#endif
13341340

src/game/shared/baseplayer_shared.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,41 @@ void CBasePlayer::SelectLastItem(void)
875875
}
876876

877877

878+
#ifdef MAPBASE
879+
//-----------------------------------------------------------------------------
880+
// Purpose:
881+
//-----------------------------------------------------------------------------
882+
Activity CBasePlayer::Weapon_TranslateActivity( Activity baseAct, bool *pRequired )
883+
{
884+
Activity weaponTranslation = BaseClass::Weapon_TranslateActivity( baseAct, pRequired );
885+
886+
#ifdef CLIENT_DLL
887+
// Since other players' weapons have invisible viewmodels
888+
bool bWeaponNotVisible = (GetActiveWeapon() && GetActiveWeapon()->IsEffectActive( EF_NODRAW )) ? true : false;
889+
#else
890+
bool bWeaponNotVisible = (GetActiveWeapon() && !GetActiveWeapon()->IsWeaponVisible()) ? true : false;
891+
#endif
892+
893+
if ( bWeaponNotVisible && baseAct != ACT_ARM )
894+
{
895+
// Our weapon is holstered. Use the base activity.
896+
return baseAct;
897+
}
898+
if ( GetModelPtr() && (!GetModelPtr()->HaveSequenceForActivity(weaponTranslation) || baseAct == weaponTranslation) )
899+
{
900+
// This is used so players can fall back to backup activities in the same way NPCs in Mapbase can
901+
Activity backupActivity = Weapon_BackupActivity(baseAct, pRequired ? *pRequired : false);
902+
if ( baseAct != backupActivity && GetModelPtr()->HaveSequenceForActivity(backupActivity) )
903+
return backupActivity;
904+
905+
return baseAct;
906+
}
907+
908+
return weaponTranslation;
909+
}
910+
#endif
911+
912+
878913
//-----------------------------------------------------------------------------
879914
// Purpose: Abort any reloads we're in
880915
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)