mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-16 16:20:42 +02:00
171 lines
6.5 KiB
C++
171 lines
6.5 KiB
C++
// AI_monster_turret.cpp
|
|
// Native state-machine replacement for ai_monster_turret.script.
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
#include "../Game_local.h"
|
|
|
|
|
|
|
|
rvmMonsterTurret::rvmMonsterTurret() {
|
|
fire = false;
|
|
attack_monsters = false;
|
|
light_is_on = false;
|
|
attackTime = 0.0f;
|
|
nextFireTime = 0.0f;
|
|
shutdownTime = 0.0f;
|
|
light = NULL;
|
|
}
|
|
|
|
void rvmMonsterTurret::Init( idAI* aiOwner ) {
|
|
rvmMonsterBase::Init( aiOwner );
|
|
IgnoreDamage();
|
|
ambush = true;
|
|
attack_monsters = GetFloatKey( "team", "1" ) != 1.0f;
|
|
if ( GetIntKey( "light" ) ) { StartAction( "spawn_light" ); }
|
|
SetAnimState( ANIMCHANNEL_TORSO, "Torso_Idle", 0 );
|
|
SetState( "state_Begin" );
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::RunStateByName( const char* stateName, stateParms_t* parms ) {
|
|
AI_DISPATCH_STATE( "Torso_Death", Torso_Death );
|
|
AI_DISPATCH_STATE( "Torso_Idle", Torso_Idle );
|
|
AI_DISPATCH_STATE( "Torso_Attack", Torso_Attack );
|
|
AI_DISPATCH_STATE( "state_Begin", state_Begin );
|
|
AI_DISPATCH_STATE( "state_Idle", state_Idle );
|
|
AI_DISPATCH_STATE( "state_Disabled", state_Disabled );
|
|
AI_DISPATCH_STATE( "state_Killed", state_Killed );
|
|
AI_DISPATCH_STATE( "state_Combat", state_Combat );
|
|
AI_DISPATCH_STATE( "combat_attack", combat_attack );
|
|
AI_DISPATCH_STATE( "spawn_light", spawn_light );
|
|
AI_DISPATCH_STATE( "light_off", light_off );
|
|
AI_DISPATCH_STATE( "light_on", light_on );
|
|
return rvmMonsterBase::RunStateByName( stateName, parms );
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::Torso_Death( stateParms_t* parms ) {
|
|
FinishAction( "dead" );
|
|
return SRESULT_WAIT;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::Torso_Idle( stateParms_t* parms ) {
|
|
if ( parms->stage == 0 ) { PlayCycle( ANIMCHANNEL_TORSO, "idle" ); parms->stage = 1; }
|
|
if ( fire ) { SetAnimState( ANIMCHANNEL_TORSO, "Torso_Attack", 0 ); return SRESULT_DONE; }
|
|
return SRESULT_WAIT;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::Torso_Attack( stateParms_t* parms ) {
|
|
enum { STAGE_WINDUP, STAGE_FIRE, STAGE_WINDDOWN };
|
|
switch ( parms->stage ) {
|
|
case STAGE_WINDUP:
|
|
PlayCycle( ANIMCHANNEL_TORSO, "idle" );
|
|
StartSoundKey( "snd_windup", SND_CHANNEL_BODY, false );
|
|
attackTime = DelayTime( TURRET_MIN_ATTACK_TIME );
|
|
nextFireTime = Time();
|
|
parms->stage = STAGE_FIRE;
|
|
return SRESULT_WAIT;
|
|
case STAGE_FIRE:
|
|
if ( ( !fire && Time() >= attackTime ) || InfluenceActive() ) {
|
|
StartSoundKey( "snd_winddown", SND_CHANNEL_BODY2, false );
|
|
parms->stage = STAGE_WINDDOWN;
|
|
scratchEndTime = DelayTime( 0.35f );
|
|
return SRESULT_WAIT;
|
|
}
|
|
if ( Time() >= nextFireTime ) {
|
|
StartSoundKey( "snd_fire", SND_CHANNEL_WEAPON, false );
|
|
AttackMissile( "barrel" );
|
|
nextFireTime = DelayTime( TURRET_FIRE_RATE );
|
|
}
|
|
return SRESULT_WAIT;
|
|
case STAGE_WINDDOWN:
|
|
if ( Time() < scratchEndTime ) { return SRESULT_WAIT; }
|
|
FinishAction( "attack" );
|
|
SetAnimState( ANIMCHANNEL_TORSO, "Torso_Idle", 0 );
|
|
return SRESULT_DONE;
|
|
}
|
|
return SRESULT_ERROR;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::spawn_light( stateParms_t* parms ) { return SRESULT_DONE; }
|
|
stateResult_t rvmMonsterTurret::light_off( stateParms_t* parms ) { light_is_on = false; return SRESULT_DONE; }
|
|
stateResult_t rvmMonsterTurret::light_on( stateParms_t* parms ) { light_is_on = true; return SRESULT_DONE; }
|
|
|
|
stateResult_t rvmMonsterTurret::state_Begin( stateParms_t* parms ) {
|
|
SetMoveType( MOVETYPE_STATIC );
|
|
if ( GetIntKey( "trigger" ) ) { SetState( "state_Disabled" ); return SRESULT_DONE; }
|
|
StartAction( "wait_for_enemy" );
|
|
parms->stage = 1;
|
|
return SRESULT_WAIT;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::state_Idle( stateParms_t* parms ) {
|
|
if ( parms->stage == 0 ) { StartSoundKey( "snd_shutdown", SND_CHANNEL_VOICE, false ); StartAction( "light_off" ); StartAction( "wait_for_enemy" ); parms->stage = 1; return SRESULT_WAIT; }
|
|
if ( InAction() ) { return SRESULT_WAIT; }
|
|
SetState( "state_Combat" );
|
|
return SRESULT_DONE;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::state_Disabled( stateParms_t* parms ) {
|
|
enum { STAGE_START, STAGE_TRIGGER };
|
|
switch ( parms->stage ) {
|
|
case STAGE_START:
|
|
StartSoundKey( "snd_shutdown", SND_CHANNEL_VOICE, false );
|
|
LookAtEnemy( 0.0f );
|
|
attackTime = 0.0f;
|
|
fire = false;
|
|
ClearEnemy();
|
|
ClearActivated();
|
|
parms->stage = STAGE_TRIGGER;
|
|
return SRESULT_WAIT;
|
|
case STAGE_TRIGGER:
|
|
if ( !Activated() ) { return SRESULT_WAIT; }
|
|
ClearActivated();
|
|
SetState( "state_Combat" );
|
|
return SRESULT_DONE;
|
|
}
|
|
return SRESULT_ERROR;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::state_Killed( stateParms_t* parms ) {
|
|
StopMove();
|
|
StartAction( "light_off" );
|
|
waitActionName = "dead";
|
|
SetAnimState( ANIMCHANNEL_TORSO, "Torso_Death", 0 );
|
|
StopThinking();
|
|
return SRESULT_WAIT;
|
|
}
|
|
|
|
bool rvmMonsterTurret::checkForEnemy( bool use_fov ) {
|
|
idEntity* enemy = FindEnemy( use_fov );
|
|
if ( !enemy && attack_monsters ) { enemy = FindEnemyAI( use_fov ); }
|
|
if ( !enemy ) { return false; }
|
|
SetEnemy( enemy );
|
|
return true;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::state_Combat( stateParms_t* parms ) {
|
|
if ( parms->stage == 0 ) { StartSoundKey( "snd_wakeup", SND_CHANNEL_VOICE, false ); StartAction( "light_on" ); shutdownTime = DelayTime( TURRET_SHUTDOWN_TIME ); parms->stage = 1; }
|
|
LookAtEnemy( 1.0f );
|
|
if ( EnemyDead() ) { enemy_dead(); return SRESULT_DONE; }
|
|
if ( Activated() ) { SetState( "state_Disabled" ); return SRESULT_DONE; }
|
|
if ( EnemyVisible() ) {
|
|
if ( owner && owner->CanHitEnemyFromJoint( "barrel" ) ) { StartAction( "combat_attack" ); } else { checkForEnemy( false ); }
|
|
shutdownTime = DelayTime( TURRET_SHUTDOWN_TIME );
|
|
return SRESULT_WAIT;
|
|
}
|
|
if ( !checkForEnemy( false ) && Time() >= shutdownTime ) { LookAtEnemy( 0.0f ); ClearEnemy(); SetState( "state_Idle" ); return SRESULT_DONE; }
|
|
return SRESULT_WAIT;
|
|
}
|
|
|
|
stateResult_t rvmMonsterTurret::combat_attack( stateParms_t* parms ) {
|
|
FaceEnemy();
|
|
fire = true;
|
|
if ( !EnemyVisible() || !( owner && owner->CanHitEnemyFromJoint( "barrel" ) ) || InfluenceActive() || Activated() ) {
|
|
fire = false;
|
|
if ( Activated() ) { SetState( "state_Disabled" ); }
|
|
return SRESULT_DONE;
|
|
}
|
|
LookAtEnemy( 1.0f );
|
|
return SRESULT_WAIT;
|
|
}
|