summaryrefslogtreecommitdiff
path: root/game/server/hl1/hl1_weapon_crowbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/hl1/hl1_weapon_crowbar.cpp')
-rw-r--r--game/server/hl1/hl1_weapon_crowbar.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/game/server/hl1/hl1_weapon_crowbar.cpp b/game/server/hl1/hl1_weapon_crowbar.cpp
new file mode 100644
index 0000000..f11f640
--- /dev/null
+++ b/game/server/hl1/hl1_weapon_crowbar.cpp
@@ -0,0 +1,379 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Crowbar - an old favorite
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "hl1mp_basecombatweapon_shared.h"
+
+#ifdef CLIENT_DLL
+#include "c_baseplayer.h"
+#include "fx_impact.h"
+#include "fx.h"
+#else
+#include "player.h"
+#include "soundent.h"
+#endif
+
+#include "gamerules.h"
+#include "ammodef.h"
+#include "mathlib/mathlib.h"
+#include "in_buttons.h"
+
+#include "vstdlib/random.h"
+
+extern ConVar sk_plr_dmg_crowbar;
+
+#define CROWBAR_RANGE 64.0f
+#define CROWBAR_REFIRE_MISS 0.5f
+#define CROWBAR_REFIRE_HIT 0.25f
+
+
+#ifdef CLIENT_DLL
+#define CWeaponCrowbar C_WeaponCrowbar
+#endif
+
+//-----------------------------------------------------------------------------
+// CWeaponCrowbar
+//-----------------------------------------------------------------------------
+
+class CWeaponCrowbar : public CBaseHL1MPCombatWeapon
+{
+ DECLARE_CLASS( CWeaponCrowbar, CBaseHL1MPCombatWeapon );
+public:
+ DECLARE_NETWORKCLASS();
+ DECLARE_PREDICTABLE();
+#ifndef CLIENT_DLL
+ DECLARE_DATADESC();
+#endif
+
+ CWeaponCrowbar();
+
+ void Precache( void );
+ virtual void ItemPostFrame( void );
+ void PrimaryAttack( void );
+
+public:
+ trace_t m_traceHit;
+ Activity m_nHitActivity;
+
+private:
+ virtual void Swing( void );
+ virtual void Hit( void );
+ virtual void ImpactEffect( void );
+ void ImpactSound( CBaseEntity *pHitEntity );
+ virtual Activity ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner );
+
+public:
+
+};
+
+IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCrowbar, DT_WeaponCrowbar );
+
+BEGIN_NETWORK_TABLE( CWeaponCrowbar, DT_WeaponCrowbar )
+/// what
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CWeaponCrowbar )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar );
+PRECACHE_WEAPON_REGISTER( weapon_crowbar );
+
+#ifndef CLIENT_DLL
+BEGIN_DATADESC( CWeaponCrowbar )
+
+ // DEFINE_FIELD( m_trLineHit, trace_t ),
+ // DEFINE_FIELD( m_trHullHit, trace_t ),
+ // DEFINE_FIELD( m_nHitActivity, FIELD_INTEGER ),
+ // DEFINE_FIELD( m_traceHit, trace_t ),
+
+ // Class CWeaponCrowbar:
+ // DEFINE_FIELD( m_nHitActivity, FIELD_INTEGER ),
+
+ // Function Pointers
+ DEFINE_FUNCTION( Hit ),
+
+END_DATADESC()
+#endif
+
+#define BLUDGEON_HULL_DIM 16
+
+static const Vector g_bludgeonMins(-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM);
+static const Vector g_bludgeonMaxs(BLUDGEON_HULL_DIM,BLUDGEON_HULL_DIM,BLUDGEON_HULL_DIM);
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CWeaponCrowbar::CWeaponCrowbar()
+{
+ m_bFiresUnderwater = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Precache the weapon
+//-----------------------------------------------------------------------------
+void CWeaponCrowbar::Precache( void )
+{
+ //Call base class first
+ BaseClass::Precache();
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Update weapon
+//------------------------------------------------------------------------------
+void CWeaponCrowbar::ItemPostFrame( void )
+{
+ CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
+
+ if ( pOwner == NULL )
+ return;
+
+ if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
+ {
+ PrimaryAttack();
+ }
+ else
+ {
+ WeaponIdle();
+ return;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Purpose :
+// Input :
+// Output :
+//------------------------------------------------------------------------------
+void CWeaponCrowbar::PrimaryAttack()
+{
+ Swing();
+}
+
+
+//------------------------------------------------------------------------------
+// Purpose: Implement impact function
+//------------------------------------------------------------------------------
+void CWeaponCrowbar::Hit( void )
+{
+ //Make sound for the AI
+#ifndef CLIENT_DLL
+
+ CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
+
+ CSoundEnt::InsertSound( SOUND_BULLET_IMPACT, m_traceHit.endpos, 400, 0.2f, pPlayer );
+
+ CBaseEntity *pHitEntity = m_traceHit.m_pEnt;
+
+ //Apply damage to a hit target
+ if ( pHitEntity != NULL )
+ {
+ Vector hitDirection;
+ pPlayer->EyeVectors( &hitDirection, NULL, NULL );
+ VectorNormalize( hitDirection );
+
+ ClearMultiDamage();
+ CTakeDamageInfo info( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB );
+ CalculateMeleeDamageForce( &info, hitDirection, m_traceHit.endpos );
+ pHitEntity->DispatchTraceAttack( info, hitDirection, &m_traceHit );
+ ApplyMultiDamage();
+
+ // Now hit all triggers along the ray that...
+ TraceAttackToTriggers( CTakeDamageInfo( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB ), m_traceHit.startpos, m_traceHit.endpos, hitDirection );
+
+ //Play an impact sound
+ ImpactSound( pHitEntity );
+ }
+#endif
+
+ //Apply an impact effect
+ ImpactEffect();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Play the impact sound
+// Input : pHitEntity - entity that we hit
+// assumes pHitEntity is not null
+//-----------------------------------------------------------------------------
+void CWeaponCrowbar::ImpactSound( CBaseEntity *pHitEntity )
+{
+ bool bIsWorld = ( pHitEntity->entindex() == 0 );
+#ifndef CLIENT_DLL
+ if ( !bIsWorld )
+ {
+ bIsWorld |= pHitEntity->Classify() == CLASS_NONE || pHitEntity->Classify() == CLASS_MACHINE;
+ }
+#endif
+
+ if( bIsWorld )
+ {
+ WeaponSound( MELEE_HIT_WORLD );
+ }
+ else
+ {
+ WeaponSound( MELEE_HIT );
+ }
+}
+
+Activity CWeaponCrowbar::ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner )
+{
+ int i, j, k;
+ float distance;
+ const float *minmaxs[2] = {mins.Base(), maxs.Base()};
+ trace_t tmpTrace;
+ Vector vecHullEnd = hitTrace.endpos;
+ Vector vecEnd;
+
+ distance = 1e6f;
+ Vector vecSrc = hitTrace.startpos;
+
+ vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2);
+ UTIL_TraceLine( vecSrc, vecHullEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace );
+ if ( tmpTrace.fraction == 1.0 )
+ {
+ for ( i = 0; i < 2; i++ )
+ {
+ for ( j = 0; j < 2; j++ )
+ {
+ for ( k = 0; k < 2; k++ )
+ {
+ vecEnd.x = vecHullEnd.x + minmaxs[i][0];
+ vecEnd.y = vecHullEnd.y + minmaxs[j][1];
+ vecEnd.z = vecHullEnd.z + minmaxs[k][2];
+
+ UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace );
+ if ( tmpTrace.fraction < 1.0 )
+ {
+ float thisDistance = (tmpTrace.endpos - vecSrc).Length();
+ if ( thisDistance < distance )
+ {
+ hitTrace = tmpTrace;
+ distance = thisDistance;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ hitTrace = tmpTrace;
+ }
+
+
+ return ACT_VM_HITCENTER;
+}
+
+#ifdef HL1MP_CLIENT_DLL
+//-----------------------------------------------------------------------------
+// Purpose: Handle jeep impacts
+//-----------------------------------------------------------------------------
+void ImpactCrowbarCallback( const CEffectData &data )
+{
+ trace_t tr;
+ Vector vecOrigin, vecStart, vecShotDir;
+ int iMaterial, iDamageType, iHitbox;
+ short nSurfaceProp;
+ C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
+
+ bool bIsWorld = ( pEntity->entindex() == 0 );
+
+ if ( !pEntity )
+ {
+ // This happens for impacts that occur on an object that's then destroyed.
+ // Clear out the fraction so it uses the server's data
+ tr.fraction = 1.0;
+ GetActiveWeapon()->WeaponSound( bIsWorld ? MELEE_HIT_WORLD : MELEE_HIT );
+ return;
+ }
+
+ // If we hit, perform our custom effects and play the sound
+ if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
+ {
+ // Check for custom effects based on the Decal index
+ PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 2 );
+ }
+
+ GetActiveWeapon()->WeaponSound( bIsWorld ? MELEE_HIT_WORLD : MELEE_HIT );
+}
+
+DECLARE_CLIENT_EFFECT( "ImpactCrowbar", ImpactCrowbarCallback );
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWeaponCrowbar::ImpactEffect( void )
+{
+ //FIXME: need new decals
+#ifdef HL1MP_CLIENT_DLL
+ // in hl1mp force the basic crowbar sound
+ UTIL_ImpactTrace( &m_traceHit, DMG_CLUB, "ImpactCrowbar" );
+#else
+ UTIL_ImpactTrace( &m_traceHit, DMG_CLUB );
+#endif
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Starts the swing of the weapon and determines the animation
+//------------------------------------------------------------------------------
+void CWeaponCrowbar::Swing( void )
+{
+ // Try a ray
+ CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
+ if ( !pOwner )
+ return;
+
+ Vector swingStart = pOwner->Weapon_ShootPosition( );
+ Vector forward;
+
+ pOwner->EyeVectors( &forward, NULL, NULL );
+
+ Vector swingEnd = swingStart + forward * CROWBAR_RANGE;
+
+ UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &m_traceHit );
+ m_nHitActivity = ACT_VM_HITCENTER;
+
+ if ( m_traceHit.fraction == 1.0 )
+ {
+ float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM; // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point
+
+ // Back off by hull "radius"
+ swingEnd -= forward * bludgeonHullRadius;
+
+ UTIL_TraceHull( swingStart, swingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &m_traceHit );
+ if ( m_traceHit.fraction < 1.0 )
+ {
+ m_nHitActivity = ChooseIntersectionPointAndActivity( m_traceHit, g_bludgeonMins, g_bludgeonMaxs, pOwner );
+ }
+ }
+
+
+ // -------------------------
+ // Miss
+ // -------------------------
+ if ( m_traceHit.fraction == 1.0f )
+ {
+ m_nHitActivity = ACT_VM_MISSCENTER;
+
+ //Play swing sound
+ WeaponSound( SINGLE );
+
+ //Setup our next attack times
+ m_flNextPrimaryAttack = gpGlobals->curtime + CROWBAR_REFIRE_MISS;
+ }
+ else
+ {
+ Hit();
+
+ //Setup our next attack times
+ m_flNextPrimaryAttack = gpGlobals->curtime + CROWBAR_REFIRE_HIT;
+ }
+
+ //Send the anim
+ SendWeaponAnim( m_nHitActivity );
+ pOwner->SetAnimation( PLAYER_ATTACK1 );
+}