aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/hl2/ai_allymanager.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/hl2/ai_allymanager.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/hl2/ai_allymanager.cpp')
-rw-r--r--mp/src/game/server/hl2/ai_allymanager.cpp263
1 files changed, 263 insertions, 0 deletions
diff --git a/mp/src/game/server/hl2/ai_allymanager.cpp b/mp/src/game/server/hl2/ai_allymanager.cpp
new file mode 100644
index 00000000..aa595934
--- /dev/null
+++ b/mp/src/game/server/hl2/ai_allymanager.cpp
@@ -0,0 +1,263 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "entitylist.h"
+#include "ai_basenpc.h"
+#include "npc_citizen17.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define MAX_ALLIES 10
+
+class CAI_AllyManager : public CBaseEntity
+{
+ DECLARE_CLASS( CAI_AllyManager, CBaseEntity );
+
+public:
+ void Spawn();
+
+ void CountAllies( int *pTotal, int *pMedics );
+
+private:
+ int m_iMaxAllies;
+ int m_iMaxMedics;
+
+ int m_iAlliesLast;
+ int m_iMedicsLast;
+public:
+ void WatchCounts();
+
+ // Input functions
+ void InputSetMaxAllies( inputdata_t &inputdata );
+ void InputSetMaxMedics( inputdata_t &inputdata );
+ void InputReplenish( inputdata_t &inputdata );
+
+ // Outputs
+ COutputEvent m_SpawnAlly[ MAX_ALLIES ];
+ COutputEvent m_SpawnMedicAlly;
+ COutputEvent m_OnZeroAllies;
+ COutputEvent m_OnZeroMedicAllies;
+
+
+ DECLARE_DATADESC();
+};
+
+ConVar ai_ally_manager_debug("ai_ally_manager_debug", "0" );
+
+
+LINK_ENTITY_TO_CLASS( ai_ally_manager, CAI_AllyManager );
+
+BEGIN_DATADESC( CAI_AllyManager )
+ DEFINE_KEYFIELD( m_iMaxAllies, FIELD_INTEGER, "maxallies" ),
+ DEFINE_KEYFIELD( m_iMaxMedics, FIELD_INTEGER, "maxmedics" ),
+ DEFINE_FIELD( m_iAlliesLast, FIELD_INTEGER ),
+ DEFINE_FIELD( m_iMedicsLast, FIELD_INTEGER ),
+
+ DEFINE_THINKFUNC( WatchCounts ),
+
+ // Inputs
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxAllies", InputSetMaxAllies ),
+ DEFINE_INPUTFUNC( FIELD_INTEGER, "SetMaxMedics", InputSetMaxMedics ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Replenish", InputReplenish ),
+
+ // Outputs
+ DEFINE_OUTPUT( m_SpawnAlly[ 0 ], "SpawnAlly0" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 1 ], "SpawnAlly1" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 2 ], "SpawnAlly2" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 3 ], "SpawnAlly3" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 4 ], "SpawnAlly4" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 5 ], "SpawnAlly5" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 6 ], "SpawnAlly6" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 7 ], "SpawnAlly7" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 8 ], "SpawnAlly8" ),
+ DEFINE_OUTPUT( m_SpawnAlly[ 9 ], "SpawnAlly9" ),
+
+ DEFINE_OUTPUT( m_SpawnMedicAlly, "SpawnMedicAlly" ),
+
+ DEFINE_OUTPUT( m_OnZeroAllies, "OnZeroAllies" ),
+ DEFINE_OUTPUT( m_OnZeroMedicAllies, "OnZeroMedicAllies" ),
+
+END_DATADESC()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::Spawn()
+{
+ SetThink( &CAI_AllyManager::WatchCounts );
+ SetNextThink( gpGlobals->curtime + 1.0 );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::WatchCounts()
+{
+ // Count the number of allies with the player right now.
+ int iCurrentAllies;
+ int iCurrentMedics;
+
+ CountAllies( &iCurrentAllies, &iCurrentMedics );
+
+ if ( !iCurrentAllies && m_iAlliesLast )
+ m_OnZeroAllies.FireOutput( this, this, 0 );
+
+ if ( !iCurrentMedics && m_iMedicsLast )
+ m_OnZeroMedicAllies.FireOutput( this, this, 0 );
+
+ m_iAlliesLast = iCurrentAllies;
+ m_iMedicsLast = iCurrentMedics;
+
+ SetNextThink( gpGlobals->curtime + 1.0 );
+
+ if ( ai_ally_manager_debug.GetBool() )
+ DevMsg( "Ally manager counts %d allies, %d of which are medics\n", iCurrentAllies, iCurrentMedics );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics )
+{
+ (*pTotal) = (*pMedics) = 0;
+
+ if ( !AI_IsSinglePlayer() )
+ {
+ // @TODO (toml 10-22-04): no MP support right now
+ return;
+ }
+
+ const Vector & vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin();
+ CAI_BaseNPC ** ppAIs = g_AI_Manager.AccessAIs();
+ int nAIs = g_AI_Manager.NumAIs();
+
+ for ( int i = 0; i < nAIs; i++ )
+ {
+ if ( ppAIs[i]->IsAlive() && ppAIs[i]->IsPlayerAlly() )
+ {
+ // Vital allies do not count.
+ if( ppAIs[i]->Classify() == CLASS_PLAYER_ALLY_VITAL )
+ continue;
+
+ // They only count if I can use them.
+ if( ppAIs[i]->HasSpawnFlags(SF_CITIZEN_NOT_COMMANDABLE) )
+ continue;
+
+ // They only count if I can use them.
+ if( ppAIs[i]->IRelationType( UTIL_GetLocalPlayer() ) != D_LI )
+ continue;
+
+ // Skip distant NPCs
+ 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;
+
+ if( FClassnameIs( ppAIs[i], "npc_citizen" ) )
+ {
+ CNPC_Citizen *pCitizen = assert_cast<CNPC_Citizen *>(ppAIs[i]);
+ if ( !pCitizen->CanJoinPlayerSquad() )
+ continue;
+
+ if ( pCitizen->WasInPlayerSquad() && !pCitizen->IsInPlayerSquad() )
+ continue;
+
+ if ( ppAIs[i]->HasSpawnFlags( SF_CITIZEN_MEDIC ) )
+ (*pMedics)++;
+ }
+
+ (*pTotal)++;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &inputdata -
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::InputSetMaxAllies( inputdata_t &inputdata )
+{
+ m_iMaxAllies = inputdata.value.Int();
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::InputSetMaxMedics( inputdata_t &inputdata )
+{
+ m_iMaxMedics = inputdata.value.Int();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &inputdata -
+//-----------------------------------------------------------------------------
+void CAI_AllyManager::InputReplenish( inputdata_t &inputdata )
+{
+ // Count the number of allies with the player right now.
+ int iCurrentAllies;
+ int iCurrentMedics;
+
+ CountAllies( &iCurrentAllies, &iCurrentMedics );
+
+ // TOTAL number of allies to be replaced.
+ int iReplaceAllies = m_iMaxAllies - iCurrentAllies;
+
+ // The number of total allies that should be medics.
+ int iReplaceMedics = m_iMaxMedics - iCurrentMedics;
+
+ if( iReplaceMedics > iReplaceAllies )
+ {
+ // Clamp medics.
+ iReplaceMedics = iReplaceAllies;
+ }
+
+// Medics.
+ if( m_iMaxMedics > 0 )
+ {
+
+ if( iReplaceMedics > MAX_ALLIES )
+ {
+ // This error is fatal now. (sjb)
+ Msg("**ERROR! ai_allymanager - ReplaceMedics > MAX_ALLIES\n" );
+ return;
+ }
+
+ if ( ai_ally_manager_debug.GetBool() )
+ DevMsg( "Ally manager spawning %d medics\n", iReplaceMedics );
+
+ int i;
+ for( i = 0 ; i < iReplaceMedics ; i++ )
+ {
+ m_SpawnMedicAlly.FireOutput( this, this, 0 );
+
+ // Don't forget to count this guy against the number of
+ // allies to be replenished.
+ iReplaceAllies--;
+ }
+ }
+
+// Allies
+ if( iReplaceAllies < 1 )
+ {
+ return;
+ }
+
+ if( iReplaceAllies > MAX_ALLIES )
+ {
+ Msg("**ERROR! ai_allymanager - ReplaceAllies > MAX_ALLIES\n" );
+ iReplaceAllies = MAX_ALLIES;
+ }
+
+ if ( ai_ally_manager_debug.GetBool() )
+ DevMsg( "Ally manager spawning %d regulars\n", iReplaceAllies );
+
+ int i;
+ for( i = 0 ; i < iReplaceAllies ; i++ )
+ {
+ m_SpawnAlly[ i ].FireOutput( this, this, 0 );
+ }
+}