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

2689 lines
No EOL
73 KiB
Text

/*-----------------------------------------------------
OKINAWA 2
scripter: Jeremy Statz, inheriting from Chris Pierro
builder: Christian Easterly, inheriting from Jeff Zaring
-----------------------------------------------------*/
#include common_scripts\utility;
#include maps\_utility;
#include maps\oki2_callbacks;
#include maps\_anim;
#include maps\oki2_util;
#include maps\_music;
main()
{
oki2_init();
flag_init( "opening_screen_dialogue_complete" );
maps\oki2_fx::main();
// type 94 truck destroy needs this
maps\_destructible_type94truck::init();
//_load baby!
maps\_load::main();
//level support scripts
maps\oki2_anim::main();
maps\oki2_amb::main();
maps\_mgturret::init_mg_animent();
maps\_banzai::init();
maps\_tree_snipers::main();
//camera stuff
maps\createcam\oki2_cam::main();
//start ambient packages
level thread maps\oki2_amb::main();
level thread maps\oki2_fx::cliffside_ambient_fire();
// weapon swapping for the flame thrower
level.onPlayerWeaponSwap = maps\_coop_weaponswap::flamethrower_swap;
cleanup_trigger_disable( "e1_cleanup_volume" );
cleanup_trigger_disable( "e2_cleanup_volume" );
cleanup_trigger_disable( "e3_right_cleanup_volume" );
cleanup_trigger_disable( "e3_left_cleanup_volume" );
cleanup_trigger_disable( "e3_rear_cleanup_volume" );
createThreatBiasGroup( "squad" );
createThreatBiasGroup( "players" );
level thread swap_in_flamethrower();
if(NumRemoteClients())
{
if(NumRemoteClients()>1) // 3 or 4 player coop
{
level.max_drones["allies"] = 5;
}
else // 2 player coop
{
level.max_drones["allies"] = 10;
}
}
level waittill("introscreen_complete");
give_players_satchel_charge_and_threatbiasgroup();
level thread oki2_objectives();
}
swap_in_flamethrower()
{
wait_for_first_player();
players = get_players();
players[0] TakeWeapon("thompson_wet");
players[0] GiveWeapon("m2_flamethrower_wet");
players[0] SwitchToWeapon("m2_flamethrower_wet");
}
give_players_satchel_charge_and_threatbiasgroup()
{
players = get_players();
for( i=0; i<players.size; i++ )
{
players[i] GiveWeapon( "satchel_charge_new" );
players[i] SetActionSlot( 3, "weapon", "satchel_charge_new" );
//players[i] SwitchToWeapon( "satchel_charge_new" );
players[i] setweaponammoclip("satchel_charge_new",3);
players[i] thread e2_track_satchel_for_player();
players[i] setThreatBiasGroup( "players" );
//make sure all this stuff is turned on
players[i] setclientDvar("miniscoreboardhide","0");
players[i] setclientDvar("compass","1");
players[i] SetClientDvar( "hud_showStance", "1" );
players[i] SetClientDvar( "ammoCounterHide", "0" );
}
}
////////////////////////////////////////////////////////////
////////////////////INITIALIZATION STUFFS///////////////////
////////////////////////////////////////////////////////////
oki2_init()
{
//starts
add_start("event3_bash",::e3_startpoint_bash, &"STARTS_OKI2_FINALBUNKER_BASH");
add_start("event3",::e3_startpoint, &"STARTS_OKI2_FINALBUNKER");
add_start("event2",::e2_startpoint, &"STARTS_OKI2_CANYON");
add_start("outro",::outro_startpoint, &"STARTS_OKI2_OUTRO");
default_start( ::e1_startpoint );
//vehicle stuff
level.tanks = 0;
maps\_sherman::main( "vehicle_usa_tracked_shermanm4a3_green_w" );
maps\_aircraft::main( "vehicle_usa_aircraft_f4ucorsair", "corsair" );
maps\_model3::main( "artillery_jap_model3" );
// maps\_artillery::main("artillery_jap_47mm", "at47"); // now a static model to save the two dudes who had to man it
maps\_jeep::main( "vehicle_usa_wheeled_jeep", "jeep" );
//maps\_jeep::main( "vehicle_usa_wheeled_gmc_truck","gmc" );
// weapon swapping for the flame thrower
maps\_coop_weaponswap::init();
//callbacks
level thread onFirstPlayerConnect();
level thread onPlayerConnect();
level thread onPlayerDisconnect();
level thread onPlayerSpawned();
level thread onPlayerKilled();
//gun objectives stuff
level.gun1 = getent("gun_1","targetname");
level.gun2 = getent("gun_2","targetname");
//level.gun3 = getent("gun3","targetname");
level.gun4 = getent("gun_4","targetname");
level.gun1_org = level.gun1.origin;
level.gun2_org = level.gun2.origin;
//level.gun3_org = level.gun3.origin;
level.gun4_org = level.gun4.origin;
level.gun1_destroyed = false;
level.gun2_destroyed = false;
//level.gun3_destroyed = false;
level.gun4_destroyed = false;
level.all_guns_destroyed = false;
level.event_1_finished = false;
level.e1_smokethrown = false;
//for cliff gun
level.cliff_intact = getent("cliff_intact","targetname");
level.cliff_destroyed = getent("destroyed_cliff","targetname");
level.cliff_rocks = getentarray("delete_these_rocks","targetname");
//model used
precachestring(&"OKI2_SATCHEL_HINT1");
precachestring(&"OKI2_SATCHEL_HINT2");
precachemodel("peleliu_aerial_rocket");
precachemodel("radio_jap_bro");
precacheitem("satchel_charge_new");
//precachemodel("weapon_ger_panzershreck_rocket");
level.drone_weaponlist_allies[0] = "m1garand_wet";
level.drone_weaponlist_allies[1] = "thompson_wet";
init_drones();
level.earthquake["bunker"]["magnitude"] = 0.185;
level.earthquake["bunker"]["duration"] = 3;
level.earthquake["bunker"]["radius"]= 2048;
setdvar ( "arcademode_score_oki2_bunker", 500 );
setdvar ( "arcademode_score_oki2_radio", 150 );
}
// all the objective changing happens here
oki2_objectives()
{
objective_add( 0, "current", &"OKI2_OBJ_1", (4612,3740,-256) ); // the elbow of the player's route
objective_current(0);
level waittill( "OBJ_1_UPDATEPOS" );
objective_position(0, (620, 700, -192) ); // the bunker itself
level waittill( "OBJ_1_COMPLETE" );
objective_state(0,"done");
objective_add(1,"current",&"OKI2_OBJ_2_3",level.gun1_org); // these are maintained by update_gun_objectives()
objective_additionalposition(1,1,level.gun2_org);
objective_additionalposition(1,2,level.gun4_org);
objective_current(1);
level waittill( "OBJ_2_COMPLETE" );
objective_string_nomessage(1, &"OKI2_OBJ_2");
objective_state(1,"done");
objective_add(2,"current",&"OKI2_OBJ_3", getent("move_to_hill","targetname").origin );
objective_current(2);
level waittill( "OBJ_3_COMPLETE" );
objective_state(2,"done");
objective_add(3,"current",&"OKI2_OBJ_4", (-4866, -4595, 393) ); // bunker location, we'll update that in a sec
objective_current(3);
level waittill( "OBJ_4_UPDATEPOS" ); // means polonsky said to go around and find an entrance, after tank blows
objective_position(3, (-6170, -6168, 332.1) ); // tunnel entrance
level waittill( "OBJ_4_COMPLETE" );
objective_state(3,"done");
objective_add(4,"current",&"OKI2_OBJ_5", (-4866, -4595, 393) ); // last bunker centerpoint
objective_current(4);
level waittill( "OBJ_5_COMPLETE" );
objective_state(4,"done");
}
//setup the friendlies for the first time..
setup_friends()
{
// facial animation
animscripts\face::initLevelFace();
spwns = getentarray("friends","targetname");
for(i=0;i<spwns.size;i++)
{
spwns[i] stalingradspawn();
wait_network_frame();
}
////okiPrint( "Setting friends!" );
friends = get_ai_group_ai("dasquad");//getentarray("friends","targetname");
for(i=0;i<friends.size;i++)
{
if(isDefined(friends[i].script_noteworthy) && friends[i].script_noteworthy == "sarge")
{
level.sarge = friends[i];
level.sarge.animname = "sarge";
//friends[i].name = "Sarge";
friends[i] thread magic_bullet_Shield();
level.sarge animscripts\face::initCharacterFace();
////okiPrint( "Setting level.sarge!" );
}
if(isDefined(friends[i].script_noteworthy) && friends[i].script_noteworthy == "hero1")
{
level.polonsky = friends[i];
level.polonsky.animname = "polonsky";
//level.polonsky.name = "polonsky";
friends[i] thread magic_bullet_Shield();
level.polonsky animscripts\face::initCharacterFace();
////okiPrint( "Setting level.polonsky!" );
}
friends[i] setwetness( 1.0, true );
friends[i].pacifist = false;
friends[i].maxSightDistSqrd = (1800 * 1800 );
friends[i] setThreatBiasGroup( "squad" );
}
battlechatter_on("allies");
}
init_friendly_reinforcements()
{
triggers = getentarray( "friendly_respawn_trigger", "targetname" );
if( !isDefined(triggers) )
{
////okiPrint( "Couldn't find friendly respawn triggers!" );
return;
}
for( i=0; i<triggers.size; i++ )
{
if( isDefined(triggers[i].target) )
{
spawner = getent( triggers[i].target, "targetname" );
if( isDefined(spawner) )
{
////okiPrint( "init_friendly_reinforcements: Adding wet_spawnfunc to spawner " + spawner.targetname );
spawner add_spawn_function( ::wet_spawnfunc );
}
}
}
}
wet_spawnfunc()
{
self setwetness( 1.0, true );
self setThreatBiasGroup( "squad" );
}
init_drones()
{
character\char_usa_marinewet_r_rifle::precache();
level.drone_spawnFunction["allies"] = character\char_usa_marinewet_r_rifle::main;
maps\_drones::init();
}
//temp until new spiderhole stuff comes in
init_spiderholes()
{
ents = getentarray("spiderhole_lid","script_noteworthy");
array_thread(ents,::monitor_spiderhole_lid);
}
monitor_spiderhole_lid()
{
self waittill("emerge");
self playsound("spider_hole_open");
//self moveto( self.origin + (0,randomintrange(68,80),0), .4,.1,.2);
//self rotateto( self.angles + (0,randomintrange(-15,15),0), .2);
}
//make the model3 on the cliff fire it's weapon
//temp until all the anims come online
e1_fake_gun_fire()
{
level endon("stop_cliffgun");
trig = getent("spawn_model3","targetname");
trig waittill("trigger");
level notify("e1_approaching_first_rocks");
gun = getent("falling_gun_hideme","targetname");
while(!isDefined(gun))
{
wait(1);
}
while(!isDefined(gun.nofire))
{
{
playfxontag(level._effect["gunflash"],gun,"tag_flash");
//maps\_model3::arty_fire(gun);
gun playsound("model3_fire");
wait(randomintrange(4,7));
}
}
}
///////////////////////////////////////////////////////////
////////////////////GAMEPLAY///////////////////////////////
///////////////////////////////////////////////////////////
//begin the assault on Wana Ridge
e1_startpoint()
{
//TEMP HAX UNTIL SPIDERHOLES ARE FINISHED
level thread init_spiderholes();
//fog settings
//maps\oki2_amb::set_opening_fog();
//gotta wait
wait_for_first_player();
//setsaveddvar("r_showmissinglightgrid","0");
if(getdvar("extra_guys") == "0")
{
atrig = getent("auto2807","target");
atrig trigger_off();
}
//turn off ai colors
disable_friendly_color();
//vision file for opening area
VisionSetNaked("Okinawa2",1);
setup_friends(); //initialize the friendlies
set_friendly_stances( "crouch", undefined, undefined );
move_players("player_start");
// play the level start dialogue
level thread e1_opening_screen_dialogue();
level waittill("introscreen_complete");
//set up the defenders by the cave opening
level thread e1_cave_defenders();
//guys get surprised by the spiderholes
level thread e1_spider_redshirt();
level thread e1_spider_surprise();
level thread e1_spider_reinforcements();
//falling gun
level thread e1_gun_fall();
// bunch of rockets that streak overhead and hit the cliff in front of you
level thread fire_rocket_series( "rocketbarrage_points", (1400,2562,-569), 30, false );
level thread e1_second_rocket_barrage(); // waits for a trigger to hit it
// now we wait for e1_opening_screen_dialogue to finish, then our boys can get moving
//level waittill( "opening_screen_dialogue_complete" );
flag_wait("opening_screen_dialogue_complete");
set_friendly_stances("crouch","prone","stand");
trig = getent("init_ai","targetname");
trig notify("trigger");
trigs = getentarray("done_allies","targetname");
for(i=0;i<trigs.size;i++)
{
trigs[i] notify("stop_drone_loop");
trigs[i] trigger_off();
}
battlechatter_off("allies");
level thread enable_friendly_color_gradual( 1.1 );
//fake gun fire until the _model3 script gets updated
level thread e1_fake_gun_fire();
level thread watersheet_on_trigger( "e1_cave_waterfall" ); // waterall inside the cave
wait(2);
players_satchel_hint();
//wait for event 1 end
event1_end = getent("end_event_1","script_noteworthy");
event1_end waittill("trigger");
e2_start();
}
e1_opening_screen_dialogue()
{
//TUEY Set Music State to INTRO
setmusicstate("INTRO");
battlechatter_off("allies");
level.sarge dialogue( "moveout", level.polonsky );
level.polonsky dialogue( "skinny", level.sarge );
level.sarge dialogue( "gordon", level.polonsky );
wait(0.5);
level.polonsky dialogue( "supplies", level.sarge );
level.sarge dialogue( "coming", level.polonsky );
level.polonsky dialogue( "when", level.sarge );
wait(0.5);
level.sarge dialogue( "uphill", level.polonsky );
flag_set("opening_screen_dialogue_complete");
//level notify( "opening_screen_dialogue_complete" );
level waittill("e1_approaching_first_rocks");
level.sarge dialogue("fortifiedmg");
level.sarge dialogue("spreadout");
}
e1_spider_redshirt()
{
level endon( "e1_spiderholes_triggered" );
trig = getent( "e1_spider_redshirt", "targetname" );
trig waittill( "trigger" );
wait(3);
// first, we need to get a random redshirt
friends = get_ai_group_ai("dasquad");
redshirt = undefined;
for( i=0; i<friends.size; i++ )
{
if( isDefined(friends[i].script_noteworthy) && friends[i].script_noteworthy == "designated_redshirt" )
{
redshirt = friends[i];
break;
}
}
// then, we tell him to stupidly oke his face out into the grass
redshirt setGoalNode( getNode("e1_spider_redshirt_destination","targetname") );
// then he hits a trigger...
trig2 = getent( "e1_spider_redshirt_inposition", "targetname" );
while( true )
{
trig2 waittill( "trigger", who );
if( who == redshirt )
{
break;
}
}
// that tells the spiderholes to go off
spiderholetrig = getent( "spider_surprise", "script_noteworthy" );
spiderholetrig notify( "trigger" );
redshirt.health = 5;
wait(2);
redshirt setGoalNode( getNode("e1_spider_redshirt_retreat","targetname") );
redshirt thread random_death();
}
/*------------------------------------
surprise the guys
------------------------------------*/
e1_spider_surprise()
{
trigs = getentarray("spider_surprise","script_noteworthy");
array_thread(trigs,::e1_spiderholes_triggered);
level waittill("e1_spiderholes_triggered");
battlechatter_on("axis");
//TUEY Set Music State to OH_SHIT
setmusicstate("OH_SHIT");
level.sarge dialogue("spiderholes");
level.sarge dialogue("returnfire");
level.sarge dialogue("burngrass");
level notify( "OBJ_1_UPDATEPOS" );
battlechatter_on("allies");
}
/*------------------------------------
guys act surprised when the spiderholes first pop
------------------------------------*/
e1_spiderholes_triggered()
{
self waittill("trigger");
wait(0.75);
level notify("e1_spiderholes_triggered");
//wait 15 seconds after the spiderholes pop and send in a few extra guys down from the caves
wait(15);
trig = getent("spiderhole_support","script_noteworthy");
trig notify("trigger");
//new fog settings
//maps\oki2_amb::set_assault_fog();
}
e1_spiderhole_guys_assign_color()
{
guys = getEntArray( "e1_spiderhole_guys", "script_noteworthy" );
okiPrint( "e1_spiderhole_guys_assign_color: Found " + guys.size );
for( i=0; i<guys.size; i++ )
{
if( isAlive(guys[i]) ) // some of these are spawners
{
guys[i] set_force_color( "o" );
okiPrint( "e1_spiderhole_guys_assign_color: Setting color!" );
}
}
}
e1_spider_reinforcements()
{
trig = getent( "e1_spider_reinforcements_trigger", "targetname" );
trig waittill( "trigger" );
level thread manage_spawners_nogoal("e1_spider_reinforcements",3,5,"e1_spider_reinforcements_stop",0.25,undefined);
}
// happens as the player's turning the corner up towards the bunker
// look for the trigger!
e1_second_rocket_barrage()
{
trig = getent( "e1_second_rocket_barrage", "targetname" );
trig waittill( "trigger" );
fire_rocket_series( "rocketbarrage_points", (3729, 2, -561), 24, false );
}
e1_mg_start()
{
trig = getent("e1_mg_start","targetname");
trig waittill( "trigger" );
mg = getent("e1_bunker_mg","targetname");
mg setturretignoregoals( true );
level thread maintain_mg_guy( "stop_cave_defenders2", "e1_mg_gunner_spawn", "e1_mg_gunner" );
level thread e1_mg_guy_banzai();
level thread e1_sarge_mg_dialogue();
}
e1_mg_guy_banzai()
{
trig = getent( "e1_mg_gunner_banzai", "targetname" );
trig waittill( "trigger" );
guy = getent( "e1_mg_gunner", "targetname" );
mg = getent("e1_bunker_mg","targetname");
////okiPrint( "e1_mg_guy_banzai triggered!" );
if( isdefined(guy) && isdefined(mg) )
{
mg setturretignoregoals( false );
guy.script_mg42 = undefined;
guy.ready_to_charge = true;
wait(0.2);
guy maps\_banzai::banzai_force();
}
}
// triggers a bit before E1 so the smoke grenade nagging isn't so protracted
e1_smokegrenade_stopthread()
{
trig = getent( "e1_smokegrenade_stop", "targetname" );
trig waittill( "trigger" );
level notify( "e1_smokegrenade_stop" );
}
// dialogue about the MG and watches for the player to throw a smoke grenade
e1_sarge_mg_dialogue()
{
level endon("OBJ_1_COMPLETE");
level endon("e1_smokegrenade_stop");
level thread e1_smokegrenade_stopthread();
players = get_players();
for( i=0; i<players.size; i++ )
{
players[i] thread e1_track_smokegrenade_for_player();
}
wait(1);
level.polonsky dialogue("mgcovered");
wait(0.5);
level.sarge dialogue("popsmoke");
for( i=0; level.e1_smokethrown == false; i++ )
{
if( i > 10 )
{
i = 0;
}
if( i == 5)
{
level.sarge dialogue("smokereminder");
}
if( i == 10)
{
level.polonsky dialogue("smokereminder");
}
wait( 2 );
}
wait(3);
level.sarge dialogue("cantseeus");
level.sarge dialogue("clearbunker");
}
// all this does is sit on a player and run the tracking thread when the player tosses a smoke grenade
e1_track_smokegrenade_for_player()
{
level endon("OBJ_1_COMPLETE");
while( true )
{
self waittill( "grenade_fire", grenade, weapname );
if ( weapname == "m8_white_smoke" )
{
self thread e1_watch_for_smoke_intersection( grenade );
}
}
}
// watch for a player-thrown smoke grenade intersecting the trigger before the E1 MG bunker
e1_watch_for_smoke_intersection( grenade )
{
trigger = getent("stop_cave_defenders","targetname");
touched_trig = false;
while( isdefined(grenade) )
{
if( grenade istouching(trigger) )
{
touched_trig = true;
}
wait( 0.25 );
}
if( touched_trig == true )
{
level.e1_smokethrown = true;
level thread random_banzai( trigger, 3 );
}
}
// grab a handful of guys who're within this trigger, and force them to banzai
random_banzai( volume, num )
{
wait(5);
guys = getaiarray("axis");
banzai_guys = [];
num_banzai_guys = 0;
if( isDefined(guys) && guys.size && num > 0 )
{
for(i=0;i<guys.size;i++)
{
if( guys[i] istouching(volume) )
{
banzai_guys[num_banzai_guys] = guys[i];
num_banzai_guys++;
if( num_banzai_guys >= num )
{
break;
}
}
}
////okiPrint( "random_banzai: found " + num_banzai_guys + " guys" );
for(i=0;i<banzai_guys.size;i++)
{
wait(0.5);
////okiPrint( "random_banzai: Setting banzai!" );
if( isdefined(banzai_guys[i]) && isalive(banzai_guys[i]) )
{
banzai_guys[i] maps\_banzai::banzai_force();
}
}
}
}
/*------------------------------------
japanese ouside of the main cave entrance
------------------------------------*/
e1_cave_defenders()
{
//wait until the trigger's hit
trig = getent("cave_defenders","script_noteworthy");
trig waittill("trigger");
level notify( "e1_spider_reinforcements_stop" );
e1_spiderhole_guys_assign_color(); // some of them might be alive still, get them fighting with their friends
level thread manage_spawners_nogoal("cave_defenders",4,8,"stop_cave_defenders",0.25,undefined);
level thread manage_spawners_nogoal("e1_flank_defenders",2,3,"stop_e1_flank_defenders",1,undefined);
//monitor the cave defenders
level thread e1_monitor_cave_defenders();
level thread e1_stop_cave_defenders();
//add some more defenders once the players get close
level thread e1_more_cave_defenders();
// start the MG once the players reach the plinth
level thread e1_mg_start();
}
e1_more_cave_defenders()
{
trig = getent("more_cave_defenders","script_noteworthy");
trig waittill("trigger");
level thread manage_spawners_nogoal("cave_defenders2",3,5,"stop_cave_defenders2",4,undefined);
level thread e1_monitor_cave_defenders2();
level thread e1_stop_cave_defenders2();
}
e1_monitor_cave_defenders()
{
level endon("stop_monitoring");
wave = 0;
while(wave < 4)
{
level waittill("cave_defenders min threshold reached");
wave++;
}
level notify("stop_cave_defenders");
}
e1_monitor_cave_defenders2()
{
level endon("stop_monitoring");
wave = 0;
while(wave < 4)
{
level waittill("cave_defenders2 min threshold reached");
wave++;
}
level notify("stop_cave_defenders2");
}
e1_stop_cave_defenders()
{
trig = getent("stop_cave_defenders","targetname");
trig waittill("trigger");
level notify("stop_cave_defenders");
level notify("stop_e1_flank_defenders");
}
e1_stop_cave_defenders2()
{
trig = getent("stop_cave_defenders2","targetname");
trig waittill("trigger");
//TUEY Set music state to UNDERSCORE
setmusicstate("UNDERSCORE");
level notify("stop_cave_defenders2");
level notify("stop_cave_mg");
level.sarge dialogue("throughcaves");
}
/*------------------------------------
for starts
------------------------------------*/
e2_startpoint()
{
wait_for_first_player();
setup_friends();
disable_friendly_color();
move_players("skipto_e2_players");
move_ai("skipto_e2_friendlies");
enable_friendly_color();
triga = getent("start_e2","script_noteworthy");
triga notify("trigger");
battlechatter_on("axis");
level notify( "OBJ_1_UPDATEPOS" );
wait_network_frame();
level notify( "OBJ_1_COMPLETE" );
e2_start();
}
/*------------------------------------
take out the guns
------------------------------------*/
e2_start()
{
//tell the level that the first event is finished
level.event_1_finished = true;
e2_hidesatchels();
//stop the firing FX playing from the broken upper grotto gun
level notify("stop_upper");
//give player grenades if he runs out ( temp hax for now until I hook it up so sarge does it for ya )
//level thread temp_player_grenade_hack();
friends = get_ai_group_ai("dasquad");//getentarray("friends","targetname");
for(i=0;i<friends.size;i++)
{
friends[i].maxSightDistSqrd = (1100 * 1100 );
}
getent("move_to_hill","targetname") trigger_off();
level thread e2_grotto_fight();
//wait for the guns to be destroyed
level thread maps\oki2_gunbunkers::monitor_gun(1);
level thread maps\oki2_gunbunkers::monitor_gun(2);
level thread maps\oki2_gunbunkers::monitor_gun(4);
//set up the bunkers
level thread maps\oki2_gunbunkers::bunker_wait_for_flame(1,"bunker_inner_fire","bunker1_flamers",maps\oki2_gunbunkers::cave_flamers,201);
level thread maps\oki2_gunbunkers::bunker_wait_for_flame(2,"bunker_inner_fire","bunker2_flamers",maps\oki2_gunbunkers::cave_flamers,202);
level thread maps\oki2_gunbunkers::bunker_wait_for_flame(4,"bunker_inner_fire","bunker4_flamers",maps\oki2_gunbunkers::cave_flamers,203);
level thread maps\oki2_gunbunkers::bunker_dialogue();
level thread e2_first_rocket_barrage();
level thread e2_second_rocket_barrage();
level thread e2_linefight_a_start();
// delete any stray axis guys on the wana ridge approach
level thread cleanup_trigger_enable( "e1_cleanup_volume" );
level thread e2_refresh_satchel_ammo( "e2_satchelbox_a", "OBJ_5_COMPLETE" ); // let these go on forever
level thread e2_refresh_satchel_ammo( "e2_satchelbox_b", "OBJ_5_COMPLETE" );
level thread e2_refresh_satchel_ammo( "e2_satchelbox_c", "OBJ_5_COMPLETE" );
level thread watersheet_on_trigger( "e2_grotto_waterfall" );
level thread e2_collectible_corpse();
e2_end_setdoorangle();
//set up the grotto fog y'all
//maps\oki2_amb::set_grotto_fog();
//wait until all the guns have been destroyed
while(!level.all_guns_destroyed)
{
wait(1);
}
//update the objectives once the guns are taken out
level notify("OBJ_2_COMPLETE");
//enable the tunnel entrance trigger
thread e2_end_playergate();
//TUEY Set the music state to UNDERSCORE
setmusicstate("UNDERSCORE");
}
#using_animtree( "generic_human" );
e2_collectible_corpse()
{
orig = getstruct( "orig_collectible_loop", "targetname" );
corpse = spawn( "script_model", orig.origin );
corpse.angles = orig.angles;
corpse character\char_jap_makpelwet_rifle::main();
corpse detach( corpse.gearModel );
corpse UseAnimTree( #animtree );
corpse.animname = "collectible";
corpse.targetname = "collectible_corpse";
level thread anim_loop_solo( corpse, "collectible_loop", undefined, "stop_collectible_loop", orig );
}
e2_grotto_fight()
{
trig = getent( "e2_grottofight_start", "targetname" );
trig waittill( "trigger" );
spawns = getentarray( "e2_grotto_spawns", "targetname" );
guys = [];
numguys = 0;
for( i=0; i<spawns.size; i++ ) // spawn all the matching spawners
{
guys[numguys] = spawns[i] stalingradspawn();
if( isDefined(guys[numguys]) ) // make a list of the resultant guys
{
numguys++;
}
}
livingguys = guys.size;
lastguy = undefined;
while( livingguys > 1 ) // loop until only one guy's left alive
{
livingguys = 0;
for( i=0; i<guys.size; i++ )
{
if( isDefined(guys[i]) && isAlive(guys[i]) )
{
livingguys++;
lastguy = guys[i];
}
}
wait(0.2);
}
// now we know only one guy is still alive, and lastguy should equal him
// let's make him run away
lastguy setGoalNode( getNode("e2_grotto_runawaynode","targetname") );
lastguy endon("death");
lastguy.ignoreall = true;
lastguy.goalradius = 64;
lastguy waittill("goal");
lastguy.ignoreall = false;
}
// hides the glowy satchels atop the duffels in E2
e2_hidesatchels()
{
ents = getentarray( "e2_satchel_glow", "targetname" );
for( i=0; i<ents.size; i++ )
{
ents[i] hide();
}
}
// shows the glowy satchels atop the duffels in E2
e2_showsatchels()
{
ents = getentarray( "e2_satchel_glow", "targetname" );
for( i=0; i<ents.size; i++ )
{
ents[i] show();
}
}
e2_refresh_satchel_ammo( triggername, end )
{
level endon( end );
while( true )
{
trig = getent( triggername, "targetname" );
trig waittill( "trigger", who );
if( isDefined(who) && isPlayer(who) && who.active_satchels < 3 )
{
if( who GetWeaponAmmoStock( "satchel_charge_new" ) < 3 )
{
who givestartammo( "satchel_charge_new" );
PlaySoundAtPosition( "ammo_pickup_plr", trig.origin );
}
}
wait(2);
}
}
// all this does is sit on a player and run the tracking thread when the player tosses a satchel
e2_track_satchel_for_player()
{
//level endon("OBJ_2_COMPLETE");
self.active_satchels = 0;
while( true )
{
self waittill( "grenade_fire", satchel, weapname );
if ( weapname == "satchel_charge_new" ) // "satchel_charge"
{
// only need to do this during e2
if( level.all_guns_destroyed == false && level.event_1_finished == true )
{
self thread e2_watch_for_bunker_intersection( satchel, self );
}
else
{
self thread watch_satchel_simple( satchel, self);
}
self.active_satchels++;
}
}
}
watch_satchel_simple( satchel, player )
{
while( isdefined(satchel) )
{
wait(0.25);
}
player.active_satchels--;
}
// runs watches whether the satchel touches any of the bunker triggers
// it tracks which one it has touched, then sends a notify to the appropriate
// trigger if necessary. This is pretty much required to make the bunker
// explosions foolproof.
e2_watch_for_bunker_intersection( satchel, player )
{
triggers[0] = getent("bunker1_dmg_trig","targetname");
triggers[1] = getent("bunker2_dmg_trig","targetname");
triggers[2] = getent("bunker4_dmg_trig","targetname");
touched_trig = -1;
while( isdefined(satchel) )
{
for( i=0; i<triggers.size; i++ )
{
if( satchel istouching(triggers[i]) )
{
touched_trig = i;
}
}
wait( 0.25 );
}
player.active_satchels--;
if( touched_trig != -1 && isDefined(triggers[touched_trig]) )
{
////okiPrint( "e2_watch_for_bunker_intersection found intersection" );
triggers[touched_trig] notify( "satchel_exploded" );
// award points in arcade mode
// no really, this is the only good way to do this
if( touched_trig == 0 && !level.gun1_destroyed )
arcademode_assignpoints( "arcademode_score_oki2_bunker" , player );
if( touched_trig == 1 && !level.gun2_destroyed )
arcademode_assignpoints( "arcademode_score_oki2_bunker" , player );
if( touched_trig == 2 && !level.gun4_destroyed )
arcademode_assignpoints( "arcademode_score_oki2_bunker" , player );
}
}
// right as the player's passing through the grotto
e2_first_rocket_barrage()
{
////okiPrint( "Beginning e2_first_rocket_barrage()" );
trig = getent( "e2_first_rocket_barrage", "targetname" );
trig waittill( "trigger" );
fire_rocket_series( "canyon_rocketbarrage_points_a", (-860,-654,36.1), 12, true );
////okiPrint( "Exiting e2_first_rocket_barrage()" );
}
// as the player's halfway down the valley, hits at the far end
e2_second_rocket_barrage()
{
////okiPrint( "Beginning e2_second_rocket_barrage()" );
trig = getent( "e2_second_rocket_barrage", "targetname" );
trig waittill( "trigger" );
fire_rocket_series( "canyon_rocketbarrage_points_b", (-5737,-313,8), 30, true );
////okiPrint( "Exiting e2_second_rocket_barrage()" );
}
e2_linefight_a_start()
{
trig = getent("e2_linefight_a_start","targetname");
trig waittill("trigger");
level thread maps\_squad_manager::manage_spawners("e2_linefight_a",2,4,"e2_linefight_a_stop",1,undefined);
level thread e2_linefight_a_stop();
}
// stops respawning guys in linefight a, sets up bridge triggers
// bridge banzai doubles as a bridge-commentary disabler
e2_linefight_a_stop()
{
trig = getent("e2_linefight_a_stop","targetname");
trig waittill("trigger");
level notify( "e2_linefight_a_stop" );
level thread e2_bridge_banzai_setup();
level thread e2_bridge_commentary_setup();
level thread e2_check_for_bridge_skip();
}
e2_check_for_bridge_skip()
{
trig = getent( "e2_player_skipping_bridge", "targetname" );
trig waittill("trigger");
trig = getent( "e2_bridge_banzai_trigger", "targetname" );
trig trigger_off();
trig = getent("e2_bridge_commentary", "targetname");
trig trigger_off();
// kill the threads that might be running
level notify( "e2_player_skipped_bridge" );
}
// gets a banzai dude to rush you as you cross the little bridge in E2
e2_bridge_banzai_setup()
{
////okiPrint( "e2_setup_bridge_banzai: starting" );
level endon("e2_player_skipped_bridge");
trig = getent("e2_bridge_banzai_trigger","targetname");
trig waittill( "trigger" );
spawner = getent("e2_bridge_banzai", "targetname" );
spawner add_spawn_function( ::e2_bridge_banzai_spawnfunc );
guy = spawner stalingradspawn();
wait(0.1);
guy allowedstances( "crouch", "prone", "stand" );
////okiPrint( "e2_setup_bridge_banzai: triggered!" );
}
e2_bridge_banzai_spawnfunc()
{
self allowedstances( "crouch" );
self.a.pose = "crouch";
}
// Sarge dialogue about crossing the bridge
e2_bridge_commentary_setup()
{
level endon( "e2_player_skipped_bridge" );
trig = getent("e2_bridge_commentary", "targetname");
trig waittill( "trigger" );
level.sarge dialogue( "otherside" );
}
// Means the player's reached the pass-through tunnel at the end of the canyons
e2_end_playergate()
{
level notify( "bunker_noneleft"); // turns off other acknowledgements if two bunkers are done at once
level.sarge dialogue( "lastone" );
checktrig = getEnt( "e2_bunker3_checkifclear", "targetname" );
deathCountdown = 15;
while( true )
{
numEnemies = 0;
guys = getaiarray("axis");
if( isDefined(guys) && guys.size )
{
for( i=0; i<guys.size; i++ )
{
if( isAlive(guys[i]) && guys[i] istouching(checktrig) )
{
numEnemies++;
if( deathCountdown == 0 ) // kill of stragglers if too long has passed
{
guys[i] thread random_death();
}
}
}
////okiPrint( "Looking for axis touching e2_bunker3_checkifclear: " + numEnemies );
}
// countdown until we just kill them to avoid player confusion... sometimes one is
// in a hard to find corner, or may have fallen through the ground or something
if( numEnemies < 3 )
{
//okiPrint( "Death Countdown: " + deathCountdown );
deathCountdown--;
}
if( numEnemies == 0 )
{
break;
}
wait(0.66);
}
level thread e2_end_sargedialogue();
// do this twice because friendlycolor could mess this up
level.sarge disable_ai_color();
level.sarge setgoalnode( getnode("e2_finish_sargenode_wait","targetname") );
trig = getent("move_to_hill","targetname");
trig trigger_on();
trig waittill("trigger");
level.sarge setgoalnode( getnode("e2_finish_sargenode_kickready","targetname") );
level.sarge waittill("goal");
// grab the player blocker, knock the gate over, remove the clip brush
thread e3_start_trigger();
e2_end_sarge_bash_door();
//enable_friendly_color();
level notify("OBJ_3_COMPLETE");
}
e2_end_setdoorangle()
{
gate = getent( "e2_finish_gate", "targetname" );
gate.angles = (0,-24,0);
}
e2_end_sargedialogue()
{
battlechatter_off("allies"); // turned back on in e2_end_bash_door_dialogue
wait(2);
level.sarge dialogue( "meetme" );
}
// sarge knocks down the big metal grating that's in the way
e2_end_sarge_bash_door()
{
level.sarge.ignoreall = true;
gate = getent( "e2_finish_gate", "targetname" );
anim_node = getnode("e2_finish_kickspot","targetname");
anim_node anim_reach_solo(level.sarge, "door_bash");
level thread e2_end_bash_door_dialogue();
anim_node anim_single_solo(level.sarge,"door_bash");
level.sarge setgoalnode( getnode("e2_finish_sargepostbash","targetname") );
level.sarge.ignoreall = false;
}
e2_end_bash_door_dialogue()
{
level.polonsky dialogue("whatnow");
level.sarge dialogue("keepmovingpolonsky");
wait(0.5);
level.sarge dialogue("keepmoving");
battlechatter_on("allies");
}
#using_animtree("oki2_falling_gun");
e2_end_cachedooranim()
{
level.scr_model["e2_door"] = "tag_origin_animate";
level.scr_anim["e2_door"]["flyopen"] = %o_okinawa2_bunkerdoor_smash;
level.scr_animtree["e2_door"] = #animtree;
}
move_e3_start_gate( GARBAGE )
{
e2_end_cachedooranim();
gate = getent( "e2_finish_gate", "targetname" );
gateclip = getent( "e2_finish_gate_clip", "targetname" );
scrorigin = getent( "e2_finish_animorigin", "targetname" );
anim_model = spawn_anim_model( "e2_door" );
anim_model.animname= "e2_door";
anim_model.origin = scrorigin.origin;
anim_model.angles = scrorigin.angles;
//anim_model thread draw_tag_name( "origin_animate_jnt" );
//anim_model thread draw_tag_name( "tag_origin" );
scrorigin maps\_anim::anim_first_frame_solo( anim_model, "flyopen" );
gate linkto( anim_model, "origin_animate_jnt", ( 0, 0, 0 ), ( 0, -24, 0 ) );
scrorigin thread anim_single_solo( anim_model, "flyopen" );
gateclip delete();
}
e3_start_trigger()
{
trig = getEnt("e3_start_trigger","targetname");
trig waittill("trigger");
e3_start();
}
e3_startpoint()
{
wait_for_first_player();
level.event_1_finished = true;
level notify("stop_upper");
level notify("stop_1" );
level notify("stop_2" );
level notify("stop_4" );
setup_friends();
move_ai("e3_ai_start");
move_players("e3_player_start");
enable_friendly_color();
level notify( "OBJ_1_UPDATEPOS" );
wait_network_frame();
level notify( "OBJ_1_COMPLETE" );
wait_network_frame();
level notify( "OBJ_2_COMPLETE" );
wait_network_frame();
level notify( "OBJ_3_COMPLETE" );
level thread e3_start_trigger();
level thread move_e3_start_gate( undefined );
startcovertrig = getent("e3_start_coverpoints","targetname"); // move guys to nearby cover spots, otherwise they act stupid
startcovertrig notify("trigger");
players = get_players();
// wait(10); // uncomment these to test doorbash easily
// level thread sarge_bash_door();
}
e3_startpoint_bash()
{
wait_for_first_player();
level.event_1_finished = true;
level notify("stop_upper");
level notify("stop_1" );
level notify("stop_2" );
level notify("stop_4" );
setup_friends();
move_ai("e3_ai_start");
move_players("e3_player_start");
enable_friendly_color();
level notify( "OBJ_1_UPDATEPOS" );
wait_network_frame();
level notify( "OBJ_1_COMPLETE" );
wait_network_frame();
level notify( "OBJ_2_COMPLETE" );
startcovertrig = getent("e3_start_coverpoints","targetname"); // move guys to nearby cover spots, otherwise they act stupid
startcovertrig notify("trigger");
e2_end_setdoorangle();
level thread e2_end_playergate();
}
/*------------------------------------
start the assault on the bunker
------------------------------------*/
e3_start()
{
//maps\oki2_amb::set_final_fog();
//level.drone_think_func = ::e3_drone_slowspeed; // guys following the tank are drones // not anymore
thread e3_tankstart(); // does some setup then waits for 'tank_move'
thread e3_playerneartank(); // waits on a trigger, which notifies level 'tank_move'
level thread e3_bunker_defenders();
level thread e3_player_enters_tunnel();
level thread e3_rightrear_linefight_start();
level thread e3_leftrear_linefight_start();
startup_e3_freeflow_triggers();
}
e3_turrets_ignoregoals_true()
{
t1 = getent("auto448","targetname");
t2 = getent("auto709","targetname");
t1 setturretignoregoals( true );
t2 setturretignoregoals( true );
}
e3_turrets_ignoregoals_false()
{
t1 = getent("auto448","targetname");
t2 = getent("auto709","targetname");
t1 setturretignoregoals( false );
t2 setturretignoregoals( false );
}
e3_playerneartank()
{
trig_playerneartank = getent("trigger_playerneartank", "targetname");
////okiPrint( "Found trigger_playerneartank" );
enable_friendly_color();
trig_playerneartank waittill("trigger");
level notify("tank_move");
spawn_array_once( "e3_hill_friendlies", "targetname" );
// delete any stray axis guys in the canyon
level thread cleanup_trigger_enable( "e2_cleanup_volume" );
//thread e3_approachfight(); // waits for the drones to hit a trigger indicating they're in front of the spiderholes
}
/*------------------------------------
tank spawns, moves forward, and eventually gets blown up
------------------------------------*/
e3_tankstart()
{
//wait for tank to be destroyed
trig_spawn = getent("tank_spawn","targetname");
trig_spawn notify("trigger");
// starts the tank moving once we're ready
level waittill("tank_move");
trig_move = getent("tank_move", "targetname");
trig_move notify("trigger");
tank1 = getent("e3_tank1","targetname");
tank2 = getent("e3_tank2","targetname");
level thread e3_tankfollowers( tank1 );
wait(1);
tank1 thread e3_tank_explode();
tank2 thread e3_tank_explode();
level thread e3_tank_dialogue();
level thread e3_extra_mortar();
}
// dudes who follow along behind the first tank in E3
e3_tankfollowers( tank )
{
spawns = getentarray( "e3_tankfollower_spawn", "targetname" );
guys = [];
dest_node = getNode("e3_tankfollower_goal","targetname");
for( i=0; i<spawns.size; i++ )
{
guys[i] = spawns[i] StalingradSpawn();
wait_network_frame();
guys[i].ignoreall = true;
guys[i].health = 1;
guys[i] thread maps\_utility::set_generic_run_anim( "combat_jog", true );
guys[i] setGoalPos( dest_node.origin );
guys[i].goalradius = 128;
wait( 0.35 );
}
tank waittill("reached_end_node");
for( i=0; i<guys.size; i++ )
{
if( isAlive(guys[i]) )
{
guys[i] doDamage( 100, tank.origin );
}
}
}
e3_tank_explode()
{
self waittill("reached_end_node");
playfx( level.mortar, self.origin );
radiusdamage( self.origin, 512, 60, 15 );
level notify( "e3_tank_destroyed" );
self notify( "death" );
}
//#using_animtree( "generic_human" );
e3_drone_slowspeed()
{
//self.drone_run_cycle = %combat_jog;
self.droneRunRate = 125;
}
e3_extra_mortar()
{
level waittill( "e3_tank_destroyed" );
locs = getStructArray( "e3_extra_mortar", "targetname" );
for( i=0; i<locs.size; i++ )
{
wait( RandomIntRange(1,4) );
playfx( level.mortar, locs[i].origin );
radiusdamage( locs[i].origin, 512, 40, 10 );
}
wait( RandomIntRange(1,4) );
jeepmortar = getstruct( "e3_jeep_mortar", "targetname" );
jeep1 = getent( "e3_parked_jeep1", "targetname" );
jeep2 = getent( "e3_parked_jeep2", "targetname" );
playfx( level.mortar, jeepmortar.origin );
radiusdamage( jeepmortar.origin, 512, 40, 10 );
wait(0.1);
jeep1 notify( "death" );
wait(0.4);
jeep2 notify( "death" );
}
e3_tank_dialogue()
{
level.sarge dialogue("tanksmoving");
// BOOM! Need to attach more chaos to this in general
// BANG! Actually happened!
level waittill( "e3_tank_destroyed" );
//TUEY Set music state to MORTARS
setmusicstate("MORTARS");
level.polonsky dialogue("mortarfire");
level.sarge dialogue("takecover");
wait(6);
level.polonsky dialogue("fortress");
level.polonsky dialogue("seepaths");
level notify( "OBJ_4_UPDATEPOS" );
}
// turns on appropriate triggers to keep the squad following the player
startup_e3_freeflow_triggers()
{
thread trigger_noteworthy_if_player0( "e3_righthand_trigger_a", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_righthand_trigger_b", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_righthand_trigger_c", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_righthand_trigger_d", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_righthand_trigger_e", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_lefthand_trigger_a", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_lefthand_trigger_b", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_lefthand_trigger_c", "player_entered_tunnel" );
thread trigger_noteworthy_if_player0( "e3_lefthand_trigger_d", "player_entered_tunnel" );
}
/*------------------------------------
Japanese defending the bunker
------------------------------------*/
e3_bunker_defenders()
{
trig = getent("start_bunker_defenders","script_noteworthy");
trig waittill("trigger");
level thread e3_righthand_defenders();
level thread e3_lefthand_defenders();
createThreatBiasGroup( "e3_gunners" );
level thread maintain_mg_guy( "player_entered_tunnel", "e3_bunker_gunner_spawn1", "e3_bunker_gunner1", "e3_gunners" );
level thread maintain_mg_guy( "player_entered_tunnel", "e3_bunker_gunner_spawn2", "e3_bunker_gunner2", "e3_gunners" );
level thread maintain_mg_guy( "player_entered_tunnel", "e3_bunker_gunner_spawn3", "e3_bunker_gunner3", "e3_gunners" );
setThreatBias( "e3_gunners", "players", 25 );
}
// start righthand guys right away
e3_righthand_defenders()
{
thread manage_spawners_nogoal("bunker_right_defenders",3,5,"stop_right_defenders",1, ::guy_to_goal_blind);
thread e3_monitor_defenders("bunker_right_defenders",6,"stop_right_defenders");
thread e3_stop_lower_defenders("stop_lower_defenders_right");
}
// this fight feels better if the dudes spawn as you get down into the valley
e3_lefthand_defenders()
{
trig = getent( "e3_start_lefthand_defenders", "targetname" );
trig waittill( "trigger" );
thread manage_spawners_nogoal( "bunker_left_defenders", 3, 7, "stop_left_defenders", 1, undefined );
thread e3_monitor_defenders("bunker_left_defenders",6,"stop_left_defenders");
thread e3_stop_lower_defenders("stop_lower_defenders_left");
thread e3_left_treesnipers();
}
e3_monitor_defenders(guys,maxWaves,strEndon)
{
level endon(strEndon);
waves = 0;
while(waves < maxWaves)
{
level waittill(guys + " min threshold reached");
waves++;
}
level notify(strEndon);
}
e3_stop_lower_defenders( triggername )
{
trig = getent(triggername,"targetname");
trig waittill("trigger");
level notify("stop_left_defenders");
level notify("stop_right_defenders");
}
e3_init_defenders()
{
self.goalradius = 64;
self.maxsightdistsqrd = ( 2048 * 2048 );
}
// prepare for spawning guys in the tunnel
e3_player_enters_tunnel()
{
////okiPrint( "starting player_enters_tunnel!" );
//wait until players enter tunnels
trig = getent("e3_player_enters_tunnel","targetname");
trig waittill("trigger");
////okiPrint( "triggered player_enters_tunnel!" );
level notify( "player_entered_tunnel" );
level notify( "OBJ_4_COMPLETE" );
//TUEY Sets music state to INTO BUNKERS
setmusicstate("INTO_BUNKERS");
// waits for player to get to the end of the tunnels
level thread e3_player_reaches_bunker();
level thread e3_tunnels_spawn();
level thread e3_tunnels_radio();
battlechatter_off( "allies" );
level.polonsky dialogue( "tunnelahead" );
level.sarge dialogue( "goodworkpeople" );
level.sarge dialogue( "convoyenroute" );
battlechatter_on( "allies" );
}
e3_tunnels_radio()
{
// oki2_radio_transmission
// oki2_radio_deadair_loop
// radio_destroyed
trig = getent( "e3_tunnels_radio_trigger", "targetname" );
trig waittill( "trigger" );
level endon("player_reaches_bunker");
radio = getent("e3_tunnel_radio","targetname");
radio endon("radio_damaged");
radio setcandamage(true);
radio thread e3_tunnels_radio_takedamage();
radio playsound("oki2_radio_transmission", "sound_finished");
radio waittill( "sound_finished" );
radio playloopsound("oki2_radio_deadair_loop");
}
// self is the radio
e3_tunnels_radio_takedamage()
{
self waittill( "damage", who );
self notify( "radio_damaged" );
self stopsounds();
wait_network_frame();
self playsound("radio_destroyed");
self setmodel("radio_jap_bro");
if( isPlayer(who) )
{
arcademode_assignpoints( "arcademode_score_oki2_radio" , who );
}
}
// walk through the spawn sets in the tunnels one by one
e3_tunnels_spawn()
{
// outro_kill_treesniper();
thread notify_when_trigger_hit( "e3_tunnel_firstwave", "start_tunnels_axis_a" );
level waittill( "start_tunnels_axis_a" );
guys = spawn_array_once( "e3_tunnels_axis_a", "targetname" );
thread e3_trigger_when_guys_dead( guys, "e3_tunnels_allies_a", "player_reaches_bunker", "e3_tunnels_allies_a_disable" );
thread notify_when_trigger_hit( "e3_trigger_tunnels_secondroom", "player_in_secondroom" );
level waittill( "player_in_secondroom" );
level thread cleanup_trigger_enable( "e3_right_cleanup_volume" );
level thread cleanup_trigger_enable( "e3_left_cleanup_volume" );
guys = spawn_array_once( "e3_tunnels_axis_b", "targetname" );
thread e3_trigger_when_guys_dead( guys, "e3_tunnels_allies_b", "player_reaches_bunker", "e3_tunnels_allies_b_disable" );
thread notify_when_trigger_hit( "e3_trigger_tunnels_firstladder", "player_climbs_first_ladder" );
level waittill( "player_climbs_first_ladder" );
level thread cleanup_trigger_enable( "e3_rear_cleanup_volume" );
thread manage_spawners_nogoal("e3_tunnels_axis_c",2,4,"e3_tunnels_allies_c_stop",.1, undefined);
thread notify_when_trigger_hit( "e3_tunnels_allies_c", "e3_tunnels_allies_c_stop" );
}
e3_trigger_when_guys_dead( guys, targetname, endmsg, disablename )
{
if( isDefined(endmsg) )
{
level endon( endmsg );
}
guysalive = true;
while( guysalive )
{
guysalive = false;
for( i=0; i<guys.size; i++ )
{
if( isDefined(guys[i]) && isAlive(guys[i]) ) // check if anybody's still alive...
{
guysalive = true;
}
}
wait(0.25);
}
trig = getent( targetname, "targetname" );
if( isDefined(trig) )
{
////okiPrint( "e3_trigger_when_guys_dead triggering " + trig.targetname );
trig notify( "trigger" );
}
if( isDefined(disablename) )
{
dtrig = getent( disablename, "targetname" );
dtrig trigger_off();
}
}
// sets up the guys in the bunker for iminent player arrival
e3_player_reaches_bunker()
{
////okiPrint( "starting player_reaches_bunker!" );
trig = getent("e3_player_reaches_bunker","targetname");
trig waittill("trigger");
////okiPrint( "triggered player_reaches_bunker!" );
level notify( "player_reaches_bunker" );
level thread e3_bunkertop_spawn();
//TUEY Set Music State to UP_THE_LADDER
setmusicstate("UP_THE_LADDER");
level.sarge dialogue( "upladder" );
level.sarge dialogue( "areasecured" );
}
// spawns the two sets of guys in the top floor of the bunker
e3_bunkertop_spawn()
{
trig = getent( "e3_start_bunkertop_axis_a", "targetname" );
trig waittill( "trigger" );
e3_bunkertop_relocategunners();
thread manage_spawners_nogoal("e3_bunkertop_axis_a",4,7,"stop_bunkertop_axis_a",.1, undefined);
thread notify_when_trigger_hit( "e3_stop_bunkertop_axis_a", "stop_bunkertop_axis_a" );
e3_turrets_ignoregoals_false();
trig = getent( "e3_start_bunkertop_axis_b", "targetname" );
trig waittill( "trigger" );
thread manage_spawners_nogoal("e3_bunkertop_axis_b",5,8,"stop_bunkertop_axis_b",.1, undefined);
thread notify_when_trigger_hit( "e3_stop_bunkertop_axis_b", "stop_bunkertop_axis_b" );
thread e3_sarge_mortar_reminder();
wait(2);
e3_monitor_bunker_status(); // end the mission when the bunker's empty
}
// grabs the dudes manning the MGs at the top of the E3 bunker and sends them to sensible nodes for the fight
e3_bunkertop_relocategunners()
{
guy1 = getent( "e3_bunker_gunner1", "targetname" );
if( isDefined(guy1) )
{
guy1 setGoalNode( getNode("e3_bunkertop_gunner1node","targetname") );
}
guy2 = getent( "e3_bunker_gunner2", "targetname" );
if( isDefined(guy2) )
{
guy2 setGoalNode( getNode("e3_bunkertop_gunner2node","targetname") );
}
guy3 = getent( "e3_bunker_gunner3", "targetname" );
if( isDefined(guy3) )
{
guy3 setGoalNode( getNode("e3_bunkertop_gunner3node","targetname") );
}
}
e3_sarge_mortar_reminder()
{
level endon( "OBJ_5_COMPLETE" );
wait(30);
level.sarge dialogue( "mortarpositions" );
}
// checks who's touching the e3_bunker_interior trigger. When all the Axis are dead, it's called secure
e3_monitor_bunker_status()
{
vol = getent("e3_bunker_interior","targetname");
guys_inside = 0;
////okiPrint ("Monitoring guys in bunker!");
while(1)
{
wait(1);
guys_inside = 0;
countdown_to_kill = 12;
guys = getaiarray("axis");
if( isDefined(guys) && guys.size )
{
for(i=0;i<guys.size;i++)
{
if( isAlive( guys[i]) && guys[i] istouching(vol) )
{
guys_inside++;
}
if( countdown_to_kill == 0 )
{
guys[i] thread random_death();
}
}
////okiPrint( "MONITOR_GUYS_IN_BUNKER: found " + guys_inside );
}
if(guys_inside == 0)
{
break;
}
if( guys_inside < 3 )
{
//okiPrint( "Death Countdown: " + countdown_to_kill );
countdown_to_kill--;
}
}
// we had to have hit the break above to get here
// this means everybody in the bunker is dead and we're good to finish the level
e3_complete();
}
/*------------------------------------
player secures the bunker
------------------------------------*/
e3_complete()
{
level notify( "OBJ_5_COMPLETE" );
battlechatter_off("allies");
wait(1);
level.sarge AllowedStances ("stand");
level.sarge dialogue( "outstandingmarines" );
level.sarge dialogue( "outfuckingstanding" );
level.sarge dialogue( "tendwounded" );
// fade to black, then play closing IGC
//thread fade_to_black(3);
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] thread hud_fade_to_black(3);
players[i] thread magic_bullet_shield();
}
wait(3);
outro_start(); // this'll finish in about 45 seconds
nextmission();
}
e3_rightrear_linefight_start()
{
level endon( "player_entered_tunnel" );
trig = getent( "e3_rightrear_linefight_start", "targetname" );
trig waittill( "trigger" );
thread manage_spawners_nogoal("e3_rightrear_linefight",4,6,"player_entered_tunnel",.1, undefined);
// want the timer to be right whichever one hits the trigger first. These threads kill each other.
thread e3_rightrear_spiderholes_start( "e3_rightrear_spiderholes_trigger_ai" );
thread e3_rightrear_spiderholes_start( "e3_rightrear_spiderholes_trigger_player" );
}
e3_rightrear_spiderholes_start( triggername )
{
level endon( "player_entered_tunnel" );
level endon( "e3_rightrear_spiderholes_triggered" );
////okiPrint( "e3_rightrear_spiderholes_start: Found spiderhole trigger " + triggername );
trig = getent( triggername, "targetname" );
trig waittill( "trigger" );
////okiPrint( "e3_rightrear_spiderholes_start: Spawning!" );
spawntrig = getent( "e3_rightrear_spiderholes_spawntrigger", "targetname" );
spawntrig notify( "trigger" );
}
e3_leftrear_linefight_start()
{
level endon( "player_entered_tunnel" );
trig = getent( "e3_leftrear_linefight_start", "targetname" );
trig waittill( "trigger" );
thread manage_spawners_nogoal("e3_leftrear_linefight",3,4,"player_entered_tunnel",.1, undefined);
}
// when the player hits the trigger, two tree snipers spawn just ahead
e3_left_treesnipers()
{
level endon( "player_entered_tunnel" );
tree = getent( "dunes_flame_tree", "script_noteworthy" );
model_tag_origin = spawn( "script_model", tree.origin );
model_tag_origin setmodel("tag_origin");
model_tag_origin linkto( tree, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
playfxontag( level._effect["sniper_leaf_loop"], model_tag_origin, "TAG_ORIGIN" );
trig = getent( "e3_left_treesnipers_trigger", "targetname" );
trig waittill( "trigger" );
// Tree snipers!
////okiPrint( "Spawning left treesnipers!" );
simple_spawn( "e3_left_treesnipers", ::e3_treesniper_spawn );
model_tag_origin unlink();
model_tag_origin delete();
playfx( level._effect["sniper_leaf_canned"], tree.origin );
// radius check to see if squad members are nearby, have them do dialogue if so
pol_distance = distancesquared( level.polonsky.origin, trig.origin );
sar_distance = distancesquared( level.sarge.origin, trig.origin );
pass_distance = 750 * 750; // the radius I want to check, squared
////okiPrint( "e3_left_treesnipers: Polonsky distance is " + pol_distance );
////okiPrint( "e3_left_treesnipers: Sarge distance is " + sar_distance );
// if both polonsky and roebuck are within distance of the sniper-activating trigger, they converse
// if just one or the other is within distance, I play the lines that make best sense
if( pol_distance < pass_distance )
{
level.polonsky dialogue("snipersintrees");
if( sar_distance < pass_distance )
{
level.sarge dialogue("iseeem");
}
}
if( sar_distance < pass_distance )
{
level.sarge dialogue("bringemdown");
}
tree waittill( "destroyed" ); // kill the sniper if the tree's destroyed
sniper = getEnt( "e3_left_treesnipers_alive", "targetname" );
if( isDefined(sniper) && isAlive(sniper) )
{
sniper thread random_death(1);
}
}
// function that runs on the actual tree sniper individual
e3_treesniper_spawn()
{
self endon("death");
////okiPrint( "Doing e3_treesniper_spawn!" );
anim_node = getnode(self.target, "targetname");
anim_point = getent(anim_node.target,"targetname");
self.ignoreme = true;
self.animname = "tree_guy";
if (self.script_noteworthy == "climb")
{
self maps\_tree_snipers::do_climb(anim_point);
}
self.ignoreme = false;
if (isdefined(self))
{
self allowedstances ("crouch");
}
self.allowdeath = true;
self thread maps\_tree_snipers::tree_death(self, anim_point);
self.health = 1;
}
#using_animtree("player");
outro_cacheplayer()
{
level.scr_model["player_hands"] = "viewmodel_usa_marinewet_rolledup_player";
level.scr_animtree["player_hands"] = #animtree;
level.scr_anim["player_hands"]["outro"] = %int_oki2_outro_player;
}
#using_animtree("generic_human");
outro_cachenpcs()
{
level.scr_anim["sarge"]["outro"] = %ch_okinawa2_outro_roebuck;
level.scr_anim["polonsky"]["outro"] = %ch_okinawa2_outro_polonski;
level.scr_anim["guy1"]["outro"] = %ch_okinawa2_outro_guy1;
level.scr_anim["guy2"]["outro"] = %ch_okinawa2_outro_guy2;
level.scr_anim["co"]["outro"] = %ch_okinawa2_outro_co;
}
#using_animtree("vehicles");
outro_cachevehicles()
{
level.scr_anim["truck"]["outro"] = %v_oki2_outro_gmc_truck;
level.scr_animtree["truck"] = #animtree;
}
#using_animtree("vehicles");
outro_set_truck_animtree()
{
self useAnimTree( #animtree );
}
outro_kill_treesniper()
{
//okiPrint( "outro_kill_treesniper: Looking for tree sniper!" );
ent = getEnt( "e3_left_treesnipers_alive", "targetname" );
if( isDefined(ent) )
{
//okiPrint( "outro_kill_treesniper: Deleting tree sniper!" );
ent Delete();
}
}
outro_start()
{
//TUEY Set music state to LEVEL_END
setmusicstate("LEVEL_END");
outro_kill_treesniper();
level.nextmission_cleanup = ::fade_cleanup;
level thread cleanup_trigger_enable( "e3_rear_cleanup_volume" ); // just in case there's a guy wandering around out back
node = getent("outro_alignment", "targetname");
disable_friendly_color();
battlechatter_off("allies");
move_players( "outro_players_start" );
move_ai_single( level.sarge, "outro_alignment_struct" );
move_ai_single( level.polonsky, "outro_alignment_struct" );
outro_cacheplayer();
outro_cachenpcs();
outro_cachevehicles();
outro_dialogue();
// turn off hud stuff
players = get_players();
for( i = 0; i < players.size; i++ )
{
player = players[i];
player SetClientDvar( "hud_showStance", "0" );
player SetClientDvar( "compass", "0" );
player SetClientDvar( "ammoCounterHide", "1" );
player setClientDvar ( "miniscoreboardhide", "1" );
}
//SetSavedDvar( "miniscoreboardhide", "1" );
share_screen( get_host(), true, true );
// get everybody into position. Teleport the AI guys to their node beforehand
players = get_players();
p1 = players[0];
// no shooting!
for( i = 0; i < players.size; i++ )
{
players[i] FreezeControls( true ); // disable this so they don't have a chance to re-use weapons or turrets
//players[i] RevivePlayer();
//players[i] thread magic_bullet_shield();
players[i] DisableWeapons();
players[i] DisableOffhandWeapons();
players[i] TakeAllWeapons();
players[i] StopUsingTurret();
players[i] AllowJump( false );
players[i] AllowCrouch( false );
players[i] AllowProne( false );
players[i] SetStance( "stand" );
players[i] thread outro_delete_grenade();
players[i] thread outro_prevent_bleedout();
players[i] hide();
// if( i != 0)
// {
// // put the player in spectator mode
// level.otherPlayersSpectate = true;
// level.otherPlayersSpectateClient = players[0];
//
// players[i] thread maps\_callbackglobal::spawnSpectator();
// }
//wait_network_frame();
players[i] thread play_outro_on_player(node);
}
guy1_spawn = getent( "outro_guy1", "targetname" );
guy2_spawn = getent( "outro_guy2", "targetname" );
co_spawn = getent( "outro_co", "targetname" );
truck = getent( "outro_truck", "targetname");
guy1 = guy1_spawn stalingradspawn();
guy2 = guy2_spawn stalingradspawn();
co = co_spawn stalingradspawn();
truck makefakeai();
guy1.animname = "guy1";
guy2.animname = "guy2";
co.animname = "co";
truck.animname = "truck";
truck outro_set_truck_animtree();
level.sarge Detach( level.sarge.hatmodel );
guy1 gun_remove();
// // Spawn in the player hands
// player_hands = spawn_anim_model( "player_hands" );
// player_hands hide();
// player_hands.animname= "player_hands";
//
// player_hands.origin = node.origin;
// player_hands.angles = node.angles;
//
// // put player camera in right place, based on the first frame of the animation
// node maps\_anim::anim_first_frame_solo( player_hands, "outro" );
// p1 lerp_player_view_to_tag( player_hands, "tag_player", 0.1, 1, 60, 25, 25, 10 );
// p1 playerlinkto( player_hands, "tag_player", 0, 1, 30, 30, 10, 10, false );
// player_hands linkto( level.sarge, "tag_sync", ( 0, 0, 0 ), ( 0, 0, 0 ) );
// level.sarge linkto( guy1, "tag_sync", ( 0, 0, 0 ), ( 0, 0, 0 ) );
// guy1 linkto( node );
//player_hands show(); // because you don't see the arms anymore
// actually play the animations for all involved parties
node thread anim_single_solo( level.sarge, "outro" );
// node thread anim_single_solo( player_hands, "outro" );
node thread anim_single_solo( level.polonsky, "outro" );
node thread anim_single_solo( guy1, "outro" );
node thread anim_single_solo( guy2, "outro" );
node thread anim_single_solo( co, "outro" );
node thread anim_single_solo( truck, "outro" );
wait(8);
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] thread hud_fade_in(2);
}
wait(29);
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] thread hud_fade_to_black(2);
}
//SetSavedDvar( "miniscoreboardhide", "1" );
share_screen( get_host(), false);
// turn back on the hud stuff
players = get_players();
for( i = 0; i < players.size; i++ )
{
player = players[i];
player SetClientDvar( "hud_showStance", "1" );
player SetClientDvar( "compass", "1" );
player SetClientDvar( "ammoCounterHide", "0" );
player setClientDvar ( "miniscoreboardhide", "0" );
}
//thread fade_to_black(2);
}
play_outro_on_player(node)
{
// Spawn in the player hands
self.player_hands = spawn_anim_model( "player_hands" );
self.player_hands hide();
self.player_hands.animname= "player_hands";
self.player_hands.origin = node.origin;
self.player_hands.angles = node.angles;
// put player camera in right place, based on the first frame of the animation
node maps\_anim::anim_first_frame_solo( self.player_hands, "outro" );
self lerp_player_view_to_tag( self.player_hands, "tag_player", 0.1, 1, 60, 25, 25, 10 );
self linkto(self.player_hands,"tag_player");
node thread anim_single_solo( self.player_hands, "outro" );
self FreezeControls( false );
}
// wait for the player to throw a grenade, then immediately delete it.
outro_delete_grenade()
{
self waittill( "grenade_fire", what );
what Delete(); // SO THERE
}
outro_prevent_bleedout()
{
self endon( "death" );
self endon( "disconnect" );
while( 1 )
{
if( self maps\_laststand::player_is_in_laststand())
{
self RevivePlayer();
self.bleedout_time = 100000;
}
wait_network_frame();
}
}
outro_dialogue()
{
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_007A_POLO" );
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_009A_POLO" );
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_011A_POLO" );
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_012A_POLO" );
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_013A_POLO" );
addnotetrack_dialogue( "polonsky", "dialog", "outro", "Oki2_OUT_017A_POLO" );
addnotetrack_dialogue( "sarge", "dialog", "outro", "Oki2_OUT_001A_ROEB" );
addnotetrack_dialogue( "sarge", "dialog", "outro", "Oki2_OUT_002A_ROEB" );
addnotetrack_dialogue( "sarge", "dialog", "outro", "Oki2_OUT_003A_ROEB" );
addnotetrack_dialogue( "sarge", "dialog", "outro", "Oki2_OUT_005A_ROEB" );
addnotetrack_dialogue( "sarge", "dialog", "outro", "Oki2_OUT_006A_ROEB" );
addnotetrack_dialogue( "co", "dialog", "outro", "Oki2_OUT_004A_MAJG" );
addnotetrack_dialogue( "co", "dialog", "outro", "Oki2_OUT_008A_MAJG" );
addnotetrack_dialogue( "co", "dialog", "outro", "Oki2_OUT_010A_MAJG" );
addnotetrack_dialogue( "co", "dialog", "outro", "Oki2_OUT_014A_MAJG" );
addnotetrack_dialogue( "co", "dialog", "outro", "Oki2_OUT_016A_MAJG" );
//addnotetrack_dialogue( "guy1", "dialog", "outro", "Oki2_OUT_015A_COR1" );
//addnotetrack_dialogue( "guy2", "dialog", "outro", "Oki2_OUT_500A_COR2" );
//addnotetrack_dialogue( "guy2", "dialog", "outro", "Oki2_OUT_501A_COR2" );
}
outro_startpoint()
{
wait_for_first_player();
setup_friends();
move_players( "outro_players_start" );
move_ai_single( level.sarge, "outro_sarge_start" );
move_ai_single( level.polonsky, "outro_polonsky_start" );
//fade_to_black(0.1);
players = get_players();
for(i=0;i<players.size;i++)
{
players[i] thread hud_fade_to_black(1);
}
level waittill("introscreen_complete");
outro_start();
nextmission();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// E1 CLIFFSIDE GUN BEING BOMBED
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e1_gun_fall()
{
//hide the destroyed cliffside
level.cliff_destroyed hide();
//hide the falling gun
level.cliff_gun = getent("falling_gun","targetname");
level.cliff_gun hide();
//explosion origins, we have three bombs hit spaced a bit apart
exp1_origin = getstruct( "e1_cliffgun_bomb_a", "targetname" ).origin;
exp2_origin = level.cliff_gun.origin;
exp3_origin = getstruct( "e1_cliffgun_bomb_b", "targetname" ).origin;
//wait until the player hits the trigger
trig = getent("more_cave_defenders", "script_noteworthy");
trig waittill("trigger");
//spawn the plane in
bomber_trig = getent("cliff_bomber","targetname");
bomber_trig notify("trigger");
wait(1);
bomber = getent("e1_bomber_a","targetname");
bomber playsound("planeby_3");
plane = getent("e1_bomber_b","targetname");
plane playsound("planeby_3");
bomber waittill("e1_bombers_above_target");
gun = getent("falling_gun_hideme","targetname"); //the crewed gun
gun notify("crew dismounted");
gun.nofire = true;
level notify("stop_cliffgun");
gun thread e1_arty_crew_setup_death(); //setup the arty crew for their death sequence
playfx( level._effect["default_explosion"], exp1_origin );
playsoundatposition( "mortar_dirt", exp1_origin );
radiusdamage( exp1_origin, 512, 1000, 250);
exp1_palm = getent( "e1_cliffgun_bomb01_palm", "targetname" );
exp1_palm thread tree_rotate();
wait(0.4);
playfx( level._effect["default_explosion"], exp2_origin );
playsoundatposition( "mortar_dirt", exp2_origin );
radiusdamage( exp2_origin, 512, 1000, 250);
level.cliff_destroyed show();
level.cliff_intact hide();
gun hide();
level.cliff_gun show();
for(i=0;i<level.cliff_rocks.size;i++)
{
level.cliff_rocks[i] delete();
}
wait(0.4);
playfx( level._effect["default_explosion"], exp3_origin );
playsoundatposition( "mortar_dirt", exp3_origin );
radiusdamage( exp3_origin, 512, 1000, 250);
exp3_palm = getent( "e1_cliffgun_bomb03_palm", "targetname" );
exp3_palm thread tree_rotate();
playfx(level._effect["falling_rocks"], (2010, 625 ,-156.5) );
//temp until the animation gets in
level.cliff_gun moveto( (2095.45 ,603.123, -353) ,2.5);
level.cliff_gun rotateto( ( 47.0138 ,302.803, -85.4194 ),2.4);
wait(1);
level.cliff_gun playsound("gun_slide");
level.cliff_gun waittill("movedone");
playfx(level._effect["gunsmoke"],level.cliff_gun.origin + (0,0,25));
}
///*------------------------------------
//arty crew gets owned if they are alive when
//the gun gets taken out
//------------------------------------*/
#using_animtree("generic_human");
e1_arty_crew_setup_death()
{
//move the arty crew to the edge of the cliff before killing them ( helps to make them always fall off the cliff )
if( isDefined(self.arty_crew) && (self.arty_crew.size > 0) && isAlive(self.arty_crew))
{
for(i=0;i<self.arty_crew.size;i++)
{
self.arty_crew[i].deathanim = %death_explosion_forward13;
throw_guy( self.arty_crew[i], self.arty_crew[i].origin + (500,0,-250) );
}
}
//notify the gun script
self notify ("dismount crew");
//set this flag so that the fake fire script stops ( won't need this once the model3 is setup and scripted )
self.nofire = true;
wait_network_frame();
radiusdamage(self.origin,256,1000,1000);
}
tree_rotate()
{
self rotateto((180, 270, 0), 1.0, 0.2, 0.3);
wait(2.0);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ROCKET BARRAGE STUFF
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fire_rocket_series( launch_points_targetname, destination_vector, total_rockets, silent_launch )
{
// rockets from each ship
num_rockets = total_rockets;
// num_rockets_per_ship = 12;
// grab start points
start_points = [];
orgs = getstructarray( launch_points_targetname, "targetname" );
// populate the ship
q = 0;
for(i = 0; i < num_rockets; i++)
{
q = i % orgs.size;
start_points[i] = orgs[q].origin;
}
level thread rocket_salvo( destination_vector, start_points, silent_launch );
}
rocket_salvo( dest_point, start_points, silent_launch )
{
use_launch_effects = true;
if( isdefined(silent_launch) && silent_launch == true )
{
use_launch_effects = false;
}
for (i = 0; i < start_points.size; i++)
{
rocket = spawn ("script_model", start_points[i]);
rocket setmodel ("peleliu_aerial_rocket");
yaw_vec = vectortoangles(dest_point - rocket.origin);
rocket.angles = (yaw_vec[0], yaw_vec[1] ,0);
rocket.targetname = "oki_salvo_rocket";
// TODO: take out this wait
wait (0.01);
if( use_launch_effects )
{
playfx( level._effect[ "rocket_launch" ], rocket.origin, anglestoforward(rocket.angles + (20,0,0) ) );
}
playfxontag( level._effect[ "rocket_trail" ], rocket, "tag_origin" );
// sound of rocket flying through the air
level thread rocket_sound(rocket);
rocket thread rocket_think((dest_point[0] - 1500 + randomint(3000), dest_point[1] - 1500 + randomint(3000), dest_point[2] + randomint (40)));
wait (randomfloatrange (0.15, 0.3));
}
wait(15);
// forcibly cleanup, because occasionally a rocket sticks around
rockets = getentarray( "oki_salvo_rocket", "targetname" );
if( isDefined(rockets) )
{
////okiPrint( "rocket_salvo: Cleaning up stray rockets!" );
for( i=0; i<rockets.size; i++ )
{
rockets[i] notify( "force delete" );
rockets[i] delete();
}
}
}
// stolen to avoid loading all of _dpad_asset
throw_object_with_gravity( object, target_pos )
{
object endon ("remove thrown object");
start_pos = object.origin; // Get the start position
///////// Math Section
// Reverse the gravity so it's negative, you could change the gravity
// by just putting a number in there, but if you keep the dvar, then the
// user will see it change.
gravity = GetDvarInt( "g_gravity" ) * -1;
// Get the distance
dist = Distance( start_pos, target_pos );
// Figure out the time depending on how fast we are going to
// throw the object... 300 changes the "strength" of the velocity.
// 300 seems to be pretty good. To make it more lofty, lower the number.
// To make it more of a b-line throw, increase the number.
time = dist / 2000;
// Get the delta between the 2 points.
delta = target_pos - start_pos;
// Here's the math I stole from the grenade code. :) First figure out
// the drop we're going to need using gravity and time squared.
drop = 0.5 * gravity * ( time * time );
// Now figure out the trajectory to throw the object at in order to
// hit our map, taking drop and time into account.
velocity = ( ( delta[0] / time ), ( delta[1] / time ), ( delta[2] - drop ) / time );
///////// End Math Section
object MoveGravity( velocity, time );
}
rocket_sound(rocket)
{
//wait(RandomIntRange(2, 5));
counter = RandomIntRange(1,2);
if (counter == 1)
{
rocket playloopsound ("rocket_run");
}
}
rocket_think( destination_pos )
{
// self is the rocket
//self endon ("remove thrown object");
self endon( "force delete" );
thread throw_object_with_gravity( self, destination_pos );
while (1)
{
if (self.origin[2] < destination_pos[2] )
{
playfx(level._effect["lci_rocket_impact"], self.origin);
thread play_sound_in_space ("rocket_dirt", self.origin); // lci rocket impact sound
earthquake( 0.5, 3, self.origin, 2050 );
break;
}
wait (0.05);
}
self notify ("remove thrown object");
// to get shit deleting again
wait (0.1);
self delete();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Throwing guys!
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
throw_guy( guy, targetpos )
{
throw_object_with_gravity( guy, targetpos );
guy StartRagdoll();
}