//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Engineer's Sentrygun // // $NoKeywords: $ //=============================================================================// #ifndef TF_OBJ_SENTRYGUN_H #define TF_OBJ_SENTRYGUN_H #ifdef _WIN32 #pragma once #endif #include "tf_obj.h" #include "tf_projectile_rocket.h" class CTFPlayer; enum { SENTRY_LEVEL_1 = 0, // SENTRY_LEVEL_1_UPGRADING, SENTRY_LEVEL_2, // SENTRY_LEVEL_2_UPGRADING, SENTRY_LEVEL_3, }; #define SF_SENTRY_UPGRADEABLE (LAST_SF_BASEOBJ<<1) #define SF_SENTRY_INFINITE_AMMO (LAST_SF_BASEOBJ<<2) #define SENTRYGUN_MAX_HEALTH 150 #define SENTRYGUN_MINI_MAX_HEALTH 100 #define SENTRY_MAX_RANGE 1100.0f // magic numbers are evil, people. adding this #define to demystify the value. (MSB 5/14/09) #define SENTRY_MAX_RANGE_SQRD 1210000.0f // ------------------------------------------------------------------------ // // Sentrygun object that's built by the player // ------------------------------------------------------------------------ // class CObjectSentrygun : public CBaseObject { DECLARE_CLASS( CObjectSentrygun, CBaseObject ); public: DECLARE_SERVERCLASS(); CObjectSentrygun(); static CObjectSentrygun* Create(const Vector &vOrigin, const QAngle &vAngles); virtual void Spawn(); virtual void FirstSpawn(); virtual void Precache(); virtual void OnGoActive( void ); virtual int DrawDebugTextOverlays(void); virtual int OnTakeDamage( const CTakeDamageInfo &info ); virtual void Killed( const CTakeDamageInfo &info ); virtual void SetModel( const char *pModel ); virtual bool StartBuilding( CBaseEntity *pBuilder ); virtual void SetStartBuildingModel( void ); virtual void StartPlacement( CTFPlayer *pPlayer ); // Engineer hit me with a wrench virtual bool OnWrenchHit( CTFPlayer *pPlayer, CTFWrench *pWrench, Vector hitLoc ); virtual void OnStartDisabled( void ); virtual void OnEndDisabled( void ); virtual int GetTracerAttachment( void ); virtual bool IsUpgrading( void ) const { return m_iState == SENTRY_STATE_UPGRADING; } virtual float GetTimeSinceLastFired( void ) const { return m_timeSinceLastFired.GetElapsedTime(); } virtual const QAngle &GetTurretAngles( void ) const { return m_vecCurAngles; } virtual void SetBuildingSize( void ); void ClearTarget( void ) { m_hEnemy = NULL; } CBaseEntity *GetTarget( void ) { return m_hEnemy.Get(); } void FireNextFrame( void ) { m_bFireNextFrame = true; } void FireRocketNextFrame( void ) {m_bFireRocketNextFrame = true; } void SetAutoAimTarget( CTFPlayer* pPlayer ); int GetFireAttachment( void ); void OnKilledEnemy(CBasePlayer* pVictim); virtual void MakeMiniBuilding( CTFPlayer* pPlayer ); virtual void MakeCarriedObject( CTFPlayer *pCarrier ); void MakeScaledBuilding( CTFPlayer* pPlayer ); float GetPushMultiplier(); void EmitSentrySound( const char* soundname ); void EmitSentrySound( IRecipientFilter& filter, int iEntIndex, const char *soundname ); CTFPlayer * GetAssistingTeammate( float maxAssistDuration = -1.0f ) const; virtual int GetBaseHealth( void ) { return SENTRYGUN_MAX_HEALTH; } void SetShieldLevel( int nLevel, float flDuration ) { m_nShieldLevel = nLevel; m_flShieldFadeTime = gpGlobals->curtime + flDuration; } virtual int GetMaxUpgradeLevel( void ) OVERRIDE; virtual int GetMiniBuildingStartingHealth( void ) OVERRIDE { return SENTRYGUN_MINI_MAX_HEALTH; } void RemoveAllAmmo(); virtual int GetMaxHealthForCurrentLevel( void ); virtual int GetUpgradeMetalRequired(); bool IsScaledSentry() { return m_flScaledSentry != 1.0f; } virtual int GetShieldLevel() { return m_nShieldLevel; } virtual bool IsTruceValidForEnt( void ) const OVERRIDE { return true; } private: Vector GetEnemyAimPosition( CBaseEntity* pEnemy ) const; // Main think void SentryThink( void ); // If the players hit us with a wrench, should we upgrade bool CanBeUpgraded( CTFPlayer *pPlayer ); void StartUpgrading( void ); void FinishUpgrading( void ); // Target acquisition bool FindTarget( void ); bool ValidTargetPlayer( CTFPlayer *pPlayer, const Vector &vecStart, const Vector &vecEnd ); bool ValidTargetObject( CBaseObject *pObject, const Vector &vecStart, const Vector &vecEnd ); bool ValidTargetBot( CBaseCombatCharacter *pBot, const Vector &vecStart, const Vector &vecEnd ); void FoundTarget( CBaseEntity *pTarget, const Vector &vecSoundCenter, bool bNoSound=false ); bool FInViewCone ( CBaseEntity *pEntity ); int Range( CBaseEntity *pTarget ); // Rotations void SentryRotate( void ); bool MoveTurret( void ); // Attack void Attack( void ); void MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ); bool Fire( void ); bool FireRocket( void ); virtual void ModifyFireBulletsDamage( CTakeDamageInfo* dmgInfo ); int GetBaseTurnRate( void ); virtual void MakeDisposableBuilding( CTFPlayer *pPlayer ); CNetworkVar( int, m_iState ); float m_flNextAttack; float m_flFireRate; IntervalTimer m_timeSinceLastFired; // Rotation int m_iRightBound; int m_iLeftBound; int m_iBaseTurnRate; bool m_bTurningRight; QAngle m_vecCurAngles; QAngle m_vecGoalAngles; float m_flTurnRate; // Ammo CNetworkVar( int, m_iAmmoShells ); CNetworkVar( int, m_iMaxAmmoShells ); CNetworkVar( int, m_iAmmoRockets ); CNetworkVar( int, m_iMaxAmmoRockets ); int m_iOldAmmoShells; int m_iOldAmmoRockets; int m_iAmmoType; float m_flNextRocketAttack; // Target player / object CNetworkHandle( CBaseEntity, m_hEnemy ); bool m_bFireNextFrame; bool m_bFireRocketNextFrame; float m_flSentryRange; // Player control shield. CNetworkVar( bool, m_bPlayerControlled ); CNetworkVar( uint32, m_nShieldLevel ); float m_flShieldFadeTime; // PDQ Sentry CNetworkVar( bool, m_bPDQSentry ); //cached attachment indeces int m_iAttachments[4]; int m_iPitchPoseParameter; int m_iYawPoseParameter; float m_flLastAttackedTime; float m_flHeavyBulletResist; CNetworkHandle( CTFPlayer, m_hAutoAimTarget ); float m_flAutoAimStartTime; // for achievement: ACHIEVEMENT_TF_ENGINEER_MANUAL_SENTRY_ABSORB_DMG int m_iLifetimeShieldedDamage; DECLARE_DATADESC(); CountdownTimer m_inCombatThrottleTimer; void UpdateNavMeshCombatStatus( void ); CHandle< CTFPlayer > m_lastTeammateWrenchHit; // which teammate last hit us with a wrench IntervalTimer m_lastTeammateWrenchHitTimer; // time since last wrench hit int m_iLastMuzzleAttachmentFired; float m_flScaledSentry; }; // sentry rocket class just to give it a unique class name, so we can distinguish it from other rockets class CTFProjectile_SentryRocket : public CTFProjectile_Rocket { public: DECLARE_CLASS( CTFProjectile_SentryRocket, CTFProjectile_Rocket ); DECLARE_NETWORKCLASS(); CTFProjectile_SentryRocket(); virtual int GetProjectileType() const OVERRIDE { return TF_PROJECTILE_SENTRY_ROCKET; } // Creation. static CTFProjectile_SentryRocket *Create( const Vector &vecOrigin, const QAngle &vecAngles, CBaseEntity *pOwner = NULL, CBaseEntity *pScorer = NULL ); virtual void Spawn(); }; #endif // TF_OBJ_SENTRYGUN_H