174 lines
5.0 KiB
C
174 lines
5.0 KiB
C
|
#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 */
|