source-sdk-2013-mapbase/sp/src/game/server/ai_squad.h
Blixibon eb014cce6c Mapbase v6.0
- Fixed path_track paths saving as pointers instead of handles
- Fixed player animations not falling to base class correctly
- Fixed logic_externaldata creating garbage in trailing spaces
- Added "SetHandModelSkin" input
- Added unique colors for various types of console message, adjustable via convars
- Added the ability to use map-specific weapon scripts
- Added a way to display (placeholder) text entirely from Faceposer scenes
- Added "autobreak" keyvalue to game_text, which automatically breaks long text into different lines
- Added the ability to change a game_text's font (very limited)
- Added LightToggle input to point_spotlight
- Added Enable/DisableSprites on npc_manhack
- Added ai_goal_police behavior from metrocops to Combine soldiers and citizens
- Added func_precipitation particle rain systems from the Alien Swarm SDK
- Added new func_precipitation spawnflags for controlling behavior in particle types
- Added "mapbase_version" cvar which shows the version of Mapbase a mod might be running on
- Fixed an oversight with NPC crouch activities which was causing npc_metropolice to stop firing in standoffs
- Added toggleable patches to npc_combine AI which make soldiers less likely to stand around without shooting or rush to melee when not needed
- Added key for custom logo font on env_credits scripts
- Added SetSpeed and SetPushDir inputs for trigger_push
- Added a bunch of I/O/KV to func_fish_pool to allow for more control over the fish
- Added OnLostEnemy/Player support for npc_combine_camera
- Added enhanced save/restore for the Response System, toggleable via convar
- Added a convar which allows users to disable weapon autoswitching when picking up ammo
- Split VScript base script into its own file
- Added VScript descriptions for NPC squads and the manager class which handles them
- Moved several classes, functions, etc. to the VScript library itself for future usage in other projects, like VBSP
- Added VScript to VBSP with basic map file interfacing
- Made some VScript documentation more clear due to deprecation of online documentation
- Added VScript "hook" registration, creating a standardized system which shows up in script_help documentation
- Added VScript-driven custom weapons
- Added clientside VScript scopes
- Added a bunch of weapon-related VScript functions
- Split a bunch of cluttered VScript stuff into different files
- Added VScript functions for "following" entities/bonemerging
- Added VScript functions for grenades
- Added a few more VScript trigger functions
- Added OnDeath hook for VScript
- Fixed documentation for aliased functions in VScript
- Fixed $bumpmask not working on SDK_LightmappedGeneric
- Made vertex blend swapping in Hammer use a constant instead of a combo (makes it easier to compile the shader, especially for $bumpmask's sake)
- Fixed brush phong, etc. causing SDK_WorldVertexTransition to stop working
- Added limited support for $envmapmask in the bumpmapping shader
- Fixed more issues with parallax corrected cubemaps and instances
- Made instance variable recursion consistent with VMFII
2020-11-26 02:26:55 +00:00

315 lines
9.0 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Squad classes
//
//=============================================================================//
#ifndef AI_SQUAD_H
#define AI_SQUAD_H
#include "ai_memory.h"
#include "ai_squadslot.h"
#include "bitstring.h"
class CAI_Squad;
typedef CHandle<CAI_BaseNPC> AIHANDLE;
#define PER_ENEMY_SQUADSLOTS 1
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE(AISquadsIter_t);
DECLARE_POINTER_HANDLE(AISquadIter_t);
#define MAX_SQUAD_MEMBERS 16
#define MAX_SQUAD_DATA_SLOTS 4
//-----------------------------------------------------------------------------
// CAI_SquadManager
//
// Purpose: Manages all the squads in the system
//
//-----------------------------------------------------------------------------
class CAI_SquadManager
{
public:
CAI_SquadManager()
{
m_pSquads = NULL;
}
CAI_Squad * GetFirstSquad( AISquadsIter_t *pIter );
CAI_Squad * GetNextSquad( AISquadsIter_t *pIter );
int NumSquads();
CAI_Squad * FindSquad( string_t squadName ); // Returns squad of the given name
CAI_Squad * CreateSquad( string_t squadName ); // Returns squad of the given name
CAI_Squad * FindCreateSquad( string_t squadName ); // Returns squad of the given name
CAI_Squad * FindCreateSquad( CAI_BaseNPC *pNPC, string_t squadName ); // Returns squad of the given name
void DeleteSquad( CAI_Squad *pSquad );
void DeleteAllSquads(void);
#ifdef MAPBASE_VSCRIPT
HSCRIPT ScriptGetFirstSquad();
HSCRIPT ScriptGetNextSquad( HSCRIPT hStart );
HSCRIPT ScriptFindSquad( const char *squadName );
HSCRIPT ScriptFindCreateSquad( const char *squadName );
#endif
private:
CAI_Squad * m_pSquads; // A linked list of all squads
};
//-------------------------------------
extern CAI_SquadManager g_AI_SquadManager;
//-----------------------------------------------------------------------------
#ifdef PER_ENEMY_SQUADSLOTS
struct AISquadEnemyInfo_t
{
EHANDLE hEnemy;
CBitVec<MAX_SQUADSLOTS> slots; // What squad slots are filled?
DECLARE_SIMPLE_DATADESC();
};
#endif
//-----------------------------------------------------------------------------
// CAI_Squad
//
// Purpose: Tracks enemies, squad slots, squad members
//
//-----------------------------------------------------------------------------
class CAI_Squad
{
public:
const char * GetName() const { return STRING(m_Name); }
void RemoveFromSquad( CAI_BaseNPC *pNPC, bool bDeath = false );
CAI_BaseNPC * GetFirstMember( AISquadIter_t *pIter = NULL, bool bIgnoreSilentMembers = true );
CAI_BaseNPC * GetNextMember( AISquadIter_t *pIter, bool bIgnoreSilentMembers = true );
CAI_BaseNPC * GetAnyMember();
int NumMembers( bool bIgnoreSilentMembers = true );
int GetSquadIndex( CAI_BaseNPC * );
void SquadNewEnemy ( CBaseEntity *pEnemy );
void UpdateEnemyMemory( CAI_BaseNPC *pUpdater, CBaseEntity *pEnemy, const Vector &position );
bool OccupyStrategySlotRange( CBaseEntity *pEnemy, int slotIDStart, int slotIDEnd, int *pSlot );
void VacateStrategySlot( CBaseEntity *pEnemy, int slot);
bool IsStrategySlotRangeOccupied( CBaseEntity *pEnemy, int slotIDStart, int slotIDEnd );
CAI_BaseNPC * SquadMemberInRange( const Vector &vecLocation, float flDist );
CAI_BaseNPC * NearestSquadMember( CAI_BaseNPC *pMember );
int GetVisibleSquadMembers( CAI_BaseNPC *pMember );
CAI_BaseNPC * GetSquadMemberNearestTo( const Vector &vecLocation );
bool SquadIsMember( CBaseEntity *pMember );
bool IsLeader( CAI_BaseNPC *pLeader );
CAI_BaseNPC *GetLeader( void );
int BroadcastInteraction( int interactionType, void *data, CBaseCombatCharacter *sender = NULL );
void AddToSquad(CAI_BaseNPC *pNPC);
bool FOkToMakeSound( int soundPriority );
void JustMadeSound( int soundPriority, float time );
float GetSquadSoundWaitTime() const { return m_flSquadSoundWaitTime; }
void SetSquadSoundWaitTime( float time ) { m_flSquadSoundWaitTime = time; }
void SquadRemember( int iMemory );
void SetSquadInflictor( CBaseEntity *pInflictor );
bool IsSquadInflictor( CBaseEntity *pInflictor );
static bool IsSilentMember( const CAI_BaseNPC *pNPC );
template <typename T>
void SetSquadData( unsigned slot, const T &data )
{
Assert( slot < MAX_SQUAD_DATA_SLOTS );
if ( slot < MAX_SQUAD_DATA_SLOTS )
{
m_SquadData[slot] = *((int *)&data);
}
}
template <typename T>
void GetSquadData( unsigned slot, T *pData )
{
Assert( slot < MAX_SQUAD_DATA_SLOTS );
if ( slot < MAX_SQUAD_DATA_SLOTS )
{
*pData = *((T *)&m_SquadData[slot]);
}
}
private:
void OccupySlot( CBaseEntity *pEnemy, int i );
void VacateSlot( CBaseEntity *pEnemy, int i );
bool IsSlotOccupied( CBaseEntity *pEnemy, int i ) const;
#ifdef MAPBASE_VSCRIPT
// Functions tailored specifically for VScript.
ALLOW_SCRIPT_ACCESS();
private:
HSCRIPT ScriptGetFirstMember( bool bIgnoreSilentMembers );
HSCRIPT ScriptGetMember( int iIndex );
HSCRIPT ScriptGetAnyMember();
//int ScriptNumMembers( bool bIgnoreSilentMembers );
int ScriptGetSquadIndex( HSCRIPT hNPC );
void ScriptUpdateEnemyMemory( HSCRIPT hUpdater, HSCRIPT hEnemy, const Vector &position );
HSCRIPT ScriptSquadMemberInRange( const Vector &vecLocation, float flDist );
HSCRIPT ScriptNearestSquadMember( HSCRIPT hMember );
int ScriptGetVisibleSquadMembers( HSCRIPT hMember );
HSCRIPT ScriptGetSquadMemberNearestTo( const Vector &vecLocation );
bool ScriptIsMember( HSCRIPT hMember );
bool ScriptIsLeader( HSCRIPT hLeader );
HSCRIPT ScriptGetLeader( void );
void ScriptAddToSquad( HSCRIPT hNPC );
void ScriptRemoveFromSquad( HSCRIPT hNPC );
bool ScriptIsSilentMember( HSCRIPT hNPC );
void ScriptSetSquadData( int iSlot, const char *data );
const char *ScriptGetSquadData( int iSlot );
#endif
private:
friend class CAI_SaveRestoreBlockHandler;
friend class CAI_SquadManager;
CAI_Squad();
CAI_Squad(string_t squadName);
~CAI_Squad(void);
CAI_Squad* GetNext() { return m_pNextSquad; }
void Init( string_t squadName );
CAI_Squad * m_pNextSquad; // The next squad is list of all squads
string_t m_Name;
CUtlVectorFixed<AIHANDLE, MAX_SQUAD_MEMBERS> m_SquadMembers;
float m_flSquadSoundWaitTime; // Time when I'm allowed to make another sound
int m_nSquadSoundPriority; // if we're still waiting, this is the priority of the current sound
EHANDLE m_hSquadInflictor;
int m_SquadData[MAX_SQUAD_DATA_SLOTS];
#ifdef PER_ENEMY_SQUADSLOTS
AISquadEnemyInfo_t *FindEnemyInfo( CBaseEntity *pEnemy );
const AISquadEnemyInfo_t *FindEnemyInfo( CBaseEntity *pEnemy ) const { return const_cast<CAI_Squad *>(this)->FindEnemyInfo( pEnemy ); }
AISquadEnemyInfo_t * m_pLastFoundEnemyInfo; // Occupy/Vacate need to be reworked to not want this
CUtlVector<AISquadEnemyInfo_t> m_EnemyInfos;
float m_flEnemyInfoCleanupTime;
#else
CVarBitVec m_squadSlotsUsed; // What squad slots are filled?
#endif
//---------------------------------
public:
DECLARE_SIMPLE_DATADESC();
};
//-----------------------------------------------------------------------------
//
// Purpose: CAI_SquadManager inline functions
//
//-----------------------------------------------------------------------------
inline CAI_Squad *CAI_SquadManager::GetFirstSquad( AISquadsIter_t *pIter )
{
*pIter = (AISquadsIter_t)m_pSquads;
return m_pSquads;
}
//-------------------------------------
inline CAI_Squad *CAI_SquadManager::GetNextSquad( AISquadsIter_t *pIter )
{
CAI_Squad *pSquad = (CAI_Squad *)*pIter;
if ( pSquad )
pSquad = pSquad->m_pNextSquad;
*pIter = (AISquadsIter_t)pSquad;
return pSquad;
}
//-------------------------------------
// Purpose: Returns squad of the given name or creates a new squad with the
// given name if none exists and add pNPC to the list of members
//-------------------------------------
inline CAI_Squad *CAI_SquadManager::FindCreateSquad(CAI_BaseNPC *pNPC, string_t squadName)
{
CAI_Squad* pSquad = FindSquad( squadName );
if ( !pSquad )
pSquad = CreateSquad( squadName );
pSquad->AddToSquad( pNPC );
return pSquad;
}
//-----------------------------------------------------------------------------
inline CAI_Squad *CAI_SquadManager::FindCreateSquad(string_t squadName)
{
CAI_Squad* pSquad = FindSquad( squadName );
if ( !pSquad )
pSquad = CreateSquad( squadName );
return pSquad;
}
//-------------------------------------
inline CAI_BaseNPC *CAI_Squad::GetAnyMember()
{
if ( m_SquadMembers.Count() )
return m_SquadMembers[random->RandomInt( 0, m_SquadMembers.Count()-1 )];
return NULL;
}
//-------------------------------------
inline int CAI_Squad::GetSquadIndex( CAI_BaseNPC *pAI )
{
for ( int i = 0; i < m_SquadMembers.Count(); i++ )
{
if ( m_SquadMembers[i] == pAI )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
#endif // AI_SQUAD_H