// Weapon_pistol.cpp // #pragma hdrstop #include "precompiled.h" #include "../Game_local.h" #define PISTOL_FIRERATE 0.4 #define PISTOL_LOWAMMO 4 #define PISTOL_NUMPROJECTILES 1 // blend times #define PISTOL_IDLE_TO_LOWER 2 #define PISTOL_IDLE_TO_FIRE 1 #define PISTOL_IDLE_TO_RELOAD 3 #define PISTOL_RAISE_TO_IDLE 3 #define PISTOL_FIRE_TO_IDLE 4 #define PISTOL_RELOAD_TO_IDLE 40 /* =============== rvmWeaponPistol::Init =============== */ void rvmWeaponPistol::Init( idWeapon* weapon ) { rvmWeaponObject::Init( weapon ); next_attack = 0; spread = weapon->GetFloat( "spread" ); snd_lowammo = FindSound( "snd_lowammo" ); } /* =============== rvmWeaponPistol::Raise =============== */ stateResult_t rvmWeaponPistol::Raise( stateParms_t* parms ) { enum RisingState { RISING_NOTSET = 0, RISING_WAIT }; switch( parms->stage ) { case RISING_NOTSET: owner->Event_PlayAnim( ANIMCHANNEL_ALL, "raise", false ); parms->stage = RISING_WAIT; return SRESULT_WAIT; case RISING_WAIT: if( owner->Event_AnimDone( ANIMCHANNEL_ALL, PISTOL_RAISE_TO_IDLE ) ) { return SRESULT_DONE; } return SRESULT_WAIT; } return SRESULT_ERROR; } /* =============== rvmWeaponPistol::Lower =============== */ stateResult_t rvmWeaponPistol::Lower( stateParms_t* parms ) { enum LoweringState { LOWERING_NOTSET = 0, LOWERING_WAIT }; switch( parms->stage ) { case LOWERING_NOTSET: owner->Event_PlayAnim( ANIMCHANNEL_ALL, "putaway", false ); parms->stage = LOWERING_WAIT; return SRESULT_WAIT; case LOWERING_WAIT: if( owner->Event_AnimDone( ANIMCHANNEL_ALL, 0 ) ) { SetState( "Holstered" ); return SRESULT_DONE; } return SRESULT_WAIT; } return SRESULT_ERROR; } /* =============== rvmWeaponPistol::Idle =============== */ stateResult_t rvmWeaponPistol::Idle( stateParms_t* parms ) { enum IdleState { IDLE_NOTSET = 0, IDLE_WAIT }; switch( parms->stage ) { case IDLE_NOTSET: owner->Event_WeaponReady(); if( !owner->AmmoInClip() ) { owner->Event_PlayCycle( ANIMCHANNEL_ALL, "idle_empty" ); } else { owner->Event_PlayCycle( ANIMCHANNEL_ALL, "idle" ); } parms->stage = IDLE_WAIT; return SRESULT_WAIT; case IDLE_WAIT: // Do nothing. return SRESULT_DONE; } return SRESULT_ERROR; } /* =============== rvmWeaponPistol::Fire =============== */ stateResult_t rvmWeaponPistol::Fire( stateParms_t* parms ) { int ammoClip = owner->AmmoInClip(); enum FIRE_State { FIRE_NOTSET = 0, FIRE_WAIT }; if( ammoClip == 0 && owner->AmmoAvailable() && owner->AutoReload() && parms->stage == 0 ) { //owner->WeaponState( WP_RELOAD, PISTOL_IDLE_TO_RELOAD ); owner->Reload(); return SRESULT_DONE; } switch( parms->stage ) { case FIRE_NOTSET: next_attack = gameLocal.realClientTime + SEC2MS( PISTOL_FIRERATE ); if( ammoClip == PISTOL_LOWAMMO ) { int length; owner->StartSoundShader( snd_lowammo, SND_CHANNEL_ITEM, 0, false, &length ); } owner->Event_LaunchProjectiles( PISTOL_NUMPROJECTILES, spread, 0, 1, 1 ); owner->Event_PlayAnim( ANIMCHANNEL_ALL, "fire", false ); parms->stage = FIRE_WAIT; return SRESULT_WAIT; case FIRE_WAIT: if( owner->Event_AnimDone( ANIMCHANNEL_ALL, PISTOL_FIRE_TO_IDLE ) ) { return SRESULT_DONE; } return SRESULT_WAIT; } return SRESULT_ERROR; } /* =============== rvmWeaponPistol::Reload =============== */ stateResult_t rvmWeaponPistol::Reload( stateParms_t* parms ) { enum RELOAD_State { RELOAD_NOTSET = 0, RELOAD_WAIT }; switch( parms->stage ) { case RELOAD_NOTSET: owner->Event_PlayAnim( ANIMCHANNEL_ALL, "reload", false ); parms->stage = RELOAD_WAIT; return SRESULT_WAIT; case RELOAD_WAIT: if( owner->Event_AnimDone( ANIMCHANNEL_ALL, 0 ) ) { owner->Event_AddToClip( owner->ClipSize() ); return SRESULT_DONE; } return SRESULT_WAIT; } return SRESULT_ERROR; }