summaryrefslogtreecommitdiff
path: root/game/shared/dod/weapon_dodbasegrenade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/dod/weapon_dodbasegrenade.cpp')
-rw-r--r--game/shared/dod/weapon_dodbasegrenade.cpp474
1 files changed, 474 insertions, 0 deletions
diff --git a/game/shared/dod/weapon_dodbasegrenade.cpp b/game/shared/dod/weapon_dodbasegrenade.cpp
new file mode 100644
index 0000000..d04255a
--- /dev/null
+++ b/game/shared/dod/weapon_dodbasegrenade.cpp
@@ -0,0 +1,474 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "weapon_dodbasegrenade.h"
+#include "in_buttons.h"
+#include "dod_gamerules.h"
+
+
+#if defined( CLIENT_DLL )
+ #include "c_dod_player.h"
+#else
+ #include "dod_player.h"
+#endif
+
+extern ConVar dod_bonusround;
+
+IMPLEMENT_NETWORKCLASS_ALIASED( WeaponDODBaseGrenade, DT_WeaponDODBaseGrenade )
+
+BEGIN_NETWORK_TABLE(CWeaponDODBaseGrenade, DT_WeaponDODBaseGrenade)
+#if !defined( CLIENT_DLL )
+ SendPropBool( SENDINFO( m_bPinPulled ) ),
+ SendPropBool( SENDINFO( m_bArmed ) ),
+#else
+ RecvPropBool( RECVINFO( m_bPinPulled ) ),
+ RecvPropBool( RECVINFO( m_bArmed ) ),
+#endif
+END_NETWORK_TABLE()
+
+BEGIN_PREDICTION_DATA( CWeaponDODBaseGrenade )
+END_PREDICTION_DATA()
+
+LINK_ENTITY_TO_CLASS( weapon_basedodgrenade, CWeaponDODBaseGrenade );
+
+acttable_t CWeaponDODBaseGrenade::m_acttable[] =
+{
+ // Move this out to the specific grenades???
+ { ACT_DOD_STAND_AIM, ACT_DOD_STAND_AIM_GREN_FRAG, false },
+ { ACT_DOD_CROUCH_AIM, ACT_DOD_CROUCH_AIM_GREN_FRAG, false },
+ { ACT_DOD_CROUCHWALK_AIM, ACT_DOD_CROUCHWALK_AIM_GREN_FRAG, false },
+ { ACT_DOD_WALK_AIM, ACT_DOD_WALK_AIM_GREN_FRAG, false },
+ { ACT_DOD_RUN_AIM, ACT_DOD_RUN_AIM_GREN_FRAG, false },
+ { ACT_PRONE_IDLE, ACT_DOD_PRONE_AIM_GREN_FRAG, false },
+ { ACT_PRONE_FORWARD, ACT_DOD_PRONEWALK_AIM_GREN_FRAG, false },
+ { ACT_DOD_STAND_IDLE, ACT_DOD_STAND_AIM_GREN_FRAG, false },
+ { ACT_DOD_CROUCH_IDLE, ACT_DOD_CROUCH_AIM_GREN_FRAG, false },
+ { ACT_DOD_CROUCHWALK_IDLE, ACT_DOD_CROUCHWALK_AIM_GREN_FRAG, false },
+ { ACT_DOD_WALK_IDLE, ACT_DOD_WALK_AIM_GREN_FRAG, false },
+ { ACT_DOD_RUN_IDLE, ACT_DOD_RUN_AIM_GREN_FRAG, false },
+ { ACT_SPRINT, ACT_DOD_SPRINT_AIM_GREN_FRAG, false },
+
+ { ACT_RANGE_ATTACK1, ACT_DOD_PRIMARYATTACK_GREN_FRAG, false },
+ { ACT_DOD_PRIMARYATTACK_PRONE, ACT_DOD_PRIMARYATTACK_PRONE_GREN_FRAG, false },
+ { ACT_DOD_PRIMARYATTACK_CROUCH, ACT_DOD_PRIMARYATTACK_CROUCH_GREN_FRAG, false },
+
+ // Hand Signals
+ { ACT_DOD_HS_IDLE, ACT_DOD_HS_IDLE_STICKGRENADE, false },
+ { ACT_DOD_HS_CROUCH, ACT_DOD_HS_CROUCH_STICKGRENADE, false },
+};
+
+IMPLEMENT_ACTTABLE( CWeaponDODBaseGrenade );
+
+CWeaponDODBaseGrenade::CWeaponDODBaseGrenade()
+{
+ m_bRedraw = false;
+ m_bPinPulled = false;
+ SetArmed( false );
+
+ m_iAltFireHint = HINT_USE_PRIME;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CWeaponDODBaseGrenade::CanHolster( void )
+{
+ // can only holster hand grenades when not primed!
+ return ( m_bPinPulled == false && !IsArmed() );
+}
+
+#ifdef CLIENT_DLL
+
+ void CWeaponDODBaseGrenade::PrimaryAttack()
+ {
+ //nothing on the client
+ }
+
+#else
+
+ BEGIN_DATADESC( CWeaponDODBaseGrenade )
+ DEFINE_FIELD( m_bRedraw, FIELD_BOOLEAN ),
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "DetonateTime", InputSetDetonateTime ),
+ END_DATADESC()
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::Precache()
+ {
+ PrecacheScriptSound( "Weapon_Grenade.Throw" );
+
+ // Precache all the grenade minimap icons.
+ PrecacheMaterial( "sprites/minimap_icons/minimap_riflegren_ger" );
+ PrecacheMaterial( "sprites/minimap_icons/minimap_riflegren_us" );
+ PrecacheMaterial( "sprites/minimap_icons/grenade_hltv" );
+ PrecacheMaterial( "sprites/minimap_icons/stick_hltv" );
+ PrecacheMaterial( "sprites/minimap_icons/minimap_smoke_us" );
+ PrecacheMaterial( "sprites/minimap_icons/minimap_smoke_ger" );
+
+ BaseClass::Precache();
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ bool CWeaponDODBaseGrenade::Deploy()
+ {
+ m_bRedraw = false;
+ m_bPinPulled = false;
+
+ return BaseClass::Deploy();
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ // Output : Returns true on success, false on failure.
+ //-----------------------------------------------------------------------------
+ bool CWeaponDODBaseGrenade::Holster( CBaseCombatWeapon *pSwitchingTo )
+ {
+ m_bRedraw = false;
+
+#ifndef CLIENT_DLL
+ // If they attempt to switch weapons before the throw animation is done,
+ // allow it, but kill the weapon if we have to.
+
+ CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
+
+ if( pPlayer && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
+ {
+ pPlayer->Weapon_Drop( this, NULL, NULL );
+ UTIL_Remove(this);
+ }
+#endif
+
+ return BaseClass::Holster( pSwitchingTo );
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ // Output : Returns true on success, false on failure.
+ //-----------------------------------------------------------------------------
+ bool CWeaponDODBaseGrenade::Reload()
+ {
+ if ( ( m_bRedraw ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) )
+ {
+ //Redraw the weapon
+ SendWeaponAnim( GetDrawActivity() );
+
+ //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;
+ }
+
+enum
+{
+ THROW_THROW = 0,
+ THROW_PRIME
+};
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::PrimaryAttack()
+ {
+ if ( IsArmed() ) // live grenade already?
+ {
+ StartThrow( THROW_THROW );
+ }
+ else
+ {
+ StartThrow( THROW_PRIME );
+ }
+ }
+
+ void CWeaponDODBaseGrenade::StartThrow( int throwType )
+ {
+ if( GetPlayerOwner()->GetWaterLevel() > 2 )
+ {
+ PlayEmptySound();
+ m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
+ return;
+ }
+
+ if ( !m_bPinPulled )
+ {
+ m_bPinPulled = true;
+
+ SendWeaponAnim( GetPrimaryAttackActivity() );
+
+ // Can't prime an already primed grenade!
+ if ( !IsArmed() && throwType == THROW_PRIME )
+ {
+ SetArmed( true );
+
+ m_flDetonateTime = gpGlobals->curtime + GetDetonateTimerLength();
+
+ // start the hissing noise
+ }
+
+ m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
+ m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
+ m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::ItemPostFrame()
+ {
+ CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
+ if ( !pPlayer )
+ return;
+
+ CBaseViewModel *pViewModel = pPlayer->GetViewModel( m_nViewModelIndex );
+ if ( !pViewModel )
+ return;
+
+ if( IsArmed() && gpGlobals->curtime > m_flDetonateTime )
+ {
+ //Drop it!
+ DropGrenade();
+ m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
+ m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
+ return;
+ }
+
+ if ( m_bPinPulled &&
+ !(pPlayer->m_nButtons & IN_ATTACK) &&
+ !(pPlayer->m_nButtons & IN_ATTACK2) // If they let go of the fire button, they want to throw the grenade.
+ )
+ {
+ pPlayer->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE );
+
+ ThrowGrenade(false);
+
+ m_bRedraw = true;
+ m_bPinPulled = false;
+ SetArmed( false );
+
+ DecrementAmmo( pPlayer );
+
+ SendWeaponAnim( ACT_VM_THROW );
+ }
+ else
+ {
+ BaseClass::ItemPostFrame();
+
+ if ( m_bRedraw )
+ {
+ if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
+ {
+ pPlayer->Weapon_Drop( this, NULL, NULL );
+ UTIL_Remove(this);
+ }
+ else
+ Reload();
+ }
+ }
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ // Input : *pOwner -
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::DecrementAmmo( CBaseCombatCharacter *pOwner )
+ {
+ pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
+
+ if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
+ {
+ pOwner->Weapon_Drop( this, NULL, NULL );
+ UTIL_Remove(this);
+ }
+ }
+
+ void CWeaponDODBaseGrenade::DropGrenade( void )
+ {
+ CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
+ if ( !pPlayer )
+ return;
+
+ pPlayer->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE );
+
+ bool bThrow = true;
+
+ DODRoundState state = DODGameRules()->State_Get();
+
+ // If the player is holding a nade that is going to explode
+ // and the round is over, not allowing them to throw it
+ // just don't emit a grenade.
+ if ( dod_bonusround.GetBool() )
+ {
+ int team = pPlayer->GetTeamNumber();
+
+ if ( ( team == TEAM_ALLIES && state == STATE_AXIS_WIN ) ||
+ ( team == TEAM_AXIS && state == STATE_ALLIES_WIN ) )
+ {
+ bThrow = false;
+ }
+ }
+
+ if ( bThrow )
+ ThrowGrenade(true);
+
+ m_bRedraw = true;
+ m_bPinPulled = false;
+ SetArmed( false );
+
+ DecrementAmmo( pPlayer );
+
+ SendWeaponAnim( ACT_VM_THROW );
+ }
+
+ ConVar dod_grenadespeed( "dod_grenadespeed", "4.2", FCVAR_CHEAT );
+ ConVar dod_grenademaxspeed( "dod_grenademaxspeed", "1400", FCVAR_CHEAT );
+ ConVar dod_grenademinspeed( "dod_grenademinspeed", "500", FCVAR_CHEAT );
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::ThrowGrenade( bool bDrop )
+ {
+ CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
+ if ( !pPlayer )
+ {
+ Assert( false );
+ return;
+ }
+
+ QAngle angThrow = pPlayer->LocalEyeAngles();
+
+ Vector vForward, vRight, vUp;
+
+ if( angThrow.x > 180 )
+ angThrow.x -= 360;
+
+ if (angThrow.x < 0)
+ angThrow.x = -10 + angThrow.x * ((90 - 10) / 90.0);
+ else
+ angThrow.x = -10 + angThrow.x * ((90 + 10) / 90.0);
+
+ AngleVectors( angThrow, &vForward, &vRight, &vUp );
+
+ Vector eyes = pPlayer->GetAbsOrigin() + pPlayer->GetViewOffset();
+ Vector vecSrc = eyes + vForward * 16;
+
+ // Start with the player's velocity as the grenade vel
+ Vector vecPlayerVel;
+ pPlayer->GetVelocity( &vecPlayerVel, NULL );
+
+ // Get player angles, not eye angles!
+ QAngle angPlayerAngles = pPlayer->GetAbsAngles();
+ Vector vecPlayerForward;
+ AngleVectors( angPlayerAngles, &vecPlayerForward );
+ Vector vecThrow = DotProduct( vecPlayerVel, vecPlayerForward ) * vecPlayerForward;
+
+ if( bDrop )
+ {
+ vecThrow = vForward;
+ }
+ else // we are throwing the grenade
+ {
+ // change the speed depending on the throw angle
+ // straight down is 0%, straight up is 100%, linear between
+ float flSpeed = ( 90 - angThrow.x ) * dod_grenadespeed.GetFloat();
+
+ //Msg( "speed %.f\n", flSpeed );
+
+ flSpeed = clamp( flSpeed, dod_grenademinspeed.GetFloat(), dod_grenademaxspeed.GetFloat() );
+
+ vecThrow += vForward * flSpeed;
+ }
+
+ trace_t tr;
+ UTIL_TraceLine( eyes, vecSrc, MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr );
+
+ // don't go into the ground
+ if( tr.fraction < 1.0 )
+ {
+ vecSrc = tr.endpos;
+ }
+
+ float flTimeLeft;
+
+ if ( IsArmed() )
+ flTimeLeft = MAX( 0, m_flDetonateTime - gpGlobals->curtime );
+ else
+ flTimeLeft = GetDetonateTimerLength();
+
+ EmitGrenade( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, flTimeLeft );
+
+ pPlayer->EmitSound( "Weapon_Grenade.Throw" );
+
+#ifndef CLIENT_DLL
+ IGameEvent * event = gameeventmanager->CreateEvent( "dod_stats_weapon_attack" );
+ if ( event )
+ {
+ event->SetInt( "attacker", pPlayer->GetUserID() );
+ event->SetInt( "weapon", GetStatsWeaponID() );
+
+ gameeventmanager->FireEvent( event );
+ }
+#endif //CLIENT_DLL
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ void CWeaponDODBaseGrenade::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel, AngularImpulse angImpulse, CBasePlayer *pPlayer, float flLifeTime /* = GRENADE_FUSE_LENGTH */ )
+ {
+ Assert( 0 && "CBaseCSGrenade::EmitGrenade should not be called. Make sure to implement this in your subclass!\n" );
+ }
+
+ //-----------------------------------------------------------------------------
+ // Purpose:
+ //-----------------------------------------------------------------------------
+ bool CWeaponDODBaseGrenade::AllowsAutoSwitchFrom( void ) const
+ {
+ return ( m_bPinPulled == false );
+ }
+
+ void CWeaponDODBaseGrenade::InputSetDetonateTime( inputdata_t &inputdata )
+ {
+ SetDetonateTime( inputdata.value.Float() );
+ }
+
+#endif // !CLIENT_DLL
+
+Activity CWeaponDODBaseGrenade::GetIdleActivity( void )
+{
+ if ( IsArmed() )
+ return ACT_VM_IDLE_EMPTY;
+ else
+ return ACT_VM_IDLE;
+}
+
+Activity CWeaponDODBaseGrenade::GetPrimaryAttackActivity( void )
+{
+ if ( IsArmed() )
+ return ACT_VM_PRIMARYATTACK_EMPTY;
+ else
+ return ACT_VM_PULLPIN;
+}
+
+Activity CWeaponDODBaseGrenade::GetDrawActivity( void )
+{
+ if ( IsArmed() )
+ return ACT_VM_DRAW_EMPTY;
+ else
+ return ACT_VM_DRAW;
+}
+