0
0
Fork 0
mirror of https://github.com/id-Software/DOOM-3-BFG.git synced 2025-03-15 23:21:35 +00:00
doom3-bfg/base/script/d3le-ai_monster_boss_guardian2.script
2022-08-27 13:19:00 +02:00

1062 lines
No EOL
25 KiB
Text

/***********************************************************************
ai_monster_boss_guardian2.script
monster_boss_guardian2
***********************************************************************/
#define GUARDIAN2_PAIN_DELAY 0.25
#define GUARDIAN2_RANGE_ATTACK_RANGE 1024
#define GUARDIAN2_RANGE_ATTACK_DELAY 7
#define GUARDIAN2_CHARGE_ATTACK_RANGE 680
#define GUARDIAN2_NUM_PROJECTILES 12
#define GUARDIAN2_ARTILLERY_PROJECTILES 4
// anim blend times
#define GUARDIAN2_PAIN_TO_IDLE 3
#define GUARDIAN2_PAIN_TO_PAIN 3
#define GUARDIAN2_SIGHT_TO_IDLE 8
#define GUARDIAN2_MELEE_TO_IDLE 12
#define GUARDIAN2_IDLE_TO_PAIN 3
#define GUARDIAN2_IDLE_TO_WALK 12
#define GUARDIAN2_IDLE_TO_CHARGE 12
#define GUARDIAN2_IDLE_TO_MELEE 12
#define GUARDIAN2_IDLE_TO_RANGE 12
#define GUARDIAN2_IDLE_TO_SIGHT 12
#define GUARDIAN2_IDLE_TO_LOST 12
#define GUARDIAN2_WALK_TO_IDLE 12
#define GUARDIAN2_WALK_TO_PAIN 3
#define GUARDIAN2_WALK_TO_CHARGE 8
#define GUARDIAN2_CHARGE_TO_WALK 0
#define GUARDIAN2_CHARGE_TO_IDLE 12
#define GUARDIAN2_CHARGE_TO_PAIN 3
#define GUARDIAN2_LOST_TO_IDLE 10
#define GUARDIAN2_LOST_TO_PAIN 3
#define GUARDIAN2_LOST_TO_WALK 24
#define GUARDIAN2_LOST_TO_CHARGE 24
#define GUARDIAN2_RANGEATTACK_TO_IDLE 4
#define GUARDIAN2_SPAWN_TO_IDLE 4
#define GUARDIAN2_IDLE_TO_SPAWN 4
// object seeker_base : monster_base {
// boolean isAlive() { return !AI_DEAD; }
// void respawnSeeker( entity enemy ) { 0; }
// };
object monster_boss_guardian2_spawner_obj : monster_base {
entity lightning;
entity guardianEnt;
entity light;
entity beam;
entity beam_target;
vector beam_offset;
vector rotation;
vector beam_pain_color;
vector beam_color;
vector lightning_pain_color;
vector lightning_color;
float pain_time;
float inactive_time;
float active_time;
void init();
void destory();
void setGuardian( entity owner );
void update_effects();
void state_Inactive();
void state_Active();
void state_Killed();
};
object monster_boss_guardian2 : monster_base {
float nextAttack;
// seeker_base seeker1;
// seeker_base seeker2;
// seeker_base seeker3;
float sightEnemyTime;
boolean in_melee;
boolean rightfoot;
boolean charge;
float ranged_combat_type;
float canDamageTime;
entity light1;
entity light2;
monster_boss_guardian2_spawner_obj spawner;
void Legs_Sight();
void Legs_Death();
void Legs_Pain();
void Legs_RangeAttack();
void Legs_MeleeAttack();
void Legs_Walk_Melee_Left();
void Legs_Walk_Melee_Right();
void Legs_Walk();
void Legs_Run_Melee_Left();
void Legs_Run_Melee_Right();
void Legs_Charge();
void Legs_Lost();
void Legs_Idle();
void Legs_SpawnSeeker();
void init();
void destory();
// void addSeeker( entity seeker );
void sightEnemy();
// boolean seekersAreDead();
// boolean spawnSeeker();
boolean combat_artillery_strike();
boolean combat_pound_fireball();
void state_Idle();
void state_Killed();
void state_Combat();
void combat_melee();
void combat_range();
void combat_charge();
};
void monster_boss_guardian2_spawner_obj::init() {
active_time = 0;
inactive_time = 0;
pain_time = 0;
beam_offset = getVectorKey( "beam_offset" );
rotation = getVectorKey( "rotate" );
beam_pain_color = getVectorKey( "beam_pain_color" );
beam_color = getVectorKey( "beam_color" );
lightning_pain_color = getVectorKey( "lightning_pain_color" );
lightning_color = getVectorKey( "lightning_color" );
sys.setSpawnArg( "_color", beam_color );
sys.setSpawnArg( "name", getName() + "light" );
sys.setSpawnArg( "light", "1024" );
sys.setSpawnArg( "texture", getKey( "mtr_beam_light_shader" ) );
sys.setSpawnArg( "start_off", "1" );
light = sys.spawn( "light" );
light.setOrigin( getWorldOrigin() );
light.bind( self );
sys.setSpawnArg( "name", getName() + "beam_target" );
beam_target = sys.spawn( "func_beam" );
beam_target.setOrigin( getWorldOrigin() );
beam_target.bind( self );
sys.setSpawnArg( "_color", beam_color );
sys.setSpawnArg( "name", getName() + "beam" );
sys.setSpawnArg( "skin", getKey( "mtr_beam_skin" ) );
sys.setSpawnArg( "target", getName() + "beam_target" );
sys.setSpawnArg( "start_off", "1" );
beam = sys.spawn( "func_beam" );
beam.setOrigin( getWorldOrigin() + beam_offset );
beam.bind( self );
setMoveType( MOVETYPE_STATIC );
setState( "state_Inactive" );
}
void monster_boss_guardian2_spawner_obj::destory() {
light.remove();
beam.remove();
beam_target.remove();
}
void monster_boss_guardian2_spawner_obj::setGuardian( entity owner ) {
vector offset;
guardianEnt = owner;
setOwner( owner );
offset = getVectorKey( "offset" );
setOrigin( guardianEnt.getWorldOrigin() + offset );
sys.setSpawnArg( "name", getName() + "_lightning" );
sys.setSpawnArg( "nopush", "1" );
sys.setSpawnArg( "solid", "0" );
sys.setSpawnArg( "model", getKey( "lightning_model" ) );
lightning = sys.spawn( "func_mover_amodel" );
lightning.setOrigin( guardianEnt.getWorldOrigin() + offset );
bindToJoint( guardianEnt, "origin", false );
lightning.bind( self );
}
void monster_boss_guardian2_spawner_obj::update_effects() {
vector c;
float pain_frac;
float normal_frac;
float hide_frac;
if ( active_time <= inactive_time ) {
hide_frac = ( inactive_time + SPAWNER_FADEOUT - sys.getTime() ) / SPAWNER_FADEOUT;
} else {
hide_frac = ( sys.getTime() - active_time ) / SPAWNER_FADEIN_TIME;
if ( hide_frac > 1 ) {
hide_frac = 1;
}
}
if ( hide_frac < 0 ) {
hide();
beam.hide();
lightning.hide();
return;
}
lightning.show();
show();
beam.show();
lightning.setAngles( rotation * sys.getTime() );
pain_frac = ( pain_time + SPAWNER_PAIN_FADEOUT - sys.getTime() ) / SPAWNER_PAIN_FADEOUT;
if ( pain_frac < 0 ) {
pain_frac = 0;
}
normal_frac = 1 - pain_frac;
pain_frac *= hide_frac;
normal_frac *= hide_frac;
c = beam_pain_color * pain_frac + beam_color * normal_frac;
setColor( c_x, c_y, c_z );
beam.setColor( c_x, c_y, c_z );
light.setColor( c_x, c_y, c_z );
c = lightning_pain_color * pain_frac + lightning_color * normal_frac;
lightning.setColor( c_x, c_y, c_z );
}
void monster_boss_guardian2_spawner_obj::state_Inactive() {
inactive_time = sys.getTime();
while( 1 ) {
update_effects();
waitFrame();
}
}
void monster_boss_guardian2_spawner_obj::state_Active() {
monster_boss_guardian2 guardian;
active_time = sys.getTime();
guardian = guardianEnt;
lightning.show();
show();
light.fadeInLight( 0.5 );
beam.show();
while( 1 ) {
if ( AI_DAMAGE ) {
guardian.AI_PAIN = true;
guardian.startSound( "snd_pain", SND_CHANNEL_VOICE, false );
pain_time = sys.getTime();
AI_DAMAGE = false;
}
update_effects();
waitFrame();
}
}
void monster_boss_guardian2_spawner_obj::state_Killed() {
guardianEnt.setState( "state_Killed" );
remove();
/*
setMoveType( MOVETYPE_STATIC );
inactive_time = sys.getTime();
pain_time = sys.getTime();
update_effects();
while( !isHidden() ) {
update_effects();
waitFrame();
}
stopThinking();
*/
}
/***********************************************************************
animation control
***********************************************************************/
void monster_boss_guardian2::Legs_Sight() {
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "sight" );
while( !animDone( ANIMCHANNEL_LEGS, GUARDIAN2_SIGHT_TO_IDLE ) ) {
waitFrame();
}
finishAction( "sight" );
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_SIGHT_TO_IDLE );
}
void monster_boss_guardian2::Legs_Death() {
// seeker1.kill();
// seeker2.kill();
// seeker3.kill();
playAnim( ANIMCHANNEL_LEGS, "death_ew" );
// never exit
waitUntil( 0 );
}
void monster_boss_guardian2::Legs_Pain() {
float nextpain;
float currenttime;
float damageDelay = sys.random( 2 ) + 3;
canDamageTime = sys.getTime() + damageDelay;
ignoreDamage();
//sys.print( "ignoreDamage()\n" );
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "pain" );
nextpain = sys.getTime() + GUARDIAN2_PAIN_DELAY;
while( !animDone( ANIMCHANNEL_LEGS, GUARDIAN2_PAIN_TO_IDLE ) ) {
if ( AI_PAIN ) {
currenttime = sys.getTime();
if ( currenttime > nextpain ) {
animState( ANIMCHANNEL_LEGS, "Legs_Pain", GUARDIAN2_PAIN_TO_PAIN );
}
}
waitFrame();
}
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_PAIN_TO_IDLE );
}
void monster_boss_guardian2::Legs_RangeAttack() {
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "range_attack" );
while( !animDone( ANIMCHANNEL_LEGS, GUARDIAN2_RANGEATTACK_TO_IDLE ) ) {
preventPain( 1 );
waitFrame();
}
preventPain( 1 );
waitFrame();
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_RANGEATTACK_TO_IDLE );
}
void monster_boss_guardian2::Legs_MeleeAttack() {
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "melee_attack" );
while( !animDone( ANIMCHANNEL_LEGS, GUARDIAN2_MELEE_TO_IDLE ) ) {
preventPain( 1 );
waitFrame();
}
preventPain( 1 );
waitFrame();
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_MELEE_TO_IDLE );
}
void monster_boss_guardian2::Legs_Walk_Melee_Left() {
in_melee = true;
rightfoot = false;
playAnim( ANIMCHANNEL_LEGS, "walk_attack_left" );
while( !animDone( ANIMCHANNEL_LEGS, 0 ) ) {
preventPain( 1 );
waitFrame();
}
preventPain( 1 );
in_melee = false;
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Left", 0 );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Walk", 0 );
}
}
void monster_boss_guardian2::Legs_Walk_Melee_Right() {
in_melee = true;
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "walk_attack_right" );
while( !animDone( ANIMCHANNEL_LEGS, 0 ) ) {
preventPain( 1 );
waitFrame();
}
in_melee = false;
preventPain( 1 );
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Right", 0 );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Walk", 0 );
}
}
void monster_boss_guardian2::Legs_Walk() {
if ( rightfoot ) {
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Right", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "walk_right" );
} else {
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Left", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "walk_left" );
}
eachFrame {
if ( AI_PAIN ) {
animState( ANIMCHANNEL_LEGS, "Legs_Pain", GUARDIAN2_WALK_TO_PAIN );
}
if ( !AI_FORWARD ) {
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_WALK_TO_IDLE );
}
if ( animDone( ANIMCHANNEL_LEGS, 0 ) ) {
if ( charge ) {
animState( ANIMCHANNEL_LEGS, "Legs_Charge", GUARDIAN2_WALK_TO_CHARGE );
}
rightfoot = !rightfoot;
if ( rightfoot ) {
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Right", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "walk_right" );
} else {
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
animState( ANIMCHANNEL_LEGS, "Legs_Walk_Melee_Left", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "walk_left" );
}
}
}
}
void monster_boss_guardian2::Legs_Run_Melee_Left() {
in_melee = true;
rightfoot = false;
attackBegin( "damage_guardian2Charge" );
playAnim( ANIMCHANNEL_LEGS, "run_attack_left" );
while( !animDone( ANIMCHANNEL_LEGS, 0 ) ) {
preventPain( 1 );
waitFrame();
}
attackEnd();
preventPain( 1 );
in_melee = false;
boolean canMelee = testMeleeAttack() && AI_ENEMY_IN_FOV;
if ( canMelee || testAnimAttack( "run_attack_left" ) ) {
animState( ANIMCHANNEL_LEGS, "Legs_Run_Melee_Left", 0 );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Charge", 0 );
}
}
void monster_boss_guardian2::Legs_Run_Melee_Right() {
in_melee = true;
rightfoot = true;
attackBegin( "damage_guardian2Charge" );
playAnim( ANIMCHANNEL_LEGS, "run_attack_right" );
while( !animDone( ANIMCHANNEL_LEGS, 0 ) ) {
preventPain( 1 );
waitFrame();
}
attackEnd();
in_melee = false;
preventPain( 1 );
boolean canMelee = testMeleeAttack() && AI_ENEMY_IN_FOV;
if ( canMelee || testAnimAttack( "run_attack_right" ) ) {
animState( ANIMCHANNEL_LEGS, "Legs_Run_Melee_Right", 0 );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Charge", 0 );
}
}
void monster_boss_guardian2::Legs_Charge() {
boolean canMelee = testMeleeAttack() && AI_ENEMY_IN_FOV;
if ( rightfoot ) {
if ( canMelee || testAnimAttack( "run_attack_right" ) ) {
animState( ANIMCHANNEL_LEGS, "Legs_Run_Melee_Right", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "run_right" );
} else {
if ( canMelee || testAnimAttack( "run_attack_left" ) ) {
animState( ANIMCHANNEL_LEGS, "Legs_Run_Melee_Left", 0 );
}
playAnim( ANIMCHANNEL_LEGS, "run_left" );
}
eachFrame {
if ( AI_PAIN ) {
animState( ANIMCHANNEL_LEGS, "Legs_Pain", GUARDIAN2_CHARGE_TO_PAIN );
}
if ( animDone( ANIMCHANNEL_LEGS, GUARDIAN2_CHARGE_TO_WALK ) ) {
// sys.print( "charge = false in Legs_Charge()\n" );
charge = false;
animState( ANIMCHANNEL_LEGS, "Legs_Walk", GUARDIAN2_CHARGE_TO_WALK );
}
}
}
void monster_boss_guardian2::Legs_Lost() {
rightfoot = true;
idleAnim( ANIMCHANNEL_LEGS, "lost_enemy" );
eachFrame {
if ( AI_PAIN ) {
animState( ANIMCHANNEL_LEGS, "Legs_Pain", GUARDIAN2_LOST_TO_PAIN );
}
if ( AI_FORWARD ) {
if ( charge ) {
animState( ANIMCHANNEL_LEGS, "Legs_Charge", GUARDIAN2_LOST_TO_CHARGE );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Walk", GUARDIAN2_LOST_TO_WALK );
}
}
if ( sightEnemyTime >= sys.getTime() ) {
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_LOST_TO_IDLE );
}
}
}
void monster_boss_guardian2::Legs_Idle() {
idleAnim( ANIMCHANNEL_LEGS, "idle" );
eachFrame {
if ( AI_PAIN ) {
animState( ANIMCHANNEL_LEGS, "Legs_Pain", GUARDIAN2_IDLE_TO_PAIN );
}
if ( AI_FORWARD ) {
if ( charge ) {
animState( ANIMCHANNEL_LEGS, "Legs_Charge", GUARDIAN2_IDLE_TO_CHARGE );
} else {
animState( ANIMCHANNEL_LEGS, "Legs_Walk", GUARDIAN2_IDLE_TO_WALK );
}
}
if ( getEnemy() ) {
if ( sightEnemyTime < sys.getTime() ) {
animState( ANIMCHANNEL_LEGS, "Legs_Lost", GUARDIAN2_IDLE_TO_LOST );
}
}
}
}
void monster_boss_guardian2::Legs_SpawnSeeker() {
rightfoot = true;
playAnim( ANIMCHANNEL_LEGS, "spawn_seeker" );
while( !animDone( ANIMCHANNEL_LEGS, GUARDIAN2_SPAWN_TO_IDLE ) ) {
preventPain( 1 );
waitFrame();
}
animState( ANIMCHANNEL_LEGS, "Legs_Idle", GUARDIAN2_SPAWN_TO_IDLE );
}
/***********************************************************************
AI
***********************************************************************/
/*
=====================
monster_boss_guardian2::init
=====================
*/
void monster_boss_guardian2::init() {
vector color;
ranged_combat_type = 1;
color = getVectorKey( "light_color" );
sys.setSpawnArg( "name", getName() + "_light1" );
light1 = sys.spawn( "light" );
light1.setShader( getKey( "mtr_light_shader" ) );
light1.setRadius( getFloatKey( "light_radius" ) );
light1.bindToJoint( self, "Rhand", true );
light1.setOrigin( getVectorKey( "light_offset_right" ) );
light1.setColor( color_x, color_y, color_z );
sys.setSpawnArg( "name", getName() + "_light2" );
light2 = sys.spawn( "light" );
light2.setShader( getKey( "mtr_light_shader" ) );
light2.setRadius( getFloatKey( "light_radius" ) );
light2.bindToJoint( self, "Lhand", true );
light2.setOrigin( getVectorKey( "light_offset_left" ) );
light2.setColor( color_x, color_y, color_z );
rightfoot = true;
charge = false;
canDamageTime = 1;
setMoveType( MOVETYPE_ANIM );
// ignoreDamage();
sightEnemyTime = -1;
sys.setSpawnArg( "name", getName() + "_spawn" );
spawner = sys.spawn( "monster_boss_guardian2_spawner_obj" );
spawner.setGuardian( self );
animState( ANIMCHANNEL_LEGS, "Legs_Idle", 0 );
setState( "state_Idle" );
}
/*
=====================
monster_boss_guardian2::destory
=====================
*/
void monster_boss_guardian2::destory() {
spawner.remove();
light1.remove();
light2.remove();
}
/*
=====================
monster_boss_guardian2::addSeeker
=====================
*/
// void monster_boss_guardian2::addSeeker( entity seeker ) {
// if ( !seeker1 ) {
// seeker1 = seeker;
// } else if ( !seeker2 ) {
// seeker2 = seeker;
// } else if ( !seeker3 ) {
// seeker3 = seeker;
// } else {
// sys.error( "'" + getName() + "' was targeted by more than 3 seekers" );
// }
// }
/*
=====================
monster_boss_guardian2::sightEnemy
=====================
*/
void monster_boss_guardian2::sightEnemy() {
sightEnemyTime = sys.getTime() + 0.5;
locateEnemy();
// all seeker's now know the location
// seeker1.locateEnemy();
// seeker2.locateEnemy();
// seeker3.locateEnemy();
}
/*
=====================
monster_boss_guardian2::seekersAreDead
=====================
*/
// boolean monster_boss_guardian2::seekersAreDead() {
// if ( seeker1.isAlive() ) {
// return false;
// }
//
// if ( seeker2.isAlive() ) {
// return false;
// }
//
// if ( seeker3.isAlive() ) {
// return false;
// }
//
// return true;
// }
/*
=====================
monster_boss_guardian2::spawnSeeker
=====================
*/
// boolean monster_boss_guardian2::spawnSeeker() {
// entity enemy;
//
// // don't go into lost anim for a bit
// sightEnemyTime = sys.getTime() + 20;
// stopMove();
//
// spawner.setState( "state_Active" );
// sys.wait( 1 );
//
// animState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker", GUARDIAN2_IDLE_TO_SPAWN );
// while( inAnimState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker" ) ) {
// waitFrame();
// }
//
// enemy = getEnemy();
// if ( !( !seeker1 ) && !seeker1.isAlive() ) {
// seeker1.respawnSeeker( enemy );
// }
//
// animState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker", GUARDIAN2_IDLE_TO_SPAWN );
// while( inAnimState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker" ) ) {
// waitFrame();
// }
//
// if ( !( !seeker2 ) && !seeker2.isAlive() ) {
// seeker2.respawnSeeker( enemy );
// }
//
// animState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker", GUARDIAN2_IDLE_TO_SPAWN );
// while( inAnimState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker" ) ) {
// waitFrame();
// }
//
// if ( !( !seeker3 ) && !seeker3.isAlive() ) {
// seeker3.respawnSeeker( enemy );
// }
//
// sys.wait( 0.5 );
// sightEnemyTime = sys.getTime() - 0.1;
// spawner.setState( "state_Inactive" );
// }
/*
=====================
monster_boss_guardian2::state_Idle
=====================
*/
void monster_boss_guardian2::state_Idle() {
if ( getIntKey( "hide" ) ) {
//
// hide until triggered
//
hide();
waitUntil( AI_ACTIVATED );
if ( getIntKey( "hide" ) == 1 ) {
AI_ACTIVATED = false;
clearEnemy();
}
waitUntil( canBecomeSolid() );
show();
// ignoreDamage();
}
wait_for_enemy();
faceEnemy();
// don't go into lost anim for a bit
sightEnemyTime = sys.getTime() + 20;
animState( ANIMCHANNEL_LEGS, "Legs_Sight", GUARDIAN2_IDLE_TO_SIGHT );
waitAction( "sight" );
nextAttack = RandomTime( GUARDIAN2_RANGE_ATTACK_DELAY );
setState( "state_Combat" );
}
/*
=====================
monster_boss_guardian2::state_Killed
=====================
*/
void monster_boss_guardian2::state_Killed() {
activateTargets( $world );
light1.fadeOutLight( 0.5 );
light2.fadeOutLight( 0.5 );
AI_DEAD = true;
stopMove();
animState( ANIMCHANNEL_LEGS, "Legs_Death", 0 );
waitAction( "dead" );
stopThinking();
}
/*
=====================
monster_boss_guardian2::state_Combat
=====================
*/
void monster_boss_guardian2::state_Combat() {
while( 1 ) {
if ( canDamageTime > 0 && canDamageTime < sys.getTime() ) {
allowDamage();
canDamageTime = 0;
}
//sys.print( "state_Combat\n" );
if ( AI_ENEMY_DEAD ) {
enemy_dead();
continue;
}
while( sightEnemyTime < sys.getTime() ) {
//sys.print( "state_Combat : 1\n" );
stopMove();
// if ( seekersAreDead() ) {
// spawnSeeker();
// }
sightEnemyTime = sys.getTime() + 20;
waitFrame();
if ( canDamageTime > 0 && canDamageTime < sys.getTime() ) {
allowDamage();
canDamageTime = 0;
}
}
while( sightEnemyTime >= sys.getTime() ) {
if ( canDamageTime > 0 && canDamageTime < sys.getTime() ) {
allowDamage();
canDamageTime = 0;
}
//sys.print( "state_Combat : 2\n" );
if ( in_melee ) {
waitFrame();
continue;
}
// if ( seekersAreDead() ) {
// spawnSeeker();
// }
sightEnemyTime = sys.getTime() + 20;
//sys.print( "moveToEnemy()\n" );
moveToEnemy();
if ( !inAnimState( ANIMCHANNEL_TORSO, "Legs_Pain" ) ) {
if ( AI_DEST_UNREACHABLE || ( sys.getTime() >= nextAttack ) ) {
if ( enemyRange() < GUARDIAN2_RANGE_ATTACK_RANGE ) {
if ( canHitEnemy() ) {
combat_range();
waitFrame();
continue;
}
}
} else if ( enemyRange() > GUARDIAN2_CHARGE_ATTACK_RANGE ) {
if ( canHitEnemy() ) {
combat_charge();
waitFrame();
continue;
}
}
}
if ( testMeleeAttack() && AI_ENEMY_IN_FOV ) {
combat_melee();
}
waitFrame();
}
}
}
/*
=====================
monster_boss_guardian2::combat_melee
=====================
*/
void monster_boss_guardian2::combat_melee() {
//sys.print( "combat_melee()\n" );
stopMove();
animState( ANIMCHANNEL_LEGS, "Legs_MeleeAttack", GUARDIAN2_IDLE_TO_MELEE );
while( inAnimState( ANIMCHANNEL_LEGS, "Legs_MeleeAttack" ) ) {
waitFrame();
}
}
/*
=====================
monster_boss_guardian2::combat_range
=====================
*/
void monster_boss_guardian2::combat_range() {
//sys.print( "combat_range()\n" );
faceEnemy();
stopMove();
if ( ranged_combat_type > 1 ) {
combat_pound_fireball();
ranged_combat_type--;
} else {
combat_artillery_strike();
ranged_combat_type = sys.random( 3 ) + 1;
}
if ( ranged_combat_type > 1 ) {
nextAttack = sys.getTime() + 1;
} else {
nextAttack = DelayTime( GUARDIAN2_RANGE_ATTACK_DELAY );
}
}
/*
=====================
monster_boss_guardian2::combat_charge
=====================
*/
void monster_boss_guardian2::combat_charge() {
//sys.print( "combat_charge()\n" );
charge = true;
//sys.print( "moveToEnemy()\n" );
moveToEnemy();
//sys.print( "while charge()\n" );
while( charge ) {
waitFrame();
}
//sys.print( "stopMove()\n" );
stopMove();
//sys.print( "combat_charge() ... done\n" );
charge = false;
}
/*
=====================
monster_boss_guardian2::combat_pound_fireball
=====================
*/
boolean monster_boss_guardian2::combat_pound_fireball() {
//sys.print( "combat_pound_fireball()\n" );
animState( ANIMCHANNEL_LEGS, "Legs_RangeAttack", GUARDIAN2_IDLE_TO_RANGE );
while( inAnimState( ANIMCHANNEL_LEGS, "Legs_RangeAttack" ) ) {
waitFrame();
}
}
/*
=====================
monster_boss_guardian2::combat_artillery_strike
=====================
*/
boolean monster_boss_guardian2::combat_artillery_strike() {
//sys.print( "combat_artillery_strike()\n" );
animState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker", GUARDIAN2_IDLE_TO_SPAWN );
while( inAnimState( ANIMCHANNEL_LEGS, "Legs_SpawnSeeker" ) ) {
waitFrame();
}
}
/*
=====================
monster_boss_guardian2::pound_impact
=====================
*/
void monster_boss_guardian2::pound_impact( string joint ) {
//sys.print( "pound_impact()\n" );
string entname;
entity explosion;
float handJoint;
vector org;
handJoint = getJointHandle( joint );
org = getJointPos( handJoint );
sys.radiusDamage( org, self, self, spawner, "damage_guardian2PoundGround", 1.0 );
entname = getKey( "def_poundground" );
explosion = sys.spawn( entname );
explosion.setOrigin( org - '0 0 32');
explosion.setShaderParm( 4, -sys.getTime() );
sys.wait( 0.75 );
explosion.remove();
}
/*
=====================
monster_boss_guardian2::pound_attack
=====================
*/
void monster_boss_guardian2::pound_attack( string joint ) {
//sys.print( "pound_attack()\n" );
float handJoint;
vector org;
vector ang;
float i;
handJoint = getJointHandle( joint );
org = getJointPos( handJoint );
sys.radiusDamage( org, self, self, spawner, "damage_guardian2PoundGround", 1.0 );
ang = getAngles();
for( i = 0; i < GUARDIAN2_NUM_PROJECTILES; i++ ) {
ang_y += 360 / GUARDIAN2_NUM_PROJECTILES;
launchMissile( org, ang );
}
thread pound_impact( joint );
}
/*
=====================
monster_boss_guardian2::pound_attack_left
=====================
*/
void monster_boss_guardian2::pound_attack_left() {
pound_attack( "lhand" );
}
/*
=====================
monster_boss_guardian2::pound_attack_right
=====================
*/
void monster_boss_guardian2::pound_attack_right() {
pound_attack( "rhand" );
}
/*
=====================
monster_boss_guardian2::smash_ground
=====================
*/
void monster_boss_guardian2::smash_ground() {
float handJoint;
vector org1, org2, org;
vector ang;
float i;
thread pound_impact( "lhand" );
thread pound_impact( "rhand" );
handJoint = getJointHandle( "lhand" );
org1 = getJointPos( handJoint );
handJoint = getJointHandle( "rhand" );
org2 = getJointPos( handJoint );
org = ( org1 + org2 ) * 0.5;
ang = getAngles();
for( i = 0; i < GUARDIAN2_NUM_PROJECTILES; i++ ) {
ang_y += 360 / GUARDIAN2_NUM_PROJECTILES;
launchMissile( org, ang );
}
}
/*
=====================
monster_boss_guardian2::artillery_strike
=====================
*/
void monster_boss_guardian2::artillery_strike() {
// float i;
// setHomingMissileGoal();
// for( i = 0; i < GUARDIAN2_ARTILLERY_PROJECTILES; i++ ) {
launchHomingMissile();
wait( 0.25 );
launchHomingMissile();
wait( 0.25 );
launchHomingMissile();
wait( 0.25 );
launchHomingMissile();
wait( 0.25 );
// }
}