diff options
Diffstat (limited to 'mp/src/game/shared/hl2mp/weapon_frag.cpp')
| -rw-r--r-- | mp/src/game/shared/hl2mp/weapon_frag.cpp | 1104 |
1 files changed, 552 insertions, 552 deletions
diff --git a/mp/src/game/shared/hl2mp/weapon_frag.cpp b/mp/src/game/shared/hl2mp/weapon_frag.cpp index 9319b869..9ddcb813 100644 --- a/mp/src/game/shared/hl2mp/weapon_frag.cpp +++ b/mp/src/game/shared/hl2mp/weapon_frag.cpp @@ -1,552 +1,552 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "npcevent.h"
-#include "in_buttons.h"
-
-#ifdef CLIENT_DLL
- #include "c_hl2mp_player.h"
- #include "c_te_effect_dispatch.h"
-#else
- #include "hl2mp_player.h"
- #include "te_effect_dispatch.h"
- #include "grenade_frag.h"
-#endif
-
-#include "weapon_ar2.h"
-#include "effect_dispatch_data.h"
-#include "weapon_hl2mpbasehlmpcombatweapon.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define GRENADE_TIMER 2.5f //Seconds
-
-#define GRENADE_PAUSED_NO 0
-#define GRENADE_PAUSED_PRIMARY 1
-#define GRENADE_PAUSED_SECONDARY 2
-
-#define GRENADE_RADIUS 4.0f // inches
-
-#define GRENADE_DAMAGE_RADIUS 250.0f
-
-#ifdef CLIENT_DLL
-#define CWeaponFrag C_WeaponFrag
-#endif
-
-//-----------------------------------------------------------------------------
-// Fragmentation grenades
-//-----------------------------------------------------------------------------
-class CWeaponFrag: public CBaseHL2MPCombatWeapon
-{
- DECLARE_CLASS( CWeaponFrag, CBaseHL2MPCombatWeapon );
-public:
-
- DECLARE_NETWORKCLASS();
- DECLARE_PREDICTABLE();
-
- CWeaponFrag();
-
- void Precache( void );
- void PrimaryAttack( void );
- void SecondaryAttack( void );
- void DecrementAmmo( CBaseCombatCharacter *pOwner );
- void ItemPostFrame( void );
-
- bool Deploy( void );
- bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
-
- bool Reload( void );
-
-#ifndef CLIENT_DLL
- void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
-#endif
-
- void ThrowGrenade( CBasePlayer *pPlayer );
- bool IsPrimed( bool ) { return ( m_AttackPaused != 0 ); }
-
-private:
-
- void RollGrenade( CBasePlayer *pPlayer );
- void LobGrenade( CBasePlayer *pPlayer );
- // check a throw from vecSrc. If not valid, move the position back along the line to vecEye
- void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc );
-
- CNetworkVar( bool, m_bRedraw ); //Draw the weapon again after throwing a grenade
-
- CNetworkVar( int, m_AttackPaused );
- CNetworkVar( bool, m_fDrawbackFinished );
-
- CWeaponFrag( const CWeaponFrag & );
-
-#ifndef CLIENT_DLL
- DECLARE_ACTTABLE();
-#endif
-};
-
-#ifndef CLIENT_DLL
-
-acttable_t CWeaponFrag::m_acttable[] =
-{
- { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false },
- { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
- { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
- { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
- { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
- { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
- { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false },
-};
-
-IMPLEMENT_ACTTABLE(CWeaponFrag);
-
-#endif
-
-IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFrag, DT_WeaponFrag )
-
-BEGIN_NETWORK_TABLE( CWeaponFrag, DT_WeaponFrag )
-
-#ifdef CLIENT_DLL
- RecvPropBool( RECVINFO( m_bRedraw ) ),
- RecvPropBool( RECVINFO( m_fDrawbackFinished ) ),
- RecvPropInt( RECVINFO( m_AttackPaused ) ),
-#else
- SendPropBool( SENDINFO( m_bRedraw ) ),
- SendPropBool( SENDINFO( m_fDrawbackFinished ) ),
- SendPropInt( SENDINFO( m_AttackPaused ) ),
-#endif
-
-END_NETWORK_TABLE()
-
-#ifdef CLIENT_DLL
-BEGIN_PREDICTION_DATA( CWeaponFrag )
- DEFINE_PRED_FIELD( m_bRedraw, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_fDrawbackFinished, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_AttackPaused, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
-END_PREDICTION_DATA()
-#endif
-
-LINK_ENTITY_TO_CLASS( weapon_frag, CWeaponFrag );
-PRECACHE_WEAPON_REGISTER(weapon_frag);
-
-CWeaponFrag::CWeaponFrag( void ) :
- CBaseHL2MPCombatWeapon()
-{
- m_bRedraw = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CWeaponFrag::Precache( void )
-{
- BaseClass::Precache();
-
-#ifndef CLIENT_DLL
- UTIL_PrecacheOther( "npc_grenade_frag" );
-#endif
-
- PrecacheScriptSound( "WeaponFrag.Throw" );
- PrecacheScriptSound( "WeaponFrag.Roll" );
-}
-
-#ifndef CLIENT_DLL
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pEvent -
-// *pOperator -
-//-----------------------------------------------------------------------------
-void CWeaponFrag::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
-{
- CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
- bool fThrewGrenade = false;
-
- switch( pEvent->event )
- {
- case EVENT_WEAPON_SEQUENCE_FINISHED:
- m_fDrawbackFinished = true;
- break;
-
- case EVENT_WEAPON_THROW:
- ThrowGrenade( pOwner );
- DecrementAmmo( pOwner );
- fThrewGrenade = true;
- break;
-
- case EVENT_WEAPON_THROW2:
- RollGrenade( pOwner );
- DecrementAmmo( pOwner );
- fThrewGrenade = true;
- break;
-
- case EVENT_WEAPON_THROW3:
- LobGrenade( pOwner );
- DecrementAmmo( pOwner );
- fThrewGrenade = true;
- break;
-
- default:
- BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
- break;
- }
-
-#define RETHROW_DELAY 0.5
- if( fThrewGrenade )
- {
- m_flNextPrimaryAttack = gpGlobals->curtime + RETHROW_DELAY;
- m_flNextSecondaryAttack = gpGlobals->curtime + RETHROW_DELAY;
- m_flTimeWeaponIdle = FLT_MAX; //NOTE: This is set once the animation has finished up!
- }
-}
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CWeaponFrag::Deploy( void )
-{
- m_bRedraw = false;
- m_fDrawbackFinished = false;
-
- return BaseClass::Deploy();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CWeaponFrag::Holster( CBaseCombatWeapon *pSwitchingTo )
-{
- m_bRedraw = false;
- m_fDrawbackFinished = false;
-
- return BaseClass::Holster( pSwitchingTo );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CWeaponFrag::Reload( void )
-{
- if ( !HasPrimaryAmmo() )
- return false;
-
- if ( ( m_bRedraw ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) )
- {
- //Redraw the weapon
- SendWeaponAnim( ACT_VM_DRAW );
-
- //Update our times
- m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
- m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
- m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
-
- //Mark this as done
- m_bRedraw = false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CWeaponFrag::SecondaryAttack( void )
-{
- if ( m_bRedraw )
- return;
-
- if ( !HasPrimaryAmmo() )
- return;
-
- CBaseCombatCharacter *pOwner = GetOwner();
-
- if ( pOwner == NULL )
- return;
-
- CBasePlayer *pPlayer = ToBasePlayer( pOwner );
-
- if ( pPlayer == NULL )
- return;
-
- // Note that this is a secondary attack and prepare the grenade attack to pause.
- m_AttackPaused = GRENADE_PAUSED_SECONDARY;
- SendWeaponAnim( ACT_VM_PULLBACK_LOW );
-
- // Don't let weapon idle interfere in the middle of a throw!
- m_flTimeWeaponIdle = FLT_MAX;
- m_flNextSecondaryAttack = FLT_MAX;
-
- // If I'm now out of ammo, switch away
- if ( !HasPrimaryAmmo() )
- {
- pPlayer->SwitchToNextBestWeapon( this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CWeaponFrag::PrimaryAttack( void )
-{
- if ( m_bRedraw )
- return;
-
- CBaseCombatCharacter *pOwner = GetOwner();
-
- if ( pOwner == NULL )
- {
- return;
- }
-
- CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );;
-
- if ( !pPlayer )
- return;
-
- // Note that this is a primary attack and prepare the grenade attack to pause.
- m_AttackPaused = GRENADE_PAUSED_PRIMARY;
- SendWeaponAnim( ACT_VM_PULLBACK_HIGH );
-
- // Put both of these off indefinitely. We do not know how long
- // the player will hold the grenade.
- m_flTimeWeaponIdle = FLT_MAX;
- m_flNextPrimaryAttack = FLT_MAX;
-
- // If I'm now out of ammo, switch away
- if ( !HasPrimaryAmmo() )
- {
- pPlayer->SwitchToNextBestWeapon( this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pOwner -
-//-----------------------------------------------------------------------------
-void CWeaponFrag::DecrementAmmo( CBaseCombatCharacter *pOwner )
-{
- pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CWeaponFrag::ItemPostFrame( void )
-{
- if( m_fDrawbackFinished )
- {
- CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
-
- if (pOwner)
- {
- switch( m_AttackPaused )
- {
- case GRENADE_PAUSED_PRIMARY:
- if( !(pOwner->m_nButtons & IN_ATTACK) )
- {
- SendWeaponAnim( ACT_VM_THROW );
- m_fDrawbackFinished = false;
- }
- break;
-
- case GRENADE_PAUSED_SECONDARY:
- if( !(pOwner->m_nButtons & IN_ATTACK2) )
- {
- //See if we're ducking
- if ( pOwner->m_nButtons & IN_DUCK )
- {
- //Send the weapon animation
- SendWeaponAnim( ACT_VM_SECONDARYATTACK );
- }
- else
- {
- //Send the weapon animation
- SendWeaponAnim( ACT_VM_HAULBACK );
- }
-
- m_fDrawbackFinished = false;
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- BaseClass::ItemPostFrame();
-
- if ( m_bRedraw )
- {
- if ( IsViewModelSequenceFinished() )
- {
- Reload();
- }
- }
-}
-
- // check a throw from vecSrc. If not valid, move the position back along the line to vecEye
-void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc )
-{
- trace_t tr;
-
- UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2),
- pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr );
-
- if ( tr.DidHit() )
- {
- vecSrc = tr.endpos;
- }
-}
-
-void DropPrimedFragGrenade( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade )
-{
- CWeaponFrag *pWeaponFrag = dynamic_cast<CWeaponFrag*>( pGrenade );
-
- if ( pWeaponFrag )
- {
- pWeaponFrag->ThrowGrenade( pPlayer );
- pWeaponFrag->DecrementAmmo( pPlayer );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pPlayer -
-//-----------------------------------------------------------------------------
-void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer )
-{
-#ifndef CLIENT_DLL
- Vector vecEye = pPlayer->EyePosition();
- Vector vForward, vRight;
-
- pPlayer->EyeVectors( &vForward, &vRight, NULL );
- Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f;
- CheckThrowPosition( pPlayer, vecEye, vecSrc );
-// vForward[0] += 0.1f;
- vForward[2] += 0.1f;
-
- Vector vecThrow;
- pPlayer->GetVelocity( &vecThrow, NULL );
- vecThrow += vForward * 1200;
- CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false );
-
- if ( pGrenade )
- {
- if ( pPlayer && pPlayer->m_lifeState != LIFE_ALIVE )
- {
- pPlayer->GetVelocity( &vecThrow, NULL );
-
- IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
- if ( pPhysicsObject )
- {
- pPhysicsObject->SetVelocity( &vecThrow, NULL );
- }
- }
-
- pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
- pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
- }
-#endif
-
- m_bRedraw = true;
-
- WeaponSound( SINGLE );
-
- // player "shoot" animation
- pPlayer->SetAnimation( PLAYER_ATTACK1 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pPlayer -
-//-----------------------------------------------------------------------------
-void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer )
-{
-#ifndef CLIENT_DLL
- Vector vecEye = pPlayer->EyePosition();
- Vector vForward, vRight;
-
- pPlayer->EyeVectors( &vForward, &vRight, NULL );
- Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 );
- CheckThrowPosition( pPlayer, vecEye, vecSrc );
-
- Vector vecThrow;
- pPlayer->GetVelocity( &vecThrow, NULL );
- vecThrow += vForward * 350 + Vector( 0, 0, 50 );
- CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER, false );
-
- if ( pGrenade )
- {
- pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
- pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
- }
-#endif
-
- WeaponSound( WPN_DOUBLE );
-
- // player "shoot" animation
- pPlayer->SetAnimation( PLAYER_ATTACK1 );
-
- m_bRedraw = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pPlayer -
-//-----------------------------------------------------------------------------
-void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )
-{
-#ifndef CLIENT_DLL
- // BUGBUG: Hardcoded grenade width of 4 - better not change the model :)
- Vector vecSrc;
- pPlayer->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecSrc );
- vecSrc.z += GRENADE_RADIUS;
-
- Vector vecFacing = pPlayer->BodyDirection2D( );
- // no up/down direction
- vecFacing.z = 0;
- VectorNormalize( vecFacing );
- trace_t tr;
- UTIL_TraceLine( vecSrc, vecSrc - Vector(0,0,16), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
- if ( tr.fraction != 1.0 )
- {
- // compute forward vec parallel to floor plane and roll grenade along that
- Vector tangent;
- CrossProduct( vecFacing, tr.plane.normal, tangent );
- CrossProduct( tr.plane.normal, tangent, vecFacing );
- }
- vecSrc += (vecFacing * 18.0);
- CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc );
-
- Vector vecThrow;
- pPlayer->GetVelocity( &vecThrow, NULL );
- vecThrow += vecFacing * 700;
- // put it on its side
- QAngle orientation(0,pPlayer->GetLocalAngles().y,-90);
- // roll it
- AngularImpulse rotSpeed(0,0,720);
- CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, orientation, vecThrow, rotSpeed, pPlayer, GRENADE_TIMER, false );
-
- if ( pGrenade )
- {
- pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
- pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
- }
-
-#endif
-
- WeaponSound( SPECIAL1 );
-
- // player "shoot" animation
- pPlayer->SetAnimation( PLAYER_ATTACK1 );
-
- m_bRedraw = true;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "npcevent.h" +#include "in_buttons.h" + +#ifdef CLIENT_DLL + #include "c_hl2mp_player.h" + #include "c_te_effect_dispatch.h" +#else + #include "hl2mp_player.h" + #include "te_effect_dispatch.h" + #include "grenade_frag.h" +#endif + +#include "weapon_ar2.h" +#include "effect_dispatch_data.h" +#include "weapon_hl2mpbasehlmpcombatweapon.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define GRENADE_TIMER 2.5f //Seconds + +#define GRENADE_PAUSED_NO 0 +#define GRENADE_PAUSED_PRIMARY 1 +#define GRENADE_PAUSED_SECONDARY 2 + +#define GRENADE_RADIUS 4.0f // inches + +#define GRENADE_DAMAGE_RADIUS 250.0f + +#ifdef CLIENT_DLL +#define CWeaponFrag C_WeaponFrag +#endif + +//----------------------------------------------------------------------------- +// Fragmentation grenades +//----------------------------------------------------------------------------- +class CWeaponFrag: public CBaseHL2MPCombatWeapon +{ + DECLARE_CLASS( CWeaponFrag, CBaseHL2MPCombatWeapon ); +public: + + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + + CWeaponFrag(); + + void Precache( void ); + void PrimaryAttack( void ); + void SecondaryAttack( void ); + void DecrementAmmo( CBaseCombatCharacter *pOwner ); + void ItemPostFrame( void ); + + bool Deploy( void ); + bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); + + bool Reload( void ); + +#ifndef CLIENT_DLL + void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); +#endif + + void ThrowGrenade( CBasePlayer *pPlayer ); + bool IsPrimed( bool ) { return ( m_AttackPaused != 0 ); } + +private: + + void RollGrenade( CBasePlayer *pPlayer ); + void LobGrenade( CBasePlayer *pPlayer ); + // check a throw from vecSrc. If not valid, move the position back along the line to vecEye + void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc ); + + CNetworkVar( bool, m_bRedraw ); //Draw the weapon again after throwing a grenade + + CNetworkVar( int, m_AttackPaused ); + CNetworkVar( bool, m_fDrawbackFinished ); + + CWeaponFrag( const CWeaponFrag & ); + +#ifndef CLIENT_DLL + DECLARE_ACTTABLE(); +#endif +}; + +#ifndef CLIENT_DLL + +acttable_t CWeaponFrag::m_acttable[] = +{ + { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, + { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false }, + { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false }, + { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false }, + { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, + { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, + { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false }, +}; + +IMPLEMENT_ACTTABLE(CWeaponFrag); + +#endif + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFrag, DT_WeaponFrag ) + +BEGIN_NETWORK_TABLE( CWeaponFrag, DT_WeaponFrag ) + +#ifdef CLIENT_DLL + RecvPropBool( RECVINFO( m_bRedraw ) ), + RecvPropBool( RECVINFO( m_fDrawbackFinished ) ), + RecvPropInt( RECVINFO( m_AttackPaused ) ), +#else + SendPropBool( SENDINFO( m_bRedraw ) ), + SendPropBool( SENDINFO( m_fDrawbackFinished ) ), + SendPropInt( SENDINFO( m_AttackPaused ) ), +#endif + +END_NETWORK_TABLE() + +#ifdef CLIENT_DLL +BEGIN_PREDICTION_DATA( CWeaponFrag ) + DEFINE_PRED_FIELD( m_bRedraw, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_fDrawbackFinished, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_AttackPaused, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), +END_PREDICTION_DATA() +#endif + +LINK_ENTITY_TO_CLASS( weapon_frag, CWeaponFrag ); +PRECACHE_WEAPON_REGISTER(weapon_frag); + +CWeaponFrag::CWeaponFrag( void ) : + CBaseHL2MPCombatWeapon() +{ + m_bRedraw = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponFrag::Precache( void ) +{ + BaseClass::Precache(); + +#ifndef CLIENT_DLL + UTIL_PrecacheOther( "npc_grenade_frag" ); +#endif + + PrecacheScriptSound( "WeaponFrag.Throw" ); + PrecacheScriptSound( "WeaponFrag.Roll" ); +} + +#ifndef CLIENT_DLL +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pEvent - +// *pOperator - +//----------------------------------------------------------------------------- +void CWeaponFrag::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) +{ + CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); + bool fThrewGrenade = false; + + switch( pEvent->event ) + { + case EVENT_WEAPON_SEQUENCE_FINISHED: + m_fDrawbackFinished = true; + break; + + case EVENT_WEAPON_THROW: + ThrowGrenade( pOwner ); + DecrementAmmo( pOwner ); + fThrewGrenade = true; + break; + + case EVENT_WEAPON_THROW2: + RollGrenade( pOwner ); + DecrementAmmo( pOwner ); + fThrewGrenade = true; + break; + + case EVENT_WEAPON_THROW3: + LobGrenade( pOwner ); + DecrementAmmo( pOwner ); + fThrewGrenade = true; + break; + + default: + BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); + break; + } + +#define RETHROW_DELAY 0.5 + if( fThrewGrenade ) + { + m_flNextPrimaryAttack = gpGlobals->curtime + RETHROW_DELAY; + m_flNextSecondaryAttack = gpGlobals->curtime + RETHROW_DELAY; + m_flTimeWeaponIdle = FLT_MAX; //NOTE: This is set once the animation has finished up! + } +} + +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponFrag::Deploy( void ) +{ + m_bRedraw = false; + m_fDrawbackFinished = false; + + return BaseClass::Deploy(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CWeaponFrag::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + m_bRedraw = false; + m_fDrawbackFinished = false; + + return BaseClass::Holster( pSwitchingTo ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CWeaponFrag::Reload( void ) +{ + if ( !HasPrimaryAmmo() ) + return false; + + if ( ( m_bRedraw ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) ) + { + //Redraw the weapon + SendWeaponAnim( ACT_VM_DRAW ); + + //Update our times + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); + m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); + m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration(); + + //Mark this as done + m_bRedraw = false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponFrag::SecondaryAttack( void ) +{ + if ( m_bRedraw ) + return; + + if ( !HasPrimaryAmmo() ) + return; + + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return; + + CBasePlayer *pPlayer = ToBasePlayer( pOwner ); + + if ( pPlayer == NULL ) + return; + + // Note that this is a secondary attack and prepare the grenade attack to pause. + m_AttackPaused = GRENADE_PAUSED_SECONDARY; + SendWeaponAnim( ACT_VM_PULLBACK_LOW ); + + // Don't let weapon idle interfere in the middle of a throw! + m_flTimeWeaponIdle = FLT_MAX; + m_flNextSecondaryAttack = FLT_MAX; + + // If I'm now out of ammo, switch away + if ( !HasPrimaryAmmo() ) + { + pPlayer->SwitchToNextBestWeapon( this ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponFrag::PrimaryAttack( void ) +{ + if ( m_bRedraw ) + return; + + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + { + return; + } + + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );; + + if ( !pPlayer ) + return; + + // Note that this is a primary attack and prepare the grenade attack to pause. + m_AttackPaused = GRENADE_PAUSED_PRIMARY; + SendWeaponAnim( ACT_VM_PULLBACK_HIGH ); + + // Put both of these off indefinitely. We do not know how long + // the player will hold the grenade. + m_flTimeWeaponIdle = FLT_MAX; + m_flNextPrimaryAttack = FLT_MAX; + + // If I'm now out of ammo, switch away + if ( !HasPrimaryAmmo() ) + { + pPlayer->SwitchToNextBestWeapon( this ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pOwner - +//----------------------------------------------------------------------------- +void CWeaponFrag::DecrementAmmo( CBaseCombatCharacter *pOwner ) +{ + pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponFrag::ItemPostFrame( void ) +{ + if( m_fDrawbackFinished ) + { + CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); + + if (pOwner) + { + switch( m_AttackPaused ) + { + case GRENADE_PAUSED_PRIMARY: + if( !(pOwner->m_nButtons & IN_ATTACK) ) + { + SendWeaponAnim( ACT_VM_THROW ); + m_fDrawbackFinished = false; + } + break; + + case GRENADE_PAUSED_SECONDARY: + if( !(pOwner->m_nButtons & IN_ATTACK2) ) + { + //See if we're ducking + if ( pOwner->m_nButtons & IN_DUCK ) + { + //Send the weapon animation + SendWeaponAnim( ACT_VM_SECONDARYATTACK ); + } + else + { + //Send the weapon animation + SendWeaponAnim( ACT_VM_HAULBACK ); + } + + m_fDrawbackFinished = false; + } + break; + + default: + break; + } + } + } + + BaseClass::ItemPostFrame(); + + if ( m_bRedraw ) + { + if ( IsViewModelSequenceFinished() ) + { + Reload(); + } + } +} + + // check a throw from vecSrc. If not valid, move the position back along the line to vecEye +void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc ) +{ + trace_t tr; + + UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), + pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr ); + + if ( tr.DidHit() ) + { + vecSrc = tr.endpos; + } +} + +void DropPrimedFragGrenade( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade ) +{ + CWeaponFrag *pWeaponFrag = dynamic_cast<CWeaponFrag*>( pGrenade ); + + if ( pWeaponFrag ) + { + pWeaponFrag->ThrowGrenade( pPlayer ); + pWeaponFrag->DecrementAmmo( pPlayer ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +//----------------------------------------------------------------------------- +void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) +{ +#ifndef CLIENT_DLL + Vector vecEye = pPlayer->EyePosition(); + Vector vForward, vRight; + + pPlayer->EyeVectors( &vForward, &vRight, NULL ); + Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; + CheckThrowPosition( pPlayer, vecEye, vecSrc ); +// vForward[0] += 0.1f; + vForward[2] += 0.1f; + + Vector vecThrow; + pPlayer->GetVelocity( &vecThrow, NULL ); + vecThrow += vForward * 1200; + CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false ); + + if ( pGrenade ) + { + if ( pPlayer && pPlayer->m_lifeState != LIFE_ALIVE ) + { + pPlayer->GetVelocity( &vecThrow, NULL ); + + IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject(); + if ( pPhysicsObject ) + { + pPhysicsObject->SetVelocity( &vecThrow, NULL ); + } + } + + pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); + pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); + } +#endif + + m_bRedraw = true; + + WeaponSound( SINGLE ); + + // player "shoot" animation + pPlayer->SetAnimation( PLAYER_ATTACK1 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +//----------------------------------------------------------------------------- +void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer ) +{ +#ifndef CLIENT_DLL + Vector vecEye = pPlayer->EyePosition(); + Vector vForward, vRight; + + pPlayer->EyeVectors( &vForward, &vRight, NULL ); + Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 ); + CheckThrowPosition( pPlayer, vecEye, vecSrc ); + + Vector vecThrow; + pPlayer->GetVelocity( &vecThrow, NULL ); + vecThrow += vForward * 350 + Vector( 0, 0, 50 ); + CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER, false ); + + if ( pGrenade ) + { + pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); + pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); + } +#endif + + WeaponSound( WPN_DOUBLE ); + + // player "shoot" animation + pPlayer->SetAnimation( PLAYER_ATTACK1 ); + + m_bRedraw = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +//----------------------------------------------------------------------------- +void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer ) +{ +#ifndef CLIENT_DLL + // BUGBUG: Hardcoded grenade width of 4 - better not change the model :) + Vector vecSrc; + pPlayer->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecSrc ); + vecSrc.z += GRENADE_RADIUS; + + Vector vecFacing = pPlayer->BodyDirection2D( ); + // no up/down direction + vecFacing.z = 0; + VectorNormalize( vecFacing ); + trace_t tr; + UTIL_TraceLine( vecSrc, vecSrc - Vector(0,0,16), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr ); + if ( tr.fraction != 1.0 ) + { + // compute forward vec parallel to floor plane and roll grenade along that + Vector tangent; + CrossProduct( vecFacing, tr.plane.normal, tangent ); + CrossProduct( tr.plane.normal, tangent, vecFacing ); + } + vecSrc += (vecFacing * 18.0); + CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc ); + + Vector vecThrow; + pPlayer->GetVelocity( &vecThrow, NULL ); + vecThrow += vecFacing * 700; + // put it on its side + QAngle orientation(0,pPlayer->GetLocalAngles().y,-90); + // roll it + AngularImpulse rotSpeed(0,0,720); + CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, orientation, vecThrow, rotSpeed, pPlayer, GRENADE_TIMER, false ); + + if ( pGrenade ) + { + pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); + pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); + } + +#endif + + WeaponSound( SPECIAL1 ); + + // player "shoot" animation + pPlayer->SetAnimation( PLAYER_ATTACK1 ); + + m_bRedraw = true; +} + |