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.

330 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "in_buttons.h"
  9. #include "takedamageinfo.h"
  10. #include "ammodef.h"
  11. #include "hl2mp_gamerules.h"
  12. #ifdef CLIENT_DLL
  13. extern IVModelInfoClient* modelinfo;
  14. #else
  15. extern IVModelInfo* modelinfo;
  16. #endif
  17. #if defined( CLIENT_DLL )
  18. #include "vgui/ISurface.h"
  19. #include "vgui_controls/Controls.h"
  20. #include "c_hl2mp_player.h"
  21. #include "hud_crosshair.h"
  22. #else
  23. #include "hl2mp_player.h"
  24. #include "vphysics/constraints.h"
  25. #endif
  26. #include "weapon_hl2mpbase.h"
  27. // ----------------------------------------------------------------------------- //
  28. // Global functions.
  29. // ----------------------------------------------------------------------------- //
  30. bool IsAmmoType( int iAmmoType, const char *pAmmoName )
  31. {
  32. return GetAmmoDef()->Index( pAmmoName ) == iAmmoType;
  33. }
  34. static const char * s_WeaponAliasInfo[] =
  35. {
  36. "none", // WEAPON_NONE = 0,
  37. //Melee
  38. "shotgun", //WEAPON_AMERKNIFE,
  39. NULL, // end of list marker
  40. };
  41. // ----------------------------------------------------------------------------- //
  42. // CWeaponHL2MPBase tables.
  43. // ----------------------------------------------------------------------------- //
  44. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHL2MPBase, DT_WeaponHL2MPBase )
  45. BEGIN_NETWORK_TABLE( CWeaponHL2MPBase, DT_WeaponHL2MPBase )
  46. #ifdef CLIENT_DLL
  47. #else
  48. // world weapon models have no aminations
  49. // SendPropExclude( "DT_AnimTimeMustBeFirst", "m_flAnimTime" ),
  50. // SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
  51. // SendPropExclude( "DT_LocalActiveWeaponData", "m_flTimeWeaponIdle" ),
  52. #endif
  53. END_NETWORK_TABLE()
  54. BEGIN_PREDICTION_DATA( CWeaponHL2MPBase )
  55. END_PREDICTION_DATA()
  56. LINK_ENTITY_TO_CLASS( weapon_hl2mp_base, CWeaponHL2MPBase );
  57. #ifdef GAME_DLL
  58. BEGIN_DATADESC( CWeaponHL2MPBase )
  59. END_DATADESC()
  60. #endif
  61. // ----------------------------------------------------------------------------- //
  62. // CWeaponHL2MPBase implementation.
  63. // ----------------------------------------------------------------------------- //
  64. CWeaponHL2MPBase::CWeaponHL2MPBase()
  65. {
  66. SetPredictionEligible( true );
  67. AddSolidFlags( FSOLID_TRIGGER ); // Nothing collides with these but it gets touches.
  68. m_flNextResetCheckTime = 0.0f;
  69. }
  70. bool CWeaponHL2MPBase::IsPredicted() const
  71. {
  72. return true;
  73. }
  74. void CWeaponHL2MPBase::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
  75. {
  76. #ifdef CLIENT_DLL
  77. // If we have some sounds from the weapon classname.txt file, play a random one of them
  78. const char *shootsound = GetWpnData().aShootSounds[ sound_type ];
  79. if ( !shootsound || !shootsound[0] )
  80. return;
  81. CBroadcastRecipientFilter filter; // this is client side only
  82. if ( !te->CanPredict() )
  83. return;
  84. CBaseEntity::EmitSound( filter, GetPlayerOwner()->entindex(), shootsound, &GetPlayerOwner()->GetAbsOrigin() );
  85. #else
  86. BaseClass::WeaponSound( sound_type, soundtime );
  87. #endif
  88. }
  89. CBasePlayer* CWeaponHL2MPBase::GetPlayerOwner() const
  90. {
  91. return dynamic_cast< CBasePlayer* >( GetOwner() );
  92. }
  93. CHL2MP_Player* CWeaponHL2MPBase::GetHL2MPPlayerOwner() const
  94. {
  95. return dynamic_cast< CHL2MP_Player* >( GetOwner() );
  96. }
  97. #ifdef CLIENT_DLL
  98. void CWeaponHL2MPBase::OnDataChanged( DataUpdateType_t type )
  99. {
  100. BaseClass::OnDataChanged( type );
  101. if ( GetPredictable() && !ShouldPredict() )
  102. ShutdownPredictable();
  103. }
  104. bool CWeaponHL2MPBase::ShouldPredict()
  105. {
  106. if ( GetOwner() && GetOwner() == C_BasePlayer::GetLocalPlayer() )
  107. return true;
  108. return BaseClass::ShouldPredict();
  109. }
  110. #else
  111. void CWeaponHL2MPBase::Spawn()
  112. {
  113. BaseClass::Spawn();
  114. // Set this here to allow players to shoot dropped weapons
  115. SetCollisionGroup( COLLISION_GROUP_WEAPON );
  116. }
  117. void CWeaponHL2MPBase::Materialize( void )
  118. {
  119. if ( IsEffectActive( EF_NODRAW ) )
  120. {
  121. // changing from invisible state to visible.
  122. EmitSound( "AlyxEmp.Charge" );
  123. RemoveEffects( EF_NODRAW );
  124. DoMuzzleFlash();
  125. }
  126. if ( HasSpawnFlags( SF_NORESPAWN ) == false )
  127. {
  128. VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false );
  129. SetMoveType( MOVETYPE_VPHYSICS );
  130. HL2MPRules()->AddLevelDesignerPlacedObject( this );
  131. }
  132. if ( HasSpawnFlags( SF_NORESPAWN ) == false )
  133. {
  134. if ( GetOriginalSpawnOrigin() == vec3_origin )
  135. {
  136. m_vOriginalSpawnOrigin = GetAbsOrigin();
  137. m_vOriginalSpawnAngles = GetAbsAngles();
  138. }
  139. }
  140. SetPickupTouch();
  141. SetThink (NULL);
  142. }
  143. int CWeaponHL2MPBase::ObjectCaps()
  144. {
  145. return BaseClass::ObjectCaps() & ~FCAP_IMPULSE_USE;
  146. }
  147. #endif
  148. void CWeaponHL2MPBase::FallInit( void )
  149. {
  150. #ifndef CLIENT_DLL
  151. SetModel( GetWorldModel() );
  152. VPhysicsDestroyObject();
  153. if ( HasSpawnFlags( SF_NORESPAWN ) == false )
  154. {
  155. SetMoveType( MOVETYPE_NONE );
  156. SetSolid( SOLID_BBOX );
  157. AddSolidFlags( FSOLID_TRIGGER );
  158. UTIL_DropToFloor( this, MASK_SOLID );
  159. }
  160. else
  161. {
  162. if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) )
  163. {
  164. SetMoveType( MOVETYPE_NONE );
  165. SetSolid( SOLID_BBOX );
  166. AddSolidFlags( FSOLID_TRIGGER );
  167. }
  168. else
  169. {
  170. #if !defined( CLIENT_DLL )
  171. // Constrained start?
  172. if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) )
  173. {
  174. //Constrain the weapon in place
  175. IPhysicsObject *pReferenceObject, *pAttachedObject;
  176. pReferenceObject = g_PhysWorldObject;
  177. pAttachedObject = VPhysicsGetObject();
  178. if ( pReferenceObject && pAttachedObject )
  179. {
  180. constraint_fixedparams_t fixed;
  181. fixed.Defaults();
  182. fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );
  183. fixed.constraint.forceLimit = lbs2kg( 10000 );
  184. fixed.constraint.torqueLimit = lbs2kg( 10000 );
  185. IPhysicsConstraint *pConstraint = GetConstraint();
  186. pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );
  187. pConstraint->SetGameData( (void *) this );
  188. }
  189. }
  190. #endif //CLIENT_DLL
  191. }
  192. }
  193. SetPickupTouch();
  194. SetThink( &CBaseCombatWeapon::FallThink );
  195. SetNextThink( gpGlobals->curtime + 0.1f );
  196. #endif
  197. }
  198. const CHL2MPSWeaponInfo &CWeaponHL2MPBase::GetHL2MPWpnData() const
  199. {
  200. const FileWeaponInfo_t *pWeaponInfo = &GetWpnData();
  201. const CHL2MPSWeaponInfo *pHL2MPInfo;
  202. #ifdef _DEBUG
  203. pHL2MPInfo = dynamic_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
  204. Assert( pHL2MPInfo );
  205. #else
  206. pHL2MPInfo = static_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
  207. #endif
  208. return *pHL2MPInfo;
  209. }
  210. void CWeaponHL2MPBase::FireBullets( const FireBulletsInfo_t &info )
  211. {
  212. FireBulletsInfo_t modinfo = info;
  213. modinfo.m_iPlayerDamage = GetHL2MPWpnData().m_iPlayerDamage;
  214. BaseClass::FireBullets( modinfo );
  215. }
  216. #if defined( CLIENT_DLL )
  217. #include "c_te_effect_dispatch.h"
  218. #define NUM_MUZZLE_FLASH_TYPES 4
  219. bool CWeaponHL2MPBase::OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options )
  220. {
  221. return BaseClass::OnFireEvent( pViewModel, origin, angles, event, options );
  222. }
  223. void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip )
  224. {
  225. QAngle final = in + punch;
  226. //Clip each component
  227. for ( int i = 0; i < 3; i++ )
  228. {
  229. if ( final[i] > clip[i] )
  230. {
  231. final[i] = clip[i];
  232. }
  233. else if ( final[i] < -clip[i] )
  234. {
  235. final[i] = -clip[i];
  236. }
  237. //Return the result
  238. in[i] = final[i] - punch[i];
  239. }
  240. }
  241. #endif