mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-09 05:35:30 +03:00
eb014cce6c
- 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
315 lines
9.0 KiB
C++
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
|