mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-20 20:50:58 +02:00
Quake 4 integrated with DoomRTX
This commit is contained in:
@@ -0,0 +1,929 @@
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "../Game_local.h"
|
||||
#include "../Weapon.h"
|
||||
#include "../client/ClientEffect.h"
|
||||
#include "../Projectile.h"
|
||||
|
||||
// Available drum speeds
|
||||
const int NAILGUN_DRUMSPEED_STOPPED = 0;
|
||||
const int NAILGUN_DRUMSPEED_SLOW = 1;
|
||||
const int NAILGUN_DRUMSPEED_FAST = 2;
|
||||
|
||||
// Spinup and spindown times
|
||||
const int NAILGUN_SPINDOWN_TIME = 1000;
|
||||
const int NAILGUN_SPINUP_TIME = 1000;
|
||||
|
||||
// Nailgun shader parms
|
||||
const int NAILGUN_SPARM_PLAYLEADIN = 7;
|
||||
|
||||
// Nailgun weapon modifications
|
||||
const int NAILGUN_MOD_ROF_AMMO = BIT(0); // power mod combines Rate of fire and ammoo
|
||||
const int NAILGUN_MOD_SEEK = BIT(1);
|
||||
//const int NAILGUN_MOD_AMMO = BIT(2);
|
||||
|
||||
const int NAILGUN_SPIN_SNDCHANNEL = SND_CHANNEL_BODY2;
|
||||
|
||||
class rvWeaponNailgun : public rvWeapon {
|
||||
public:
|
||||
|
||||
CLASS_PROTOTYPE( rvWeaponNailgun );
|
||||
|
||||
rvWeaponNailgun ( void );
|
||||
~rvWeaponNailgun ( 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:
|
||||
|
||||
idEntityPtr<idEntity> guideEnt;
|
||||
int guideTime;
|
||||
int guideStartTime;
|
||||
rvClientEntityPtr<rvClientEffect> guideEffect;
|
||||
bool guideLocked;
|
||||
float guideRange;
|
||||
int guideHoldTime;
|
||||
int guideAquireTime;
|
||||
|
||||
jointHandle_t jointDrumView;
|
||||
jointHandle_t jointPinsView;
|
||||
jointHandle_t jointSteamRightView;
|
||||
jointHandle_t jointSteamLeftView;
|
||||
|
||||
jointHandle_t jointGuideEnt;
|
||||
|
||||
int drumSpeed;
|
||||
int drumSpeedIdeal;
|
||||
float drumMultiplier;
|
||||
|
||||
virtual void OnLaunchProjectile ( idProjectile* proj );
|
||||
|
||||
private:
|
||||
|
||||
void UpdateGuideStatus ( float range = 0.0f );
|
||||
void CancelGuide ( void );
|
||||
bool DrumSpin ( int speed, int blendFrames );
|
||||
|
||||
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_Raise ( const stateParms_t& parms );
|
||||
stateResult_t State_Lower ( const stateParms_t& parms );
|
||||
|
||||
stateResult_t State_DrumSpinDown ( const stateParms_t& parms );
|
||||
stateResult_t State_DrumSpinUp ( const stateParms_t& parms );
|
||||
|
||||
stateResult_t Frame_ClaspOpen ( const stateParms_t& parms );
|
||||
stateResult_t Frame_ClaspClose ( const stateParms_t& parms );
|
||||
|
||||
CLASS_STATES_PROTOTYPE ( rvWeaponNailgun );
|
||||
};
|
||||
|
||||
CLASS_DECLARATION( rvWeapon, rvWeaponNailgun )
|
||||
END_CLASS
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::rvWeaponNailgun
|
||||
================
|
||||
*/
|
||||
rvWeaponNailgun::rvWeaponNailgun ( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::~rvWeaponNailgun
|
||||
================
|
||||
*/
|
||||
rvWeaponNailgun::~rvWeaponNailgun ( void ) {
|
||||
if ( guideEffect ) {
|
||||
guideEffect->Stop();
|
||||
}
|
||||
if( viewModel ) {
|
||||
viewModel->StopSound( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Spawn
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::Spawn ( void ) {
|
||||
spawnArgs.GetFloat ( "lockRange", "1000", guideRange );
|
||||
guideHoldTime = SEC2MS ( spawnArgs.GetFloat ( "lockHoldTime", "10" ) );
|
||||
guideAquireTime = SEC2MS ( spawnArgs.GetFloat ( "lockAquireTime", ".1" ) );
|
||||
|
||||
jointDrumView = viewAnimator->GetJointHandle ( spawnArgs.GetString ( "joint_view_drum" ) );
|
||||
jointPinsView = viewAnimator->GetJointHandle ( spawnArgs.GetString ( "joint_view_pins" ) );
|
||||
jointSteamRightView = viewAnimator->GetJointHandle ( spawnArgs.GetString ( "joint_view_steamRight" ) );
|
||||
jointSteamLeftView = viewAnimator->GetJointHandle ( spawnArgs.GetString ( "joint_view_steamLeft" ) );
|
||||
|
||||
jointGuideEnt = INVALID_JOINT;
|
||||
|
||||
drumSpeed = NAILGUN_DRUMSPEED_STOPPED;
|
||||
drumSpeedIdeal = drumSpeed;
|
||||
drumMultiplier = spawnArgs.GetFloat ( "drumSpeed" );
|
||||
|
||||
ExecuteState ( "ClaspClose" );
|
||||
SetState ( "Raise", 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Save
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::Save ( idSaveGame *savefile ) const {
|
||||
guideEnt.Save( savefile );
|
||||
savefile->WriteInt( guideTime );
|
||||
savefile->WriteInt( guideStartTime );
|
||||
guideEffect.Save( savefile );
|
||||
savefile->WriteBool ( guideLocked );
|
||||
savefile->WriteFloat ( guideRange );
|
||||
savefile->WriteInt ( guideHoldTime );
|
||||
savefile->WriteInt ( guideAquireTime );
|
||||
|
||||
savefile->WriteJoint ( jointDrumView );
|
||||
savefile->WriteJoint ( jointPinsView );
|
||||
savefile->WriteJoint ( jointSteamRightView );
|
||||
savefile->WriteJoint ( jointSteamLeftView );
|
||||
savefile->WriteJoint ( jointGuideEnt );
|
||||
|
||||
savefile->WriteInt ( drumSpeed );
|
||||
savefile->WriteInt ( drumSpeedIdeal );
|
||||
savefile->WriteFloat ( drumMultiplier );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Restore
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::Restore ( idRestoreGame *savefile ) {
|
||||
guideEnt.Restore( savefile );
|
||||
savefile->ReadInt( guideTime );
|
||||
savefile->ReadInt( guideStartTime );
|
||||
guideEffect.Restore( savefile );
|
||||
savefile->ReadBool ( guideLocked );
|
||||
savefile->ReadFloat ( guideRange );
|
||||
savefile->ReadInt ( guideHoldTime );
|
||||
savefile->ReadInt ( guideAquireTime );
|
||||
|
||||
savefile->ReadJoint ( jointDrumView );
|
||||
savefile->ReadJoint ( jointPinsView );
|
||||
savefile->ReadJoint ( jointSteamRightView );
|
||||
savefile->ReadJoint ( jointSteamLeftView );
|
||||
savefile->ReadJoint ( jointGuideEnt );
|
||||
|
||||
|
||||
savefile->ReadInt ( drumSpeed );
|
||||
savefile->ReadInt ( drumSpeedIdeal );
|
||||
savefile->ReadFloat ( drumMultiplier );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::PreSave
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::PreSave ( void ) {
|
||||
|
||||
//disable sounds
|
||||
StopSound( SND_CHANNEL_ANY, false);
|
||||
|
||||
//remove the guide gui cursor if there is one.
|
||||
if ( guideEffect ) {
|
||||
guideEffect->Stop();
|
||||
guideEffect->Event_Remove();
|
||||
guideEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::PostSave
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::PostSave ( void ) {
|
||||
|
||||
//restore sounds-- but which one?
|
||||
if( drumSpeed == NAILGUN_DRUMSPEED_FAST ) {
|
||||
viewModel->StartSound ( "snd_spinfast", NAILGUN_SPIN_SNDCHANNEL, 0, false, NULL );
|
||||
} else if( drumSpeed == NAILGUN_DRUMSPEED_SLOW ) {
|
||||
viewModel->StartSound ( "snd_spinslow", NAILGUN_SPIN_SNDCHANNEL, 0, false, NULL );
|
||||
}
|
||||
|
||||
//the guide gui effect will restore itself naturally
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::CancelGuide
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::CancelGuide ( void ) {
|
||||
if ( zoomGui && guideEnt ) {
|
||||
zoomGui->HandleNamedEvent ( "lockStop" );
|
||||
}
|
||||
|
||||
guideEnt = NULL;
|
||||
guideLocked = false;
|
||||
jointGuideEnt = INVALID_JOINT;
|
||||
UpdateGuideStatus ( );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::UpdateGuideStatus
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::UpdateGuideStatus ( float range ) {
|
||||
// Update the zoom GUI variables
|
||||
if ( zoomGui ) {
|
||||
float lockStatus;
|
||||
if ( guideEnt ) {
|
||||
if ( guideLocked ) {
|
||||
lockStatus = 1.0f;
|
||||
} else {
|
||||
lockStatus = Min((float)(gameLocal.time - guideStartTime)/(float)guideTime, 1.0f);
|
||||
}
|
||||
} else {
|
||||
lockStatus = 0.0f;
|
||||
}
|
||||
|
||||
if ( owner == gameLocal.GetLocalPlayer( ) ) {
|
||||
zoomGui->SetStateFloat ( "lockStatus", lockStatus );
|
||||
zoomGui->SetStateFloat ( "playerYaw", playerViewAxis.ToAngles().yaw );
|
||||
}
|
||||
|
||||
if ( guideEnt ) {
|
||||
idVec3 diff;
|
||||
diff = guideEnt->GetPhysics()->GetOrigin ( ) - playerViewOrigin;
|
||||
diff.NormalizeFast ( );
|
||||
zoomGui->SetStateFloat ( "lockYaw", idMath::AngleDelta ( diff.ToAngles ( ).yaw, playerViewAxis.ToAngles().yaw ) );
|
||||
zoomGui->SetStateString ( "lockRange", va("%4.2f", range) );
|
||||
zoomGui->SetStateString ( "lockTime", va("%02d", (int)MS2SEC(guideStartTime + guideTime - gameLocal.time) + 1) );
|
||||
}
|
||||
}
|
||||
|
||||
// Update the guide effect
|
||||
if ( guideEnt ) {
|
||||
idVec3 eyePos = static_cast<idActor *>(guideEnt.GetEntity())->GetEyePosition();
|
||||
if( jointGuideEnt == INVALID_JOINT ) {
|
||||
eyePos += guideEnt->GetPhysics()->GetAbsBounds().GetCenter ( );
|
||||
} else {
|
||||
idMat3 jointAxis;
|
||||
idVec3 jointLoc;
|
||||
static_cast<idAnimatedEntity *>(guideEnt.GetEntity())->GetJointWorldTransform( jointGuideEnt, gameLocal.GetTime(),jointLoc,jointAxis );
|
||||
eyePos += jointLoc;
|
||||
}
|
||||
eyePos *= 0.5f;
|
||||
if ( guideEffect ) {
|
||||
guideEffect->SetOrigin ( eyePos );
|
||||
guideEffect->SetAxis ( playerViewAxis.Transpose() );
|
||||
} else {
|
||||
guideEffect = gameLocal.PlayEffect (
|
||||
gameLocal.GetEffect( spawnArgs, guideLocked ? "fx_guide" : "fx_guidestart" ),
|
||||
eyePos, playerViewAxis.Transpose(), true, vec3_origin, false );
|
||||
if ( guideEffect ) {
|
||||
guideEffect->GetRenderEffect()->weaponDepthHackInViewID = owner->entityNumber + 1;
|
||||
guideEffect->GetRenderEffect()->allowSurfaceInViewID = owner->entityNumber + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( guideEffect ) {
|
||||
guideEffect->Stop();
|
||||
guideEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Think
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::Think ( void ) {
|
||||
idEntity* ent;
|
||||
trace_t tr;
|
||||
|
||||
// Let the real weapon think first
|
||||
rvWeapon::Think ( );
|
||||
|
||||
// If no guide range is set then we dont have the mod yet
|
||||
if ( !guideRange ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the zoom button isnt down then dont update the lock
|
||||
if ( !wsfl.zoom || IsReloading ( ) || IsHolstered ( ) ) {
|
||||
CancelGuide ( );
|
||||
return;
|
||||
}
|
||||
|
||||
// Dont update the target if the current target is still alive, unhidden and we have already locked
|
||||
if ( guideEnt && guideEnt->health > 0 && !guideEnt->IsHidden() && guideLocked ) {
|
||||
float range;
|
||||
range = (guideEnt->GetPhysics()->GetOrigin() - playerViewOrigin).LengthFast();
|
||||
if ( range > guideRange || gameLocal.time > guideStartTime + guideTime ) {
|
||||
CancelGuide ( );
|
||||
} else {
|
||||
UpdateGuideStatus ( range );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Cast a ray out to the lock range
|
||||
// RAVEN BEGIN
|
||||
// ddynerman: multiple clip worlds
|
||||
gameLocal.TracePoint( owner, tr,
|
||||
playerViewOrigin,
|
||||
playerViewOrigin + playerViewAxis[0] * guideRange,
|
||||
MASK_SHOT_BOUNDINGBOX, owner );
|
||||
// RAVEN END
|
||||
|
||||
if ( tr.fraction >= 1.0f ) {
|
||||
CancelGuide( );
|
||||
return;
|
||||
}
|
||||
|
||||
ent = gameLocal.entities[tr.c.entityNum];
|
||||
|
||||
//if we're using a target nailable...
|
||||
if( ent->IsType ( rvTarget_Nailable::GetClassType() ) ) {
|
||||
const char* jointName = ent->spawnArgs.GetString("lock_joint");
|
||||
ent = ent->targets[ 0 ].GetEntity();
|
||||
if( !ent) {
|
||||
CancelGuide( );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ent->GetAnimator() ) {
|
||||
jointGuideEnt = ent->GetAnimator()->GetJointHandle( jointName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !ent->IsType ( idActor::GetClassType() ) ) {
|
||||
CancelGuide( );
|
||||
return;
|
||||
}
|
||||
if ( gameLocal.GetLocalPlayer() && static_cast<idActor *>(ent)->team == gameLocal.GetLocalPlayer()->team ) {
|
||||
CancelGuide( );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( guideEnt != ent ) {
|
||||
guideStartTime = gameLocal.time;
|
||||
guideTime = guideAquireTime;
|
||||
guideEnt = ent;
|
||||
if ( zoomGui ) {
|
||||
zoomGui->HandleNamedEvent ( "lockStart" );
|
||||
}
|
||||
} else if ( gameLocal.time > guideStartTime + guideTime ) {
|
||||
// Stop the guide effect since it was just the guide_Start effect
|
||||
if ( guideEffect ) {
|
||||
guideEffect->Stop();
|
||||
guideEffect = NULL;
|
||||
}
|
||||
guideLocked = true;
|
||||
guideTime = guideHoldTime;
|
||||
guideStartTime = gameLocal.time;
|
||||
if ( zoomGui ) {
|
||||
zoomGui->HandleNamedEvent ( "lockAquired" );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateGuideStatus ( (ent->GetPhysics()->GetOrigin() - playerViewOrigin).LengthFast() );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::OnLaunchProjectile
|
||||
================
|
||||
*/
|
||||
void rvWeaponNailgun::OnLaunchProjectile ( idProjectile* proj ) {
|
||||
rvWeapon::OnLaunchProjectile(proj);
|
||||
|
||||
idGuidedProjectile* guided;
|
||||
guided = dynamic_cast<idGuidedProjectile*>(proj);
|
||||
if ( guided ) {
|
||||
guided->GuideTo ( guideEnt, jointGuideEnt );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::DrumSpin
|
||||
|
||||
Set the drum spin speed
|
||||
================
|
||||
*/
|
||||
bool rvWeaponNailgun::DrumSpin ( int speed, int blendFrames ) {
|
||||
// Dont bother if the drum is already spinning at the desired speed
|
||||
if ( drumSpeedIdeal == speed ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
drumSpeedIdeal = speed;
|
||||
|
||||
switch ( speed ) {
|
||||
case NAILGUN_DRUMSPEED_STOPPED:
|
||||
viewModel->StopSound ( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
viewAnimator->SetJointAngularVelocity ( jointDrumView, idAngles(0,0,0), gameLocal.time, 250 );
|
||||
viewAnimator->SetJointAngularVelocity ( jointPinsView, idAngles(0,0,0), gameLocal.time, 250 );
|
||||
|
||||
// Spin the barrel down if we were spinning fast
|
||||
if ( drumSpeed == NAILGUN_DRUMSPEED_FAST ) {
|
||||
PostState ( "DrumSpinDown", blendFrames );
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAILGUN_DRUMSPEED_SLOW:
|
||||
viewAnimator->SetJointAngularVelocity ( jointDrumView, idAngles(0,0,45), gameLocal.time, NAILGUN_SPINDOWN_TIME );
|
||||
viewAnimator->SetJointAngularVelocity ( jointPinsView, idAngles(0,0,-35), gameLocal.time, NAILGUN_SPINDOWN_TIME );
|
||||
viewModel->StopSound ( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
viewModel->StartSound ( "snd_spinslow", NAILGUN_SPIN_SNDCHANNEL, 0, false, NULL );
|
||||
|
||||
// Spin the barrel down if we were spinning fast
|
||||
if ( drumSpeed == NAILGUN_DRUMSPEED_FAST ) {
|
||||
PostState ( "DrumSpinDown", blendFrames );
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAILGUN_DRUMSPEED_FAST:
|
||||
// Start the barrel spinning faster
|
||||
viewAnimator->SetJointAngularVelocity ( jointDrumView, idAngles(0,0,360.0f * drumMultiplier), gameLocal.time, NAILGUN_SPINUP_TIME );
|
||||
viewAnimator->SetJointAngularVelocity ( jointPinsView, idAngles(0,0,-300.0f * drumMultiplier), gameLocal.time, NAILGUN_SPINUP_TIME );
|
||||
|
||||
PostState ( "DrumSpinUp", blendFrames );
|
||||
return true;
|
||||
}
|
||||
|
||||
drumSpeed = drumSpeedIdeal;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
States
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
CLASS_STATES_DECLARATION ( rvWeaponNailgun )
|
||||
STATE ( "Raise", rvWeaponNailgun::State_Raise )
|
||||
STATE ( "Lower", rvWeaponNailgun::State_Lower )
|
||||
STATE ( "Idle", rvWeaponNailgun::State_Idle)
|
||||
STATE ( "Fire", rvWeaponNailgun::State_Fire )
|
||||
STATE ( "Reload", rvWeaponNailgun::State_Reload )
|
||||
STATE ( "DrumSpinDown", rvWeaponNailgun::State_DrumSpinDown )
|
||||
STATE ( "DrumSpinUp", rvWeaponNailgun::State_DrumSpinUp )
|
||||
|
||||
STATE ( "ClaspOpen", rvWeaponNailgun::Frame_ClaspOpen )
|
||||
STATE ( "ClaspClose", rvWeaponNailgun::Frame_ClaspClose )
|
||||
END_CLASS_STATES
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_Raise
|
||||
|
||||
Raise the weapon
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_Raise ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_WAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
// Start the weapon raising
|
||||
case STAGE_INIT:
|
||||
SetStatus ( WP_RISING );
|
||||
PlayAnim( ANIMCHANNEL_LEGS, "raise", 0 );
|
||||
DrumSpin ( NAILGUN_DRUMSPEED_SLOW, 0 );
|
||||
return SRESULT_STAGE ( STAGE_WAIT );
|
||||
|
||||
case STAGE_WAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 4 ) ) {
|
||||
SetState ( "Idle", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_Lower
|
||||
|
||||
Lower the weapon
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_Lower ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_WAIT,
|
||||
STAGE_WAITRAISE
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
// Stop any looping sounds
|
||||
viewModel->StopSound ( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
|
||||
SetStatus ( WP_LOWERING );
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "putaway", parms.blendFrames );
|
||||
return SRESULT_STAGE(STAGE_WAIT);
|
||||
|
||||
case STAGE_WAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 0 ) ) {
|
||||
SetStatus ( WP_HOLSTERED );
|
||||
return SRESULT_STAGE(STAGE_WAITRAISE);
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
|
||||
case STAGE_WAITRAISE:
|
||||
if ( wsfl.raiseWeapon ) {
|
||||
SetState ( "Raise", 0 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_Idle
|
||||
|
||||
Manage the idle state of the weapon
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_Idle( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_WAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
if ( !AmmoInClip ( ) ) {
|
||||
SetStatus ( WP_OUTOFAMMO );
|
||||
} else {
|
||||
SetStatus ( WP_READY );
|
||||
}
|
||||
// Do we need to spin the drum down?
|
||||
if ( DrumSpin ( NAILGUN_DRUMSPEED_SLOW, parms.blendFrames ) ) {
|
||||
PostState ( "Idle", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
PlayCycle( ANIMCHANNEL_LEGS, "idle", parms.blendFrames );
|
||||
return SRESULT_STAGE ( STAGE_WAIT );
|
||||
|
||||
case STAGE_WAIT:
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
if ( !clipSize ) {
|
||||
if ( gameLocal.time > nextAttackTime && wsfl.attack && AmmoAvailable ( ) ) {
|
||||
SetState ( "Fire", 0 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
} else {
|
||||
if ( 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;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_Fire
|
||||
|
||||
Fire the weapon
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_Fire( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_FIRE,
|
||||
STAGE_FIREWAIT,
|
||||
STAGE_DONE,
|
||||
STAGE_SPINEMPTY,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
if ( !wsfl.attack ) {
|
||||
SetState ( "Idle", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( DrumSpin ( NAILGUN_DRUMSPEED_FAST, 2 ) ) {
|
||||
PostState ( "Fire", 2 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
nextAttackTime = gameLocal.time;
|
||||
|
||||
return SRESULT_STAGE ( STAGE_FIRE );
|
||||
|
||||
case STAGE_FIRE:
|
||||
if ( !wsfl.attack || wsfl.reload || wsfl.lowerWeapon || AmmoInClip ( ) <= 0 ) {
|
||||
return SRESULT_STAGE ( STAGE_DONE );
|
||||
}
|
||||
if ( mods & NAILGUN_MOD_ROF_AMMO ) {
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, "fire_fast", 4 );
|
||||
} else {
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, "fire_slow", 4 );
|
||||
}
|
||||
|
||||
if ( wsfl.zoom ) {
|
||||
Attack ( true, 1, spread, 0.0f, 1.0f );
|
||||
nextAttackTime = gameLocal.time + (altFireRate * owner->PowerUpModifier ( PMOD_FIRERATE ));
|
||||
} else {
|
||||
Attack ( false, 1, spread, 0.0f, 1.0f );
|
||||
nextAttackTime = gameLocal.time + (fireRate * owner->PowerUpModifier ( PMOD_FIRERATE ));
|
||||
}
|
||||
|
||||
// Play the exhaust effects
|
||||
viewModel->PlayEffect ( "fx_exhaust", jointSteamRightView, false );
|
||||
viewModel->PlayEffect ( "fx_exhaust", jointSteamLeftView, false );
|
||||
|
||||
viewModel->StartSound ( "snd_fire", SND_CHANNEL_WEAPON, 0, false, NULL );
|
||||
viewModel->StartSound ( "snd_fireStereo", SND_CHANNEL_ITEM, 0, false, NULL );
|
||||
|
||||
return SRESULT_STAGE ( STAGE_FIREWAIT );
|
||||
|
||||
case STAGE_FIREWAIT:
|
||||
if ( !wsfl.attack || wsfl.reload || wsfl.lowerWeapon || AmmoInClip ( ) <= 0 ) {
|
||||
return SRESULT_STAGE ( STAGE_DONE );
|
||||
}
|
||||
if ( gameLocal.time >= nextAttackTime ) {
|
||||
return SRESULT_STAGE ( STAGE_FIRE );
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
|
||||
case STAGE_DONE:
|
||||
if ( clipSize && wsfl.attack && !wsfl.lowerWeapon && !wsfl.reload ) {
|
||||
PlayCycle ( ANIMCHANNEL_LEGS, "spinempty", 4 );
|
||||
return SRESULT_STAGE ( STAGE_SPINEMPTY );
|
||||
}
|
||||
DrumSpin ( NAILGUN_DRUMSPEED_SLOW, 4 );
|
||||
if ( !wsfl.attack && !AmmoInClip() && AmmoAvailable() && AutoReload ( ) && !wsfl.lowerWeapon ) {
|
||||
PostState ( "Reload", 4 );
|
||||
} else {
|
||||
PostState ( "Idle", 4 );
|
||||
}
|
||||
return SRESULT_DONE;
|
||||
|
||||
case STAGE_SPINEMPTY:
|
||||
if ( !wsfl.attack || wsfl.reload || wsfl.lowerWeapon ) {
|
||||
return SRESULT_STAGE ( STAGE_DONE );
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_Reload
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_Reload ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_RELOAD,
|
||||
STAGE_RELOADWAIT,
|
||||
STAGE_RELOADLEFT,
|
||||
STAGE_RELOADLEFTWAIT,
|
||||
STAGE_RELOADRIGHT,
|
||||
STAGE_RELOADRIGHTWAIT,
|
||||
STAGE_RELOADDONE,
|
||||
STAGE_RELOADDONEWAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
if ( DrumSpin ( NAILGUN_DRUMSPEED_STOPPED, parms.blendFrames ) ) {
|
||||
PostState ( "reload", parms.blendFrames );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
|
||||
SetStatus ( WP_RELOAD );
|
||||
|
||||
if ( wsfl.netReload ) {
|
||||
wsfl.netReload = false;
|
||||
} else {
|
||||
NetReload ( );
|
||||
}
|
||||
|
||||
if ( mods & NAILGUN_MOD_ROF_AMMO ) {
|
||||
return SRESULT_STAGE( STAGE_RELOADLEFT );
|
||||
}
|
||||
return SRESULT_STAGE( STAGE_RELOAD );
|
||||
|
||||
case STAGE_RELOAD:
|
||||
PlayAnim( ANIMCHANNEL_LEGS, "reload", parms.blendFrames );
|
||||
return SRESULT_STAGE( STAGE_RELOADWAIT );
|
||||
|
||||
case STAGE_RELOADWAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 4 ) ) {
|
||||
AddToClip( ClipSize ( ) );
|
||||
SetState ( "Idle", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
|
||||
case STAGE_RELOADLEFT:
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "reload_clip1hold", parms.blendFrames );
|
||||
return SRESULT_STAGE ( STAGE_RELOADLEFTWAIT );
|
||||
|
||||
case STAGE_RELOADLEFTWAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 0 ) ) {
|
||||
AddToClip ( ClipSize() / 2 );
|
||||
return SRESULT_STAGE ( STAGE_RELOADRIGHT );
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
|
||||
case STAGE_RELOADRIGHT:
|
||||
if ( wsfl.attack || AmmoInClip() >= ClipSize() || !AmmoAvailable() ) {
|
||||
return SRESULT_STAGE ( STAGE_RELOADDONE );
|
||||
}
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "reload_clip2", 0 );
|
||||
return SRESULT_STAGE ( STAGE_RELOADRIGHTWAIT );
|
||||
|
||||
case STAGE_RELOADRIGHTWAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 4 ) ) {
|
||||
AddToClip( ClipSize() / 2 );
|
||||
SetState ( "Idle", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
|
||||
case STAGE_RELOADDONE:
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "reload_clip1finish", 0 );
|
||||
return SRESULT_STAGE ( STAGE_RELOADDONEWAIT );
|
||||
|
||||
case STAGE_RELOADDONEWAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 4 ) ) {
|
||||
SetState ( "Idle", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_DrumSpinUp
|
||||
|
||||
Spin the drum from a slow speed to a fast speed
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_DrumSpinUp ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_WAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
viewModel->StartSound ( "snd_spinup", NAILGUN_SPIN_SNDCHANNEL, 0, false, NULL);
|
||||
PlayAnim ( ANIMCHANNEL_LEGS, "spinup", 4 );
|
||||
return SRESULT_STAGE(STAGE_WAIT);
|
||||
|
||||
case STAGE_WAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 0 ) ) {
|
||||
viewModel->StartSound ( "snd_spinfast", NAILGUN_SPIN_SNDCHANNEL, 0, false, NULL );
|
||||
drumSpeed = drumSpeedIdeal;
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( !wsfl.attack ) {
|
||||
int oldSpeed = drumSpeed;
|
||||
drumSpeed = drumSpeedIdeal;
|
||||
DrumSpin ( oldSpeed, 0 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::State_DrumSpinDown
|
||||
|
||||
Spin the drum down from a faster speed
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::State_DrumSpinDown ( const stateParms_t& parms ) {
|
||||
enum {
|
||||
STAGE_INIT,
|
||||
STAGE_WAIT,
|
||||
};
|
||||
switch ( parms.stage ) {
|
||||
case STAGE_INIT:
|
||||
viewModel->StartSound ( "snd_spindown", SND_CHANNEL_ANY, 0, false, 0 );
|
||||
|
||||
// Spin down animation
|
||||
PlayAnim( ANIMCHANNEL_LEGS, "spindown", parms.blendFrames );
|
||||
return SRESULT_STAGE ( STAGE_WAIT );
|
||||
|
||||
case STAGE_WAIT:
|
||||
if ( AnimDone ( ANIMCHANNEL_LEGS, 4 ) ) {
|
||||
drumSpeed = drumSpeedIdeal;
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.lowerWeapon ) {
|
||||
viewModel->StopSound ( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
SetState ( "Lower", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.attack && AmmoInClip ( ) ) {
|
||||
viewModel->StopSound ( NAILGUN_SPIN_SNDCHANNEL, false );
|
||||
SetState ( "Fire", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
if ( wsfl.netReload || (wsfl.reload && AmmoAvailable() > AmmoInClip() && AmmoInClip() < ClipSize()) ) {
|
||||
SetState ( "Reload", 4 );
|
||||
return SRESULT_DONE;
|
||||
}
|
||||
return SRESULT_WAIT;
|
||||
}
|
||||
return SRESULT_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Frame_ClaspOpen
|
||||
|
||||
Open the clasp that holds in the clips
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::Frame_ClaspOpen ( const stateParms_t& parms ) {
|
||||
PlayAnim ( ANIMCHANNEL_TORSO, "clasp_open", 0 );
|
||||
return SRESULT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
rvWeaponNailgun::Frame_ClaspOpen
|
||||
|
||||
Close the clasp that holds in the clips and make sure to use the
|
||||
correct positioning depending on whether you have one or two clips
|
||||
in the gun.
|
||||
================
|
||||
*/
|
||||
stateResult_t rvWeaponNailgun::Frame_ClaspClose ( const stateParms_t& parms ) {
|
||||
if ( mods & NAILGUN_MOD_ROF_AMMO ) {
|
||||
PlayAnim( ANIMCHANNEL_TORSO, "clasp_2clip", 0 );
|
||||
} else {
|
||||
PlayAnim( ANIMCHANNEL_TORSO, "clasp_1clip", 0 );
|
||||
}
|
||||
return SRESULT_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user