328 lines
7.2 KiB
C++
328 lines
7.2 KiB
C++
|
#include "../../idlib/precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "../Game_local.h"
|
||
|
#include "../Weapon.h"
|
||
|
|
||
|
class rvWeaponMachinegun : public rvWeapon {
|
||
|
public:
|
||
|
|
||
|
CLASS_PROTOTYPE( rvWeaponMachinegun );
|
||
|
|
||
|
rvWeaponMachinegun ( void );
|
||
|
|
||
|
virtual void Spawn ( void );
|
||
|
virtual void Think ( void );
|
||
|
void Save ( idSaveGame *savefile ) const;
|
||
|
void Restore ( idRestoreGame *savefile );
|
||
|
void PreSave ( void );
|
||
|
void PostSave ( void );
|
||
|
|
||
|
protected:
|
||
|
|
||
|
float spreadZoom;
|
||
|
bool fireHeld;
|
||
|
|
||
|
bool UpdateFlashlight ( void );
|
||
|
void Flashlight ( bool on );
|
||
|
|
||
|
private:
|
||
|
|
||
|
stateResult_t State_Idle ( const stateParms_t& parms );
|
||
|
stateResult_t State_Fire ( const stateParms_t& parms );
|
||
|
stateResult_t State_Reload ( const stateParms_t& parms );
|
||
|
stateResult_t State_Flashlight ( const stateParms_t& parms );
|
||
|
|
||
|
CLASS_STATES_PROTOTYPE ( rvWeaponMachinegun );
|
||
|
};
|
||
|
|
||
|
CLASS_DECLARATION( rvWeapon, rvWeaponMachinegun )
|
||
|
END_CLASS
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::rvWeaponMachinegun
|
||
|
================
|
||
|
*/
|
||
|
rvWeaponMachinegun::rvWeaponMachinegun ( void ) {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::Spawn
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::Spawn ( void ) {
|
||
|
spreadZoom = spawnArgs.GetFloat ( "spreadZoom" );
|
||
|
fireHeld = false;
|
||
|
|
||
|
SetState ( "Raise", 0 );
|
||
|
|
||
|
Flashlight ( owner->IsFlashlightOn() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::Save
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::Save ( idSaveGame *savefile ) const {
|
||
|
savefile->WriteFloat ( spreadZoom );
|
||
|
savefile->WriteBool ( fireHeld );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::Restore
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::Restore ( idRestoreGame *savefile ) {
|
||
|
savefile->ReadFloat ( spreadZoom );
|
||
|
savefile->ReadBool ( fireHeld );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::PreSave
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::PreSave ( void ) {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::PostSave
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::PostSave ( void ) {
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::Think
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::Think()
|
||
|
{
|
||
|
rvWeapon::Think();
|
||
|
if ( zoomGui && owner == gameLocal.GetLocalPlayer( ) ) {
|
||
|
zoomGui->SetStateFloat( "playerYaw", playerViewAxis.ToAngles().yaw );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::UpdateFlashlight
|
||
|
================
|
||
|
*/
|
||
|
bool rvWeaponMachinegun::UpdateFlashlight ( void ) {
|
||
|
if ( !wsfl.flashlight ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
SetState ( "Flashlight", 0 );
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::Flashlight
|
||
|
================
|
||
|
*/
|
||
|
void rvWeaponMachinegun::Flashlight ( bool on ) {
|
||
|
owner->Flashlight ( on );
|
||
|
|
||
|
if ( on ) {
|
||
|
viewModel->ShowSurface ( "models/weapons/blaster/flare" );
|
||
|
worldModel->ShowSurface ( "models/weapons/blaster/flare" );
|
||
|
} else {
|
||
|
viewModel->HideSurface ( "models/weapons/blaster/flare" );
|
||
|
worldModel->HideSurface ( "models/weapons/blaster/flare" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
States
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
CLASS_STATES_DECLARATION ( rvWeaponMachinegun )
|
||
|
STATE ( "Idle", rvWeaponMachinegun::State_Idle)
|
||
|
STATE ( "Fire", rvWeaponMachinegun::State_Fire )
|
||
|
STATE ( "Reload", rvWeaponMachinegun::State_Reload )
|
||
|
STATE ( "Flashlight", rvWeaponMachinegun::State_Flashlight )
|
||
|
END_CLASS_STATES
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::State_Idle
|
||
|
================
|
||
|
*/
|
||
|
stateResult_t rvWeaponMachinegun::State_Idle( const stateParms_t& parms ) {
|
||
|
enum {
|
||
|
STAGE_INIT,
|
||
|
STAGE_WAIT,
|
||
|
};
|
||
|
switch ( parms.stage ) {
|
||
|
case STAGE_INIT:
|
||
|
if ( !AmmoAvailable ( ) ) {
|
||
|
SetStatus ( WP_OUTOFAMMO );
|
||
|
} else {
|
||
|
SetStatus ( WP_READY );
|
||
|
}
|
||
|
|
||
|
PlayCycle( ANIMCHANNEL_ALL, "idle", parms.blendFrames );
|
||
|
return SRESULT_STAGE ( STAGE_WAIT );
|
||
|
|
||
|
case STAGE_WAIT:
|
||
|
if ( wsfl.lowerWeapon ) {
|
||
|
SetState ( "Lower", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( UpdateFlashlight ( ) ) {
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
|
||
|
if ( fireHeld && !wsfl.attack ) {
|
||
|
fireHeld = false;
|
||
|
}
|
||
|
if ( !clipSize ) {
|
||
|
if ( !fireHeld && gameLocal.time > nextAttackTime && wsfl.attack && AmmoAvailable ( ) ) {
|
||
|
SetState ( "Fire", 0 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
} else {
|
||
|
if ( !fireHeld && gameLocal.time > nextAttackTime && wsfl.attack && AmmoInClip ( ) ) {
|
||
|
SetState ( "Fire", 0 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( wsfl.attack && AutoReload() && !AmmoInClip ( ) && AmmoAvailable () ) {
|
||
|
SetState ( "Reload", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( wsfl.netReload || (wsfl.reload && AmmoInClip() < ClipSize() && AmmoAvailable()>AmmoInClip()) ) {
|
||
|
SetState ( "Reload", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
}
|
||
|
return SRESULT_WAIT;
|
||
|
}
|
||
|
return SRESULT_ERROR;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::State_Fire
|
||
|
================
|
||
|
*/
|
||
|
stateResult_t rvWeaponMachinegun::State_Fire ( const stateParms_t& parms ) {
|
||
|
enum {
|
||
|
STAGE_INIT,
|
||
|
STAGE_WAIT,
|
||
|
};
|
||
|
switch ( parms.stage ) {
|
||
|
case STAGE_INIT:
|
||
|
if ( wsfl.zoom ) {
|
||
|
nextAttackTime = gameLocal.time + (altFireRate * owner->PowerUpModifier ( PMOD_FIRERATE ));
|
||
|
Attack ( true, 1, spreadZoom, 0, 1.0f );
|
||
|
fireHeld = true;
|
||
|
} else {
|
||
|
nextAttackTime = gameLocal.time + (fireRate * owner->PowerUpModifier ( PMOD_FIRERATE ));
|
||
|
Attack ( false, 1, spread, 0, 1.0f );
|
||
|
}
|
||
|
PlayAnim ( ANIMCHANNEL_ALL, "fire", 0 );
|
||
|
return SRESULT_STAGE ( STAGE_WAIT );
|
||
|
|
||
|
case STAGE_WAIT:
|
||
|
if ( !fireHeld && wsfl.attack && gameLocal.time >= nextAttackTime && AmmoInClip() && !wsfl.lowerWeapon ) {
|
||
|
SetState ( "Fire", 0 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( AnimDone ( ANIMCHANNEL_ALL, 0 ) ) {
|
||
|
SetState ( "Idle", 0 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( UpdateFlashlight ( ) ) {
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
return SRESULT_WAIT;
|
||
|
}
|
||
|
return SRESULT_ERROR;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::State_Reload
|
||
|
================
|
||
|
*/
|
||
|
stateResult_t rvWeaponMachinegun::State_Reload ( const stateParms_t& parms ) {
|
||
|
enum {
|
||
|
STAGE_INIT,
|
||
|
STAGE_WAIT,
|
||
|
};
|
||
|
switch ( parms.stage ) {
|
||
|
case STAGE_INIT:
|
||
|
if ( wsfl.netReload ) {
|
||
|
wsfl.netReload = false;
|
||
|
} else {
|
||
|
NetReload ( );
|
||
|
}
|
||
|
|
||
|
SetStatus ( WP_RELOAD );
|
||
|
PlayAnim ( ANIMCHANNEL_ALL, "reload", parms.blendFrames );
|
||
|
return SRESULT_STAGE ( STAGE_WAIT );
|
||
|
|
||
|
case STAGE_WAIT:
|
||
|
if ( AnimDone ( ANIMCHANNEL_ALL, 4 ) ) {
|
||
|
AddToClip ( ClipSize() );
|
||
|
SetState ( "Idle", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
if ( wsfl.lowerWeapon ) {
|
||
|
SetState ( "Lower", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
return SRESULT_WAIT;
|
||
|
}
|
||
|
return SRESULT_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
rvWeaponMachinegun::State_Flashlight
|
||
|
================
|
||
|
*/
|
||
|
stateResult_t rvWeaponMachinegun::State_Flashlight ( const stateParms_t& parms ) {
|
||
|
enum {
|
||
|
FLASHLIGHT_INIT,
|
||
|
FLASHLIGHT_WAIT,
|
||
|
};
|
||
|
switch ( parms.stage ) {
|
||
|
case FLASHLIGHT_INIT:
|
||
|
SetStatus ( WP_FLASHLIGHT );
|
||
|
// Wait for the flashlight anim to play
|
||
|
PlayAnim( ANIMCHANNEL_ALL, "flashlight", 0 );
|
||
|
return SRESULT_STAGE ( FLASHLIGHT_WAIT );
|
||
|
|
||
|
case FLASHLIGHT_WAIT:
|
||
|
if ( !AnimDone ( ANIMCHANNEL_ALL, 4 ) ) {
|
||
|
return SRESULT_WAIT;
|
||
|
}
|
||
|
|
||
|
if ( owner->IsFlashlightOn() ) {
|
||
|
Flashlight ( false );
|
||
|
} else {
|
||
|
Flashlight ( true );
|
||
|
}
|
||
|
|
||
|
SetState ( "Idle", 4 );
|
||
|
return SRESULT_DONE;
|
||
|
}
|
||
|
return SRESULT_ERROR;
|
||
|
}
|