cod5-sdk/raw/maps/hol3_yard.gsc
2008-11-20 00:00:00 +00:00

1270 lines
26 KiB
Text

#include common_scripts\utility;
#include maps\_anim;
#include maps\_utility;
#include maps\pel2_util;
// hol3 yard script
#using_animtree ("generic_human");
main()
{
// triggers in yard event that need to be turned back on
triggers_to_turn_on = getentarray( "yard_ents_to_hide", "script_noteworthy" );
array_thread( triggers_to_turn_on, common_scripts\utility::trigger_on );
level.maddock set_force_color( "y" );
// change one of the yellow redshirts to green
redshirt_y_to_g();
set_color_chain( "chain_yard_advance" );
// wasp behavior
level thread wasp_trigger_moves();
level thread wasp_1_yard_strat();
level thread wasp_2_yard_strat();
//spawn extra friendlies for color reinforcements
simple_spawn( "yard_extras" );
trig = getent( "trig_yard_friendlies", "script_noteworthy" );
trig notify( "trigger" );
yard_action();
}
///////////////////
//
// Put a random yellow redshirt on the green chain
//
///////////////////////////////
redshirt_y_to_g()
{
guys = getaiarray( "allies" );
for( i = 0; i < guys.size; i++ )
{
if( guys[i].script_forceColor == "y" )
{
guys[i] set_force_color( "g" );
break;
}
}
/#
if( i == guys.size )
{
assertmsg( "redshirt_y_to_g() failed!" );
}
#/
}
///////////////////
//
// Set up the action that happens in the yard event
//
///////////////////////////////
yard_action()
{
trigger_wait( "trig_yard_1", "targetname" );
// stop wasp drones
level notify( "end_yard_drones_2" );
simple_spawn( "yard_1_spawners" );
simple_spawn( "yard_1_runners" );
// ignored so wasps have a chance to take care of them
special_guys = simple_spawn( "yard_1_spawners_special" );
array_thread( special_guys, ::set_ignoreme_on );
level thread backyard_1_check();
level thread backyard_2_check();
level thread courtyard_spawn();
level thread yard_runners();
level thread fallback_430();
house_blocker_off( "brush_house_10" );
house_blocker_off( "brush_house_5" );
yard_mghouse();
}
fallback_430()
{
trigger_wait( "trig_fallback_430", "targetname" );
guys = get_ai_group_ai( "courtyard_ai" );
for( i = 0; i < guys.size; i++ )
{
guys[i].script_goalvolume = "";
}
}
///////////////////
//
// Guys that spawn in courtyard on right side of main street
//
///////////////////////////////
courtyard_spawn()
{
// don't spawn dudes if house was set on fire already
level endon( "house_7_burned" );
level thread trig_override( "trig_courtyard_spawn" );
trigger_wait( "trig_courtyard_spawn", "targetname" );
quick_text( "courtyard_spawn", 3, true );
simple_floodspawn( "courtyard_spawners" );
}
///////////////////
//
// ambient: spawners that run from a distance into some buildings, then are killed
//
///////////////////////////////
yard_runners()
{
level endon( "stop_yard_runners" );
// POLISH better trigger to do this off of?
trigger_wait( "auto2810", "target" );
level thread stop_yard_runners();
while( 1 )
{
guys = get_ai_group_ai( "yard_runners_ai" );
if( guys.size < 1 )
{
simple_spawn( "yard_runners", ::yard_runners_strat );
}
wait( RandomIntRange( 5, 9 ) );
}
}
///////////////////
//
// stop yard runners when progressed far enough
//
///////////////////////////////
stop_yard_runners()
{
trigger_wait( "trig_blue_schrek", "targetname" );
level notify( "stop_yard_runners" );
simple_spawn_single( "blue_schrek_spawner", ::blue_schrek_strat );
}
yard_runners_strat()
{
self endon( "death" );
self.ignoresuppression = 1;
self waittill( "goal" );
self delete();
//self dodamage( self.health + 50, ( 0, 0, 0 ) );
}
blue_schrek_strat()
{
self endon( "death" );
self waittill( "goal" );
blue_shutters();
}
///////////////////
//
// Blue shutters pop open
//
///////////////////////////////
blue_shutters()
{
left_shudder = getent( "shutter_blue_l", "targetname" ); right_shudder =
getent( "shutter_blue_r", "targetname" ); left_shudder rotateyaw( -130, 0.6,
0.3, .1 ); right_shudder rotateyaw( 130, 0.7, 0.3, .1 );
}
///////////////////
//
// helps determine when backyard color chain should move up
//
///////////////////////////////
backyard_1_check()
{
// wait till backyard guys are spawned
trigger_wait( "backyard_spawners", "target" );
// wait till some guys get to their nodes
wait( 4 );
// because the chain trig has this flag set on it, the thread should die if it's physically hit
level endon( "chain_backyard_1" );
trig = getent( "chain_backyard_1", "targetname" );
level thread set_flag_on_trigger( trig, "chain_backyard_1" );
while( 1 )
{
guys = getAIarrayTouchingVolume( "axis", "vol_backyard_1" );
if( guys.size < 2 )
{
break;
}
wait( 1 );
}
extra_text( "chain_backyard_1" );
// no axis around backyard, manually trigger color chain to move up guys
trig notify( "trigger" );
// TODO check this! this is in case chain_backyard_1 gets triggered as the wasp is moving to flame this area, but won't entirely
// prevent flames from hitting friendlies if they move up as it's about to fire
wasp_trig = getent( "trig_wasp_2_house_6", "script_noteworthy" );
wasp_trig notify( "trigger" );
}
///////////////////
//
// helps determine when backyard color chain should move up
//
///////////////////////////////
backyard_2_check()
{
// wait till backyard guys are spawned
trigger_wait( "auto2921", "target" );
// wait till some guys get to their nodes
wait( 4 );
// because the chain trig has this flag set on it, the thread should die if it's physically hit
level endon( "chain_backyard_1" );
// lets wasp_2_yard_strat() know whether the wasp should flame this area. if the trigger with this flag has been hit, don't flame.
trig = getent( "chain_backyard_2", "targetname" );
level thread set_flag_on_trigger( trig, "chain_backyard_2" );
// check the amount of axis in the the volume
while( 1 )
{
guys = getAIarrayTouchingVolume( "axis", "vol_backyard_2" );
if( guys.size < 2 )
{
break;
}
wait( 1 );
}
// manually trigger color chain to move up guys
trig notify( "trigger" );
extra_text( "chain_backyard_2" );
// TODO check this! this is in case chain_backyard_2 gets triggered as the wasp is moving to flame this area, but won't entirely
// prevent flames from hitting friendlies if they move up as it's about to fire
wasp_trig = getent( "trig_wasp_2_house_10", "script_noteworthy" );
wasp_trig notify( "trigger" );
}
///////////////////
//
// Wasp 1 strategy
//
///////////////////////////////
wasp_1_yard_strat()
{
level.wasp_1 resumespeed( 5 );
level.wasp_1 veh_stop_at_node( "wasp_1_house_2" );
level thread flame_death_canned( "flame_death_house_2", "node_house_2_fire", "death_balcony_e", undefined, "lookat_house_2", 19, "wasp_1_house_2" );
house_fire( level.wasp_1, "orig_house_2_fire", 14, undefined, "wasp_1_house_2" );
house_blocker_delete( "brush_house_2" );
// wait for flames or flag_override
level.wasp_1 resumespeed( 5 );
level.wasp_1 veh_stop_at_node( "wasp_1_house_5" );
//HOUSE FIRE!!!
//////////////
house_blocker_on( "brush_house_5" );
level thread house_fire_5_deaths();
house_fire( level.wasp_1, "orig_house_5_fire", 14, undefined, "wasp_1_house_5" );
house_blocker_delete( "brush_house_5" );
/////////////////////
level.wasp_1 resumespeed( 5 );
level.wasp_1 veh_stop_at_node( "wasp_1_house_7" );
//flag_wait( "wasp_1_house_5" );
//HOUSE FIRE!!!
//////////////
// manually trigger killspawner cuz the building is on FIRE! (only if it hasn't been hit already)
trig = getent( "trig_killspawner_403", "targetname" );
if( isdefined( trig ) )
{
flag_set( "house_7_burned" );
trig notify( "trigger" );
}
level thread house_fire_7_deaths();
house_fire( level.wasp_1, "orig_house_7_fire", undefined, undefined, "yard_mghouse_active" );
//////////////////////
// wait for mg house to be active
flag_wait( "yard_mghouse_active" );
level.wasp_1 resumespeed( 5 );
level.wasp_1 veh_stop_at_node( "wasp_1_house_4" );
//HOUSE FIRE!!!
//////////////
flag_set( "house_4_flamed" );
// manually trigger killspawner cuz the building is on FIRE!
trig = getent( "trig_killspawner_402", "targetname" );
trig notify( "trigger" );
level thread house_fire_4_deaths();
house_fire( level.wasp_1, "orig_house_4_fire", 12, undefined, "wasp_1_house_4" );
///////////////////////
// wait
flag_wait( "wasp_1_house_4" );
level.wasp_1 resumespeed( 5 );
level.wasp_1 veh_stop_at_node( "wasp_1_house_8" );
house_fire( level.wasp_1, "orig_house_8_fire", 13, undefined, "wasp_1_house_8" );
house_blocker_delete( "brush_house_8" );
// wait
flag_wait( "wasp_1_house_8" );
level.wasp_1 resumespeed( 5 );
level thread maps\hol3_end::wasp_1_square_strat();
}
///////////////////
//
// Wasp 2 strategy
//
///////////////////////////////
wasp_2_yard_strat()
{
level.wasp_2 resumespeed( 5 );
level.wasp_2 veh_stop_at_node( "wasp_2_house_3" );
//HOUSE FIRE!!!
level thread flame_death_canned( "flame_death_house_3", "node_house_3_fire", "death_balcony_d", undefined, "lookat_house_3", undefined, "wasp_2_house_3", true );
house_fire( level.wasp_2, "orig_house_3_fire", undefined, undefined, "wasp_2_house_3" );
house_blocker_delete( "brush_house_3" );
//////////////////
// wait
//flag_wait( "wasp_2_house_3" );
level.wasp_2 resumespeed( 5 );
level.wasp_2 veh_stop_at_node( "wasp_2_house_1" );
//HOUSE FIRE!!!
level thread flame_death_canned( "flame_death_house_1", "node_house_1_fire", "death_balcony_c", undefined, "lookat_house_1", undefined, "wasp_2_house_1" );
house_fire( level.wasp_2, "orig_house_1_fire", 14, undefined, "wasp_2_house_1" );
house_blocker_delete( "brush_house_1" );
////////////////////
// wait for flames or flag_override
level.wasp_2 resumespeed( 5 );
// dont' flame this area if this color chain has been hit!
if( !flag( "chain_backyard_1" ) )
{
level.wasp_2 veh_stop_at_node( "wasp_2_house_6" );
// skip this area if player(s) would get flamed. set house flag so wasp just moves on
vol = getent( "vol_backyard_1", "targetname" );
if( any_player_istouching( vol ) )
{
wasp_trig = getent( "trig_wasp_2_house_6", "script_noteworthy" );
if( isdefined( wasp_trig ) )
{
wasp_trig notify( "trigger" );
}
}
//HOUSE FIRE!!!
house_fire( level.wasp_2, "orig_house_6_fire", 0, 17, "wasp_2_house_6" );
///////////////////////
// wait for flames or flag_override
level.wasp_2 resumespeed( 5 );
}
// dont' flame this area if this color chain has been hit!
if( !flag( "chain_backyard_2" ) )
{
house_blocker_on( "brush_house_10" );
level.wasp_2 veh_stop_at_node( "wasp_2_house_10" );
house_fire( level.wasp_2, "orig_house_10_fire", 12, undefined, "wasp_2_house_10" );
house_blocker_delete( "brush_house_10" );
// wait for flames or flag_override
level.wasp_2 resumespeed( 5 );
}
level.wasp_2 veh_stop_at_node( "wasp_2_house_9" );
level thread house_fire_9_deaths();
house_fire( level.wasp_2, "orig_house_9_fire", undefined, undefined, "wasp_1_house_8" );
house_blocker_delete( "brush_house_9" );
// wait
flag_wait( "wasp_1_house_8" );
level.wasp_2 resumespeed( 5 );
level.wasp_2 veh_stop_at_node( "wasp_2_house_11" );
// wait
flag_wait( "wasp_2_house_11" );
level.wasp_2 resumespeed( 7 );
level thread maps\hol3_end::wasp_2_square_strat();
}
///////////////////
//
// Sets up triggers that tell the wasps when to move
//
///////////////////////////////
wasp_trigger_moves()
{
// WASP 1
/////////
trig = getent( "trig_wasp_1_house_2", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_1_house_2" );
trig = getent( "trig_wasp_1_house_4", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_1_house_4" );
trig = getent( "trig_wasp_1_house_5", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_1_house_5" );
trig = getent( "trig_wasp_1_house_8", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_1_house_8" );
// WASP 2
/////////
trig = getent( "trig_wasp_2_house_1", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_2_house_1" );
trig = getent( "trig_wasp_2_house_3", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_2_house_3" );
trig = getent( "trig_wasp_2_house_6", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_2_house_6" );
trig = getent( "trig_wasp_2_house_10", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_2_house_10" );
trig = getent( "trig_wasp_2_house_11", "script_noteworthy" );
level thread set_flag_on_trigger( trig, "wasp_2_house_11" );
}
///////////////////
//
// Guys on 2nd floor of building with badly-destroyed roof get flamed
//
///////////////////////////////
house_fire_5_deaths()
{
vol = getent( "vol_fire_5", "targetname" );
guys = getAIarrayTouchingVolume( "axis", "vol_fire_5" );
array_thread( guys, ::house_fire_5_deaths_think );
wait( 3.5 );
// now some canned deaths
level thread flame_death_canned( "flame_death_house_5_a", "node_house_5_fire_3", "death_balcony_a" );
level thread flame_death_canned( "flame_death_house_5_b", "node_house_5_fire_1", "death_balcony_d", undefined, undefined, undefined, undefined, true );
}
house_fire_5_deaths_think()
{
self endon( "death" );
if( isdefined( self.script_aigroup ) && self.script_aigroup == "yard_1_ai" )
{
self setcandamage( false );
wait( RandomFloatRange( 1.0, 2.5 ) );
self.animname = "yard";
anim_node = getnode( self.script_noteworthy, "targetname" );
anim_names = [];
anim_names[0] = "death_balcony_a";
anim_names[1] = "death_balcony_b";
anim_names[2] = "death_balcony_e";
playfxontag( level._effect["wasp_guy_fire"], self, "TAG_ORIGIN" );
anim_reach_solo( self, random( anim_names ), undefined, anim_node );
self setcandamage( true );
self take_away_weapon();
anim_single_solo( self, random( anim_names ), undefined, anim_node );
}
}
house_fire_4_deaths()
{
guys = get_ai_group_ai( "yard_mghouse_front_ai" );
array_thread( guys, ::house_fire_4_deaths_think );
}
house_fire_4_deaths_think()
{
self endon( "death" );
self setcandamage( false );
wait( RandomFloatRange( 1.0, 2.5 ) );
self.animname = "yard";
anim_node = getnode( self.script_noteworthy, "targetname" );
anim_names = [];
anim_names[0] = "death_balcony_a";
anim_names[1] = "death_balcony_b";
anim_names[2] = "death_balcony_e";
playfxontag( level._effect["wasp_guy_fire"], self, "TAG_ORIGIN" );
anim_reach_solo( self, random( anim_names ), undefined, anim_node );
self setcandamage( true );
self take_away_weapon();
anim_single_solo( self, random( anim_names ), undefined, anim_node );
}
house_fire_7_deaths()
{
guys = get_ai_group_ai( "house_7_a_ai" );
array_thread( guys, ::house_fire_7_deaths_think );
}
house_fire_7_deaths_think()
{
self endon( "death" );
// make them do flame deaths
self.a.special = "none";
self.a.forceflamedeath = 1;
// so death doesn't get interrupted
self setcandamage( false );
playfxontag( level._effect["wasp_guy_fire"], self, "TAG_ORIGIN" );
wait( RandomIntRange( 2, 4 ) );
self setcandamage( true );
self take_away_weapon();
self dodamage( self.health + 1, (0,0,0) );
}
house_fire_9_deaths()
{
guys = get_ai_group_ai( "yard_mghouse_back_ai" );
array_thread( guys, ::house_fire_9_deaths_think );
}
house_fire_9_deaths_think()
{
self endon( "death" );
// make them do flame deaths
self.a.special = "none";
self.a.forceflamedeath = 1;
// so death doesn't get interrupted
self setcandamage( false );
playfxontag( level._effect["wasp_guy_fire"], self, "TAG_ORIGIN" );
wait( RandomIntRange( 2, 4 ) );
self setcandamage( true );
self take_away_weapon();
self dodamage( self.health + 1, (0,0,0) );
}
///////////////////
//
// Action centered around mghouse in the yard
//
///////////////////////////////
yard_mghouse()
{
trigger_wait( "trig_yard_mghouse_2", "targetname" );
// TODO make sure trig_yard_mghouse_2 isn't possible to hit before trig_mghouse_retreat's targeted trigger
level thread mg_house_retreat();
level thread end_yard_retreat();
simple_floodspawn( "mghouse_2_spawners" );
trigger_wait( "trig_yard_mghouse_3", "targetname" );
// set up town square action
level thread town_square();
simple_floodspawn( "yard_mg_spawners" );
simple_floodspawn( "mghouse_spawners" );
flag_set( "yard_mghouse_active" );
// wait till it's being flamed
flag_wait( "house_4_flamed" );
guys = getAIarrayTouchingVolume( "axis", "vol_mghouse" );
// have them retreat
for( i = 0; i < guys.size; i++ )
{
guys[i] setgoalpos( ( 4547.5, 5957, 242 ) );
guys[i] thread mghouse_retreater_strat();
}
}
///////////////////
//
// Guys that retreat into mghouse
//
///////////////////////////////
mg_house_retreat()
{
level thread trig_override( "trig_mghouse_retreat" );
trigger_wait( "trig_mghouse_retreat", "targetname" );
quick_text( "mghouse_retreat", 3, true );
simple_spawn( "mghouse_retreaters", ::mghouse_retreater_strat );
}
///////////////////
//
// Guys that retreat into townsquare
//
///////////////////////////////
end_yard_retreat()
{
trigger_wait( "trig_end_yard_retreaters", "targetname" );
quick_text( "end_yard_retreat", 3, true );
simple_spawn( "end_yard_retreaters", ::mghouse_retreater_strat );
}
mghouse_retreater_strat()
{
self endon( "death" );
self.goalradius = 30;
self.ignoreall = 1;
self.pacifist = 1;
self.ignoresuppression = 1;
self waittill( "goal" );
self.goalradius = 100;
self.ignoreall = 0;
self.pacifist = 0;
self.ignoresuppression = 0;
}
///////////////////
//
// Moves a script origin back and forth that a Wasp targets
//
///////////////////////////////
wasp_move_target( orig )
{
orig endon( "stop_fakefire_mover" );
targ_1 = orig.origin;
targ_2 = getstruct( orig.target, "targetname" ).origin;
while( 1 )
{
orig MoveTo( targ_2, 4 );
orig waittill( "movedone" );
orig MoveTo( targ_1, 4 );
orig waittill( "movedone" );
}
}
///////////////////
//
// Wasp shoots at an area
//
///////////////////////////////
// max_time_to_fire - the max time that the wasp will fire its turret
// flag_override - if set, the fire loop will break out
// min_time_to_fire - the minimum amount of time the wasp will fire
wasp_shoot_at_ent( wasp, targ_ent, min_time_to_fire, max_time_to_fire, flag_override )
{
wasp endon( "death" );
if( !isdefined( max_time_to_fire ) )
{
max_time_to_fire = 35;
}
if( !isdefined( min_time_to_fire ) )
{
min_time_to_fire = 8;
}
assertex( max_time_to_fire >= min_time_to_fire, "bad min,max times for targ_ent: " + targ_ent.targetname );
// aim at the script_origin target
wasp SetTurretTargetEnt( targ_ent );
wasp waittill_notify_or_timeout( "turret_on_target", 2 );
level thread wasp_move_target( targ_ent );
time_elapsed = 0;
// keep firing until the max_time_to_fire has been satisfied
while( time_elapsed < max_time_to_fire )
{
// break out if flag has been hit
if( isdefined( flag_override ) && flag( flag_override ) )
{
// make sure we've fired for the minimum amount of time
if( time_elapsed >= min_time_to_fire )
{
break;
}
}
// start firing
wasp fireweapon();
// how long the fire burst lasts
burst_time = RandomFloatRange( 2.5, 4 );
wait( burst_time );
time_elapsed += burst_time;
// stop firing
wasp stopfireweapon();
// break out if flag has been hit
if( isdefined( flag_override ) && flag( flag_override ) )
{
// make sure we've fired for the minimum amount of time
if( time_elapsed >= min_time_to_fire )
{
break;
}
}
// how long to let the gun cool down
rest_time = RandomFloatRange( 2, 3 );
wait( rest_time );
time_elapsed += burst_time;
}
wasp ClearTurretTarget();
// stop moving the script_origin target and delete it
targ_ent notify( "stop_fakefire_mover" );
targ_ent delete();
}
///////////////////
//
// Sets a house on fire
//
///////////////////////////////
house_fire( wasp, orig_name, min_time_to_fire, max_time_to_fire, flag_override )
{
wasp endon( "death" );
orig = getent( orig_name, "targetname" );
orig_2 = getstruct( orig_name + "_a", "targetname" );
wasp_shoot_at_ent( wasp, orig, min_time_to_fire, max_time_to_fire, flag_override );
if( isdefined( orig_2 ) )
{
playfx( level._effect["wasp_fire"], orig_2.origin );
playfx( level._effect["wasp_smoke"], orig_2.origin + ( 0, 0, 30 ) );
level thread basic_fire( orig_name + "_a" );
}
}
// OLD
///////////////////
//
// Does damage to guys in a volume
//
///////////////////////////////
//
//house_fire_damage( vol_name )
//{
//
// wait( 1.5 );
//
// guys = getAIarrayTouchingVolume( "axis", vol_name );
//
// for( i = 0; i < guys.size; i++ )
// {
// guys[i] dodamage( guys[i].health + 10, ( 0, 0, 0 ) );
// }
//
//}
///////////////////
//
// FX that persist after Wasp stops flaming them
//
///////////////////////////////
basic_fire( orig_name )
{
orig = getstruct( orig_name, "targetname" );
orig.looper = playLoopedFx( level._effect["wasp_fire"], 1, orig.origin );
wait( 15 );
orig.looper delete();
}
///////////////////
//
// For cutting off the pathing in front of a wasp while it's flaming an area (so ai don't path there)
//
///////////////////////////////
house_blocker_delete( brush_name )
{
blocker = getent( brush_name, "targetname" );
blocker connectpaths();
blocker delete();
}
house_blocker_on( brush_name )
{
blocker = getent( brush_name, "targetname" );
blocker solid();
blocker disconnectpaths();
}
house_blocker_off( brush_name )
{
blocker = getent( brush_name, "targetname" );
blocker notsolid();
blocker connectpaths();
}
// TODO make these bloody deaths? should kill_aigroup automatically do bloody death?
cleanup_yard_ai()
{
kill_aigroup( "yard_1_ai" );
wait( 1 );
kill_aigroup( "yard_1_runner_ai" );
wait( 1 );
kill_aigroup( "yard_annoying" );
}
///////////////////
//
// Play a canned flame death on a guy
//
///////////////////////////////
flame_death_canned( guy_name, node_name, anim_name, start_delay, lookat_name, lookat_timeout, lookat_flag, flame_death_d )
{
// delay before starting anything
if( isdefined( start_delay ) )
{
wait( start_delay );
}
if( !isdefined( flame_death_d ) )
{
flame_death_d = false;
}
// if we want to wait for a lookat
if( isdefined( lookat_name ) )
{
// if we dont specify a timeout setting
if( !isdefined( lookat_timeout ) )
{
lookat_timeout = 7;
}
trigger_or_flag_or_timeout( lookat_name, lookat_flag, lookat_timeout );
}
anim_node = getnode( node_name, "targetname" );
spawner_org = getstartorigin( anim_node.origin, anim_node.angles, level.scr_anim[ "yard" ][ anim_name ] );
spawner_ang = getstartangles( anim_node.origin, anim_node.angles, level.scr_anim[ "yard" ][ anim_name ] );
spawner = getent( guy_name, "targetname" );
spawner.origin = spawner_org;
spawner.angles = spawner_ang;
guy = simple_spawn_single( guy_name );
// he may not have spawned because of ai limit
if( !isdefined( guy ) )
{
return;
}
guy.animname = "yard";
guy setcandamage( false );
//guy.deathanim = level.scr_anim[ "yard" ][ anim_name ];
if( flame_death_d )
{
guy.deathanim = level.scr_anim["yard"]["death_balcony_d"];
}
playfxontag( level._effect["wasp_guy_fire"], guy, "TAG_ORIGIN" );
anim_reach_solo( guy, anim_name, undefined, anim_node );
guy setcandamage( true );
//guy dodamage( guy.health + 1, (0,0,0) );
guy take_away_weapon();
if( flame_death_d )
{
guy dodamage( guy.health + 1, (0,0,0) );
return;
}
anim_single_solo( guy, anim_name, undefined, anim_node );
}
// for use with flame death logic
trigger_or_flag_or_timeout( trig_name, flag_name, time, key )
{
assertex( isdefined( time ), "time needs to be defined!" );
if( !isdefined( key ) )
{
key = "targetname";
}
// dont want trigger_once types involved here...
trig = getent( trig_name, key );
assertex( ( trig.classname == "trigger_multiple" || trig.classname == "trigger_lookat" ), "trigger must be a trigger_multiple or trigger_lookat to use this function!" );
// trigger it if timeout happens
level thread trigger_wait_or_timeout_helper( trig_name, time, key );
// trigger it if flag happens (can't use set_flag_on_trigger if 2 independent flags are involved)
level thread flag_wait_helper( trig_name, flag_name );
trigger_wait( trig_name, key );
}
///////////////////
//
// used with trigger_or_flag_or_timeout()
//
///////////////////////////////
flag_wait_helper( trig_name, flag_name )
{
trig = getent( trig_name, "targetname" );
trig endon( "trigger" );
flag_wait( flag_name );
trig notify( "trigger" );
}
take_away_weapon()
{
self.ignoreall = 1;
self.pacifist = 1;
self.pacifistwait = 0.05;
self.maxsightdistsqrd = 0.0;
// stop any animscript threads
self notify( "killanimscript" );
self notify( "stopShooting" );
// take away his weapon
// self animscripts\shared::placeWeaponOn( self.primaryweapon, "none" );
// self.weapon = "none";
self animscripts\shared::DropAIWeapon();
}
///////////////////
//
// Prepare for town square end event
//
///////////////////////////////
town_square()
{
trigger_wait( "trig_town_square_pre", "targetname" );
level notify( "obj_yard_complete" );
level thread cleanup_yard_ai();
maps\hol3_end::main();
}