Team Fortress 2 Source Code as on 22/4/2020
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.

750 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Weapons.
  4. //
  5. // CTFWeaponBase
  6. // |
  7. // |--> CTFWeaponBaseMelee
  8. // | |
  9. // | |--> CTFWeaponCrowbar
  10. // | |--> CTFWeaponKnife
  11. // | |--> CTFWeaponMedikit
  12. // | |--> CTFWeaponWrench
  13. // |
  14. // |--> CTFWeaponBaseGrenade
  15. // | |
  16. // | |--> CTFWeapon
  17. // | |--> CTFWeapon
  18. // |
  19. // |--> CTFWeaponBaseGun
  20. //
  21. //=============================================================================
  22. #ifndef TF_WEAPONBASE_H
  23. #define TF_WEAPONBASE_H
  24. #ifdef _WIN32
  25. #pragma once
  26. #endif
  27. #include "tf_playeranimstate.h"
  28. #include "tf_weapon_parse.h"
  29. #include "npcevent.h"
  30. #include "ihasowner.h"
  31. #include "tf_item_wearable.h"
  32. // Client specific.
  33. #if defined( CLIENT_DLL )
  34. #define CTFWeaponBase C_TFWeaponBase
  35. #define CTFWeaponAttachmentModel C_TFWeaponAttachmentModel
  36. #define CTFWeaponBaseGrenadeProj C_TFWeaponBaseGrenadeProj
  37. #include "tf_fx_muzzleflash.h"
  38. #include "GameEventListener.h"
  39. #endif
  40. #define MAX_TRACER_NAME 128
  41. class CTFPlayer;
  42. class CBaseObject;
  43. class CTFWeaponBaseGrenadeProj;
  44. class CTFWeaponAttachmentModel;
  45. // Given an ammo type (like from a weapon's GetPrimaryAmmoType()), this compares it
  46. // against the ammo name you specify.
  47. // TFTODO: this should use indexing instead of searching and strcmp()'ing all the time.
  48. bool IsAmmoType( int iAmmoType, const char *pAmmoName );
  49. void FindHullIntersection( const Vector &vecSrc, trace_t &tr, const Vector &mins, const Vector &maxs, CBaseEntity *pEntity );
  50. // Reloading singly.
  51. enum
  52. {
  53. TF_RELOAD_START = 0,
  54. TF_RELOADING,
  55. TF_RELOADING_CONTINUE,
  56. TF_RELOAD_FINISH
  57. };
  58. // structure to encapsulate state of head bob
  59. struct BobState_t
  60. {
  61. BobState_t()
  62. {
  63. m_flBobTime = 0;
  64. m_flLastBobTime = 0;
  65. m_flLastSpeed = 0;
  66. m_flVerticalBob = 0;
  67. m_flLateralBob = 0;
  68. }
  69. float m_flBobTime;
  70. float m_flLastBobTime;
  71. float m_flLastSpeed;
  72. float m_flVerticalBob;
  73. float m_flLateralBob;
  74. };
  75. enum EWeaponStrangeType_t
  76. {
  77. STRANGE_UNKNOWN = -1,
  78. STRANGE_NOT_STRANGE = 0,
  79. STRANGE_IS_STRANGE = 1,
  80. };
  81. enum EWeaponStatTrakModuleType_t
  82. {
  83. MODULE_UNKNOWN = -1,
  84. MODULE_NONE = 0,
  85. MODULE_FOUND = 1,
  86. };
  87. #ifdef CLIENT_DLL
  88. float CalcViewModelBobHelper( CBasePlayer *player, BobState_t *pBobState );
  89. void AddViewModelBobHelper( Vector &origin, QAngle &angles, BobState_t *pBobState );
  90. #endif
  91. // Interface for weapons that have a charge time
  92. class ITFChargeUpWeapon
  93. {
  94. public:
  95. virtual bool CanCharge( void ) = 0;
  96. virtual float GetChargeBeginTime( void ) = 0;
  97. virtual float GetChargeMaxTime( void ) = 0;
  98. virtual float GetCurrentCharge( void )
  99. {
  100. return ( gpGlobals->curtime - GetChargeBeginTime() ) / GetChargeMaxTime();
  101. }
  102. };
  103. class CTraceFilterIgnoreTeammates : public CTraceFilterSimple
  104. {
  105. public:
  106. // It does have a base, but we'll never network anything below here..
  107. DECLARE_CLASS( CTraceFilterIgnoreTeammates, CTraceFilterSimple );
  108. CTraceFilterIgnoreTeammates( const IHandleEntity *passentity, int collisionGroup, int iIgnoreTeam )
  109. : CTraceFilterSimple( passentity, collisionGroup ), m_iIgnoreTeam( iIgnoreTeam )
  110. {
  111. }
  112. virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
  113. {
  114. CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
  115. if ( ( pEntity->IsPlayer() || pEntity->IsCombatItem() ) && ( pEntity->GetTeamNumber() == m_iIgnoreTeam || m_iIgnoreTeam == TEAM_ANY ) )
  116. {
  117. return false;
  118. }
  119. return BaseClass::ShouldHitEntity( pServerEntity, contentsMask );
  120. }
  121. int m_iIgnoreTeam;
  122. };
  123. class CTraceFilterIgnorePlayers : public CTraceFilterSimple
  124. {
  125. public:
  126. // It does have a base, but we'll never network anything below here..
  127. DECLARE_CLASS( CTraceFilterIgnorePlayers, CTraceFilterSimple );
  128. CTraceFilterIgnorePlayers( const IHandleEntity *passentity, int collisionGroup )
  129. : CTraceFilterSimple( passentity, collisionGroup )
  130. {
  131. }
  132. virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
  133. {
  134. CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
  135. if ( pEntity && pEntity->IsPlayer() )
  136. return false;
  137. return BaseClass::ShouldHitEntity( pServerEntity, contentsMask );
  138. }
  139. };
  140. class CTraceFilterIgnoreFriendlyCombatItems : public CTraceFilterSimple
  141. {
  142. public:
  143. DECLARE_CLASS( CTraceFilterIgnoreFriendlyCombatItems, CTraceFilterSimple );
  144. CTraceFilterIgnoreFriendlyCombatItems( const IHandleEntity *passentity, int collisionGroup, int iIgnoreTeam, bool bIsProjectile = false )
  145. : CTraceFilterSimple( passentity, collisionGroup ), m_iIgnoreTeam( iIgnoreTeam )
  146. {
  147. m_bCallerIsProjectile = bIsProjectile;
  148. }
  149. virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
  150. {
  151. CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
  152. // if ( ( pEntity->MyCombatCharacterPointer() || pEntity->MyCombatWeaponPointer() ) && pEntity->GetTeamNumber() == m_iIgnoreTeam )
  153. // return false;
  154. //
  155. // if ( pEntity->IsPlayer() && pEntity->GetTeamNumber() == m_iIgnoreTeam )
  156. // return false;
  157. if ( pEntity->IsCombatItem() )
  158. {
  159. if ( pEntity->GetTeamNumber() == m_iIgnoreTeam )
  160. return false;
  161. // If source is a enemy projectile, be explicit, otherwise we fail a "IsTransparent" test downstream
  162. if ( m_bCallerIsProjectile )
  163. return true;
  164. }
  165. return BaseClass::ShouldHitEntity( pServerEntity, contentsMask );
  166. }
  167. int m_iIgnoreTeam;
  168. bool m_bCallerIsProjectile;
  169. };
  170. #define ENERGY_WEAPON_MAX_CHARGE 20
  171. #define TF_PARTICLE_WEAPON_BLUE_1 Vector( 0.345, 0.52, 0.635 )
  172. #define TF_PARTICLE_WEAPON_BLUE_2 Vector( 0.145, 0.427, 0.55 )
  173. #define TF_PARTICLE_WEAPON_RED_1 Vector( 0.72, 0.22, 0.23 )
  174. #define TF_PARTICLE_WEAPON_RED_2 Vector( 0.5, 0.18, 0.125 )
  175. //=============================================================================
  176. //
  177. // Base TF Weapon Class
  178. //
  179. #if defined( CLIENT_DLL )
  180. class CTFWeaponBase : public CBaseCombatWeapon, public IHasOwner, public CGameEventListener
  181. #else
  182. class CTFWeaponBase : public CBaseCombatWeapon, public IHasOwner
  183. #endif
  184. {
  185. DECLARE_CLASS( CTFWeaponBase, CBaseCombatWeapon );
  186. DECLARE_NETWORKCLASS();
  187. DECLARE_PREDICTABLE();
  188. #if !defined ( CLIENT_DLL )
  189. DECLARE_DATADESC();
  190. #endif
  191. // Setup.
  192. CTFWeaponBase();
  193. ~CTFWeaponBase();
  194. virtual void Spawn();
  195. virtual void Activate( void );
  196. virtual void Precache();
  197. virtual bool IsPredicted() const { return true; }
  198. virtual void FallInit( void );
  199. // Weapon Data.
  200. CTFWeaponInfo const &GetTFWpnData() const;
  201. virtual int GetWeaponID( void ) const;
  202. bool IsWeapon( int iWeapon ) const;
  203. virtual int GetDamageType() const { return g_aWeaponDamageTypes[ GetWeaponID() ]; }
  204. virtual int GetCustomDamageType() const { return TF_DMG_CUSTOM_NONE; }
  205. virtual int GetMaxClip1( void ) const;
  206. virtual int GetDefaultClip1( void ) const;
  207. virtual bool UsesPrimaryAmmo();
  208. virtual float UberChargeAmmoPerShot( void ) { float fAmmo = 0; CALL_ATTRIB_HOOK_FLOAT( fAmmo, ubercharge_ammo ); return fAmmo * 0.01f; }
  209. virtual int Clip1() { return IsEnergyWeapon() ? Energy_GetEnergy() : m_iClip1; }
  210. virtual int Clip2() { return m_iClip2; }
  211. virtual bool HasAmmo( void );
  212. // View model.
  213. virtual const char *GetViewModel( int iViewModel = 0 ) const;
  214. virtual const char *GetWorldModel( void ) const;
  215. virtual bool SendWeaponAnim( int iActivity ) OVERRIDE;
  216. virtual CBaseEntity *GetOwnerViaInterface( void ) { return GetOwner(); }
  217. virtual void Equip( CBaseCombatCharacter *pOwner );
  218. virtual void Drop( const Vector &vecVelocity );
  219. virtual void UpdateOnRemove( void );
  220. virtual bool CanHolster( void ) const;
  221. virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
  222. virtual bool Deploy( void );
  223. virtual bool ForceWeaponSwitch() const OVERRIDE;
  224. virtual void Detach( void );
  225. virtual void OnActiveStateChanged( int iOldState );
  226. virtual bool OwnerCanJump( void ) { return true; }
  227. virtual bool VisibleInWeaponSelection( void );
  228. virtual void UpdateHands( void );
  229. virtual bool OwnerCanTaunt( void ) { return true; }
  230. virtual bool CanBeCritBoosted( void );
  231. bool CanHaveRevengeCrits( void );
  232. // Extra wearables.
  233. #ifdef GAME_DLL
  234. virtual void ChangeTeam( int iTeamNum ) OVERRIDE;
  235. virtual void UpdateExtraWearables();
  236. virtual void ExtraWearableEquipped( CTFWearable *pExtraWearableItem );
  237. virtual void ExtraWearableViewModelEquipped( CTFWearable *pExtraWearableItem );
  238. virtual bool HideAttachmentsAndShowBodygroupsWhenPerformingWeaponIndependentTaunt() const { return true; }
  239. #endif // GAME_DLL
  240. virtual void RemoveExtraWearables( void );
  241. // Attacks.
  242. virtual void Misfire( void );
  243. virtual void FireFullClipAtOnce( void );
  244. virtual void PrimaryAttack();
  245. virtual void SecondaryAttack();
  246. void CalcIsAttackCritical( void );
  247. virtual bool CalcIsAttackCriticalHelper();
  248. virtual bool CalcIsAttackCriticalHelperNoCrits();
  249. bool IsCurrentAttackACrit() const { return m_bCurrentAttackIsCrit; }
  250. bool IsCurrentAttackARandomCrit() const { return m_bCurrentAttackIsCrit && m_bCurrentCritIsRandom; }
  251. bool IsCurrentAttackDuringDemoCharge() const { return m_bCurrentAttackIsDuringDemoCharge; }
  252. virtual ETFDmgCustom GetPenetrateType() const;
  253. virtual void GetProjectileFireSetup( CTFPlayer *pPlayer, Vector vecOffset, Vector *vecSrc, QAngle *angForward, bool bHitTeammates = true, float flEndDist = 2000.f );
  254. virtual QAngle GetSpreadAngles( void );
  255. float GetLastPrimaryAttackTime( void ) const { return m_flLastPrimaryAttackTime; }
  256. virtual bool CanPerformSecondaryAttack() const OVERRIDE;
  257. virtual bool IsFiring( void ) const { return false; }
  258. virtual bool AreRandomCritsEnabled( void );
  259. // Reloads.
  260. virtual bool Reload( void );
  261. virtual void AbortReload( void );
  262. virtual bool DefaultReload( int iClipSize1, int iClipSize2, int iActivity );
  263. void SendReloadEvents();
  264. virtual bool IsReloading() const; // is the weapon reloading right now?
  265. virtual bool AutoFiresFullClip( void ) const OVERRIDE;
  266. bool AutoFiresFullClipAllAtOnce( void ) const;
  267. bool CanOverload( void ) const;
  268. virtual bool CheckReloadMisfire( void ) { return false; }
  269. virtual bool CanDrop( void ) { return false; }
  270. virtual bool AllowTaunts( void ) { return true; }
  271. // Fire Rate
  272. float ApplyFireDelay( float flDelay ) const;
  273. // Sound.
  274. bool PlayEmptySound();
  275. bool IsSilentKiller();
  276. // Activities.
  277. virtual void ItemBusyFrame( void );
  278. virtual void ItemPostFrame( void );
  279. virtual void ItemHolsterFrame( void );
  280. virtual void SetWeaponVisible( bool visible );
  281. virtual int GetActivityWeaponRole() const;
  282. virtual acttable_t *ActivityList( int &iActivityCount ) OVERRIDE;
  283. virtual Activity TranslateViewmodelHandActivityInternal( Activity actBase );
  284. virtual int GetViewModelWeaponRole() { return GetTFWpnData().m_iWeaponType; }
  285. #ifdef GAME_DLL
  286. virtual void AddAssociatedObject( CBaseObject *pObject ) { }
  287. virtual void RemoveAssociatedObject( CBaseObject *pObject ) { }
  288. virtual void ApplyOnHitAttributes( CBaseEntity *pVictimBaseEntity, CTFPlayer *pAttacker, const CTakeDamageInfo &info );
  289. virtual void ApplyPostHitEffects( const CTakeDamageInfo &inputInfo, CTFPlayer *pPlayer );
  290. virtual void ApplyOnInjuredAttributes( CTFPlayer *pVictim, CTFPlayer *pAttacker, const CTakeDamageInfo &info ); // when owner of this weapon is hit
  291. virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  292. virtual bool DeflectProjectiles();
  293. virtual bool DeflectPlayer( CTFPlayer *pTarget, CTFPlayer *pOwner, Vector &vecForward, Vector &vecCenter, Vector &vecSize );
  294. virtual bool DeflectEntity( CBaseEntity *pTarget, CTFPlayer *pOwner, Vector &vecForward, Vector &vecCenter, Vector &vecSize );
  295. static void SendObjectDeflectedEvent( CTFPlayer *pNewOwner, CTFPlayer *pPrevOwner, int iWeaponID, CBaseAnimating *pObject );
  296. static float DeflectionForce( const Vector &size, float damage, float scale );
  297. virtual void PlayDeflectionSound( bool bPlayer ) {}
  298. virtual Vector GetDeflectionSize() { return Vector( 128, 128, 64 ); }
  299. virtual float GetJarateTime() { return 0.f; }
  300. void ApplyItemRegen( void );
  301. kill_eater_event_t GetKillEaterKillEventType() const;
  302. #endif
  303. // Utility.
  304. CBasePlayer *GetPlayerOwner() const;
  305. CTFPlayer *GetTFPlayerOwner() const;
  306. #ifdef CLIENT_DLL
  307. virtual bool ShouldPlayClientReloadSound() { return false; }
  308. C_BaseEntity *GetWeaponForEffect();
  309. virtual const char* ModifyEventParticles( const char* token ) { return token; }
  310. // Shadows
  311. virtual ShadowType_t ShadowCastType( void ) OVERRIDE;
  312. #endif
  313. virtual bool CanAttack();
  314. virtual int GetCanAttackFlags() const { return TF_CAN_ATTACK_FLAG_NONE; }
  315. // Raising & Lowering for grenade throws
  316. bool WeaponShouldBeLowered( void );
  317. virtual bool Ready( void );
  318. virtual bool Lower( void );
  319. virtual void WeaponIdle( void );
  320. virtual void WeaponReset( void );
  321. virtual void WeaponRegenerate( void );
  322. // Muzzleflashes
  323. virtual const char *GetMuzzleFlashEffectName_3rd( void ) { return NULL; }
  324. virtual const char *GetMuzzleFlashEffectName_1st( void ) { return NULL; }
  325. virtual const char *GetMuzzleFlashModel( void );
  326. virtual float GetMuzzleFlashModelLifetime( void );
  327. virtual const char *GetMuzzleFlashParticleEffect( void );
  328. virtual const char *GetTracerType( void );
  329. virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
  330. // CEconEntity
  331. virtual const char *GetInventoryModel( void );
  332. virtual void ReapplyProvision( void );
  333. virtual float GetSpeedMod( void ) { return 1.f; };
  334. virtual bool CanFireCriticalShot( bool bIsHeadshot = false );
  335. virtual bool CanFireRandomCriticalShot( float flCritChance );
  336. virtual char const *GetShootSound( int iIndex ) const;
  337. void UpdateHiddenParentBodygroup( bool bHide );
  338. virtual void OnControlStunned( void );
  339. virtual bool HideWhileStunned( void ) { return true; }
  340. virtual bool IsViewModelFlipped( void );
  341. virtual int GetMaxHealthMod() { return 0; }
  342. virtual float GetLastDeployTime( void ) { return m_flLastDeployTime; }
  343. // Energy Weapons
  344. virtual bool IsEnergyWeapon( void ) const { return false; }
  345. virtual bool IsBlastImpactWeapon( void ) const { return false; }
  346. float Energy_GetMaxEnergy( void ) const;
  347. float Energy_GetEnergy( void ) const { return m_flEnergy; }
  348. void Energy_SetEnergy( float flEnergy ) { m_flEnergy = flEnergy; }
  349. bool Energy_FullyCharged( void ) const;
  350. bool Energy_HasEnergy( void );
  351. void Energy_DrainEnergy( void );
  352. void Energy_DrainEnergy( float flDrain );
  353. bool Energy_Recharge( void );
  354. virtual float Energy_GetShotCost( void ) const { return 4.f; }
  355. virtual float Energy_GetRechargeCost( void ) const { return 4.f; }
  356. virtual Vector GetParticleColor( int iColor );
  357. virtual void CheckReload( void );
  358. virtual void FinishReload( void );
  359. virtual bool HasLastShotCritical( void ) { return false; }
  360. virtual bool UseServerRandomSeed( void ) const { return true; }
  361. // Server specific.
  362. #if !defined( CLIENT_DLL )
  363. // Spawning.
  364. virtual void CheckRespawn();
  365. virtual CBaseEntity* Respawn();
  366. void Materialize();
  367. void AttemptToMaterialize();
  368. // Death.
  369. void Die( void );
  370. void SetDieThink( bool bDie );
  371. // Disguise weapon.
  372. void DisguiseWeaponThink( void );
  373. // Ammo.
  374. virtual const Vector& GetBulletSpread();
  375. // Hit tracking for achievements
  376. // Track the number of kills we've had since we missed. Only works for bullet firing weapons right now.
  377. virtual void OnBulletFire( int iEnemyPlayersHit );
  378. virtual void OnPlayerKill( CTFPlayer *pVictim, const CTakeDamageInfo &info );
  379. virtual float GetLastHitTime( void ) { return m_flLastHitTime; }
  380. virtual int GetDropSkinOverride( void ) { return -1; }
  381. int GetKillStreak () const { return m_iKillStreak; }
  382. void SetKillStreak ( int value ) { m_iKillStreak = value; };
  383. float GetClipScale () const { return m_flClipScale; }
  384. void SetClipScale ( float flScale ) { m_flClipScale = flScale; }
  385. // Client specific.
  386. #else
  387. bool IsFirstPersonView();
  388. bool UsingViewModel();
  389. C_BaseAnimating *GetAppropriateWorldOrViewModel();
  390. virtual bool ShouldDraw( void ) OVERRIDE;
  391. virtual void UpdateVisibility( void ) OVERRIDE;
  392. virtual void ProcessMuzzleFlashEvent( void );
  393. virtual void DispatchMuzzleFlash( const char* effectName, C_BaseEntity* pAttachEnt );
  394. virtual int InternalDrawModel( int flags );
  395. virtual bool ShouldPredict();
  396. virtual void PostDataUpdate( DataUpdateType_t updateType );
  397. virtual void OnDataChanged( DataUpdateType_t type );
  398. virtual void OnPreDataChanged( DataUpdateType_t updateType );
  399. virtual int GetWorldModelIndex( void );
  400. virtual bool ShouldDrawCrosshair( void );
  401. virtual void Redraw( void );
  402. virtual void FireGameEvent( IGameEvent *event );
  403. virtual void AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles );
  404. virtual float CalcViewmodelBob( void );
  405. BobState_t *GetBobState();
  406. virtual bool AttachmentModelsShouldBeVisible( void ) OVERRIDE { return (m_iState == WEAPON_IS_ACTIVE) && !IsBeingRepurposedForTaunt(); }
  407. virtual bool ShouldEjectBrass() { return true; }
  408. bool OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options );
  409. // ItemEffect Hud defaults
  410. virtual const char * GetEffectLabelText() { return ""; }
  411. virtual float GetProgress() { return 0; }
  412. // Model muzzleflashes
  413. CHandle<C_MuzzleFlashModel> m_hMuzzleFlashModel[2];
  414. bool IsUsingOverrideModel() const { return m_iWorldModelIndex != m_iCachedModelIndex; }
  415. #endif
  416. virtual int GetSkin();
  417. static void UpdateWeaponBodyGroups( CTFPlayer* pPlayer, bool bHandleDeployedBodygroups );
  418. void SetIsBeingRepurposedForTaunt( bool bCanOverride ) { m_bBeingRepurposedForTaunt = bCanOverride; }
  419. bool IsBeingRepurposedForTaunt() const { return m_bBeingRepurposedForTaunt; }
  420. int GetKillComboClass( void ) const { return m_nKillComboClass; }
  421. int GetKillComboCount( void ) const { return m_nKillComboCount; }
  422. void ClearKillComboCount( void ) { m_nKillComboCount = 0; }
  423. void AddKillCombo( int nClassKilled )
  424. {
  425. if ( m_nKillComboClass != nClassKilled )
  426. {
  427. m_nKillComboClass = nClassKilled;
  428. ClearKillComboCount();
  429. }
  430. m_nKillComboCount = Min( 3, m_nKillComboCount + 1 );
  431. }
  432. // Effect / Regeneration bar handling
  433. virtual float GetEffectBarProgress( void ); // Get the current bar state (will return a value from 0.0 to 1.0)
  434. bool HasEffectBarRegeneration( void ) { return InternalGetEffectBarRechargeTime() > 0; } // Check the base, not modified by attribute, because attrib may have reduced it to 0.
  435. float GetEffectBarRechargeTime( void ) { float flTime = InternalGetEffectBarRechargeTime(); CALL_ATTRIB_HOOK_FLOAT( flTime, effectbar_recharge_rate ); return flTime; }
  436. void DecrementBarRegenTime( float flTime ) { m_flEffectBarRegenTime -= flTime; }
  437. bool IsHonorBound( void ) const;
  438. virtual bool CanPickupOtherWeapon() const { return true; }
  439. EWeaponStrangeType_t GetStrangeType();
  440. bool BHasStatTrakModule();
  441. #ifdef CLIENT_DLL
  442. // StatTrak View Model Test
  443. void UpdateAllViewmodelAddons( void );
  444. void AddStatTrakModel( CEconItemView *pItem, int nStatTrakType, AccountID_t holderAcctId );
  445. void RemoveViewmodelStatTrak( void );
  446. void RemoveWorldmodelStatTrak( void );
  447. CHandle< CTFWeaponAttachmentModel > m_viewmodelStatTrakAddon;
  448. CHandle< CTFWeaponAttachmentModel > m_worldmodelStatTrakAddon;
  449. virtual const Vector& GetViewmodelOffset() OVERRIDE;
  450. #endif
  451. virtual bool ShouldRemoveInvisibilityOnPrimaryAttack() const { return true; }
  452. protected:
  453. virtual int GetEffectBarAmmo( void ) { return m_iPrimaryAmmoType; }
  454. virtual float InternalGetEffectBarRechargeTime( void ) { return 0; } // Time it takes for this regeneration bar to fully recharge from 0 to full.
  455. void StartEffectBarRegen( void ); // Call this when you want your bar to start recharging (usually when you've deployed your action)
  456. void EffectBarRegenFinished( void );
  457. void CheckEffectBarRegen( void );
  458. private:
  459. CNetworkVar( float, m_flEffectBarRegenTime ); // The time Regen is scheduled to complete
  460. protected:
  461. #ifdef CLIENT_DLL
  462. virtual void CreateMuzzleFlashEffects( C_BaseEntity *pAttachEnt, int nIndex );
  463. virtual void UpdateExtraWearablesVisibility();
  464. #endif // CLIENT_DLL
  465. // Reloads.
  466. void UpdateReloadTimers( bool bStart );
  467. void SetReloadTimer( float flReloadTime );
  468. bool ReloadSingly( void );
  469. void ReloadSinglyPostFrame( void );
  470. void IncrementAmmo( void );
  471. bool NeedsReloadForAmmo1( int iClipSize1 ) const;
  472. bool NeedsReloadForAmmo2( int iClipSize2 ) const;
  473. protected:
  474. void PlayUpgradedShootSound( const char *pszSound );
  475. int m_iWeaponMode;
  476. CNetworkVar( int, m_iReloadMode );
  477. CNetworkVar( float, m_flReloadPriorNextFire );
  478. CTFWeaponInfo *m_pWeaponInfo;
  479. bool m_bInAttack;
  480. bool m_bInAttack2;
  481. bool m_bCurrentAttackIsCrit;
  482. bool m_bCurrentCritIsRandom;
  483. bool m_bCurrentAttackIsDuringDemoCharge;
  484. EWeaponStrangeType_t m_eStrangeType;
  485. EWeaponStatTrakModuleType_t m_eStatTrakModuleType;
  486. CNetworkVar( bool, m_bLowered );
  487. int m_iAltFireHint;
  488. int m_iReloadStartClipAmount;
  489. float m_flCritTime;
  490. CNetworkVar( float, m_flLastCritCheckTime ); // Deprecated
  491. int m_iLastCritCheckFrame;
  492. int m_iCurrentSeed;
  493. float m_flLastRapidFireCritCheckTime;
  494. float m_flLastDeployTime;
  495. char m_szTracerName[MAX_TRACER_NAME];
  496. CNetworkVar( bool, m_bResetParity );
  497. int m_iAmmoToAdd;
  498. float m_flLastPrimaryAttackTime;
  499. #ifdef GAME_DLL
  500. // Stores the number of kills we've made since we last shot & didn't hit a player.
  501. // Only hooked up to bullet firing right now, so you'll need to do plumbing if you want it for other weaponry.
  502. int m_iConsecutiveKills;
  503. // Accuracy tracking
  504. float m_flLastHitTime;
  505. int m_iHitsInTime;
  506. int m_iFiredInTime;
  507. // Used to generate active-weapon-only regen
  508. float m_flRegenTime;
  509. // for penetrating weapons with drain - only drain each victim once
  510. CHandle< CTFPlayer > m_hLastDrainVictim;
  511. CountdownTimer m_lastDrainVictimTimer;
  512. int m_iKillStreak;
  513. float m_flClipScale;
  514. #endif
  515. #ifdef CLIENT_DLL
  516. bool m_bOldResetParity;
  517. int m_iCachedModelIndex;
  518. int m_iEjectBrassAttachpoint;
  519. #endif
  520. CNetworkVar( bool, m_bReloadedThroughAnimEvent );
  521. CNetworkVar( float, m_flEnergy );
  522. public:
  523. CNetworkVar( bool, m_bDisguiseWeapon );
  524. CNetworkVar( float, m_flLastFireTime );
  525. CNetworkHandle( CTFWearable, m_hExtraWearable );
  526. CNetworkHandle( CTFWearable, m_hExtraWearableViewModel );
  527. CNetworkVar( float, m_flObservedCritChance );
  528. virtual bool CanInspect() const;
  529. void HandleInspect();
  530. enum TFWeaponInspectStage
  531. {
  532. INSPECT_INVALID = -1,
  533. INSPECT_START,
  534. INSPECT_IDLE,
  535. INSPECT_END,
  536. INSPECT_STAGE_COUNT
  537. };
  538. TFWeaponInspectStage GetInspectStage() const { return (TFWeaponInspectStage)m_nInspectStage.Get(); }
  539. float GetInspectAnimTime() const { return m_flInspectAnimTime; }
  540. private:
  541. CTFWeaponBase( const CTFWeaponBase & );
  542. CNetworkVar( bool, m_bBeingRepurposedForTaunt );
  543. CNetworkVar( int, m_nKillComboClass );
  544. CNetworkVar( int, m_nKillComboCount );
  545. int GetInspectActivity( TFWeaponInspectStage inspectStage );
  546. bool IsInspectActivity( int iActivity );
  547. CNetworkVar( float, m_flInspectAnimTime );
  548. CNetworkVar( int, m_nInspectStage );
  549. bool m_bInspecting;
  550. friend class CTFDroppedWeapon;
  551. #ifdef CLIENT_DLL
  552. bool m_bInitViewmodelOffset;
  553. Vector m_vecViewmodelOffset;
  554. #endif // CLIENT_DLL
  555. };
  556. bool WeaponID_IsSniperRifle( int iWeaponID );
  557. bool WeaponID_IsSniperRifleOrBow( int iWeaponID );
  558. #define WEAPON_RANDOM_RANGE 10000
  559. #ifdef CLIENT_DLL
  560. //-----------------------------------------------------------------------------
  561. // CTFWeaponAttachmentModel
  562. //-----------------------------------------------------------------------------
  563. class CTFWeaponAttachmentModel : public CBaseAnimating, public IHasOwner
  564. {
  565. DECLARE_CLASS( CTFWeaponAttachmentModel, CBaseAnimating );
  566. public:
  567. CTFWeaponAttachmentModel() { m_bIsViewModelAttachment = false; m_hWeaponAssociatedWith = NULL; }
  568. virtual bool ShouldDraw( void );
  569. void Init( CBaseEntity *pParent, CTFWeaponBase *pAssociatedWeapon, bool bIsViewModel );
  570. void SetWeaponAssociatedWith( CTFWeaponBase *pWeapon ) { m_hWeaponAssociatedWith = pWeapon; }
  571. CBaseEntity* GetWeaponAssociatedWith( void ) const { return m_hWeaponAssociatedWith.Get(); }
  572. bool BIsViewModelAttachment() { return m_bIsViewModelAttachment; }
  573. virtual CBaseEntity *GetOwnerViaInterface( void ) OVERRIDE { return m_hWeaponAssociatedWith.Get() ? m_hWeaponAssociatedWith.Get()->GetOwner() : NULL; }
  574. private:
  575. bool m_bIsViewModelAttachment;
  576. CHandle< CTFWeaponBase > m_hWeaponAssociatedWith;
  577. };
  578. #endif // CLIENT_DLL
  579. #endif // TF_WEAPONBASE_H