#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 Leader() const { return m_hLeader; } inline void Leader(CHandle 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 m_hLeader; CHandle 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 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 */