sqwarmed/sdk_src/game/server/swarm/asw_marine.h

722 lines
30 KiB
C++

#ifndef ASW_MARINE_H
#define ASW_MARINE_H
#pragma once
#include "asw_marine_shared.h"
#include "asw_vphysics_npc.h"
#include "asw_shareddefs.h"
#include "asw_playeranimstate.h"
#include "asw_lag_compensation.h"
class CASW_Player;
class CASW_Marine_Resource;
class CASW_Marine_Profile;
class CASW_Weapon;
class CASW_MarineSpeech;
class CASW_SimpleAI;
class CASW_Pickup;
class CASW_Pickup_Weapon;
class CASW_Alien;
class CASW_Ammo;
class CASW_Ammo_Drop;
class CMoveData;
class IASW_Vehicle;
class CASW_Remote_Turret;
class CRagdollProp;
class CASW_Hack;
class CBeam;
class CASW_Melee_Attack;
class CASW_Use_Area;
class CASW_SquadFormation;
class CAI_Hint;
class CASW_Alien_Goo;
class CASW_BuffGrenade_Projectile;
class CBaseTrigger;
#define ASW_MAX_FOLLOWERS 6
#define ASW_INVALID_FOLLOW_SLOT -1
// marine sight cone when holding position
#define ASW_HOLD_POSITION_FOV_DOT 0.5f
#define ASW_HOLD_POSITION_SIGHT_RANGE 768.0f
// marine sight cone when in follow mode
#define ASW_FOLLOW_MODE_FOV_DOT 0.7f
#define ASW_FOLLOW_MODE_SIGHT_RANGE 525.0f
#define ASW_FOLLOW_MODE_SIGHT_HEIGHT 64.0f
// marine sight cone using the old follow mode
#define ASW_DUMB_FOLLOW_MODE_SIGHT_RANGE 200.0f
#define ASW_DUMB_FOLLOW_MODE_SIGHT_HEIGHT 64.0f
// AI marines can always see aliens within the close combat sight range
#define ASW_CLOSE_COMBAT_SIGHT_RANGE_EASY 256.0f
#define ASW_CLOSE_COMBAT_SIGHT_RANGE_NORMAL 214.0f
#define ASW_CLOSE_COMBAT_SIGHT_RANGE_HARD 171.0f
#define ASW_CLOSE_COMBAT_SIGHT_RANGE_INSANE 128.0f
#define ASW_MOB_VICTIM_SIZE 3
#define ASW_MARINE_HISTORY_POSITIONS 6
class CASW_Marine : public CASW_VPhysics_NPC, public IASWPlayerAnimStateHelpers
{
public:
DECLARE_CLASS( CASW_Marine, CASW_VPhysics_NPC );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
DEFINE_CUSTOM_AI;
CASW_Marine();
virtual ~CASW_Marine();
// Use this in preference to CASW_Marine::AsMarine( pEnt ) :
static inline CASW_Marine *AsMarine( CBaseEntity *pEnt );
virtual void Precache();
virtual void PrecacheSpeech();
virtual void Spawn( void );
virtual void NPCInit();
virtual void UpdateOnRemove();
void SetModelFromProfile();
void SelectModelFromProfile();
void SelectModel();
CAI_Senses *CreateSenses();
void SetHeightLook( float flHeightLook );
// Thinking
virtual void Think(void);
void PostThink();
virtual void ASWThinkEffects();
// Networking
virtual int ShouldTransmit( const CCheckTransmitInfo *pInfo );
virtual int UpdateTransmitState();
void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
// Camera
virtual const QAngle& ASWEyeAngles( void );
Vector EyePosition(void);
// Classification
Class_T Classify( void ) { return (Class_T) CLASS_ASW_MARINE; }
virtual bool IsPlayerAlly( CBasePlayer *pPlayer );
// Animation
IASWPlayerAnimState *m_PlayerAnimState;
void DoAnimationEvent( PlayerAnimEvent_t event );
void DoAnimationEventToAll( PlayerAnimEvent_t event );
void HandleAnimEvent( animevent_t *pEvent );
// Marine resource
void SetMarineResource(CASW_Marine_Resource *pMR);
CASW_Marine_Resource* GetMarineResource() const;
CASW_Marine_Profile* GetMarineProfile();
EHANDLE m_MarineResource;
// Commander/Inhabiting
void SetCommander(CASW_Player *player); // sets which player commands this marine
CASW_Player* GetCommander() const;
bool IsInhabited();
void SetInhabited(bool bInhabited);
void InhabitedBy(CASW_Player *player); // called when a player takes direct control of this marine
void UninhabitedBy(CASW_Player *player); // called when a player stops direct control of this marine
CNetworkHandle (CASW_Player, m_Commander); // the player in charge of this marine
void SetInitialCommander(CASW_Player *player);
char m_szInitialCommanderNetworkID[64]; // ASWNetworkID of the first commander for this marine in this mission
const char *GetPlayerName() const;
// Alien related
bool IsAlienNear(); // is an alien nearby? (used by speech to know if we should shout urgent lines)
void HurtAlien(CBaseEntity *pAlien, const CTakeDamageInfo &info);
void HurtJunkItem(CBaseEntity *pAlien, const CTakeDamageInfo &info);
float m_fMadFiringCounter;
static float s_fNextMadFiringChatter;
float m_fNextAlienWalkDamage; // timer for pain from walking on aliens
// Sound, speech
CASW_MarineSpeech* GetMarineSpeech() { return m_MarineSpeech; }
CASW_MarineSpeech* m_MarineSpeech;
void ModifyOrAppendCriteria( AI_CriteriaSet& set );
const char *GetResponseRulesName(); ///< returns the name used for the 'who' clause in a response rules query
float m_fLastStillTime;
float m_fIdleChatterDelay;
static float s_fNextIdleChatterTime; // team next chatter time
// Light related
void FlashlightTurnOn();
void FlashlightTurnOff();
void FlashlightToggle();
bool HasFlashlight();
// Movement
// these stop movement, doesn't actually do anything here on the server! but used for melee anims to keep in sync.
virtual bool IsCurTaskContinuousMove();
float GetStopTime() { return m_fStopMarineTime; }
void SetStopTime(float fTime) { m_fStopMarineTime = fTime; }
CNetworkVar(float, m_fStopMarineTime);
virtual bool ASWAnim_CanMove();
virtual float MaxSpeed();
void AvoidPhysicsProps( CUserCmd *pCmd );
void PhysicsSimulate( void );
virtual void InhabitedPhysicsSimulate();
int m_nOldButtons;
virtual bool ShouldPlayerAvoid( void );
virtual float GetIdealSpeed() const;
float m_fCachedIdealSpeed;
virtual float GetIdealAccel( ) const;
virtual float MaxYawSpeed( void );
float m_fLastStuckTime; // gets set when we're stuck (used to turn on our phys shadow to push away phys objects)
float m_flFirstStuckTime; // gets set the first frame we're stuck
CNetworkVar(bool, m_bPreventMovement); // if true, the player will send zeroed movement commands (used by queen tentacles)
virtual void SetPlayerAvoidState();
virtual unsigned int PhysicsSolidMaskForEntity() const;
bool TeleportStuckMarine();
CNetworkVar( bool, m_bWalking );
CASW_Lag_Compensation m_LagCompensation;
// Texture names and surface data, used by CASW_MarineGameMovement
int m_surfaceProps;
surfacedata_t* m_pSurfaceData;
float m_surfaceFriction;
char m_chTextureType;
char m_chPreviousTextureType; // Separate from m_chTextureType. This is cleared if the player's not on the ground.
// melee
void PhysicsShove();
void DoMeleeDamageTrace( float flYawStart, float flYawEnd );
void PlayMeleeImpactEffects( CBaseEntity *pEntity, trace_t *tr );
void ApplyMeleeDamage( CBaseEntity *pHitEntity, CTakeDamageInfo &dmgInfo, Vector &vecAttackDir, trace_t *tr );
CBaseEntity *MeleeTraceHullAttack( const Vector &vecStart, const Vector &vecEnd, const Vector &vecMins, const Vector &vecMaxs, bool bHitBehindMarine, float flAttackCone );
float m_fKickTime;
// Keep track of recent melee hits so we can perform wide area of effect melee attacks without double-damaging entities
CUtlVector<CBaseEntity*> m_RecentMeleeHits;
CNetworkVar(float, m_fNextMeleeTime);
int GetAlienMeleeFlinch();
CNetworkVar( int, m_iMeleeAttackID );
CNetworkVar( float, m_flKnockdownYaw );
CASW_Melee_Attack *GetCurrentMeleeAttack();
Vector m_vecMeleeStartPos;
float m_flMeleeStartTime, m_flMeleeLastCycle;
CNetworkVar( float, m_flMeleeYaw );
CNetworkVar( bool, m_bFaceMeleeYaw );
bool m_bMeleeCollisionDamage;
bool m_bMeleeComboKeypressAllowed;
bool m_bMeleeComboKeyPressed;
bool m_bMeleeComboTransitionAllowed;
bool m_bMeleeMadeContact;
int m_iMeleeAllowMovement;
bool m_bMeleeKeyReleased;
#ifdef MELEE_CHARGE_ATTACKS
bool m_bMeleeHeavyKeyHeld;
CNetworkVar( float, m_flMeleeHeavyKeyHoldStart );
#endif
bool m_bMeleeChargeActivate;
int m_iUsableItemsOnMeleePress;
virtual void HandlePredictedAnimEvent( int event, const char* options );
int m_iPredictedEvent[ASW_MAX_PREDICTED_MELEE_EVENTS];
float m_flPredictedEventTime[ASW_MAX_PREDICTED_MELEE_EVENTS];
const char* m_szPredictedEventOptions[ASW_MAX_PREDICTED_MELEE_EVENTS];
int m_iNumPredictedEvents;
int m_iOnLandMeleeAttackID;
float GetBaseMeleeDamage() { return m_flBaseMeleeDamage; }
float m_flBaseMeleeDamage;
bool m_bPlayedMeleeHitSound;
bool HasPowerFist();
CNetworkVar( bool, m_bNoAirControl );
// jump jets
CNetworkVar( int, m_iJumpJetting );
Vector m_vecJumpJetStart;
Vector m_vecJumpJetEnd;
float m_flJumpJetStartTime;
float m_flJumpJetEndTime;
// powerups are designed so that you can only have one at a time
void AddPowerup( int iType, float flExpireTime = -1 );
bool HasPowerup( int iType );
void RemoveWeaponPowerup( CASW_Weapon* pWeapon );
void RemoveAllPowerups( void );
void UpdatePowerupDuration( void );
CNetworkVar( int, m_iPowerupType );
CNetworkVar( float, m_flPowerupExpireTime );
CNetworkVar( bool, m_bPowerupExpires );
//CNetworkVar( int, m_iPowerupCount );
void AddDamageBuff( CASW_BuffGrenade_Projectile *pBuffGrenade, float flDuration ) { m_hLastBuffGrenade = pBuffGrenade; m_flDamageBuffEndTime = MAX( GetDamageBuffEndTime(), gpGlobals->curtime + flDuration ); }
void RemoveDamageBuff() { m_flDamageBuffEndTime = 0.0f; }
float GetDamageBuffEndTime() { return m_flDamageBuffEndTime.Get(); }
CNetworkVar( float, m_flDamageBuffEndTime );
CHandle<CASW_BuffGrenade_Projectile> m_hLastBuffGrenade;
void AddElectrifiedArmor( float flDuration ) { m_flElectrifiedArmorEndTime = MAX( GetElectrifiedArmorEndTime(), gpGlobals->curtime + flDuration ); }
float GetElectrifiedArmorEndTime() { return m_flElectrifiedArmorEndTime.Get(); }
bool IsElectrifiedArmorActive() { return GetElectrifiedArmorEndTime() > gpGlobals->curtime; }
CNetworkVar( float, m_flElectrifiedArmorEndTime );
void ApplyPassiveArmorEffects( CTakeDamageInfo &dmgInfo ) RESTRICT ;
void ApplyPassiveMeleeDamageEffects( CTakeDamageInfo &dmgInfo );
CBaseTrigger* IsInEscapeVolume(); // returns pointer to current escape volume, if marine is in the exit
// Custom conditions, schedules and tasks
enum
{
COND_ASW_NEW_ORDERS = BaseClass::NEXT_CONDITION,
COND_ASW_BEGIN_RAPPEL,
COND_SQUADMATE_WANTS_AMMO,
COND_SQUADMATE_NEEDS_AMMO, // out of ammo
COND_PATH_BLOCKED_BY_PHYSICS_PROP,
COND_PROP_DESTROYED,
COND_COMPLETELY_OUT_OF_AMMO,
COND_ASW_ORDER_TIME_OUT,
NEXT_CONDITION,
SCHED_ASW_HOLD_POSITION = BaseClass::NEXT_SCHEDULE,
SCHED_ASW_RANGE_ATTACK1,
SCHED_ASW_USING_OVER_TIME,
SCHED_ASW_USE_AREA,
SCHED_ASW_OVERKILL_SHOOT,
SCHED_ASW_MOVE_TO_ORDER_POS,
SCHED_ASW_FOLLOW_MOVE,
SCHED_ASW_FOLLOW_WAIT,
SCHED_ASW_PICKUP_WAIT,
SCHED_ASW_FOLLOW_BACK_OFF,
SCHED_ASW_RAPPEL_WAIT,
SCHED_ASW_RAPPEL,
SCHED_ASW_CLEAR_RAPPEL_POINT, // Get out of the way for the next guy
SCHED_ASW_GIVE_AMMO, // ammo bag
SCHED_MELEE_ATTACK_PROP1, // melee a physics prop, typically because it's obstructing
SCHED_ENGAGE_AND_MELEE_ATTACK1,
SCHED_ASW_HEAL_MARINE,
NEXT_SCHEDULE,
TASK_ASW_TRACK_AND_FIRE = BaseClass::NEXT_TASK,
TASK_ASW_FACE_HOLDING_YAW,
TASK_ASW_FACE_USING_ITEM,
TASK_ASW_START_USING_AREA,
TASK_ASW_FACE_ENEMY_WITH_ERROR,
TASK_ASW_OVERKILL_SHOOT,
TASK_ASW_GET_PATH_TO_ORDER_POS,
TASK_ASW_GET_PATH_TO_FOLLOW_TARGET,
TASK_ASW_GET_PATH_TO_PROP,
TASK_ASW_FACE_RANDOM_WAIT,
TASK_ASW_FACE_FOLLOW_WAIT,
TASK_ASW_GET_BACK_OFF_PATH,
TASK_ASW_WAIT_FOR_FOLLOW_MOVEMENT,
TASK_ASW_WAIT_FOR_MOVEMENT,
TASK_ASW_CHATTER_CONFIRM,
TASK_ASW_RAPPEL,
TASK_ASW_HIT_GROUND,
TASK_ASW_ORDER_TO_DEPLOY_SPOT,
TASK_ASW_GET_PATH_TO_GIVE_AMMO,
TASK_ASW_MOVE_TO_GIVE_AMMO,
TASK_ASW_SWAP_TO_AMMO_BAG,
TASK_ASW_GIVE_AMMO_TO_MARINE,
TASK_ASW_GET_PATH_TO_HEAL,
TASK_ASW_MOVE_TO_HEAL,
TASK_ASW_SWAP_TO_HEAL_GUN,
TASK_ASW_HEAL_MARINE,
NEXT_TASK,
};
// asw schedule stuff
virtual bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
virtual void GatherConditions();
virtual void BuildScheduleTestBits();
virtual int SelectSchedule();
virtual int SelectMeleeSchedule();
virtual int SelectFollowSchedule();
virtual int TranslateSchedule( int scheduleType );
int SelectHackingSchedule();
virtual void RunTaskRangeAttack1( const Task_t *pTask );
virtual void StartTaskRangeAttack1( const Task_t *pTask );
virtual void RunTask( const Task_t *pTask );
virtual void StartTask(const Task_t *pTask);
virtual void UpdateEfficiency( bool bInPVS );
//virtual void TaskFail( AI_TaskFailureCode_t );
virtual void TaskFail( AI_TaskFailureCode_t );
void TaskFail( const char *pszGeneralFailText ) { TaskFail( MakeFailCode( pszGeneralFailText ) ); }
void CheckForAIWeaponSwitch();
private:
EHANDLE m_hAlienGooTarget;
EHANDLE m_hPhysicsPropTarget;
public:
float m_flLastGooScanTime;
CBaseEntity *BestAlienGooTarget();
void SetAlienGooTarget( CBaseEntity *pAlienGooTarget ) { m_hAlienGooTarget = pAlienGooTarget; }
EHANDLE GetAlienGooTarget() { return m_hAlienGooTarget.Get(); }
EHANDLE GetAlienGooTarget() const { return m_hAlienGooTarget.Get(); }
bool EngageNewAlienGooTarget();
void SetPhysicsPropTarget( CBaseEntity *pPhysicsPropTarget ) { m_hPhysicsPropTarget = pPhysicsPropTarget; }
EHANDLE GetPhysicsPropTarget() { return m_hPhysicsPropTarget.Get(); }
EHANDLE GetPhysicsPropTarget() const { return m_hPhysicsPropTarget.Get(); }
void CheckForDisablingAICollision( CBaseEntity *pEntity );
virtual const Vector & GetEnemyLKP() const;
// hacking
CHandle<CASW_Use_Area> m_hAreaToUse;
void OnWeldStarted();
void OnWeldFinished();
bool m_bWaitingForWeld;
float m_flBeginWeldTime;
// orders and holding position
virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );
void UpdateFacing();
float GetHoldingYaw() { return m_fHoldingYaw; }
float m_fHoldingYaw;
CNetworkVar(int, m_ASWOrders);
ASW_Orders GetASWOrders() { return (ASW_Orders) m_ASWOrders.Get(); }
void SetASWOrders(ASW_Orders NewOrders, float fHoldingYaw=-1, const Vector *pOrderPos=NULL);
void OrdersFromPlayer(CASW_Player* pPlayer, ASW_Orders NewOrders, CBaseEntity *pMarine, bool bChatter, float fHoldingYaw=-1, Vector *pVecOrderPos = NULL); // called by the player when ordering this marine about
virtual bool CreateBehaviors();
void ProjectBeam( const Vector &vecStart, const Vector &vecDir, int width, int brightness, float duration );
void Scan();
float m_flTimeNextScanPing;
Vector m_vecMoveToOrderPos;
bool m_bDoneOrderChatter;
CASW_Marine* TooCloseToAnotherMarine(); // returns a marine we're standing too close to
float m_fRandomFacing;
float m_fNewRandomFacingTime;
bool NeedToUpdateSquad(); // whether I am a squad leader and should update the follow positions for my squad
bool NeedToFollowMove();
bool m_bWasFollowing; // were we previously doing follow orders?
void RecalculateAIYawOffset();
float m_flAIYawOffset; // AI marine will offset his yaw by this amount. this value changes periodically to make the marine seem less robotic
float m_flNextYawOffsetTime; // time at which to recalculate the yaw offset
CNetworkVar( bool, m_bAICrouch ); // if set, the AI will appear crouched when still
float m_flLastEnemyYaw;
float m_flLastEnemyYawTime;
void OrderHackArea( CASW_Use_Area *pArea );
// AI taking ammo
virtual int SelectTakeAmmoSchedule();
float m_flNextAmmoScanTime;
CHandle<CASW_Ammo> m_hTakeAmmo;
CHandle<CASW_Ammo_Drop> m_hTakeAmmoDrop;
float m_flResetAmmoIgnoreListTime;
CUtlVector<EHANDLE> m_hIgnoreAmmo;
// detecting squad combat state
void UpdateCombatStatus();
bool IsInCombat();
float m_flLastHurtAlienTime;
float m_flLastSquadEnemyTime;
float m_flLastSquadShotAlienTime;
bool m_bInCombat;
virtual bool FValidateHintType( CAI_Hint *pHint );
inline CASW_SquadFormation *GetSquadFormation(); // get the formation in which I participate
CASW_Marine *GetSquadLeader(); // If I'm following in a squad, get the leader I'm following
// tracking movement through the level
void AddPositionHistory();
float GetOverallMovementDirection();
struct PositionHistory_t
{
Vector vecPosition;
float flTime;
};
int m_nPositionHistoryTail;
PositionHistory_t m_PositionHistory[ ASW_MARINE_HISTORY_POSITIONS ];
float m_flNextPositionHistoryTime;
protected:
inline const Vector &GetFollowPos();
// this is not authoritative -- it's a bit of cruft because some old code in the client needs
// to know if this marine is following someone. this just caches the results of a GetSquadLeader() call.
CNetworkHandle(CBaseEntity, m_hMarineFollowTarget); // the marine we're currently ordered to follow, to be shown on the scanner and used by custom follow code
public:
void OrderUseOffhandItem( int iInventorySlot, const Vector &vecDest );
int SelectOffhandItemSchedule();
void FinishedUsingOffhandItem( bool bItemThrown = false, bool bFailed = false );
bool CanThrowOffhand( CASW_Weapon *pWeapon, const Vector &vecSrc, const Vector &vecDest, bool bDrawArc = false );
const Vector& GetOffhandItemSpot() { return m_vecOffhandItemSpot; }
Vector GetOffhandThrowSource( const Vector *vecStandingPos = NULL );
int FindThrowNode( const Vector &vThreatPos, float flMinThreatDist, float flMaxThreatDist, float flBlockTime );
Vector m_vecOffhandItemSpot; // the place we want to throw/deploy our offhand item
CHandle<CASW_Weapon> m_hOffhandItemToUse; // ordering the marine to use an offhand item
// Hacking
CNetworkVar( bool, m_bHacking ); // is this marine currently hacking a button panel or computer?
CNetworkHandle( CASW_Hack, m_hCurrentHack ); // the current hack object (not the computer console itself) we're hacking
bool IsHacking( void );
// ammo
bool CarryingAGunThatUsesAmmo( int iAmmoIndex);
virtual int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false );
virtual int GiveAmmoToAmmoBag( int iCount, int iAmmoIndex, bool bSuppressSound = false );
void Weapon_Equip( CBaseCombatWeapon *pWeapon );
void Weapon_Equip_In_Index( CBaseCombatWeapon *pWeapon, int index ); // like weapon_equip, but tries to put the weapon in the specific index
void Weapon_Equip_Post( CBaseCombatWeapon *pWeapon);
int GetWeaponIndex( CBaseCombatWeapon *pWeapon ) const; // returns weapon's position in our myweapons array
int GetNumberOfWeaponsUsingAmmo(int iAmmoType);
bool CanPickupPrimaryAmmo();
virtual void TookAmmoPickup( CBaseEntity* pAmmoPickup );
int GetAllAmmoCount( void );
int GetTotalAmmoCount(int iAmmoIndex);
int GetTotalAmmoCount(char *szName);
int GetWeaponAmmoCount(int iAmmoIndex);
int GetWeaponAmmoCount(char *szName);
void ThrowAmmo(int iInventorySlot, int iTargetMarine, int iAmmoType); // throwing ammo from the ammo bag
bool CheckAutoWeaponSwitch(); // AI switching weapons automatically if hurt while using a non-offensive weapon
int m_iHurtWithoutOffensiveWeapon; // tracks how many times the AI marine's been hurt without a weapon selected
void CheckAndRequestAmmo();
bool IsOutOfAmmo();
virtual void OnWeaponOutOfAmmo(bool bChatter);
// ammo bag/give ammo
bool CanGiveAmmoTo( CASW_Marine* pMarine );
int SelectGiveAmmoSchedule( void );
CHandle<CASW_Marine> m_hGiveAmmoTarget;
CHandle<CASW_Marine> m_hHealTarget;
bool CanHeal() const;
int SelectHealSchedule();
// weapons
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex=0 ) ;
virtual bool Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon );
CASW_Weapon* GetASWWeapon(int index) const;
int GetWeaponPositionForPickup(const char* szWeaponClass); // returns which slot in the m_hWeapons array this pickup should go in
bool TakeWeaponPickup(CASW_Weapon* pWeapon);
bool TakeWeaponPickup(CASW_Pickup_Weapon* pPickup); // takes a weapon
bool DropWeapon(int iWeaponIndex, bool bNoSwap = false); // drops the weapon on the ground as a weapon pickup
bool DropWeapon(CASW_Weapon* pWeapon, bool bNoSwap, const Vector *pvecTarget=NULL, const Vector *pVelocity=NULL);
virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget /* = NULL */, const Vector *pVelocity /* = NULL */ ); // HL version
virtual CBaseCombatWeapon* ASWAnim_GetActiveWeapon();
CASW_Weapon* GetActiveASWWeapon( void ) const;
virtual Vector Weapon_ShootPosition(); // source point for firing weapons
virtual bool IsFiring();
void DoDamagePowerupEffects( CBaseEntity *pTarget, CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
int m_iDamageAttributeEffects;
virtual void FireBullets( const FireBulletsInfo_t &info );
virtual void FireRegularBullets( const FireBulletsInfo_t &info );
virtual void FirePenetratingBullets( const FireBulletsInfo_t &info, int iMaxPenetrate, float fPenetrateChance, int iSeedPlus, bool bAllowChange=true, Vector *pPiercingTracerEnd=NULL, bool bSegmentTracer = true );
virtual void FireBouncingBullets( const FireBulletsInfo_t &info, int iMaxBounce, int iSeedPlus=0 );
CBaseCombatWeapon* GetLastWeaponSwitchedTo();
EHANDLE m_hLastWeaponSwitchedTo;
float m_fStartedFiringTime;
virtual void AimGun();
float m_fLastShotAlienTime;
float m_fLastShotJunkTime;
virtual void DoMuzzleFlash();
virtual void DoImpactEffect( trace_t &tr, int nDamageType );
void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
void MakeUnattachedTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
void OnWeaponFired( const CBaseEntity *pWeapon, int nShotsFired, bool bIsSecondary = false );
float m_flLastAttributeExplosionSound;
int m_nFastReloadsInARow;
CNetworkVar( float, m_flPreventLaserSightTime );
// AI control of firing
bool AIWantsToFire();
bool AIWantsToFire2();
bool AIWantsToReload();
bool m_bWantsToFire, m_bWantsToFire2;
float m_fMarineAimError;
CNetworkVar(float, m_fAIPitch); // pitch aim of the AI, so it can be shown by the clientside anims
virtual bool SetNewAimError(CBaseEntity *pTarget);
virtual void AddAimErrorToTarget(Vector &vecTarget);
virtual Vector GetActualShootTrajectory( const Vector &shootOrigin );
virtual Vector GetActualShootPosition( const Vector &shootOrigin );
virtual bool FInViewCone( const Vector &vecSpot );
virtual bool FInViewCone( CBaseEntity *pEntity ) { return FInViewCone( pEntity->WorldSpaceCenter() ); }
virtual bool FInAimCone( const Vector &vecSpot );
virtual bool WeaponLOSCondition(const Vector &ownerPos, const Vector &targetPos, bool bSetConditions );
virtual float GetFollowSightRange();
virtual float GetCloseCombatSightRange();
// overkill shooting (the AI marine firing for a period longer than strictly necessary)
float m_fOverkillShootTime;
Vector m_vecOverkillPos;
// health related
void AddSlowHeal(int iHealAmount, float flHealRateScale, CASW_Marine *pMedic, CBaseEntity* pHealingWeapon = NULL );
CNetworkVar(bool, m_bSlowHeal);
CNetworkVar(int, m_iSlowHealAmount);
float m_flHealRateScale;
float m_fNextSlowHealTick;
void MeleeBleed(CTakeDamageInfo* info);
void BecomeInfested(CASW_Alien* pAlien);
void CureInfestation(CASW_Marine *pHealer, float fCureFraction);
bool m_bPlayedCureScream; // have we played a scream sound for our parasite?
bool IsInfested();
CNetworkVar(float, m_fInfestedTime); // how much time left on the infestation
CNetworkVar(float, m_fInfestedStartTime); // when the marine first got infested
int m_iInfestCycle;
virtual void ASW_Ignite( float flFlameLifetime, float flSize, CBaseEntity *pAttacker, CBaseEntity *pDamagingWeapon = NULL );
virtual void Ignite( float flFlameLifetime, bool bNPCOnly = true, float flSize = 0.0f, bool bCalledByLevelDesigner = false );
virtual void Extinguish();
virtual bool AllowedToIgnite( void );
float m_flFirstBurnTime;
float m_flLastBurnTime;
float m_flLastBurnSoundTime;
float m_fNextPainSoundTime;
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual bool BecomeRagdollOnClient( const Vector &force );
void Suicide();
bool IsWounded() const; // less than 60% health
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
virtual bool CorpseGib( const CTakeDamageInfo &info );
virtual bool ShouldGib( const CTakeDamageInfo &info );
virtual bool Event_Gibbed( const CTakeDamageInfo &info );
virtual bool HasHumanGibs() { return true; }
//CNetworkVar(float, m_fDieHardTime); // If set, marine is in DIE HARD mode, this is the time at which marine will die
virtual float GetReceivedDamageScale( CBaseEntity *pAttacker );
CNetworkVar(float, m_fFFGuardTime); // if set, marine cannot fire any weapons for a certain amount of time
virtual void ActivateFriendlyFireGuard(CASW_Marine *pVictim);
virtual float GetFFAbsorptionScale();
float m_fLastFriendlyFireTime;
float m_fFriendlyFireAbsorptionTime; // timer for friendly fire damage
float m_fLastAmmoCheckTime;
bool m_bDoneWoundedRebuke;
float m_fFriendlyFireDamage; // keeps track of friendly fire damage done to this marine (so healing medals don't reward healing of FF damage)
int m_pRecentAttackers[ ASW_MOB_VICTIM_SIZE ];
float m_fLastMobDamageTime;
bool m_bHasBeenMobAttacked;
CHandle<CASW_Marine> m_hInfestationCurer; // the last medic to cure us of some infestation - give him some stats if I survive the infestation
CNetworkVar(bool, m_bOnFire);
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
virtual void Bleed( const CTakeDamageInfo &info, const Vector &vecPos, const Vector &vecDir, trace_t *ptr );
void PerformResurrectionEffect( void ); ///< issue any special effects or sounds on resurrection
// we want to no part of this freezing business!
void Freeze( float flFreezeAmount, CBaseEntity *pFreezer, Ray_t *pFreezeRay ) { }
// using entities over time
virtual bool StartUsing(CBaseEntity *pEntity);
virtual void StopUsing();
inline CBaseEntity *GetUsingEntity() const { return m_hUsingEntity.Get(); }
CNetworkHandle( CBaseEntity, m_hUsingEntity );
void SetFacingPoint(const Vector &vec, float fDuration);
CNetworkVar(Vector, m_vecFacingPointFromServer);
float m_fStopFacingPointTime;
float m_fLastASWThink;
virtual int DrawDebugTextOverlays();
virtual void DrawDebugGeometryOverlays();
float m_fUsingEngineeringAura; // last time this tech marine had his engineering aura used
// emote system
void TickEmotes(float d);
bool TickEmote(float d, bool bEmote, bool& bClientEmote, float& fEmoteTime);
void DoEmote(int iEmote);
CNetworkVar(bool, bEmoteMedic);
CNetworkVar(bool, bEmoteAmmo);
CNetworkVar(bool, bEmoteSmile);
CNetworkVar(bool, bEmoteStop);
CNetworkVar(bool, bEmoteGo);
CNetworkVar(bool, bEmoteExclaim);
CNetworkVar(bool, bEmoteAnimeSmile);
CNetworkVar(bool, bEmoteQuestion);
bool bClientEmoteMedic, bClientEmoteAmmo, bClientEmoteSmile, bClientEmoteStop,
bClientEmoteGo, bClientEmoteExclaim, bClientEmoteAnimeSmile, bClientEmoteQuestion; // these are unused by the server.dll but are here for shared code purposes
float fEmoteMedicTime, fEmoteAmmoTime, fEmoteSmileTime, fEmoteStopTime,
fEmoteGoTime, fEmoteExclaimTime, fEmoteAnimeSmileTime, fEmoteQuestionTime;
// driving
virtual void StartDriving(IASW_Vehicle* pVehicle);
virtual void StopDriving(IASW_Vehicle* pVehicle);
IASW_Vehicle* GetASWVehicle();
bool IsDriving() { return m_bDriving; }
bool IsInVehicle() { return m_bIsInVehicle; }
CNetworkHandle( CBaseEntity, m_hASWVehicle );
CNetworkVar( bool, m_bDriving );
CNetworkVar( bool, m_bIsInVehicle );
// controlling a turret
bool IsControllingTurret();
CASW_Remote_Turret* GetRemoteTurret();
CNetworkHandle( CASW_Remote_Turret, m_hRemoteTurret );
// falling over
void SetKnockedOut(bool bKnockedOut);
CNetworkVar( bool, m_bKnockedOut );
//CRagdollProp * m_pKnockedOutRagdoll;
CRagdollProp* GetRagdollProp();
EHANDLE m_hKnockedOutRagdoll;
float m_fUnfreezeTime;
// custom rappeling
bool IsWaitingToRappel() { return m_bWaitingToRappel; }
void BeginRappel();
void SetDescentSpeed();
void CreateZipline();
void CutZipline();
virtual void CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput );
// We want to do this on our marines even when they're not using move type step (i.e. inhabited by the player)
virtual bool ShouldCheckPhysicsContacts( void ) { return ( (GetMoveType() == MOVETYPE_STEP || Classify() == CLASS_ASW_MARINE) && VPhysicsGetObject() ); }
virtual float StepHeight() const { return 24.0f; }
bool m_bWaitingToRappel;
bool m_bOnGround;
CHandle<CBeam> m_hLine;
Vector m_vecRopeAnchor;
virtual void PhysicsLandedOnGround( float fFallSpeed );
// vars from parent that we're networking
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_hGroundEntity );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iHealth );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iMaxHealth );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_vecBaseVelocity );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_vecVelocity );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_fFlags );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iAmmo );
int m_iLightLevel;
// skill related
bool IsReflectingProjectiles() { return m_bReflectingProjectiles.Get(); }
CNetworkVar( bool, m_bReflectingProjectiles );
// stumbling
void Stumble( CBaseEntity *pSource, const Vector &vecStumbleDir, bool bShort );
void Knockdown( CBaseEntity *pSource, const Vector &vecKnockdownDir, bool bForce = false );
int GetForcedActionRequest() { return m_iForcedActionRequest.Get(); }
void ClearForcedActionRequest() { m_iForcedActionRequest = 0; }
bool CanDoForcedAction( int iForcedAction ); // check if we're allowed to perform a forced action (certain abilities limit this)
void RequestForcedAction( int iForcedAction ) { m_iForcedActionRequest = iForcedAction; }
CNetworkVar( int, m_iForcedActionRequest );
void SetNextStumbleTime( float flStumbleTime ) { m_flNextStumbleTime = flStumbleTime; }
float m_flNextStumbleTime;
private:
float m_flNextBreadcrumbTime;
};
#include "asw_squadformation.h"
inline CASW_SquadFormation *CASW_Marine::GetSquadFormation() // get the formation in which I participate; in the future there may be more than one per universe
{
return &g_ASWSquadFormation;
}
inline CASW_Marine *CASW_Marine::AsMarine( CBaseEntity *pEnt )
{
return ( pEnt && pEnt->Classify() == CLASS_ASW_MARINE ) ? assert_cast<CASW_Marine *>(pEnt) : NULL;
}
#endif /* ASW_MARINE_H */