You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.8 KiB
173 lines
4.8 KiB
#ifndef ASW_SQUADFORMATION_H |
|
#define ASW_SQUADFORMATION_H |
|
#pragma once |
|
|
|
/* |
|
#include "asw_marine.h" |
|
#include "asw_vphysics_npc.h" |
|
#include "asw_shareddefs.h" |
|
*/ |
|
|
|
class CAI_Hint; |
|
class HintData_t; |
|
|
|
/*! Aggregates state about all marines assigned to a squad, |
|
eg, AI marines following a leader in formation. |
|
|
|
*/ |
|
class CASW_SquadFormation : protected CAutoGameSystem |
|
{ |
|
typedef CAutoGameSystem BaseClass; |
|
|
|
public: |
|
/// local compiler constants |
|
enum |
|
{ |
|
MAX_SQUAD_SIZE = 3, ///< NOT including the leader. |
|
INVALID_SQUADDIE, |
|
}; |
|
|
|
virtual void LevelInitPostEntity(); |
|
|
|
inline CHandle<CASW_Marine> Leader() const { return m_hLeader; } |
|
inline void Leader(CHandle<CASW_Marine> val) { m_hLeader = val; } |
|
inline int Count() const ; ///< number of followers |
|
|
|
|
|
inline CASW_Marine *Squaddie( unsigned int slotnum ) const ; |
|
inline CASW_Marine *operator[]( unsigned int slotnum ) const { return Squaddie(slotnum); } |
|
|
|
/// return the slot number for a particular marine. |
|
/// Return INVALID_SQUADDIE ( or some number > MAX_SQUAD_SIZE ) if the marine is not in this squad. |
|
unsigned int Find( CASW_Marine *pMarine ) const; |
|
inline static bool IsValid( unsigned slotnum ); |
|
|
|
float GetYaw( unsigned slotnum ); |
|
inline const Vector &GetIdealPosition( unsigned slotnum ) const; |
|
|
|
unsigned int Add( CASW_Marine *pMarine ); |
|
bool Remove( CASW_Marine *pMarine, bool bIgnoreAssert = false ); // ret true if this marine was actually found and removed |
|
bool Remove( unsigned int slotnum ); // ret true if this marine was actually found and removed |
|
|
|
void ChangeLeader( CASW_Marine *pNewLeader, bool bUpdateLeaderPos = false ); |
|
|
|
/// reorganize the follower slots so that each follower has the least distance to move |
|
void RecomputeFollowerOrder( const Vector &vProjectedLeaderPos, QAngle qLeaderAim ) ; |
|
|
|
/// recompute the array of positions that squaddies should head towards. |
|
void UpdateFollowPositions(); |
|
|
|
/// should the squaddie positions be recomputed -- assumed this function is called from a marine's Think |
|
bool ShouldUpdateFollowPositions() const ; |
|
|
|
/// Current notion of "forward", is updated/cached in calls to GetLdrAnglMatrix |
|
inline const Vector &Forward() const; |
|
|
|
// disallow inadvertent construction |
|
explicit CASW_SquadFormation() : m_flLastSquadUpdateTime(0), CAutoGameSystem( "asw_squadformation" ) {Reset();}; |
|
bool SanityCheck() const ; |
|
|
|
void FindFollowHintNodes(); |
|
|
|
void Reset(); |
|
|
|
#ifdef HL2_HINTS |
|
static int FollowHintSortFunc( CAI_Hint* const *pHint1, CAI_Hint* const *pHint2 ); |
|
#else |
|
static int FollowHintSortFunc( HintData_t* const *pHint1, HintData_t* const *pHint2 ); |
|
#endif |
|
|
|
void DrawDebugGeometryOverlays(); |
|
|
|
protected: |
|
CHandle<CASW_Marine> m_hLeader; |
|
CHandle<CASW_Marine> m_hSquad[MAX_SQUAD_SIZE]; |
|
|
|
// the location in world where each squaddie is supposed |
|
// to be standing this frame. |
|
Vector m_vFollowPositions[MAX_SQUAD_SIZE]; |
|
|
|
// hint nodes for use in combat |
|
#ifdef HL2_HINTS |
|
CHandle<CAI_Hint> m_hFollowHint[MAX_SQUAD_SIZE]; |
|
#else |
|
int m_nMarineHintIndex[MAX_SQUAD_SIZE]; |
|
#endif |
|
bool m_bRearGuard[MAX_SQUAD_SIZE]; // is this hint the rearmost? if so, marine faces backwards |
|
bool m_bStandingInBeacon[MAX_SQUAD_SIZE]; |
|
bool m_bFleeingBoomerBombs[MAX_SQUAD_SIZE]; |
|
|
|
// clumsy holdovers from old system, should be replaced |
|
// with proper movement histories with prediction |
|
float m_flLastLeaderYaw; |
|
Vector m_vLastLeaderPos; |
|
|
|
Vector m_vLastLeaderVelocity; ///< velocity leader had at last update. If it changes radically, we reupdate immediately. |
|
Vector m_vCachedForward; |
|
|
|
float m_flCurrentForwardAbsoluteEulerYaw; |
|
float m_flLastSquadUpdateTime; |
|
|
|
int m_iLastHealBeaconCount; |
|
|
|
#pragma region STATICS |
|
const static Vector s_MarineFollowOffset[MAX_SQUAD_SIZE]; |
|
const static float s_MarineFollowDirection[MAX_SQUAD_SIZE]; |
|
const static Vector s_MarineBeaconOffset[MAX_SQUAD_SIZE]; |
|
const static float s_MarineBeaconDirection[MAX_SQUAD_SIZE]; |
|
#pragma endregion |
|
|
|
private: |
|
Vector GetLdrAnglMatrix( const Vector &origin, const QAngle &ang, matrix3x4_t *pout ); |
|
|
|
#pragma region From IGameSystem |
|
protected: |
|
virtual void LevelInitPreEntity(); |
|
#pragma endregion |
|
|
|
private: |
|
bool m_bLevelHasFollowHints; |
|
|
|
// thou shalt not copy |
|
CASW_SquadFormation( const CASW_SquadFormation & ); |
|
}; |
|
|
|
extern CASW_SquadFormation g_ASWSquadFormation; |
|
|
|
|
|
inline CASW_Marine *CASW_SquadFormation::Squaddie( unsigned int slotnum ) const |
|
{ |
|
Assert( IsValid(slotnum) ); |
|
return m_hSquad[slotnum]; |
|
} |
|
|
|
|
|
inline const Vector &CASW_SquadFormation::Forward() const |
|
{ |
|
return m_vCachedForward; |
|
} |
|
|
|
|
|
inline bool CASW_SquadFormation::IsValid( unsigned slotnum ) |
|
{ |
|
return slotnum < MAX_SQUAD_SIZE; |
|
} |
|
|
|
|
|
inline const Vector &CASW_SquadFormation::GetIdealPosition( unsigned slotnum ) const |
|
{ |
|
return m_vFollowPositions[slotnum]; |
|
} |
|
|
|
|
|
inline int CASW_SquadFormation::Count() const |
|
{ |
|
int ret = 0; |
|
for ( int i = 0 ; i < MAX_SQUAD_SIZE; ++i ) |
|
{ |
|
if ( !!m_hSquad[i] ) |
|
++ret; |
|
} |
|
return ret; |
|
} |
|
#endif /* ASW_SQUADFORMATION_H */
|
|
|