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.
233 lines
5.4 KiB
233 lines
5.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "fx_dod_shared.h" |
|
#include "weapon_riflegrenade.h" |
|
|
|
#ifdef CLIENT_DLL |
|
#include "prediction.h" |
|
#endif |
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponBaseRifleGrenade, DT_WeaponBaseRifleGrenade ) |
|
|
|
BEGIN_NETWORK_TABLE( CWeaponBaseRifleGrenade, DT_WeaponBaseRifleGrenade ) |
|
END_NETWORK_TABLE() |
|
|
|
BEGIN_PREDICTION_DATA( CWeaponBaseRifleGrenade ) |
|
END_PREDICTION_DATA() |
|
|
|
|
|
CWeaponBaseRifleGrenade::CWeaponBaseRifleGrenade() |
|
{ |
|
} |
|
|
|
void CWeaponBaseRifleGrenade::Spawn() |
|
{ |
|
BaseClass::Spawn(); |
|
} |
|
|
|
void CWeaponBaseRifleGrenade::PrimaryAttack( void ) |
|
{ |
|
CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); |
|
|
|
Assert( pPlayer ); |
|
|
|
// Out of ammo? |
|
if ( m_iClip1 <= 0 ) |
|
{ |
|
if (m_bFireOnEmpty) |
|
{ |
|
PlayEmptySound(); |
|
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2; |
|
} |
|
return; |
|
} |
|
|
|
if( pPlayer->GetWaterLevel() > 2 ) |
|
{ |
|
PlayEmptySound(); |
|
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; |
|
return; |
|
} |
|
|
|
// decrement before calling PlayPrimaryAttackAnim, so we can play the empty anim if necessary |
|
m_iClip1--; |
|
|
|
SendWeaponAnim( ACT_VM_PRIMARYATTACK ); |
|
|
|
// player "shoot" animation |
|
pPlayer->SetAnimation( PLAYER_ATTACK1 ); |
|
|
|
#ifdef CLIENT_DLL |
|
if( pPlayer && !pPlayer->IsDormant() ) |
|
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN ); |
|
#else |
|
if( pPlayer ) |
|
pPlayer->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN ); |
|
#endif |
|
|
|
#ifndef CLIENT_DLL |
|
ShootGrenade(); |
|
#endif |
|
|
|
WeaponSound( SINGLE ); |
|
|
|
DoFireEffects(); |
|
|
|
#ifdef CLIENT_DLL |
|
CDODPlayer *p = ToDODPlayer( GetPlayerOwner() ); |
|
|
|
if ( prediction->IsFirstTimePredicted() ) |
|
p->DoRecoil( GetWeaponID(), GetRecoil() ); |
|
#endif |
|
|
|
m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + GetFireDelay(); |
|
m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire; |
|
|
|
#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 |
|
} |
|
|
|
Activity CWeaponBaseRifleGrenade::GetDrawActivity( void ) |
|
{ |
|
return ( (m_iClip1 <= 0 ) ? ACT_VM_DRAW_EMPTY : ACT_VM_DRAW ); |
|
} |
|
|
|
Activity CWeaponBaseRifleGrenade::GetIdleActivity( void ) |
|
{ |
|
return ( (m_iClip1 <= 0 ) ? ACT_VM_IDLE_EMPTY : ACT_VM_IDLE ); |
|
} |
|
|
|
bool CWeaponBaseRifleGrenade::Holster( CBaseCombatWeapon *pSwitchingTo ) |
|
{ |
|
#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 && m_iClip1 <= 0 ) |
|
{ |
|
pPlayer->Weapon_Drop( this, NULL, NULL ); |
|
UTIL_Remove(this); |
|
return true; |
|
} |
|
#endif |
|
|
|
return BaseClass::Holster( pSwitchingTo ); |
|
} |
|
|
|
// weapon idle to destroy weapon if empty |
|
void CWeaponBaseRifleGrenade::WeaponIdle( void ) |
|
{ |
|
#ifndef CLIENT_DLL |
|
CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); |
|
if (pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 && m_iClip1 <= 0) |
|
{ |
|
pPlayer->Weapon_Drop( this, NULL, NULL ); |
|
UTIL_Remove(this); |
|
return; |
|
} |
|
#endif |
|
|
|
BaseClass::WeaponIdle(); |
|
} |
|
|
|
#define DOD_RIFLEGRENADE_SPEED 2000 |
|
extern ConVar dod_grenadegravity; |
|
|
|
#ifndef CLIENT_DLL |
|
|
|
void CWeaponBaseRifleGrenade::ShootGrenade( void ) |
|
{ |
|
CDODPlayer *pPlayer = ToDODPlayer( GetOwner() ); |
|
if ( !pPlayer ) |
|
{ |
|
Assert( false ); |
|
return; |
|
} |
|
|
|
QAngle angThrow = pPlayer->LocalEyeAngles(); |
|
|
|
Vector vForward, vRight, vUp; |
|
AngleVectors( angThrow, &vForward, &vRight, &vUp ); |
|
|
|
Vector eyes = pPlayer->GetAbsOrigin() + pPlayer->GetViewOffset(); |
|
Vector vecSrc = eyes; |
|
Vector vecThrow = vForward * DOD_RIFLEGRENADE_SPEED; |
|
|
|
// raise origin enough so that you can't shoot it straight down through the world |
|
if ( pPlayer->m_Shared.IsProne() ) |
|
{ |
|
vecSrc.z += 16; |
|
} |
|
|
|
SetCollisionGroup( COLLISION_GROUP_WEAPON ); |
|
|
|
QAngle angles; |
|
VectorAngles( -vecThrow, angles ); |
|
|
|
// estimate angular velocity based on initial conditions |
|
// uses a constant ang velocity instead of the derivative of the flight path, oh well. |
|
AngularImpulse angImpulse; |
|
angImpulse.Init(); |
|
|
|
if ( vecThrow.z > 0 ) |
|
angImpulse.y = -angles.x / ( sqrt( (-2 * vecThrow.z) / dod_grenadegravity.GetFloat() )); |
|
else |
|
angImpulse.y = -10; |
|
|
|
EmitGrenade( vecSrc, angles, vecThrow, angImpulse, pPlayer, RIFLEGRENADE_FUSE_LENGTH ); |
|
} |
|
|
|
void CWeaponBaseRifleGrenade::EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel, AngularImpulse angImpulse, CBasePlayer *pPlayer, float flLifeTime ) |
|
{ |
|
Assert( !"Deriving classes should define this" ); |
|
} |
|
|
|
#endif |
|
|
|
bool CWeaponBaseRifleGrenade::CanDeploy( void ) |
|
{ |
|
// does the player own the weapon that fires this grenade? |
|
CBasePlayer *pPlayer = GetPlayerOwner(); |
|
|
|
if ( !pPlayer ) |
|
return false; |
|
|
|
CBaseCombatWeapon *pOwnedWeapon = pPlayer->Weapon_OwnsThisType( GetCompanionWeaponName() ); |
|
|
|
if ( pOwnedWeapon == NULL ) |
|
return false; |
|
|
|
return BaseClass::CanDeploy(); |
|
} |
|
|
|
const char *CWeaponBaseRifleGrenade::GetCompanionWeaponName( void ) |
|
{ |
|
Assert( !"Should not call this version. Inheriting classes must implement." ); |
|
return ""; |
|
} |
|
|
|
float CWeaponBaseRifleGrenade::GetRecoil( void ) |
|
{ |
|
CDODPlayer *p = ToDODPlayer( GetPlayerOwner() ); |
|
|
|
if( p && p->m_Shared.IsInMGDeploy() ) |
|
{ |
|
return 0.0f; |
|
} |
|
|
|
return 10; |
|
} |