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

2512 lines
No EOL
63 KiB
Text

main()
{
maps\pby_fly_fx::main();
maps\pby_fly_anim::main();
maps\_aircraft::main( "vehicle_usa_aircraft_f4ucorsair", "corsair");
maps\_aircraft::main( "vehicle_jap_airplane_zero_fly", "zero" );
build_player_planes("pby");
build_enemy_vehicles("zero"); //-- This should take the place of maps\_aircraft::main( "vehicle_jap_airplane_zero_fly", "zero" );
build_enemy_vehicles("jap_ptboat");
build_enemy_vehicles("jap_shinyo");
//-- Precache some stuff
precacheitem("type99_lmg");
precachemodel("vehicle_jap_airplane_zero_d_wingr");
precachemodel("vehicle_jap_airplane_zero_d_wingl");
precachemodel("vehicle_jap_airplane_zero_d_tail");
precachemodel("tag_origin");
//-- Checkpoints and Default Starts
add_start( "crash", ::jumpto_event5 );
add_start( "rescue", ::jumpto_event4 );
add_start( "after_boats", ::jumpto_event3 );
add_start( "turret_tut", ::jumpto_event2 );
add_start( "boat_strafe", ::jumpto_event2_strafe_boats );
//default_start( ::event1 ); //event1
default_start( ::jumpto_event4 );
//level.custom_introscreen = ::pby_custom_introscreen;
maps\_load::main();
//reset the center of the map
SetMapCenter((0,0,0));
//-- Enable the Mitton Water
watersimenable (true);
my_level_init();
}
my_level_init()
{
wait_for_first_player();
//-- Basic Level Var Setup
level.undef = Spawn("script_origin", (0,0,0));
assert(IsDefined(level.undef), "wtf are you defined?");
//-- init flying vars
//level.max_speed = 60; //PBY
level.max_speed = 40; //PBY
level.zero_max_speed = 120;
level.zero_min_speed = 70;
//-- Setup the players on the plane
setup_player_planes();
level notify("planes_inited");
//-- I put this in here for the jumpto functions
level notify("player_plane_inited");
level.players = get_players_pby();
level.players[0].plane = level.plane_a;
for(i=0; i<4; i++)
{
if(IsDefined(level.players[i])&& (level.players[i] != level.undef))
{
level.players[i] thread turret_switch_watch();
level.players[i] setup_seat_control();
level.players[i] thread move_to_pilots_suggested_seat();
level.players[i] DisableTurretDismount();
//TODO: remove this or do it properly somewhere else
level.players[i] thread manage_pilots_suggested_seat();
level.players[i] set_pilots_suggested_seat("pby_rightgun", "pby_frontgun");
}
}
for(i=0; i<4; i++)
{
if(IsDefined(level.players[i])&& (level.players[i] != level.undef))
{
get_players_pby()[i] force_players_into_seat("starting");
}
}
init_callbacks();
//level thread maps\pby_fly_fx::spawn_cloud_effects();
/#
run_special_debug_functions();
#/
level thread debug_hud_elems();
}
debug_hud_elems()
{
level.seat_hud = newHudElem();
level.seat_hud.alignX = "left";
level.seat_hud.x = 20;
level.seat_hud.y = 290;
while(1)
{
level.seat_hud SetText(get_players_pby()[0].current_seat);
wait(0.1);
}
}
//-- Co-op Callback Init
init_callbacks()
{
level thread onPlayerConnect();
}
//-- Sets up the planes with guns/seats
setup_player_planes()
{
level.plane_a = player_pby_init("player_plane_a", "_a");
level.plane_b = player_pby_init("player_plane_b", "_b");
}
//-- setup variables for seat tracking
setup_seat_control(specific_seat)
{
if(!IsDefined(specific_seat))
{
self.current_seat = "undefined";
self.wanted_seat = "undefined";
}
else
{ //-- Used when the player is forced into a specific seat
self.current_seat = specific_seat;
self.wanted_seat = "undefined";
}
}
//-- Controls the Pilot's Suggested Seat and sets that value on the player characters
set_pilots_suggested_seat(suggested_seat, alternate_seat)
{
if(IsDefined(self))
{
self.pilots_suggested_seat = suggested_seat;
self.pilots_alternate_seat = alternate_seat;
}
}
manage_pilots_suggested_seat()
{
if(self.plane == level.plane_a)
{
waittill_ent = level.plane_a;
}
else
{
waittill_ent = level.plane_b;
}
while(1) //infinite loop go!
{
waittill_ent waittill("noteworthy", the_noteworthy);
//setup the specific pilot specified seats using noteworthys from the planes path
switch(the_noteworthy)
{
case "pilot_seats_front_right":
self set_pilots_suggested_seat("pby_frontgun", "pby_rightgun");
break;
case "pilot_seats_front_left":
self set_pilots_suggested_seat("pby_frontgun", "pby_leftgun");
break;
case "pilot_seats_front_rear":
self set_pilots_suggested_seat("pby_frontgun", "pby_backgun");
break;
case "pilot_seats_right_front":
self set_pilots_suggested_seat("pby_rightgun", "pby_frontgun");
break;
case "pilot_seats_right_left":
self set_pilots_suggested_seat("pby_rightgun", "pby_leftgun");
break;
case "pilot_seats_right_rear":
self set_pilots_suggested_seat("pby_rightgun", "pby_backgun");
break;
case "pilot_seats_left_front":
self set_pilots_suggested_seat("pby_leftgun", "pby_frontgun");
break;
case "pilot_seats_left_right":
self set_pilots_suggested_seat("pby_leftgun", "pby_rightgun");
break;
case "pilot_seats_left_rear":
self set_pilots_suggested_seat("pby_leftgun", "pby_backgun");
break;
case "pilot_seats_rear_front":
self set_pilots_suggested_seat("pby_backgun", "pby_frontgun");
break;
case "pilot_seats_rear_right":
self set_pilots_suggested_seat("pby_backgun", "pby_rightgun");
break;
case "pilot_seats_rear_left":
self set_pilots_suggested_seat("pby_backgun", "pby_leftgun");
break;
}
//iprintlnbold("pilot seats adjusted");
}
}
//-- Moves the player to the pilot's favorite seat if they hit the USE button
move_to_pilots_suggested_seat()
{
if(!IsDefined(self.in_saving_position))
{
self.in_saving_position = false;
}
while(true)
{
while(!self useButtonPressed())
{
wait(0.05);
}
if(!self.in_saving_position)
{
switch_successful = self switch_turret(self.pilots_suggested_seat);
if(!switch_successful)
{
switch_successful = self switch_turret(self.pilots_alternate_seat);
}
ASSERTEX(switch_successful, "The player failed to go to the suggested or alternate seat. Something is broken.");
wait(2); //TODO: FIGURE OUT THE ACTUAL TIME FOR THIS
}
else
{
self notify("perform_save");
wait(2);
}
}
}
//-- Returns TRUE if the player is in his proper seat according to the pilot
compare_seat_to_pilots()
{
in_proper_seat = false;
if(self.current_seat == self.pilots_suggested_seat)
{
in_proper_seat = true;
}
if(self.current_seat == self.pilots_alternate_seat)
{
in_proper_seat = true;
}
return in_proper_seat;
}
//-- Level Gameplay Functions --------------------------------------------------------------------------------
//-- Plane starts in the air, PBY calls into nearby fleet, Player gets told the instructions on how to move
event1()
{
//level waittill("finished final intro screen fadein");
//level waittill( "controls_active" );
set_objective("scout_ocean");
//-- starting pby_node
new_starting_node = GetVehicleNode("pby_a_level_start", "targetname");
//-- Start Plane A flying
level.plane_a AttachPath(new_starting_node);
level.plane_a thread maps\_vehicle::vehicle_paths(new_starting_node);
level.plane_a StartPath();
level.max_speed = 40; //slower at the beginning
level.plane_a jumpto_speed(level.max_speed);
level thread event1_dialogue();
level thread event1_player_prints();
//-- wait until specific point in the path, then switch to event2
trig_ev2 = GetEnt("trigger_event2", "targetname");
trig_ev2 waittill("trigger");
event2_strafe_boats();
}
event1_dialogue()
{
//-- intro pilot dialogue
level anim_single_solo(level.plane_a.pilot, "intro");
wait(5);
level anim_single_solo(level.plane_a.radioop, "intro");
wait(5);
level anim_single_solo(level.plane_a.radioop, "intro2");
wait(5);
//-- TODO: add in the radios response
wait(5);
level anim_single_solo(level.plane_a.pilot, "intro2");
wait(15);
level anim_single_solo(level.plane_a.pilot, "do_you_see");
wait(5);
level anim_single_solo(level.plane_a.copilot, "i_see");
wait(3);
level anim_single_solo(level.plane_a.pilot, "ok_form_up");
}
event1_player_prints()
{
iprintlnbold("Use the D-Pad to navigate around the aircraft from turret to turret.");
wait(5);
iprintlnbold("Press X to go to the seat suggested by the Pilot.");
wait(5);
}
take_off_accel()
{
current_speed = self GetSpeedMPH();
//-- Initial rolling speed
while(current_speed < (level.max_speed * 0.3))
{
current_speed = current_speed + 0.3;
self SetSpeedImmediate(current_speed, 0.1, 0.1);
wait(0.1);
}
//-- Getting faster
while(current_speed < (level.max_speed * 0.6))
{
current_speed = current_speed + 1.0;
self SetSpeedImmediate(current_speed, 0.1, 0.1);
wait(0.1);
}
//-- Yay I'm flying
while(current_speed < (level.max_speed))
{
current_speed = current_speed + 1.4;
self SetSpeedImmediate(current_speed, 0.1, 0.1);
wait(0.1);
}
}
jumpto_speed(new_speed)
{
self SetSpeedImmediate(new_speed, 0.1, 0.1);
}
//-- This will display the tutorial text for how to switch between turrets.
//-- It will also handle the tutorial targets that you shoot.
//gp_tutorial_turret()
event2()
{
level thread event3();
level thread spawn_escorting_corsairs();
//-- setup initial strings and hud elem
str_intro = &"PBY_FLY_TUT_INTRO";
str_dpad = &"PBY_FLY_TUT_SWITCH";
level.tut_hud = newHudElem();
level.tut_hud.alignX = "left";
level.tut_hud.x = 20;
level.tut_hud.y = 277;
level.tut_hud SetText(str_intro);
wait(5);
level.tut_hud SetText(str_dpad);
//-- wait until the player switches to a new turret position
//-- check and see if the player is playing co-op
}
spawn_escorting_corsairs()
{
my_trig = GetEnt("spawn_corsair_trig", "targetname");
my_trig waittill("trigger");
rcl_node = GetVehicleNode("right_corsair_lead", "targetname");
rca_node = GetVehicleNode("right_corsair_a", "targetname");
rcb_node = GetVehicleNode("right_corsair_b", "targetname");
corsair_right_lead = spawn_plane_and_pace("corsair", rcl_node, level.plane_a, 1000);
spawn_plane_and_pace("corsair", rca_node, corsair_right_lead, 500);
spawn_plane_and_pace("corsair", rcb_node, corsair_right_lead, 500);
}
watch_for_targets()
{
i = 0;
level.tut_targets = [];
//start_node = GetVehicleNode("start_zero_spawning", "targetname");
start_node = GetVehicleNode("start_chase_zeros", "targetname");
//start_node waittill("trigger");
//level thread turn_on_the_clouds();
level.spawned_hud = newHudElem();
level.spawned_hud.alignX = "left";
level.spawned_hud.x = 20;
level.spawned_hud.y = 303;
level.killed_hud = newHudElem();
level.killed_hud.alignX = "left";
level.killed_hud.x = 20;
level.killed_hud.y = 316;
level.spawned_hud SetText("Zeros Spawned: " + i);
level.killed_hud SetText("Zeros Killed: " + i);
ai_type = "doodoo";
level thread debug_watch_dead_zeros();
while(1)
{
ai_type = "basic_rear";
/*
//TODO: TURN THIS INTO THE ACTUAL TARGET TRAINING
if(RandomInt(2) == 1)
{
ai_type = "intercept_right";
}
else
{
ai_type = "intercept_left";
}
*/
level.tut_targets[i] = spawn_enemy_plane("zero", "tut_plane" +i, ai_type);
if(!IsDefined(level.tut_targets[i]))
{
break;
}
i++;
level.spawned_hud SetText("Zeros Spawned: " + i);
wait(5);
}
}
//TODO: FINISH THIS SO IT WORKS FOR BOTH PLANES
turn_on_the_clouds()
{
cloud_fx = playloopedfx(level._effect["ambient_clouds"], 3, level.plane_a.origin, 0);
}
debug_watch_dead_zeros()
{
i = 0;
while(1)
{
level waittill("zero_killed");
i++;
level.killed_hud SetText("Zeros Killed: " + i);
}
}
//-- This is the event where the player(s) taxi to the victim(s) and rescue the victim(s) from the water
event3()
{
iprintlnbold("THE SUN RISES");
level thread event3_ambient();
level thread event3_dialogue();
level.plane_a waittill("reached_end_node");
new_start_node = GetVehicleNode("circling_start_node", "targetname");
level.plane_a AttachPath(new_start_node);
level.plane_a thread maps\_vehicle::vehicle_paths(new_start_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
level thread event4();
}
event3_dialogue()
{
wait(5);
level anim_single_solo(level.plane_a.radioop, "recieved_distress"); //"print: We just received a distress call from that naval fleet.";
wait(5);
level anim_single_solo(level.plane_a.radioop, "kamikaze_attack"); //"print: Sounds like they were victim of a jap kamikaze ambush.";
wait(5);
level anim_single_solo(level.plane_a.radioop, "requesting_help"); //"print: They are requesting help from anyone in the area. Do we have enough fuel to go help out?";
wait(5);
level anim_single_solo(level.plane_a.pilot, "save_and_fuel"); //"print: It doesn't matter if we have enough fuel! Tell them we are on the way!";
set_objective("respond_to_distress_call");
}
//-- This should handle the dog fights that are happening above the wreckage
//-- Need about 10 planes total probably
event3_ambient()
{
df_splines = [];
df_splines[0] = GetVehicleNode("dogfight_spline_00", "targetname");
df_splines[1] = GetVehicleNode("dogfight_spline_01", "targetname");
df_splines[2] = GetVehicleNode("dogfight_spline_02", "targetname");
//-- Spawn the fleeing planes and set them on the spline
level thread spawn_plane_loop_spline("corsair", df_splines[0]);
level thread spawn_plane_loop_spline("zero", df_splines[1]);
level thread spawn_plane_loop_spline("corsair", df_splines[2]);
wait(2);
//-- Spawn the pursuing planes and set them on the spline
level thread spawn_plane_loop_spline("zero", df_splines[0]);
level thread spawn_plane_loop_spline("corsair", df_splines[1]);
level thread spawn_plane_loop_spline("zero", df_splines[2]);
wait(10);
level thread spawn_plane_loop_spline("corsair", df_splines[0]);
wait(0.2);
level thread spawn_plane_loop_spline("zero", df_splines[1]);
wait(0.2);
level thread spawn_plane_loop_spline("zero", df_splines[2]);
wait(2.6);
level thread spawn_plane_loop_spline("zero", df_splines[0]);
wait(0.2);
level thread spawn_plane_loop_spline("corsair", df_splines[1]);
wait(0.3);
level thread spawn_plane_loop_spline("corsair", df_splines[2]);
}
spawn_plane_loop_spline(type, start_node)
{
plane = level.undef;
model = "vehicle_jap_airplane_zero_fly";
t_name = start_node.targetname + type;
position = start_node.origin;
ang = start_node.angles;
if(type == "zero")
{
model = "vehicle_jap_airplane_zero_fly";
t_name = start_node.targetname + type;
type = "zero";
position = start_node.origin;
ang = start_node.angles;
}
else if(type == "corsair")
{
model = "vehicle_usa_aircraft_f4ucorsair";
t_name = start_node.targetname + type;
type = "corsair";
position = start_node.origin;
ang = start_node.angles;
}
else
{
ASSERTEX(false, "You have a spelling error somewhere.");
}
plane = SpawnVehicle(model, t_name, type, position, ang);
while(1)
{
plane AttachPath(start_node);
plane StartPath();
plane SetSpeed(60, 20, 20);
plane waittill("reached_end_node");
}
}
spawn_plane_and_pace(type, start_node, lead_plane, distance)
{
plane = level.undef;
model = "vehicle_jap_airplane_zero_fly";
t_name = start_node.targetname + type;
position = start_node.origin;
ang = start_node.angles;
if(type == "corsair")
{
model = "vehicle_usa_aircraft_f4ucorsair";
t_name = start_node.targetname + type;
type = "corsair";
position = start_node.origin;
ang = start_node.angles;
}
else
{
ASSERTEX(false, "You have a spelling error somewhere.");
}
plane = SpawnVehicle(model, t_name, type, position, ang);
plane AttachPath(start_node);
plane StartPath();
plane SetSpeed(level.max_speed, 20, 20);
if(!IsDefined(distance))
{
distance = 30;
}
plane thread corsair_pby_pacing(lead_plane, distance);
return plane;
}
//-- This is the saving event that is long and overly complicated because I love a huge scripting mess
event4()
{
rescue_scene_init();
stop_node = GetVehicleNode("stop_for_rescue_1_a", "targetname");
stop_node waittill("trigger");
level.plane_a SetSpeed(0,100,100);
//-- This is a boat test
test_boat = GetEnt("test_boat", "targetname");
test_boat.scriptname = "test_boat";
test_boat thread track_damage_and_sink();
test_boat_node = GetVehicleNode("boat_test_node", "targetname");
test_boat AttachPath(test_boat_node);
test_boat StartPath();
test_boat SetSpeed(10, 10, 10);
//test_boat waittill("reached_end_node");
//-- This is where the first rescue will happen
wait(2);
for(i = 0; i < level.survivors_group_1.size; i++)
{
level.survivors_group_1[i] notify("swimming_notify" + i);
level.survivors_group_1[i] thread rescue_scenario();
level.survivors_group_1[i] waittill("rescued");
}
wait(5);
//-- This is where the slo-mo event will happen
//-- Taxi to the next section
level.plane_a SetSpeed(20, 10, 10);
//-- Stop for 2nd rescue
stop_node = GetVehicleNode("stop_for_rescue_2_a", "targetname");
stop_node waittill("trigger");
level.plane_a SetSpeed(0, 100, 100);
//-- This is where the second rescue will happen
wait(5);
//-- Take off into event 5
level.plane_a SetSpeed(20, 10, 10);
level.plane_a waittill("reached_end_node");
iprintlnbold(" Zero Zig Zag Event Coming Soon! END SCRIPT ");
/* ------------------------------- THIS IS OLD EVENT 4 SCRIPT ----------------------------------------------
level.plane_a waittill("rescue_done");
taxi_start_node = GetVehicleNode("plane_a_taxi_start_b", "targetname");
level.plane_a AttachPath(taxi_start_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
//TODO: make this happen at a specific place
level thread watch_for_targets();
level thread switching_to_occupied_turret_text();
level thread event5(); //-- Next event fires at the end of the path.
*/
}
rescue_scenario()
{
self waittill("ready_to_be_saved");
possible_player = level.undef;
while(possible_player == level.undef)
{
wait(0.1);
possible_player = is_there_a_player_in_seat(self.plane, self.side);
}
possible_player.in_saving_position = true;
possible_player waittill("perform_save");
self notify("being saved");
possible_player thread play_rescue_animation(self.plane, self.side);
self.animname = "being_saved";
self anim_single_solo(self, "enter_pby");
bunk_tag = get_empty_bunk(self.plane);
if(bunk_tag == "tag_bunk_left_bottom")
{
self.animname = "rescue_a_4";
self.plane thread anim_loop_solo(self, "my_idle", bunk_tag);
}
else if(bunk_tag == "tag_bunk_left_top")
{
self.animname = "rescue_a_3";
self.plane thread anim_loop_solo(self, "my_idle", bunk_tag);
}
else if(bunk_tag == "tag_bunk_right_bottom")
{
self.animname = "rescue_a_1";
self.plane thread anim_loop_solo(self, "my_idle", bunk_tag);
}
else //tag_bunk_right_top
{
self.animname = "rescue_a_2";
self.plane thread anim_loop_solo(self, "my_idle", bunk_tag);
}
self LinkTo(self.plane, bunk_tag);
self notify("rescued");
}
play_rescue_animation(plane, side)
{
//-- Take the player off of the plane
plane UseBy(self);
if(side == "left")
{
anim_str = "pby_left_rescue";
}
else
{
anim_str = "pby_right_rescue";
}
//-- plays the animation
startorg = getstartOrigin( plane.origin, plane.angles, level.scr_anim[ "player_hands" ][ anim_str ] );
startang = getstartAngles( plane.origin, plane.angles, level.scr_anim[ "player_hands" ][ anim_str ] );
player_hands = spawn_anim_model( "player_hands" );
player_hands.origin = startorg;
player_hands.angles = startang;
player_hands LinkTo(plane);
self.origin = player_hands.origin;
self.angles = player_hands.angles;
self PlayerLinkTo(player_hands, "tag_player", 1.0, 10, 10, 10, 10);
plane maps\_anim::anim_single_solo( player_hands, anim_str );
player_hands delete();
//-- end playing the animation
if(self.current_seat == "pby_leftgun")
{
plane usevehicle(self, 2);
}
else
{
plane usevehicle(self, 3);
}
}
get_empty_bunk(plane)
{
for(i=0; i < plane.bunks.size; i++)
{
if(plane.bunks[i]["status"] == "empty")
{
//tag_position = plane GetTagOrigin(plane.bunks[i]["tag"];
//return tag_position;
plane.bunks[i]["status"] = "full";
return plane.bunks[i]["tag"];
}
}
ASSERTEX(false, "THERE WERE NO FREE BUNKS");
}
is_there_a_player_in_seat(plane, seat)
{
if(seat == "left")
{
seat_wanted = "pby_leftgun";
}
else
{
seat_wanted = "pby_rightgun";
}
current_players = get_players_pby();
for(i=0; i<current_players.size; i++)
{
if(current_players[i] != level.undef)
{
//if( pick_proper_plane(current_players[i]) == plane )
//{
if(current_players[i].current_seat == seat_wanted)
{
return current_players[i];
}
//}
}
}
return level.undef;
}
rescue_scene_init()
{
//spawn first group of survivors
surv_spawners = [];
surv_spawners = GetEntArray("survivor_rescue_1", "targetname");
level.survivors_group_1 = [];
for(i = 0; i<surv_spawners.size; i++)
{
level.survivors_group_1[i] = surv_spawners[i] StalingradSpawn();
level.survivors_group_1[i] thread survivor_init(level.plane_a, "_group_1", i);
}
}
#using_animtree ("generic_human");
//sets the survivor up to go to his goal saving position
survivor_init(plane, group, id)
{
//-- assign the guy his side
self.plane = plane;
self.side = self.script_noteworthy;
self.animname = "survivor_" + id;
self.run_noncombatanim = %ch_pby_swimming_soldier;
//setup the treading activity
self.activity = "treading";
self thread survivor_wave();
self waittill("swimming_notify" + id);
//-- send the guy to his new goal position, then raise the "i need to be saved signal", the make the player save them.
self.goalradius = 32;
goal_pos = (0,0,0);
if(self.side == "left")
{
goal_pos = plane GetTagOrigin("tag_blister_left_rescue");
}
else
{
goal_pos = plane GetTagOrigin("tag_blister_right_rescue");
}
self.activity = "swimming";
self SetGoalPos(goal_pos);
self waittill("goal");
self.activity = "treading";
self thread survivor_wave();
self notify("ready_to_be_saved");
if(self.side == "left")
{
iprintlnbold("Left Blister - survivor ready");
}
else
{
iprintlnbold("Right Blister - survivor ready");
}
}
//-- play the treading water/waving animation on the survivors when they aren't swimming or at the boat
survivor_wave()
{
//TODO: Look into this being played as an actual animloop, instead of as a looping anim_single_solo
self endon("being saved");
//self anim_single_solo(self, "enter_pby");
//anim_loop( guy, anime, tag, ender, node, tag_entity )
//self anim_loop_solo( self, "float", undefined, "end_floating");
while(self.activity == "treading")
{
self anim_single_solo(self, "float");
}
//self notify("end_floating");
}
//-- This is the EMERGENCY LANDING!!! BLAMMO
event5()
{
level.plane_a waittill("reached_end_node");
iprintlnbold("THE EMERGENCY ANIMATION GOES HERE");
missionsuccess("hol2",false);
}
//-- Player on the plane functions --------------------------------------------------------------------------------
//-- Inits all the values for each player plane
player_pby_init(plane_name, crew_id)
{
plane = GetEnt(plane_name, "targetname");
plane.plane_name = plane_name;
plane.crew_id = crew_id;
plane.front = "empty";
plane.left = "empty";
plane.right = "empty";
plane.back = "empty";
plane.bunks = [];
plane.bunks[0]["status"] = "empty";
plane.bunks[1]["status"] = "empty";
plane.bunks[2]["status"] = "empty";
plane.bunks[3]["status"] = "empty";
plane.bunks[0]["tag"] = "tag_bunk_left_bottom";
plane.bunks[1]["tag"] = "tag_bunk_left_top";
plane.bunks[2]["tag"] = "tag_bunk_right_bottom";
plane.bunks[3]["tag"] = "tag_bunk_right_top";
plane pby_crew_init();
plane thread pby_crew_idles();
return(plane);
}
//-- Sets up the crew for the plane
pby_crew_init()
{
//-- Pilot
pilot_spawner = GetEnt(self.plane_name + "_pilot", "targetname");
self.pilot = pilot_spawner StalingradSpawn();
//self.pilot LinkTo(self, "tag_pilot", (0,0,0), (0,0,0));
self.pilot.animname = "pilot" + self.crew_id;
//-- Co-Pilot
copilot_spawner = GetEnt(self.plane_name + "_copilot", "targetname");
self.copilot = copilot_spawner StalingradSpawn();
//self.copilot LinkTo(self, "tag_copilot", (0,0,0), (0,0,0));
self.copilot.animname = "copilot" + self.crew_id;
//-- Radio Operator
radioop_spawner = GetEnt(self.plane_name + "_radioop", "targetname");
self.radioop = radioop_spawner StalingradSpawn();
//self.radioop LinkTo(self, "tag_radioop", (0,0,0), (0,0,0));
self.radioop.animname = "radio_op" + self.crew_id;
//-- Engineer
engineer_spawner = GetEnt(self.plane_name + "_engineer", "targetname");
self.engineer = engineer_spawner StalingradSpawn();
//self.engineer LinkTo(self, "tag_engineer", (0,0,0), (0,0,0));
self.engineer.animname = "engineer" + self.crew_id;
}
pby_crew_idles()
{
//TODO: HOOK THIS UP FOR THE 2ND CREW
if(self.crew_id == "_b")
{
return;
}
self thread anim_loop_solo(self.pilot, "my_idle", "tag_pilot", "stop_idling");
self.pilot LinkTo(self, "tag_pilot");
self thread anim_loop_solo(self.copilot, "my_idle", "tag_copilot", "stop_idling");
self.copilot LinkTo(self, "tag_copilot");
self thread anim_loop_solo(self.radioop, "my_idle", "navigator_seat_jnt", "stop_idling");
self.radioop LinkTo(self, "navigator_seat_jnt");
self thread anim_loop_solo(self.engineer, "my_idle", "tag_engineer", "stop_idling");
self.engineer LinkTo(self, "tag_engineer");
}
//-- fires off when the weapon is changed
turret_switch_watch()
{
for(;;)
{
self waittill("weapon_change_on_turret", weapon_name);
//self waittill("weapon_change");
self switch_turret(weapon_name);
}
}
//-- Moves the player around the plane based on the selected seat.
switch_turret(weapon_name)
{
if(IsDefined(self.seat_locked))
{
if(self.seat_locked)
{
return false; //-- Players seat is locked and he can't switch
}
}
plane = "undefined";
plane = pick_proper_plane(self);
self.wanted_seat = weapon_name;
if(self.wanted_seat == "pby_frontgun")
{
if(plane.front == "empty")
{
plane.front = "has_player";
self play_transition_to_front(plane);
plane usevehicle(self, 1);
}
}
else if(self.wanted_seat == "pby_leftgun")
{
if(plane.left == "empty")
{
plane.left = "has_player";
self play_transition_to_left(plane);
plane usevehicle(self, 2);
}
}
else if(self.wanted_seat == "pby_rightgun")
{
if(plane.right == "empty")
{
plane.right = "has_player";
self play_transition_to_right(plane);
plane usevehicle(self, 3);
}
}
else if(self.wanted_seat == "pby_backgun")
{
if(plane.back == "empty")
{
plane.back = "has_player";
self play_transition_to_rear(plane);
plane usevehicle(self, 4);
}
}
else //The wanted seat was not available
{
return false; //non successful seat found
}
switch(self.current_seat)
{
case "pby_frontgun":
plane.front = "empty";
break;
case "pby_leftgun":
plane.left = "empty";
break;
case "pby_rightgun":
plane.right = "empty";
break;
case "pby_backgun":
plane.back = "empty";
break;
default:
break;
}
self.current_seat = self.wanted_seat;
self.wanted_seat = -1;
return true; //successful seat switch
}
play_transition_to_rear(plane)
{
switch(self.current_seat)
{
case "pby_frontgun":
self play_transition_animation(plane, "pby_front_to_rear");
break;
case "pby_leftgun":
self play_transition_animation(plane, "pby_left_to_rear");
break;
case "pby_rightgun":
self play_transition_animation(plane, "pby_right_to_rear");
break;
default:
break;
}
}
play_transition_to_front(plane)
{
switch(self.current_seat)
{
case "pby_backgun":
self play_transition_animation(plane, "pby_rear_to_front");
break;
case "pby_leftgun":
self play_transition_animation(plane, "pby_left_to_front");
break;
case "pby_rightgun":
self play_transition_animation(plane, "pby_right_to_front");
break;
default:
break;
}
}
play_transition_to_right(plane)
{
switch(self.current_seat)
{
case "pby_frontgun":
self play_transition_animation(plane, "pby_front_to_right");
break;
case "pby_leftgun":
self play_transition_animation(plane, "pby_left_to_right");
break;
case "pby_backgun":
self play_transition_animation(plane, "pby_rear_to_right");
break;
default:
break;
}
}
play_transition_to_left(plane)
{
switch(self.current_seat)
{
case "pby_frontgun":
self play_transition_animation(plane, "pby_front_to_left");
break;
case "pby_backgun":
self play_transition_animation(plane, "pby_rear_to_left");
break;
case "pby_rightgun":
self play_transition_animation(plane, "pby_right_to_left");
break;
default:
break;
}
}
play_transition_animation(plane, anim_str)
{
//-- Take the player off of the plane
plane UseBy(self);
//-- plays the animation
startorg = getstartOrigin( plane.origin, plane.angles, level.scr_anim[ "player_hands" ][ anim_str ] );
startang = getstartAngles( plane.origin, plane.angles, level.scr_anim[ "player_hands" ][ anim_str ] );
player_hands = spawn_anim_model( "player_hands" );
player_hands.origin = startorg;
player_hands.angles = startang;
player_hands LinkTo(plane);
//TODO: I think this is a hack and it seems like PlayerLinkTo isn't actually really linking the player and it's not clamping the angles.
self.origin = player_hands.origin;
self.angles = player_hands.angles;
//self PlayerLinkTo(player_hands, "tag_player", 1.0, 20, 20, 10, 10);
self PlayerLinkTo(player_hands, "tag_player", 1.0, 10, 10, 10, 10);
//self PlayerLinkTo(player_hands);
plane maps\_anim::anim_single_solo( player_hands, anim_str );
player_hands delete();
//-- end playing the animation
}
//-- returns the proper plane for me based on which player me is
pick_proper_plane( me )
{
placeholder = get_players_pby();
for(i=0; i<4; i++)
{
if(IsDefined(placeholder[i]))
{
if(me == placeholder[i])
{
/* TODO: MAKE THIS 2 PLANES AGAIN
if(i == 0 || i == 2)
{
return level.plane_a;
}
else
{
return level.plane_b;
}
*/
return level.plane_a;
}
}
}
}
//-- This is used to place players in specific seats during
//-- specific sections of gameplay
force_players_into_seat(position_string)
{
plane = pick_proper_plane(self);
switch(position_string) //-- The position that the players start in for the map
{
case "starting":
if(self.play_tag == "player_1")
{
plane.back = "has_player";
//plane.gun_back UseBy(self);
plane usevehicle(self, 4); //TODO CHANGE THIS BACK to 4
self setup_seat_control("pby_backgun");
}
else if(self.play_tag == "player_2")
{
plane.right = "has_player";
//plane.gun_right UseBy(self);
plane usevehicle(self, 3);
self setup_seat_control("pby_rightgun");
}
else if(self.play_tag == "player_3")
{
plane.left = "has_player";
//plane.gun_left UseBy(self);
plane usevehicle(self, 2);
self setup_seat_control("pby_leftgun");
}
else if(self.play_tag == "player_4")
{
plane.left = "has_player";
//plane.gun_left UseBy(self);
plane usevehicle(self, 2);
self setup_seat_control("pby_leftgun");
}
else
{
ASSERTEX(false, "The player being forced into a seat doesn't exist");
}
break;
case "rescue": //-- The position that the player's have to be in for the rescue portion of the map
if(self.play_tag == "player_1")
{
}
else if(self.play_tag == "player_2")
{
}
else if(self.play_tag == "player_3")
{
}
else if(self.play_tag == "player_4")
{
}
else
{
ASSERTEX(false, "The player being forced into a seat doesn't exist");
}
break;
default:
break;
}
}
//-- Initialize the specific loadouts of the plane for the mission ------------------------------------------------
//-- Builds Custom Player Plane
build_player_planes( type ) //-- There might be more than one type... maybe... or something...
{
model = undefined;
death_model = undefined;
death_fx = "explosions/large_vehicle_explosion";
death_sound = "explo_metal_rand";
bombs = false;
turretType = "default_aircraft_turret";
turretModel = "weapon_machinegun_tiger";
func = undefined;
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
if( type == "pby" )
{
model = "vehicle_usa_pby_exterior";
death_fx = "explosions/large_vehicle_explosion";
death_model = "vehicle_usa_pby_exterior";
health = 10000;
min_health = 9999;
max_health = 10001;
team = "allies";
func = ::pby_plane_init;
}
maps\_vehicle::build_template( "stuka", model, type );
maps\_vehicle::build_localinit( func );
maps\_vehicle::build_deathmodel( model, death_model );
maps\_vehicle::build_deathfx( death_fx, "tag_engine", death_sound, undefined, undefined, undefined, undefined ); // TODO change to actual explosion fx/sound when we get it
maps\_vehicle::build_life( health, min_health, max_health );
maps\_vehicle::build_treadfx();
maps\_vehicle::build_team( team );
}
pby_plane_init()
{
//-- empty currently
}
//-- Builds Custom Enemy Planes and Boat
//---- more specifically this is where you setup the planes that will break into multiple pieces as they take damage.
//---- this also includes the pt_boat
build_enemy_vehicles( type )
{
model = undefined;
death_model = undefined;
death_fx = "explosions/large_vehicle_explosion";
death_sound = "explo_metal_rand";
bombs = false;
turretType = "default_aircraft_turret";
turretModel = "weapon_machinegun_tiger";
func = undefined;
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
if( type == "zero" )
{
model = "vehicle_jap_airplane_zero_d_fuselage";
death_fx = "explosions/large_vehicle_explosion";
death_model = "vehicle_jap_airplane_zero_d_fuselage";
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
func = ::zero_plane_init;
level.vehicle_death_thread[type] = ::zero_death_thread;
}
if( type == "zero_old" )
{
model = "vehicle_jap_airplane_zero_fly";
death_fx = "explosions/large_vehicle_explosion";
death_model = "vehicle_jap_airplane_zero_fly";
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
func = ::zero_plane_init;
level.vehicle_death_thread[type] = ::zero_death_thread;
}
if( type == "jap_ptboat" )
{
model = "vehicle_jap_ship_ptboat";
death_fx = "explosions/large_vehicle_explosion";
death_model = "vehicle_jap_ship_ptboat";
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
func = ::pt_boat_init;
level.vehicle_death_thread[type] = ::pt_boat_death_thread;
}
if( type == "jap_shinyo" )
{
model = "vehicle_jap_ship_shinyou";
death_fx = "explosions/large_vehicle_explosion";
death_model = "vehicle_jap_ship_shinyou";
health = 15;
min_health = 10;
max_health = 20;
team = "axis";
func = ::shinyo_boat_init;
level.vehicle_death_thread[type] = ::shinyo_boat_death_thread;
}
maps\_vehicle::build_template( "stuka", model, type );
maps\_vehicle::build_localinit( func );
maps\_vehicle::build_deathmodel( model, death_model ); //-- We should need to do this
if(type != "jap_ptboat" && type != "jap_shinyo")
{
maps\_vehicle::build_deathfx( death_fx, "tag_engine", death_sound, undefined, undefined, undefined, undefined ); // TODO change to actual explosion fx/sound when we get it
}
else
{
maps\_vehicle::build_deathfx( death_fx, "tag_engine_left", death_sound, undefined, undefined, undefined, undefined ); // TODO change to actual explosion fx/sound when we get it
}
maps\_vehicle::build_life( health, min_health, max_health );
maps\_vehicle::build_treadfx();
maps\_vehicle::build_team( team );
if(type != "jap_ptboat")
{
maps\_vehicle::build_turret( turretType, "tag_gunLeft", turretModel, true );
maps\_vehicle::build_turret( turretType, "tag_gunRight", turretModel, true );
}
}
spawn_enemy_plane( type, t_name, ai_type )
{
model = undefined;
if( type == "zero" )
{
model = "vehicle_jap_airplane_zero_d_fuselage";
}
if( type == "zero_old" )
{
model = "vehicle_jap_airplane_zero_fly";
}
if( !IsDefined( t_name ) )
{
t_name = "switch_to_undefined";
}
plane_vals = ai_pilot_prethink(ai_type);
if(!plane_vals["is_plane_valid"])
{
return undefined;
}
plane = SpawnVehicle( model, t_name, type, plane_vals["org"], plane_vals["ang"] );
plane.vehicletype = type;
maps\_vehicle::vehicle_init(plane);
plane.ai_type = ai_type;
plane setturningability(0.9);
if( t_name == "switch_to_undefined" )
{
plane.targetname = undefined;
}
//-- Setup all of the planes values based on the pre-think
for(i=0; i < GetArrayKeys(plane_vals).size; i++)
{
index = GetArrayKeys(plane_vals)[i];
plane.pilot_vals[index] = plane_vals[index];
}
plane thread ai_pilot_think(ai_type);
//compass
plane AddVehicleToCompass();
return plane;
}
zero_plane_init()
{
//-- specific inits to the Zero
//-- Assemble the rest of the planes parts
self.right_wing = Spawn("script_model", self.origin);
self.right_wing SetModel("vehicle_jap_airplane_zero_d_wingr");
self.right_wing LinkTo(self, "tag_attach_wing_RI", (0,0,0), (0,0,0));
self.right_wing.health = 1000;
self.right_wing SetCanDamage(true);
self.right_wing.name_str = "right_wing";
self.left_wing = Spawn("script_model", self.origin);
self.left_wing SetModel("vehicle_jap_airplane_zero_d_wingl");
self.left_wing LinkTo(self, "tag_attach_wing_LE", (0,0,0), (0,0,0));
self.left_wing.health = 1000;
self.left_wing SetCanDamage(true);
self.left_wing.name_str = "left_wing";
self.tail = Spawn("script_model", self.origin);
self.tail SetModel("vehicle_jap_airplane_zero_d_tail");
self.tail LinkTo(self, "tag_attach_tail", (0,0,0), (0,0,0));
self.tail.health = 1000;
self.tail SetCanDamage(true);
self.tail.name_str = "tail";
/*
self thread drawTagForever( "tag_attach_wing_RI", ( 0.9, 0.2, 0.2 ) );
self thread drawTagForever( "tag_attach_wing_LE", ( 0.9, 0.2, 0.2 ) );
self thread drawTagForever( "tag_attach_tail", ( 0.9, 0.2, 0.2 ) );
self.right_wing thread drawTagForever( "tag_origin", ( 0.2, 0.9, 0.2 ) );
self.left_wing thread drawTagForever( "tag_origin", ( 0.2, 0.9, 0.2 ) );
self.tail thread drawTagForever( "tag_origin", ( 0.2, 0.9, 0.2 ) );
*/
wait(0.1); //-- Let the rest of the init function in _vehicle.gsc run before adjusting it
self notify( "stop_friendlyfire_shield" ); //-- Stop the built in friendlyfire_shield()
self thread zero_damage_thread();
}
zero_damage_thread()
{
self endon( "death" );
self.healthbuffer = 20000;
self.health += self.healthbuffer;
self.currenthealth = self.health;
attacker = undefined;
amount = undefined;
part_of_plane = undefined;
self.right_wing thread zero_piece_damage_thread(self);
self.left_wing thread zero_piece_damage_thread(self);
self.tail thread zero_piece_damage_thread(self);
self thread zero_piece_damage_thread(self);
while( self.health > 0 )
{
self waittill("partial_damage", amount, part_of_plane);
self.health = self.health - amount;
if( self.health < self.healthbuffer )
break;
}
if(IsDefined(part_of_plane.name_str))
{
self.last_damage = part_of_plane.name_str;
}
else
{
self.last_damage = "fuselage";
}
self.right_wing notify("death");
self.left_wing notify("death");
self.tail_wing notify("death");
self notify( "death", attacker );
}
zero_piece_damage_thread(fuselage)
{
self endon("death");
amount = undefined;
self.team = "axis";
while(1)
{
self waittill("damage", amount);
//self.health = self.health - amount;
fuselage notify("partial_damage", amount, self);
}
}
zero_death_thread()
{
//-- specific thread for a zero's death
//self notify("death");
//self setspeed(0, 1000, 1000);
//self endon("death");
//TODO: REMOVE THIS
level notify("zero_killed");
self RemoveVehicleFromCompass();
crashing_plane = Spawn("script_model", self.origin);
crashing_plane SetModel("vehicle_jap_airplane_zero_d_fuselage");
crashing_plane.angles = self.angles;
//-- unlink parts from vehicle
self hide();
self.right_wing unlink();
self.left_wing unlink();
self.tail unlink();
//-- relink parts to new script model
self.right_wing LinkTo(crashing_plane, "tag_attach_wing_RI", (0,0,0), (0,0,0));
self.left_wing LinkTo(crashing_plane, "tag_attach_wing_LE", (0,0,0), (0,0,0));
self.tail LinkTo(crashing_plane, "tag_attach_tail", (0,0,0), (0,0,0));
switch(self.last_damage)
{
case "right_wing":
self.right_wing unlink();
crashing_plane MoveGravity(VectorNormalize(AnglesToForward(self.angles - (0, 45, 0))) * self getspeed(), 10);
self.right_wing MoveGravity(VectorNormalize(AnglesToForward(self.angles + (0, 45, 0))) * (self getspeed() * 0.5), 10);
break;
case "left_wing":
self.left_wing unlink();
crashing_plane MoveGravity(VectorNormalize(AnglesToForward(self.angles + (0, 45, 0))) * self getspeed(), 10);
self.left_wing MoveGravity(VectorNormalize(AnglesToForward(self.angles - (0, 45, 0))) * (self getspeed() * 0.5), 10);
break;
case "tail":
self.tail unlink();
crashing_plane MoveGravity(VectorNormalize(AnglesToForward(self.angles)) * self getspeed(), 10);
break;
case "fuselage":
crashing_plane MoveGravity(VectorNormalize(AnglesToForward(self.angles)) * self getspeed(), 10);
break;
default:
//ASSERTEX(false, "Plane crashed in a non-handled manner");
break;
}
self notify( "crash_done" );
}
pt_boat_init()
{
self.script_crashtypeoverride = "none"; //-- should keep this from running the airplane crash code
}
pt_boat_death_thread()
{
//TODO: REMOVE THIS
iprintlnbold("pt_boat_destroyed");
self notify( "crash_done" );
}
shinyo_boat_init()
{
self.script_crashtypeoverride = "none"; //-- should keep this from running the airplane crash code
}
shinyo_boat_death_thread()
{
//iprintlnbold("shinyo_destroyed");
self SetSpeed(0, 5, 5);
self notify("crash_done");
}
ai_pilot_prethink(ai_type)
{
new_plane_vals = [];
//new_plane_vals["speed_offset"] = the offset of speed faster than the target;
//new_plane_vals["strafe_start_pos"] = the location that the plane starts in: ("rear", "front", etc);
//new_plane_vals["strafe_start_val"] = the distance offset from the target plane that the new plane spawns in at;
//new_plane_vals["strafe_end_pos"] = the position that the plane will end it's strafing run at;
//new_plane_vals["strafe_end_val"] = the distance offset from the target plane that the plane will stop its strafing run;
//new_plane_vals["end_strafe_action"] = the action taken when the plane reaches the end of its strafing path: ("death", "loop_around", "start_tailing", etc);
switch(ai_type)
{
case "basic_rear":
//-- move 10 faster than the target
new_plane_vals["speed_offset"] = 10;
//-- start attack 500 units from the rear
new_plane_vals["strafe_start_pos"] = "rear";
new_plane_vals["strafe_start_val"] = 500;
//-- end attack 500 units to the front
new_plane_vals["strafe_end_pos"] = "front";
new_plane_vals["strafe_end_val"] = 4000;
//-- what to do at the end of a strafing run
new_plane_vals["end_strafe_action"] = "death";
break;
case "intercept_right":
case "intercept_left":
new_plane_vals["speed_offset"] = 30;
//-- start attack 500 units from the rear
if(ai_type == "intercept_right") new_plane_vals["strafe_start_pos"] = "front_right";
if(ai_type == "intercept_left") new_plane_vals["strafe_start_pos"] = "front_left";
new_plane_vals["strafe_start_val"] = 20000;
//-- end attack 500 units to the front
if(ai_type == "intercept_right") new_plane_vals["strafe_end_pos"] = "right";
if(ai_type == "intercept_left") new_plane_vals["strafe_end_pos"] = "left";
new_plane_vals["strafe_end_val"] = 500;
//-- what to do at the end of a strafing run
new_plane_vals["end_strafe_action"] = "peel_off";
//-- SPECIFIC TO INTERCEPT FLIGHT
new_plane_vals["target_offset"] = 200;
new_plane_vals["max_height_diff"] = 200;
break;
default:
break;
}
//-- TODO: MAKE IT SO THIS TARGETS ALL THE PLAYERS, NOT JUST PLAYER 1
new_plane_vals["target"] = pick_proper_plane(get_players_pby()[0]);
switch(new_plane_vals["strafe_start_pos"])
{
case "rear":
new_plane_vals["org"] = new_plane_vals["target"].origin - ( VectorNormalize(AnglesToForward(new_plane_vals["target"].angles)) * new_plane_vals["strafe_start_val"]);
new_plane_vals["ang"] = new_plane_vals["target"].angles;
break;
case "front":
//-- empty
break;
case "front_right":
case "front_left":
ref_point = new_plane_vals["target"].origin + ( (VectorNormalize(AnglesToForward(new_plane_vals["target"].angles))* (1,0.1,1)) * 500); //-- The 2000 here is completely arbitrary
ref_ang = (0,0,0);
if(new_plane_vals["strafe_start_pos"] == "front_right") ref_ang = new_plane_vals["target"].angles - (0,RandomIntRange(160, 180),0);
if(new_plane_vals["strafe_start_pos"] == "front_left") ref_ang = new_plane_vals["target"].angles + (0,RandomIntRange(160, 180),0);
new_plane_vals["org"] = ref_point + (VectorNormalize(AnglesToForward(ref_ang)) * new_plane_vals["strafe_start_val"]) + /*elevation*/ (0, 0, RandomIntRange(-400, 400)) ;
new_plane_vals["ang"] = VectorNormalize(ref_point - new_plane_vals["org"]);
new_plane_vals["target_point"] = ref_point;
break;
default:
//-- empty
break;
}
//-- Check to see if plane is spawned inside the map
new_plane_vals["is_plane_valid"] = true;
if(new_plane_vals["org"][0] > 65000 || new_plane_vals["org"][0] < -65000)
{
new_plane_vals["is_plane_valid"] = false;
}
if(new_plane_vals["org"][1] > 65000 || new_plane_vals["org"][1] < -65000)
{
new_plane_vals["is_plane_valid"] = false;
}
if(new_plane_vals["org"][2] > 32000 || new_plane_vals["org"][2] < -32000)
{
new_plane_vals["is_plane_valid"] = false;
}
return new_plane_vals;
}
//-- This function is threaded on all the enemy planes that fight the player dynamically.
//-- This is not used on planes that are attached to splines.
//-- TODO: see if i need the keep_flying VAR
ai_pilot_think(ai_type)
{
self endon("death");
//TODO: temporarily turned off -- Thread the cannons
//self thread ai_turret_think(ai_type);
target = self.pilot_vals["target"];
keep_flying = true;
switch(ai_type)
{
case "basic_rear": //CURRENTLY TWEAKING THIS ONE TO USE THE setplanegoalpos() functionality!!
while(keep_flying)
{
target.current_speed = target GetSpeed();
//self SetSpeed( target.current_speed + self.pilot_vals["speed_offset"] , 1000, 1000);
target_speed = (target.current_speed * 3600) / 63360; //convert the target speed to mph
self.pilot_vals["destination"] = target.origin + ( VectorNormalize(AnglesToForward(target.angles)) * self.pilot_vals["strafe_end_val"]);
//self SetVehGoalPos( self.pilot_vals["destination"]);
self.wanted_angles = VectorNormalize(self.pilot_vals["destination"] - self.origin);
self setplanegoalpos( self.pilot_vals["destination"], self.wanted_angles, target_speed + self.pilot_vals["speed_offset"] );
wait(1); // plane adjusts for new player plane position every second
/*
target.current_speed = target GetSpeed();
self SetSpeed( target.current_speed + self.pilot_vals["speed_offset"] , 1000, 1000);
self.pilot_vals["destination"] = target.origin + ( VectorNormalize(AnglesToForward(target.angles)) * self.pilot_vals["strafe_end_val"]);
self SetVehGoalPos( self.pilot_vals["destination"]);
//-- Destination Reached Check
if(Distance(self.origin, self.pilot_vals["destination"]) < 1000)
{
switch(self.pilot_vals["end_strafe_action"])
{
case "death":
//self DoDamage(self.health + 10000, (0,0,0));
self notify("death", self);
break;
default:
break;
}
}
// else continue what you were doing
wait(1); // plane adjusts for new player plane position every second
*/
}
break;
case "intercept_right":
case "intercept_left":
while(keep_flying)
{
target.current_speed = target GetSpeedMPH();
self.pilot_vals["target_point"] = self.pilot_vals["target"].origin + ( (VectorNormalize(AnglesToForward(self.pilot_vals["target"].angles))* (1,0.1,1)) * 500); //-- The 200 here is completely arbitrary
//goal_speed = distance from target point / time for target to get to target point;
goal_speed = 0;
if(target.current_speed > 0)
{
goal_speed = Distance(self.origin, self.pilot_vals["target_point"]) / ( Distance(target.origin, self.pilot_vals["target_point"]) / target.current_speed);
}
if(goal_speed > level.zero_max_speed)
{
goal_speed = level.zero_max_speed;
}
else if(goal_speed < level.zero_min_speed)
{
goal_speed = level.zero_min_speed;
}
self SetSpeed(goal_speed, 30, 30);
self SetVehGoalPos( self.pilot_vals["target_point"]);
//-- Destination Reached Check
if(Distance2d(self.origin, self.pilot_vals["target"].origin) < 1500)
{
break;
}
wait (0.1);
}
break;
case "peel_off":
//-- Obtain peel off point
peel_off_angle = (0,0,0);
if(self.ai_type == "intercept_right") peel_off_angle = (0, -90, 0);
if(self.ai_type == "intercept_left") peel_off_angle = (0, 90, 0);
self.pilot_vals["target_point"] = self.origin + VectorNormalize( AnglesToForward(self.angles) + peel_off_angle ) * 2000;
self SetNearGoalNotifyDist( 300 );
self SetVehGoalPos( self.pilot_vals["target_point"]);
self waittill_any( "goal", "near_goal" );
self SetVehGoalPos( self.origin, 1);
self.pilot_vals["end_strafe_action"] = "death";
break;
default:
break;
}
if(self.pilot_vals["end_strafe_action"] != "death")
{
self thread ai_pilot_think(self.pilot_vals["end_strafe_action"]);
}
}
ai_turret_think(ai_type)
{
self endon("death");
i = 0;
while(1)
{
//magicbullet("mosin_nagant_sniper", self.origin, target.origin)
turret_origin = self.origin + (AnglesToForward(self.angles) * 300);
turret_target = self.origin + (AnglesToForward(self.angles) * 5000);
MagicBullet("type99_lmg", turret_origin, turret_target);
i++;
wait(0.1);
/*
if(i > 20)
{
wait(2);
i = 0;
}
*/
}
}
//-- Co-op Functions ------------------------------------------------
//-- returns a player array with each player in their initial player position regardless of who has joined/dropped
//-- (or 3rd player is always 3rd player, even if there are only 2 players playing now)
get_players_pby()
{
if(!IsDefined(level.players))
{
level.players = get_players();
for(i=0; i<4; i++)
{
if(!IsDefined(level.players[i]))
{
level.players[i] = level.undef;
}
}
}
old_players = level.players; //-- the last known version of players[]
new_players = get_players(); //-- new version of players[]
players = [];
for(i=0; i<4; i++)
{
players[i] = level.undef;
}
//-- Checks to see if the old players are still playing. Sets any missing players to undefined.
for(i=0; i<4; i++)
{
player_exists = false;
if(IsDefined(old_players[i]))
{
if(old_players[i] != level.undef)
{
for(j=0; j<new_players.size; j++)
{
if(old_players[i] == new_players[j])
{
players[i] = old_players[i]; //-- add player to new array
new_players[j] = level.undef; //-- removed player already dealt with
player_exists = true;
break;
}
}
}
if(!player_exists)
{
players[i] = level.undef;
}
}
else
{
players[i] = level.undef;
}
}
//-- Swaps in the new players in the first available open position.
//found_position = false;
for(i=0; i<new_players.size; i++)
{
if(IsDefined(new_players[i]))
{
if(new_players[i] != level.undef)
{
for(j=0; j<4; j++)
{
if(players[i] == level.undef)
{
players[i] = new_players[i];
break;
}
}
}
}
}
//-- Quickly label the players
for(i=0; i<4; i++)
{
if(players[i] != level.undef)
{
players[i].play_tag = "player_" + (i+1);
}
}
//-- Return the valid player array
return players;
}
//-- Displays text if the player tries to switch to an occupied turret.
//-- This text needs to be sent to only the client that tried to switch to
// an occupied turret.
switching_to_occupied_turret_text()
{
// "You cannot switch to a turret occupied by another player."
// TODO: FINISH THIS FUNCTION
}
corsair_pby_pacing(plane, my_dist)
{
self endon("reached_end_node");
level.corsair_pacing_distance = 10;
self.keep_pacing = true;
current_speed = self GetSpeedMPH();
plane_speed = plane GetSpeedMPH();
if(IsDefined(my_dist))
{
self.pacing_distance = my_dist;
}
else
{
self.pacing_distance = level.corsair_pacing_distance;
}
while(self.keep_pacing)
{
dist = VectorDot((plane.origin - self.origin), AnglesToForward(plane.angles));
current_speed = self GetSpeedMPH();
plane_speed = plane GetSpeedMPH();
if(dist < 0) //plane is ahead of pacing point and needs to slowdown
{
if(current_speed > plane_speed)
{
current_speed = plane_speed - 3;
}
else
{
current_speed = current_speed - 1;
}
}
else if(dist > 0 && dist < self.pacing_distance - (self.pacing_distance * 0.1))
{
if(current_speed > plane_speed)
{
current_speed = plane_speed - 3;
}
else
{
current_speed = current_speed - 1;
}
}
else if(dist > self.pacing_distance + (self.pacing_distance * 0.1)) //assumed that the plane is behind then
{
if(current_speed < plane_speed)
{
current_speed = plane_speed + 3;
}
else
{
current_speed = current_speed + 1;
}
}
else
{
current_speed = plane_speed;
}
self SetSpeedImmediate(current_speed, 1, 1);
wait(0.5);
}
}
player_one_setup( player )
{
//-- This matches the OnPlayerConnect setup done for any players that connect after it starts
}
onPlayerConnect()
{
for(;;)
{
level waittill("connecting", player);
player thread onPlayerDisconnect();
player thread onPlayerSpawned();
player thread onPlayerKilled();
// put any calls here that you want to happen when the player connects to the game
println("Player connected to game.");
//-- init the players plane and a bunch of other stuff
player.my_plane = pick_proper_plane(player);
player thread turret_switch_watch();
player setup_seat_control();
player set_pilots_suggested_seat("pby_rightgun", "pby_leftgun");
player thread manage_pilots_suggested_seat();
player thread move_to_pilots_suggested_seat();
player DisableTurretDismount();
}
}
onPlayerDisconnect()
{
self waittill("disconnect");
// put any calls here that you want to happen when the player disconnects from the game
// this is a good place to do any clean up you need to do
println("Player disconnected from the game.");
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
// put any calls here that you want to happen when the player spawns
// this will happen every time the player spawns
println("Player spawned in to game at " + self.origin);
}
}
onPlayerKilled()
{
self endon("disconnect");
for(;;)
{
self waittill("killed_player");
// put any calls here that you want to happen when the player gets killed
println("Player killed at " + self.origin);
}
}
//----------------------------------------------------------------------------------------------------------
//
//
//
// DEBUG FUNCTIONS
//
//
//
//----------------------------------------------------------------------------------------------------------
//TODO: MAKE THESE JUMPTO FUNCTIONS HANDLE CO-OP...
jumpto_event2()
{
//-- this is the path that moves onto the main one
new_starting_node = GetVehicleNode("debug_start_tutorial", "targetname");
//-- Start Plane A flying
level.plane_a AttachPath(new_starting_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
level thread event2();
}
jumpto_event2_strafe_boats()
{
//-- this is the path that moves onto the main one
new_starting_node = GetVehicleNode("boat_strafing_node", "targetname");
//-- Start Plane A flying
level.plane_a AttachPath(new_starting_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
level thread event2_strafe_boats();
}
jumpto_event3()
{
level thread event3();
new_start_node = GetVehicleNode("ev3_jumpto_node", "targetname");
level.plane_a AttachPath(new_start_node);
level.plane_a thread maps\_vehicle::vehicle_paths(new_start_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
}
jumpto_event4()
{
//level waittill("finished final intro screen fadein");
//new_start_node = GetVehicleNode("event4_start_path", "targetname");
//new_start_node = GetVehicleNode("circling_start_node", "targetname");
new_start_node = GetVehicleNode("debug_node_rescue", "targetname");
level.plane_a AttachPath(new_start_node);
level.plane_a thread maps\_vehicle::vehicle_paths(new_start_node);
level.plane_a StartPath();
level.plane_a thread take_off_accel();
level thread event4();
}
jumpto_event5()
{
}
run_special_debug_functions()
{
//level thread dbg_training_planes();
}
dbg_training_planes()
{
my_trig = GetEnt("debug_training_target", "targetname");
my_trig waittill("trigger");
wait(1);
plane0 = GetEnt("training_plane_0", "targetname");
plane1 = GetEnt("training_plane_1", "targetname");
plane2 = GetEnt("training_plane_2", "targetname");
plane0 thread dbg_plane_taking_damage();
plane1 thread dbg_plane_taking_damage();
plane2 thread dbg_plane_taking_damage();
}
dbg_plane_taking_damage()
{
i = 0;
while(1)
{
self waittill("damage", amount);
level.dbg_text_plane_dmg = newHudElem();
level.dbg_text_plane_dmg.alignX = "center";
level.dbg_text_plane_dmg.x = 200;
level.dbg_text_plane_dmg.y = 300;
//level.dbg_text_plane_dmg SetText(self.targetname + " took " + amount + " damage " + i + " times.");
//iprintlnbold(self.targetname + " took " + amount + " damage " + i + " times.");
iprintlnbold(self.targetname + " has " + self.health + " remaining ");
}
}
event2_strafe_boats()
{
//-- setup objective
set_objective("merchant_boats");
/*
Boats available: ev2_ship_00, ev2_ship_01, ev2_ship_02, ev2_ship_03, ev2_ship_04, ev2_ship_05
*/
level.boats = [];
level.boats = GetEntArray("ev2_ship", "targetname");
for(i = 0; i < level.boats.size; i++)
{
level.boats[i] SetCanDamage(true);
level.boats[i].scriptname = "boat_" + i;
level.boats[i] thread track_damage_and_sink();
}
level.plane_a waittill("start_event_3");
set_objective("back_to_base");
//level.plane_a waittill("reached_end_node");
level thread event3();
}
track_damage_and_sink()
{
/* AROUND 40,000 DAMAGE for 3 Passes with pretty even distribution of fire*/
boat_alive = true;
total_damage = 0;
while(boat_alive)
{
self waittill("damage", amt);
total_damage = (total_damage + amt);
iprintlnbold(self.scriptname + " taken " + total_damage + " damage.");
if(total_damage > 40000)
{
boat_alive = false;
}
}
self Delete();
}
//-- OBJECTIVES
set_objective(my_obj, ent)
{
// Scout The Ocean
if(my_obj == "scout_ocean")
{
obj_marker = GetEnt("obj_ev1", "targetname");
objective_add(1, "active", &"PBY_FLY_OBJ_EV1", obj_marker.origin );
objective_current( 1 );
}
// Sink the Boats
else if (my_obj == "merchant_boats")
{
objective_state (1, "done");
objective_add( 2, "active", &"PBY_FLY_OBJ_EV2", ( 42399, 1718, 531 ) );
objective_current( 2 );
}
//Setup the other objectives .. in the proper order and everything
else if (my_obj == "back_to_base")
{
objective_state (2, "done");
obj_marker = GetEnt("base_obj", "targetname");
objective_add( 3, "active", &"PBY_FLY_OBJ_EV3", obj_marker.origin );
objective_current( 3 );
}
else if(my_obj == "respond_to_distress_call")
{
objective_state (3, "done");
obj_marker = GetEnt("fleet_obj", "targetname");
objective_add( 4, "active", &"PBY_FLY_OBJ_EV3B", obj_marker.origin );
objective_current( 4 );
}
}
//introscreen test
pby_custom_introscreen(string1, string2, string3, string4)
{
level.introblack = NewHudElem();
level.introblack.x = 0;
level.introblack.y = 0;
level.introblack.horzAlign = "fullscreen";
level.introblack.vertAlign = "fullscreen";
level.introblack.foreground = true;
level.introblack SetShader( "black", 640, 480 );
// SCRIPTER_MOD
// MikeD( 3/16/200 ): Freeze all of the players controls
// level.player FreezeControls( true );
//freezecontrols_all( true );
// MikeD (11/14/2007): Used for freezing controls on players who connect during the introscreen
level._introscreen = true;
wait( 0.05 );
level.introstring = [];
//Title of level
if( IsDefined( string1 ) )
{
maps\_introscreen::introscreen_create_line( string1 );
}
wait( 2 );
//City, Country, Date
if( IsDefined( string2 ) )
{
maps\_introscreen::introscreen_create_line( string2 );
}
if( IsDefined( string3 ) )
{
maps\_introscreen::introscreen_create_line( string3 );
}
//Optional Detailed Statement
if( IsDefined( string4 ) )
{
wait( 2 );
}
if( IsDefined( string4 ) )
{
maps\_introscreen::introscreen_create_line( string4 );
}
level notify( "finished final intro screen fadein" );
wait( 3 );
// Fade out black
level.introblack FadeOverTime( 1.5 );
level.introblack.alpha = 0;
flag_set( "starting final intro screen fadeout" );
// Restore player controls part way through the fade in
//freezecontrols_all( false );
level._introscreen = false;
level notify( "controls_active" ); // Notify when player controls have been restored
// Fade out text
maps\_introscreen::introscreen_fadeOutText();
flag_set( "introscreen_complete" ); // Notify when complete
}