#include maps\_utility;
#include maps\_vehicle;
#include maps\_anim;
#include maps\_hud_util;
#include common_scripts\utility;
main()
{
set_console_status();
if ( level.console )
level.hint_text_size = 1.6;
else
level.hint_text_size = 1.2;
setDvarIfUninitialized( "trainer_debug", "0" );
level.objectiveRegroup = 0; //used to determine if the string for the course objective is "regroup upstairs" or "run the course blah blah"
level.endingThreadStarted = false;
level.tryagain = false;
level.translatordelay = 1.5;
level.droneCallbackThread = ::AI_drone_think;
level.spawnerCallbackThread = ::AI_think;
level.oldObjectiveAlpha = getDvar( "objectiveAlpha" );
level.skippingTimedADS = false; //may skip if player is elite and has turned autoaim off in the options menu
setsaveddvar( "r_lightGridEnableTweaks", 1 );
setsaveddvar( "r_lightGridIntensity", 1.2 );
setsaveddvar( "r_lightGridContrast", 0 );
/*-----------------------
PIT SCORING/TIMING
-------------------------*/
level.targets_hit_with_melee = 0;
level.patrolDudes = [];
level.recommendedDifficulty = undefined;
level.bestPitTime = 29.05; //IW best time
level.timeFail = 240; //anything higher than this will fail
level.timeEasy = 75; //anything above this number will choose "easy"
level.timeRegular = 43; //anything above this number but less than timeEast will choose "regular"
level.timeHard = 35; //anything above this number but less than timeRegular will choose "hard"
//veteran time..... //anything below "timeHard" will choose "veteran"
level.maximumfriendliesalloweddead = 5; //if you kill more than 5 friendlies, you will fail
level.minimumenemiestokill = 18; //you have to kill at leat 18 enemies to pass
level.timepenaltyForMissedEnemies = 2; //in seconds
level.timepenaltyForKilledCivvies = 2; //in seconds
level.timelimitMax = 160;
level.timelimitMin = 80;
level.courseFriendlies = [];
level.courseEnemies = [];
level.color[ "white" ] = ( 1, 1, 1 );
level.color[ "red" ] = ( 1, 0, 0 );
level.color[ "blue" ] = ( .1, .3, 1 );
/*-----------------------
STARTS
-------------------------*/
add_start( "timed_ads", ::start_timed_ads, "timed_ads" );
add_start( "bullet_penetration", ::start_bullet_penetration, "bullet_penetration" );
add_start( "frag", ::start_frag_training, "frag" );
add_start( "pit", ::start_pit, "pit" );
add_start( "course", ::start_course, "course" );
add_start( "end", ::start_ending, "end" );
if ( is_specialop() )
{
add_start( "so_killspree_trainer_start_map", level.so_trainer_start );
default_start( level.so_trainer_start );
}
else
{
// Delete the special ops gate
array_call( GetEntArray( "so_gate", "targetname" ), ::Delete );
default_start( ::start_default );
pit = getent( "pit", "targetname" );
}
init_precache();
maps\createart\trainer_fog::main();
maps\trainer_precache::main();
maps\createfx\trainer_audio::main();
maps\trainer_fx::main();
maps\_drone_ai::init();
maps\_load::main();
maps\_compass::setupMiniMap("compass_map_trainer");
thread maps\trainer_amb::main();
maps\trainer_anim::main();
//misc
flag_init( "never" );
flag_init( "can_talk" );
flag_set( "can_talk" );
flag_init( "start_anims" );
flag_init( "no_more_course_nags" );
//firing range
flag_init( "firing_range_initialized" );
flag_init( "player_picked_up_rifle" );
//hip fire and ads
flag_init( "player_facing_targets_for_hip_fire" );
flag_init( "foley_turns_for_hip_demo" );
flag_init( "hip_fire_done" );
flag_init( "firing_range_hip_and_ads_done" );
flag_init( "foley_turns_for_ads_demo" );
flag_init( "foley_done_talking_from_hip_ads_training" );
//timed ads
flag_init( "aa_timed_shooting_training" );
flag_init( "foley_done_talking_from_timed_ads_training" );
flag_init( "foley_turns_for_adstimed_demo" );
//penetration
flag_init( "foley_turns_for_penetration_demo" );
flag_init( "firing_range_timed_ads_done" );
flag_init( "firing_range_penetration_done" );
flag_init( "foley_done_talking_from_penetration_training" );
//frags
flag_init( "player_just_threw_a_frag" );
flag_init( "foley_turns_for_frag_demo" );
flag_init( "frags_have_been_spawned" );
flag_init( "player_picked_up_frags" );
flag_init( "targets_hit_with_grenades" );
flag_init( "player_has_thrown_frag_into_target" );
flag_init( "firing_range_frags_done" );
flag_init( "foley_done_talking_from_frag_training" );
//objective training
flag_init( "obj_go_to_the_pit_given" );
flag_init( "obj_go_to_the_pit_done" );
//sidearm training
flag_init( "dunn_dialogue_welcome_01" );
flag_init( "dunn_dialogue_welcome_02" );
flag_init( "dunn_finished_welcome_anim" );
flag_init( "sidearm_complete" );
flag_init( "case_flip_01" );
flag_init( "case_flip_02" );
flag_init( "button_press" );
//course/pit
flag_init( "dunn_finished_with_open_case_dialogue" );
flag_init( "melee_target_hit" );
flag_init( "course_end_targets_dead" );
flag_init( "sprinted" );
flag_init( "pit_dialogue_starting" );
flag_init( "course_start_targets_dead" );
flag_init( "course_first_floor_targets_dead" );
flag_init( "course_second_floor_targets_dead" );
flag_init( "course_end_targets_dead" );
flag_init( "dunn_finished_with_difficulty_selection_dialogue" );
//ending
flag_init( "player_done_with_course" );
flag_init( "end_sequence_starting" );
/*-----------------------
POP-UP TARGETS
-------------------------*/
level.penetration_targets = [];
level.grenade_targets = [];
level.hip_targets = [];
level.pit_enemies = [];
level.plywood = getent( "plywood", "script_noteworthy" );
level.plywood rotateRoll( -90, 0.25, 0.1, 0.1 );
level.lastTimePlywoodWasHit = gettime();
level.target_rail_start_points = getentarray( "target_rail_start_point", "targetname" );
target_triggers = getentarray( "target_trigger", "targetname" );
array_thread( target_triggers,::target_triggers_think );
targets_enemy = getentarray( "target_enemy", "script_noteworthy" );
targets_friendly = getentarray( "target_friendly", "script_noteworthy" );
array_thread( targets_friendly,::target_think, "friendly" );
array_thread( targets_enemy,::target_think, "enemy" );
level.targets_hit = 0;
level.friendlies_hit = 0;
target_enemy = getentarray( "target_enemy", "script_noteworthy" );
target_friendly = getentarray( "target_friendly", "script_noteworthy" );
level.targets = array_merge( target_enemy, target_friendly );
level.speakers = getentarray( "speakers", "targetname" );
/*-----------------------
WEAPONS
-------------------------*/
level.fragsGlowing = false;
level.gunPrimary = "m4_grunt";
level.gunPrimaryClipAmmo = 30;
level.gunSidearm = "deserteagle";
//array_thread( getEntArray( "pickup_rifle", "targetname" ), ::ammoRespawnThink, "spawn_rifles", level.gunPrimary );
//array_thread( getEntArray( "pickup_sidearm", "targetname" ), ::ammoRespawnThink, "spawn_sidearms", level.gunSidearm );
pit_weapons = getentarray( "pit_weapons", "targetname" );
array_thread( pit_weapons,::weapons_hide );
level.cosine = [];
level.cosine[ "45" ] = cos( 45 );
level.cosine[ "90" ] = cos( 90 );
/*-----------------------
SPAWNER THREADS
-------------------------*/
aVehicleSpawners = maps\_vehicle::_getvehiclespawnerarray();
array_thread( aVehicleSpawners, ::add_spawn_function, ::vehicle_think );
array_thread( getentarray( "ai_ambient", "script_noteworthy" ), ::add_spawn_function, ::ai_ambient_noprop_think );
array_spawn_function_noteworthy( "patrol", ::AI_patrol_think );
array_spawn_function_noteworthy( "runners", ::AI_runners_think );
/*-----------------------
KEY FRIENDLIES
-------------------------*/
level.foley = spawn_targetname( "foley", true );
level.foley.animname = "foley";
level.foley.animnode = getent( "node_foley", "targetname" );
level.foley forceUseWeapon( "m4_grunt", "primary" );
level.traineeanimnode = spawn( "script_origin", ( 0, 0, 0 ) );
level.traineeanimnode.origin = level.foley.animnode.origin;
level.traineeanimnode.angles = level.foley.animnode.angles;
level.translatoranimnode = spawn( "script_origin", ( 0, 0, 0 ) );
level.translatoranimnode.origin = level.foley.animnode.origin;
level.translatoranimnode.angles = level.foley.animnode.angles;
spawn_pitguy();
level.pit_case_01 = getent( "pit_case_01", "targetname" );
level.pit_case_02 = getent( "pit_case_02", "targetname" );
level.pit_case_01.animname = "training_case_01";
level.pit_case_02.animname = "training_case_02";
level.pit_case_01 assign_animtree();
level.pit_case_02 assign_animtree();
level.pitcases = [];
level.pitcases[ 0 ] = level.pit_case_01;
level.pitcases[ 1 ] = level.pit_case_02;
level.trainees = array_spawn( getentarray( "trainees", "targetname" ), true );
level.translator = spawn_script_noteworthy( "translator", true );
level.translator gun_remove();
level.translator.animname = "translator";
level.trainee_01 = spawn_script_noteworthy( "trainee_01", true );
level.trainee_01.animname = "trainee_01";
level.translatoranimnode thread anim_loop_solo( level.translator, "training_intro_begining", "stop_idle" ); //loop forever
level.traineeanimnode thread anim_loop_solo( level.trainee_01, "training_intro_begining", "stop_idle" ); //loop forever
level.foley.animnode thread anim_first_frame_solo( level.foley, "training_intro_begining" );
battlechatter_off( "allies" );
battlechatter_off( "axis" );
level.curObjective = 1;
level.objectives = [];
registerActions();
level.aRangeActors = [];
level.aRangeActors[ 0 ] = level.foley;
level.aRangeActors[ 1 ] = level.translator;
level.aRangeActors[ 2 ] = level.trainee_01;
level.aRangeActors = array_merge( level.aRangeActors, level.trainees );
level.gate_cqb_enter = make_door_from_prefab( "gate_cqb_enter" );
level.gate_cqb_exit = make_door_from_prefab( "gate_cqb_exit" );
level.gate_cqb_enter_main = make_door_from_prefab( "gate_cqb_enter_main" );
level.gate_cqb_enter_main.openangles = -170;
level.gate_cqb_enter_main.closeangles = 170;
level.gate_cqb_exit.openangles = -95;
level.gate_cqb_exit.closeangles = 95;
if ( !is_specialop() )
{
level.gate_cqb_enter_main thread door_open();
level.player takeAllWeapons();
}
/*-----------------------
AMBIENT AI
-------------------------*/
if ( !is_specialop() )
{
level.ambientai = array_spawn( getentarray( "friendlies_ambient", "targetname" ), true );
thread bridge_layer_think();
level.basketball_guys = array_spawn( getentarray( "friendlies_basketball", "targetname" ), true );
thread AI_runner_group_think( "runner_group_01" );
thread AI_runner_group_think( "runner_group_02" );
thread ambient_vehicles();
}
thread music();
hummer_end_main = getent( "hummer_end_main", "targetname" );
hummer_end_01 = getent( "hummer_end_01", "targetname" );
hummer_end_main hide();
hummer_end_01 hide();
end_blockers = getent( "end_blockers", "targetname" );
end_blockers hide_entity();
dummies = getentarray( "dummies", "targetname" );
array_call( dummies,::delete );
level.firing_range_area = getent( "firing_range_area", "targetname" );
thread vars_for_after_main();
thread weaponfire_failure();
thread player_camp_disable_weapons();
thread basketball_nag();
level.player thread never_run_out_of_ammo();
}
never_run_out_of_ammo()
{
level endon ( "button_press" );
while( true )
{
level.player waittill( "reload_start" );
if ( flag( "player_inside_course" ) )
break;
weaponName = self GetCurrentWeapon();
if ( level.player GetWeaponAmmoStock( weaponName ) < 100 )
{
level.player SetWeaponAmmoStock( weaponName, 9999 );
}
}
}
vars_for_after_main()
{
wait( .5 );
/*-----------------------
PUT TOTAL PIT ENEMIES/CIVVIES IN A VARIABLE
-------------------------*/
level.totalPitEnemies = level.courseEnemies.size;
level.totalPitCivvies = level.courseFriendlies.size;
}
/****************************************************************************
START FUNCTIONS
****************************************************************************/
start_default()
{
thread AA_range_start_init();
}
start_debug()
{
}
start_timed_ads()
{
firing_range_anims_foley_trainee_and_translator_start_points();
thread firing_range_init();
flag_set( "firing_range_hip_and_ads_done" );
flag_set( "foley_done_talking_from_hip_ads_training" );
thread AA_timed_ADS_init();
}
start_bullet_penetration()
{
firing_range_anims_foley_trainee_and_translator_start_points();
thread firing_range_init();
flag_set( "firing_range_timed_ads_done" );
flag_set( "foley_done_talking_from_timed_ads_training" );
thread AA_penetration_init();
}
start_frag_training()
{
firing_range_anims_foley_trainee_and_translator_start_points();
thread firing_range_init();
flag_set( "firing_range_penetration_done" );
flag_set( "foley_done_talking_from_penetration_training" );
thread AA_frags_init();
}
start_pit()
{
flag_set( "foley_done_talking_from_frag_training" );
flag_set( "firing_range_frags_done" );
level.player giveWeapon( level.gunPrimary );
level.player switchToWeapon( level.gunPrimary );
org = getent( "pit_start", "targetname" );
level.player SetOrigin( org.origin );
level.player SetPlayerAngles( org.angles );
thread AA_find_pit_init();
}
start_course()
{
flag_set( "dunn_finished_welcome_anim" );
level.player giveWeapon( level.gunSidearm );
level.player giveWeapon( level.gunPrimary );
level.player switchToWeapon( level.gunPrimary );
org = getent( "course_start_pit", "targetname" );
level.player SetOrigin( org.origin );
level.player SetPlayerAngles( org.angles );
thread AA_pit_init();
maps\_utility::vision_set_fog_changes( "trainer_pit", 0 );
}
start_ending()
{
level.player giveWeapon( level.gunSidearm );
level.player giveWeapon( level.gunPrimary );
level.player switchToWeapon( level.gunPrimary );
org = getent( "course_leave", "targetname" );
level.player SetOrigin( org.origin );
level.player SetPlayerAngles( org.angles );
registerObjective( "obj_course", &"TRAINER_OBJ_EXIT_THE_PIT", getent( "course_start", "targetname" ) );
setObjectiveState( "obj_course", "current" );
thread AA_ending_init();
maps\_utility::vision_set_fog_changes( "trainer_pit", 0 );
}
music()
{
radio_org = getent( "radio_org", "targetname" );
while( true )
{
radio_org playsound( "training_radio_music_01", "done" );
radio_org waittill( "done" );
wait( 1 );
radio_org playsound( "training_radio_music_02", "done" );
radio_org waittill( "done" );
wait( 1 );
radio_org playsound( "training_radio_music_03", "done" );
radio_org waittill( "done" );
wait( 1 );
radio_org playsound( "training_radio_music_04", "done" );
radio_org waittill( "done" );
wait( 1 );
}
}
ambient_vehicles()
{
thread spawn_vehicles_from_targetname_and_drive( "heli_group_01" );
pavelows = spawn_vehicles_from_targetname_and_drive( "pavelow_group_01" );
array_call( pavelows,::Vehicle_TurnEngineOff );
//thread spawn_vehicles_from_targetname_and_drive( "f15_takeoff_01" );
flag_wait( "player_leaving_range" );
thread spawn_vehicles_from_targetname_and_drive( "f15_flyby_01" );
}
/****************************************************************************
FIRING RANGE START - BASIC FIRING AND ADS
****************************************************************************/
AA_range_start_init()
{
thread firing_range_init();
flag_wait( "start_anims" );
thread firing_range_hip_and_ads();
flag_wait( "firing_range_hip_and_ads_done" );
thread AA_timed_ADS_init();
}
firing_range_init()
{
setsaveddvar( "g_friendlyNameDist", 196 );
setSavedDvar( "objectiveAlpha", 0.4 );
level.player takeallweapons();
player_start_range = getent( "player_start_range", "targetname" );
level.player SetOrigin( player_start_range.origin );
level.player SetPlayerAngles( player_start_range.angles );
ads_target_trigger_middle = getent( "ads_target_trigger_middle", "targetname" );
ads_target_trigger_front = getent( "ads_target_trigger_front", "targetname" );
ads_target_trigger_rear = getent( "ads_target_trigger_rear", "targetname" );
timed_ads_target_trigger = getent( "timed_ads_target_trigger", "targetname" );
ads_target_trigger_middle thread target_triggers_think();
ads_target_trigger_front thread target_triggers_think();
ads_target_trigger_rear thread target_triggers_think();
timed_ads_target_trigger thread target_triggers_think();
level.targetsFront = ads_target_trigger_front.targets;
level.targetsMiddle = ads_target_trigger_middle.targets;
level.targetsRear = timed_ads_target_trigger.targets;
level.firingRangeTimedTargets = timed_ads_target_trigger.targets;
flag_set( "firing_range_initialized" );
flag_wait( "obj_go_to_the_pit_given" );
setsaveddvar( "g_friendlyNameDist", 15000 );
}
firing_range_anims()
{
/*-----------------------
FOLEY AND TRAINEES DO INTRO ANIMS
-------------------------*/
level.foley.animnode anim_single_solo( level.foley, "training_intro_begining" ); //specific one-off anim
/*-----------------------
FOLEY GOES INTO IDLE (TRAINEE AND TRANS ALREADY IDLING)
-------------------------*/
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
/*-----------------------
FOLEY TURNS
-------------------------*/
flag_wait( "foley_turns_for_hip_demo" );
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_turnaround_1" );
/*-----------------------
FOLEY GOES INTO IDLE
-------------------------*/
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
/*-----------------------
FOLEY TALKS A BIT
-------------------------*/
flag_wait( "hip_fire_done" );
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_idle_talk_1" );
/*-----------------------
FOLEY TURNS AROUND
-------------------------*/
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_turnaround_2" );
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
flag_wait( "firing_range_hip_and_ads_done" );
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_idle_talk_2" );
flag_set( "foley_done_talking_from_hip_ads_training" );
}
firing_range_anims_foley_trainee_and_translator_start_points()
{
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
wait( 0.05 );
}
firing_range_hip_and_ads()
{
flag_wait( "firing_range_initialized" );
player_needs_to_pickup_primary_weapon = true;
thread firing_range_anims();
/*-----------------------
FOLEY INTRO DIALOGUE
-------------------------*/
//Sgt. Foley Welcome to pull-the-trigger 101.
flag_wait( "ps_train_fly_welcome" );
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_welcome" );
//level.foley dialogue_execute( "train_fly_welcome" );
//Sgt. Foley Pvt. Allen here is going to do a quick weapons demonstration to show you locals how its done.
flag_wait( "ps_train_fly_demonstration" );
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_demonstration" );
//level.foley dialogue_execute( "train_fly_demonstration" );
//Sgt. Foley No offense, but I see a lot of you guys firing from the hip and spraying bullets all over the range.
flag_wait( "ps_train_fly_nooffense" );
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_nooffense" );
//level.foley dialogue_execute( "train_fly_nooffense" );
//Sgt. Foley You don't end up hitting a damn thing and it makes you look like an ass.
flag_wait( "ps_train_fly_makesyoulook" );
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_makesyoulook" );
//level.foley dialogue_execute( "train_fly_makesyoulook" );
//Sgt. Foley Private Allen, show 'em what I'm talking about.
flag_wait( "foley_anim_pickup_weapon" );
//level.foley dialogue_execute( "train_fly_showem" );
flag_set( "foley_turns_for_hip_demo" );
/*-----------------------
PICK UP THE WEAPON
-------------------------*/
if ( !player_has_primary_weapon() )
{
registerObjective( "obj_rifle", &"TRAINER_PICK_UP_A_RIFLE_FROM", getEnt( "range_rifle", "script_noteworthy" ) );
setObjectiveState( "obj_rifle", "current" );
pickup_rifle = getent( "pickup_rifle", "targetname" );
if ( isdefined( pickup_rifle ) )
{
pickup_rifle glow();
pickup_rifle HidePart( "TAG_THERMAL_SCOPE" );
//pickup_rifle HidePart( "TAG_FOREGRIP" );
//pickup_rifle HidePart( "TAG_WEAPON"
pickup_rifle HidePart( "TAG_ACOG_2" );
pickup_rifle HidePart( "TAG_EOTECH" );
pickup_rifle HidePart( "TAG_HEARTBEAT" );
pickup_rifle HidePart( "TAG_M203" );
pickup_rifle HidePart( "TAG_RED_DOT" );
pickup_rifle HidePart( "TAG_SHOTGUN" );
pickup_rifle HidePart( "TAG_SILENCER" );
//pickup_rifle HidePart( "TAG_BRASS" );
//pickup_rifle HidePart( "TAG_CLIP" );
//pickup_rifle HidePart( "TAG_FLASH" );
//pickup_rifle HidePart( "TAG_LASER" );
//pickup_rifle HidePart( "TAG_SIGHT_OFF" );
//pickup_rifle HidePart( "TAG_SIGHT_ON" );
//pickup_rifle HidePart( "TAG_FLASH_SILENCED" );
}
//Sgt. Foley Grab that weapon off the table and fire at some targets downrange.
level.foley dialogue_execute( "train_fly_fireattargets" );
level.foley thread nag_till_flag_set( "nag_rifle_pickup_0", 2, "player_picked_up_rifle" );
}
else
{
player_needs_to_pickup_primary_weapon = false;
}
while( !player_has_primary_weapon() )
{
wait .05;
}
flag_set( "player_picked_up_rifle" );
/*-----------------------
FIRE FROM THE HIP
-------------------------*/
//Shoot each target while firing from the hip.
if ( player_needs_to_pickup_primary_weapon == false )
{
registerObjective( "obj_rifle", &"TRAINER_SHOOT_EACH_TARGET_WHILE1", getEnt( "firing_range", "targetname" ) );
setObjectiveState( "obj_rifle", "current" );
}
else
{
setObjectiveString( "obj_rifle", &"TRAINER_SHOOT_EACH_TARGET_WHILE1" );
setObjectiveLocation( "obj_rifle", getEnt( "firing_range", "targetname" ) );
}
/*-----------------------
FACE THE TARGETS HINT
-------------------------*/
if ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
{
//Sgt. Foley Turn around and fire at the targets.
level.foley thread dialogue_execute( "train_fly_turnaround" );
}
thread delaythread( 8,::turnaround_hint_if_flag_not_set, "player_facing_targets_for_hip_fire" );
/*-----------------------
FIRE FROM THE HIP TARGETS POP UP
-------------------------*/
while ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
{
wait 0.05;
}
flag_set( "player_facing_targets_for_hip_fire" );
/*-----------------------
FIRE FROM THE HIP HINT
-------------------------*/
clear_hints();
level.foley thread nag_on_notify_till_flag_set( "nag_hip_fire_0", 2, "player_needs_to_fire_from_the_hip", "hip_fire_done" );
if ( level.Xenon )
thread keyHint( "hip_attack", undefined, true );
else
thread keyHint( "pc_hip_attack", undefined, true );// PC and PS3 are both press
numberOfTagretsToHit = 2;
mustADS = false;
//cycle_targets_till_hit( targets, numberOfTagretsToHit, mustADS, mustCrouch, mustShootThroughPlywood, bInOrder )
cycle_targets_till_hit( level.hip_targets, numberOfTagretsToHit, mustADS, undefined, undefined, true );
level.player notify( "did_action_stop_ads" );
clear_hints();
playerIsInverted = undefined;
/*-----------------------
INVERT CONTROLS?
-------------------------*/
setDvar( "ui_start_inverted", 0 );
if ( level.Console )
{
if ( isdefined( level.player GetLocalPlayerProfileData( "invertedPitch" ) ) && level.player GetLocalPlayerProfileData( "invertedPitch" ) )
setDvar( "ui_start_inverted", 1 );
}
else// PC
{
if ( isdefined( getdvar( "ui_mousepitch" ) ) && getdvar( "ui_mousepitch" ) == "1" )
setDvar( "ui_start_inverted", 1 );
}
wait .1;// make sure dvar is set
setDvar( "ui_invert_string", "@TRAINER_AXIS_OPTION_MENU1_ALL" );
if ( level.console )
level.player openpopupMenu( "invert_axis" );
else
level.player openpopupMenu( "invert_axis_pc" );
level.player freezecontrols( true );
setblur( 2, .1 );
level.player waittill( "menuresponse", menu, response );
setblur( 0, .2 );
level.player freezecontrols( false );
playerIsInvertedAfterFirstMenu = false;
if ( level.Console )
{
if ( isdefined( level.player GetLocalPlayerProfileData( "invertedPitch" ) ) && level.player GetLocalPlayerProfileData( "invertedPitch" ) )
playerIsInvertedAfterFirstMenu = true;
}
else// PC
{
if ( isdefined( getdvar( "ui_mousepitch" ) ) && getdvar( "ui_mousepitch" ) == "1" )
playerIsInvertedAfterFirstMenu = true;
}
/*-----------------------
DO A FEW MORE TARGETS IF PLAYER CHOSE TO INVERT
-------------------------*/
if ( response == "try_invert" )
{
//Foley: Let's try a few more.
level.foley thread dialogue_execute( "train_fly_tryafew" );
/*-----------------------
FIRE FROM THE HIP HINT
-------------------------*/
if ( level.Xenon )
thread keyHint( "hip_attack" );
else
thread keyHint( "pc_hip_attack" );// PC and PS3 are both press
/*-----------------------
FIRE FROM THE HIP TARGETS POP UP
-------------------------*/
while ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
wait 0.05;
numberOfTagretsToHit = 2;
mustADS = false;
//cycle_targets_till_hit( targets, numberOfTagretsToHit, mustADS, mustCrouch, mustShootThroughPlywood, bInOrder )
cycle_targets_till_hit( level.hip_targets, numberOfTagretsToHit, mustADS, undefined, undefined, true );
level.player notify( "did_action_stop_ads" );
clear_hints();
/*-----------------------
DID THE PLAYER SWAP INVERSION FROM THE MAIN MENU DURING EXCERCISE?
-------------------------*/
playerIsInvertedAfterTryingAgain = false;
if ( level.Console )
{
if ( isdefined( level.player GetLocalPlayerProfileData( "invertedPitch" ) ) && level.player GetLocalPlayerProfileData( "invertedPitch" ) )
playerIsInvertedAfterTryingAgain = true;
}
else// PC
{
if ( isdefined( getdvar( "ui_mousepitch" ) ) && getdvar( "ui_mousepitch" ) == "1" )
playerIsInvertedAfterTryingAgain = true;
}
/*-----------------------
ONLY SHOW THE MENU TO KEEP CONTROLS IF PLAYER HASN'T SCREWED WITH MAIN MENU
-------------------------*/
if ( playerIsInvertedAfterFirstMenu == playerIsInvertedAfterTryingAgain )
{
setDvar( "ui_invert_string", "@TRAINER_AXIS_OPTION_MENU2_ALL" );
if ( level.console )
level.player openpopupMenu( "invert_axis" );
else
level.player openpopupMenu( "invert_axis_pc" );
level.player freezecontrols( true );
setblur( 2, .1 );
level.player waittill( "menuresponse", menu, response );
setblur( 0, .2 );
level.player freezecontrols( false );
}
}
setObjectiveState( "obj_rifle", "done" );
/*-----------------------
CROSSHAIR SPREAD HINT
-------------------------*/
// Notice that your crosshair expands as you fire.\nThe bigger the crosshairs, the less accurate you are.
//double_line = true;
//thread killhouse_hint( &"TRAINER_HINT_CROSSHAIR_CHANGES", 6, double_line );
/*-----------------------
ADS TRAINING
-------------------------*/
flag_set( "hip_fire_done" );
//Sgt. Foley See what I mean? He sprayed bullets all over the damn place.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_sprayedbullets" );
level.foley dialogue_execute( "train_fly_sprayedbullets" );
//Sgt. Foley You've got to pick your targets by aiming deliberately down your sights from a stable stance.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_pickyourtargets" );
level.foley dialogue_execute( "train_fly_pickyourtargets" );
thread autosave_by_name( "ads_training" );
//Sgt. Foley Private Allen, show our friends here how the Rangers take down a target.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_howtherangers" );
level.foley dialogue_execute( "train_fly_howtherangers" );
//Sgt. Foley Crouch first, and then aim down your sight at the targets.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_crouchfirst" );
level.foley dialogue_execute( "train_fly_crouchfirst" );
// Shoot three targets while aiming down your sights.
thread setObjectiveString( "obj_rifle", &"TRAINER_SHOOT_EACH_TARGET_WHILE" );
setObjectiveState( "obj_rifle", "current" );
numberOfTagretsToHit = 3;
mustADS = true;
mustCrouch = true;
if ( level.player GetStance() != "crouch" )
{
thread keyHint( "crouch" );
}
level.foley thread nag_on_notify_till_flag_set( "nag_ads_fire_0", 2, "player_needs_to_ADS", "firing_range_hip_and_ads_done" );
level.foley thread nag_on_notify_till_flag_set( "nag_crouch_fire_0", 2, "player_needs_to_crouch", "firing_range_hip_and_ads_done" );
cycle_targets_till_hit( level.targetsFront, numberOfTagretsToHit, mustADS, mustCrouch );
level.player notify( "did_action_crouch" );
level.player notify( "did_action_ads_360" );
level.player notify( "did_action_ads" );
clear_hints();
setObjectiveState( "obj_rifle", "done" );
flag_set( "firing_range_hip_and_ads_done" );
if ( level.player GetStance() != "stand" )
{
thread keyHint( "stand" );
}
//Sgt. Foley That's all there is to it. You want your target to go down? You gotta aim down your sights.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_gottaaim" );
level.foley dialogue_execute( "train_fly_gottaaim" );
}
turnaround_hint_if_flag_not_set( sFlag )
{
level endon( sFlag );
if ( !flag( sFlag ) )
{
//double_line = true;
thread killhouse_hint( &"TRAINER_HINT_TURN_AROUND" );
}
}
nag_till_flag_set( sNagLine, iNumberOfLines, sFlagToStop )
{
thread nag_reset_can_talk_flag( sFlagToStop ); //reset can_talk flag in case this function ends mid-dialogue
level endon( sFlagToStop );
while( !flag( sFlagToStop ) )
{
wait( randomfloatrange( 25, 35 ) );
i = 1;
if ( flag( "can_talk" ) )
{
flag_clear( "can_talk" );
self dialogue_execute( sNagLine + i );
flag_set( "can_talk" );
i++;
if ( i > iNumberOfLines )
{
i = 1;
}
}
}
}
nag_on_notify_till_flag_set( sNagLine, iNumberOfLines, sNotify, sFlagToStop )
{
thread nag_reset_can_talk_flag( sFlagToStop ); //reset can_talk flag in case this function ends mid-dialogue
level endon( sFlagToStop );
i = 1;
while( !flag( sFlagToStop ) )
{
level waittill( sNotify );
if ( flag( "can_talk" ) )
{
flag_clear( "can_talk" );
self dialogue_execute( sNagLine + i );
flag_set( "can_talk" );
i++;
if ( i > iNumberOfLines )
{
i = 1;
}
}
}
}
nag_reset_can_talk_flag( sFlagToWaitFor )
{
flag_wait( sFlagToWaitFor );
wait( 0.05 );
flag_set( "can_talk" );
}
cycle_targets_till_hit( targets, numberOfTagretsToHit, mustADS, mustCrouch, mustShootThroughPlywood, bInOrder )
{
numberOfTagretsHit = 0;
/*-----------------------
IF NEED TO DO IN A CERTAIN ORDER, USE SCRIPT_GROUP NUMBER
-------------------------*/
if ( isdefined( bInOrder ) )
{
newArray = [];
while ( newArray.size < targets.size )
{
wait( 0.05 );
foreach( target in targets )
{
if ( target.script_group == newArray.size )
newArray[ newArray.size ] = target;
}
}
targets = newArray;
}
/*-----------------------
LOOP THROUGH TARGETS TILL KILLED ENOUGH
-------------------------*/
while( true )
{
wait( 0.05 );
//have we already killed enough?
if ( numberOfTagretsHit >= numberOfTagretsToHit )
break;
foreach( target in targets )
{
//have we already killed enough?
if ( numberOfTagretsHit >= numberOfTagretsToHit )
break;
target notify( "pop_up" );
target waittill ( "hit" );
/*-----------------------
DO WE NEED TO CROUCH?
-------------------------*/
if ( isdefined( mustCrouch ) )
{
if ( level.player GetStance() == "crouch" )
{
level.player notify( "did_action_crouch" );
}
else
{
thread keyHint( "crouch" );
level notify( "player_needs_to_crouch" );
continue;
}
}
/*-----------------------
DO WE NEED TO ADS OR FIRE FROM THE HIP?
-------------------------*/
if ( isdefined( mustADS ) )
{
if ( mustADS == false )
{
if ( !level.player isADS() )
{
numberOfTagretsHit++;
level.player notify( "did_action_stop_ads" );
}
else
{
thread keyHint( "stop_ads", undefined, true );
level notify( "player_needs_to_fire_from_the_hip" );
}
}
if ( mustADS == true )
{
if ( level.player isADS() )
{
numberOfTagretsHit++;
level.player notify( "did_action_ads" );
level.player notify( "did_action_ads_360" );
}
else
{
if ( level.Xenon )
thread keyHint( "ads_360" );
else
thread keyHint( "ads" );// PC and PS3 are both press
level notify( "player_needs_to_ADS" );
}
}
}
/*-----------------------
DO WE NEED TO SHOOT THROUGH PLYWOOD?
-------------------------*/
if ( isdefined( mustShootThroughPlywood ) )
{
waittillframeend;
time = gettime();
if ( level.lastTimePlywoodWasHit == time )
{
numberOfTagretsHit++;
clear_hints();
}
else
{
clear_hints();
//thread killhouse_hint( &"TRAINER_SHOOT_THE_TARGET_THROUGH", 6 );
level notify( "player_needs_to_shoot_through_plywood" );
continue;
}
}
}
}
/*-----------------------
ENOUGH KILLED...RESET ALL TARGETS
-------------------------*/
array_thread( targets,::target_reset_manual );
}
/****************************************************************************
FIRING RANGE START - TIMED ADS
****************************************************************************/
AA_timed_ADS_init()
{
hasAutoAim = ( level.player GetLocalPlayerProfileData( "autoAim" ) );
if ( ( !hasAutoAim ) || ( !level.console ) )
{
level.skippingTimedADS = true;
//Skip timed ADS training if autoaim is turned off or if we are on a PC
flag_set( "firing_range_timed_ads_done" );
flag_set( "foley_done_talking_from_timed_ads_training" );
thread AA_penetration_init();
}
else
{
//Do full training...player has not mucked with autoaim in options menu
thread firing_range_timed_ads();
flag_wait( "firing_range_timed_ads_done" );
thread AA_penetration_init();
}
}
timed_ads_anims()
{
flag_wait( "foley_done_talking_from_hip_ads_training" );
/*-----------------------
FOLEY GOES INTO IDLE
-------------------------*/
level.foley.animnode notify( "stop_idle" );
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
flag_wait( "aa_timed_shooting_training" );
/*-----------------------
FOLEY TURNS AROUND
-------------------------*/
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_turnaround_1" );
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
flag_wait( "firing_range_timed_ads_done" );
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_idle_talk_1" );
flag_set( "foley_done_talking_from_timed_ads_training" );
}
firing_range_timed_ads()
{
flag_wait( "firing_range_hip_and_ads_done" );
thread timed_ads_anims();
/*-----------------------
ADS TARGET SWITCHING - TIMED
-------------------------*/
thread autosave_by_name( "timed_ads" );
//Sgt. Foley Aiming down your sights also works for switching quickly between targets.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_switching" );
level.foley dialogue_execute( "train_fly_switching" );
//Sgt. Foley Aim down your sights, then pop in and out to acquire new targets.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_popinandout" );
level.foley dialogue_execute( "train_fly_popinandout" );
//Sgt. Foley Show 'em Private.
level.foley dialogue_execute( "train_fly_showemprivate" );
// Shoot each target as quickly as possible.
registerObjective( "obj_timed_rifle", &"TRAINER_SHOOT_EACH_TARGET_AS", getEnt( "firing_range", "targetname" ) );
setObjectiveState( "obj_timed_rifle", "current" );
//(HINT: RELEASE AND PULL LT TO AUTOMATICALLY SNAP TO A NEARBY TARGET)
//Foley: If your target is close to where you are aiming, you can snap to it quickly by quickly aiming down your sight.
//OBJECTIVE: Shoot each target as quickly as possible.
flag_set( "aa_timed_shooting_training" );
//Now I'm going make the targets pop up one at a time.
//level.waters execDialog( "targetspop" );
//wait .5;
//Hit all of them as fast as you can.
//level.waters execDialog( "hitall" );
//Sgt. Foley If your target is close to where you are aiming, you can snap to it quickly by quickly aiming down your sights.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_iftargetclose" );
level.foley dialogue_execute( "train_fly_iftargetclose" );
// if ( auto_aim() )
// {
// //ps3_flipped = is_ps3_flipped();
//
// //if ( ( level.xenon ) || ( ps3_flipped ) )
// if ( level.xenon )
// actionBind = getActionBind( "ads_switch" );
// else
// actionBind = getActionBind( "ads_switch_shoulder" );
// double_line = true;
// thread killhouse_hint( actionBind.hint, 6, double_line );
// }
if ( ( level.player GetWeaponAmmoClip( level.gunPrimary ) ) < level.gunPrimaryClipAmmo )
{
keyHint( "reload" );
wait( 2.0 );
}
numRepeats = 0;
dialogueLine = 0;
level.foley thread nag_on_notify_till_flag_set( "nag_ads_snap_0", 4, "player_needs_to_ADS", "firing_range_timed_ads_done" );
while ( 1 )
{
//lowerTargetDummies( "rifle" );
if ( auto_aim() && numRepeats != 0 )
{
if ( level.xenon )
actionBind = getActionBind( "ads_switch" );
else
actionBind = getActionBind( "ads_switch_shoulder" );
double_line = true;
thread killhouse_hint( actionBind.hint, 10, double_line );
wait 4;
}
level.num_hit = 0;
level.num_hit_with_ads = 0;
level.num_hit_without_ads = 0;
thread timedTargets();
level waittill( "a timed target has been hit" );
/*-----------------------
WAIT FOR 10 SECONDS OR UNTIL TOO MANY HIT FROM THE HIP
-------------------------*/
level waittill_notify_or_timeout( "player_has_hit_too_many_from_hip", 10 );
level notify( "times_up" );
if ( level.num_hit > 6 )
{
if ( level.num_hit_with_ads > 4 )
{
//PASS: Player hit more than 6 targets in the alotted time,
//at least 5 of which were in ADS
break;
}
}
wait 1;
numRepeats++;
array_thread( level.firingRangeTimedTargets,::target_reset_manual );
/*-----------------------
FAILED - TOO SLOW OR NOT ENOUGH IN ADS
-------------------------*/
if ( level.num_hit_with_ads < 4 )
{
//Sgt. Foley Do it again. You can snap to new targets by quickly engaging and releasing your aim.
//Sgt. Foley Private Allen, you're not snapping to your targets. You need to quickly engage and release aiming down the sight to snap to new targets.
//Sgt. Foley Private Allen, you're doing it wrong. Quickly engage and release aiming down the sight to snap to new targets.
level.foley dialogue_execute( "timed_ads_not_snapping_0" + dialogueLine );
}
else
{
//Sgt. Foley That was too slow. You need engage and release your aim quickly to snap to new targets
//Sgt. Foley Too slow. Private Allen, you need to quickly pop in and out of aiming down your sights to snap to new targets.
//Sgt. Foley Do it again and speed it up. Show these men how to snap to new targets by quickly popping in and out of aiming down your sights.
level.foley dialogue_execute( "timed_ads_too_slow_0" + dialogueLine );
}
dialogueLine++;
if ( dialogueLine > 2 )
{
dialogueLine = 0;
}
wait 1;
if ( ( level.player GetWeaponAmmoClip( level.gunPrimary ) ) < level.gunPrimaryClipAmmo )
{
thread keyHint( "reload" );
while ( ( level.player GetWeaponAmmoClip( level.gunPrimary ) ) < level.gunPrimaryClipAmmo )
wait .1;
clear_hints();
wait 1;
}
}
/*-----------------------
PASSED TIMED ADS
-------------------------*/
wait 1;
setObjectiveState( "obj_timed_rifle", "done" );
array_thread( level.firingRangeTimedTargets,::target_reset_manual );
/*-----------------------
ADS TARGET SWITCHING - COMPLETE
-------------------------*/
wait 0.5;
flag_clear( "aa_timed_shooting_training" );
//Sgt. Foley Now that's how you do it. You want to take down your targets quickly and with control.
level.foley dialogue_execute( "train_fly_howyoudoit" );
flag_set( "firing_range_timed_ads_done" );
}
timedTargets()
{
level endon( "times_up" );
targets = level.firingRangeTimedTargets;
last_selection = -1;
while ( 1 )
{
while ( 1 )
{
//randomly pop up a target
wait( 0.05 );
selected_target = randomint( targets.size );
if ( selected_target != last_selection )
break;
}
last_selection = selected_target;
targets[ selected_target ] notify( "pop_up" );
//wait for target to be hit
targets[ selected_target ] waittill( "hit" );
level notify( "a timed target has been hit" );
if ( level.player isADS() )
{
level.num_hit_with_ads++;
level.player notify( "did_action_ads" );
level.player notify( "did_action_ads_360" );
}
else
{
level.num_hit_without_ads++;
if ( level.num_hit_without_ads > 2 )
{
level notify( "player_has_hit_too_many_from_hip" );
break;
}
if ( level.Xenon )
thread keyHint( "ads_360" );
else
thread keyHint( "ads" );// PC and PS3 are both press
level notify( "player_needs_to_ADS" );
}
level.num_hit++;
wait .1;
}
}
/****************************************************************************
FIRING RANGE - BULLET PENETRATION
****************************************************************************/
AA_penetration_init()
{
thread firing_range_penetration();
flag_wait( "firing_range_penetration_done" );
thread AA_frags_init();
}
penetration_anims()
{
if ( level.skippingTimedADS == true )
{
flag_wait( "foley_done_talking_from_hip_ads_training" );
}
flag_wait( "foley_done_talking_from_timed_ads_training" );
/*-----------------------
FOLEY GOES INTO IDLE
-------------------------*/
level.foley.animnode notify( "stop_idle" );
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
flag_wait( "foley_turns_for_penetration_demo" );
/*-----------------------
FOLEY TURNS AROUND
-------------------------*/
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_turnaround_1" );
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
flag_set( "foley_done_talking_from_penetration_training" );
}
firing_range_penetration()
{
thread penetration_anims();
thread autosave_by_name( "penetration" );
//Sgt. Foley Now if your target is behind light cover, remember that certain weapons can penetrate and hit your target.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_lightcover" );
level.foley dialogue_execute( "train_fly_lightcover" );
flag_set( "foley_turns_for_penetration_demo" );
//Sgt. Foley The Private here will demonstrate.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_theprivatehere" );
level.foley dialogue_execute( "train_fly_theprivatehere" );
registerObjective( "obj_penetration", &"TRAINER_SHOOT_A_TARGET_THROUGH", getEnt( "firing_range", "targetname" ) );
setObjectiveState( "obj_penetration", "current" );
while ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
wait 0.05;
level.foley thread nag_on_notify_till_flag_set( "nag_penetration_fire_0", 2, "player_needs_to_shoot_through_plywood", "firing_range_penetration_done" );
thread raisePlywoodWalls();
numberOfTagretsToHit = 1;
mustADS = undefined;
mustCrouch = undefined;
mustShootThroughPlywood = true;
cycle_targets_till_hit( level.penetration_targets, numberOfTagretsToHit, mustADS, mustCrouch, mustShootThroughPlywood );
thread spawn_frags();
setObjectiveState( "obj_penetration", "done" );
delaythread( 3,:: lowerPlywoodWalls );
clear_hints();
flag_set( "firing_range_penetration_done" );
}
raisePlywoodWalls()
{
level.plywood rotateRoll( 90, 0.25, 0.1, 0.1 );
level.plywood playSound( "trainer_target_up_wood" );
level.plywood.up = true;
level.plywood endon( "plywood_going_down" );
level.plywood solid();
level.plywood setCanDamage( true );
wait .25;
while( level.plywood.up == true )
{
level.plywood waittill ( "damage", amount, attacker, direction_vec, point, type );
if ( !isdefined( attacker ) )
continue;
if ( !isdefined( type ) )
continue;
if ( isplayer( attacker ) )
{
level.lastTimePlywoodWasHit = gettime();
}
}
}
lowerPlywoodWalls()
{
level.plywood rotateRoll( -90, 0.25, 0.1, 0.1 );
level.plywood playSound( "trainer_target_up_wood" );
level.plywood notify( "plywood_going_down" );
level.plywood.up = false;
}
/****************************************************************************
FIRING RANGE - FRAGS
****************************************************************************/
AA_frags_init()
{
thread firing_range_frags();
flag_wait( "firing_range_frags_done" );
thread AA_find_pit_init();
}
frags_anims()
{
flag_wait( "foley_done_talking_from_penetration_training" );
level.foley.animnode notify( "stop_idle" );
if ( !flag( "foley_turns_for_frag_demo" ) )
{
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_idle_talk_2" );
/*-----------------------
FOLEY GOES INTO IDLE
-------------------------*/
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
}
flag_wait( "foley_turns_for_frag_demo" );
/*-----------------------
FOLEY TURNS AROUND
-------------------------*/
if ( !flag( "firing_range_frags_done" ) )
{
level.foley.animnode notify( "stop_idle" );
level.foley.animnode anim_single_solo( level.foley, "training_intro_foley_turnaround_2" );
}
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_idle", "stop_idle" );
wait( 0.05 );
flag_set( "foley_done_talking_from_frag_training" );
}
firing_range_frags()
{
if ( !flag( "frags_have_been_spawned" ) )
thread spawn_frags();
thread autosave_by_name( "frags" );
thread frags_anims();
/*-----------------------
PICKUP SOME FRAGS
-------------------------*/
wait( 1 );
//Sgt. Foley Last but not least, you need to know how to toss a frag grenade.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_tossafrag" );
level.foley dialogue_execute( "train_fly_tossafrag" );
alreadyHadFrags = false;
if ( !flag( "player_picked_up_frags" ) )
{
thread frags_glow();
//Sgt. Foley Private Allen, pick up some frag grenades from the table.
level.foley thread dialogue_execute( "train_fly_pickupfrag" );
registerObjective( "obj_frags", &"TRAINER_PICK_UP_THE_FRAG_GRENADES", getEnt( "frag_trigger", "script_noteworthy" ) );
setObjectiveState( "obj_frags", "current" );
}
else
{
alreadyHadFrags = true;
}
while ( level.player GetWeaponAmmoStock( "fraggrenade" ) < 3 )
wait ( 0.05 );
/*-----------------------
THROW A FRAG INTO THE SPOT...
-------------------------*/
if ( alreadyHadFrags )
{
registerObjective( "obj_frags", &"TRAINER_THROW_A_GRENADE_INTO", getEnt( "firing_range", "targetname" ) );
setObjectiveState( "obj_frags", "current" );
setObjectiveLocation( "obj_frags", getent( "firing_range", "targetname" ) );
}
else
{
thread setObjectiveString( "obj_frags", &"TRAINER_THROW_A_GRENADE_INTO" );
setObjectiveState( "obj_frags", "current" );
setObjectiveLocation( "obj_frags", getent( "firing_range", "targetname" ) );
}
flag_set( "foley_turns_for_frag_demo" );
thread frag_nags();
/*-----------------------
WAITTILL FRAG SUCCESS
-------------------------*/
numberOfTagretsToHit = 1;
mustADS = undefined;
mustCrouch = undefined;
mustShootThroughPlywood = true;
while ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
wait 0.05;
//Pop translator into new idle while player not looking
level.translatoranimnode notify( "stop_idle" );
level.translatoranimnode thread anim_loop_solo( level.translator, "training_intro_idle", "stop_idle" );
level.traineeanimnode notify( "stop_idle" );
level.traineeanimnode thread anim_loop_solo( level.trainee_01, "training_intro_idle", "stop_idle" );
array_thread( level.grenade_targets,::target_pop_up_continuously, "targets_hit_with_grenades" );
array_thread( level.grenade_targets,::set_flag_when_hit_by_grenade, "targets_hit_with_grenades" );
thread keyHint( "frag", undefined, true );
flag_wait( "targets_hit_with_grenades" );
flag_set( "firing_range_frags_done" );
clear_hints();
wait( 1 );
setObjectiveState( "obj_frags", "done" );
if ( ( level.player GetWeaponAmmoStock( "fraggrenade" ) ) > 0 )
{
level.player SetWeaponAmmoStock( "fraggrenade", 0 );
}
array_thread( level.grenade_targets,::target_reset_manual );
}
frag_nags()
{
nagNumber = 0;
//Sgt. Foley Toss a grenade down range to take out several targets at once.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_grenadedownrange" );
level.foley dialogue_execute( "train_fly_grenadedownrange" );
level endon( "targets_hit_with_grenades" );
thread player_frag_usage_monitor();
while( !flag( "targets_hit_with_grenades" ) )
{
wait( 6 );
if ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
{
thread killhouse_hint( &"TRAINER_HINT_TURN_AROUND" );
while ( !within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
wait 0.05;
clear_hints();
}
else if ( !flag( "player_just_threw_a_frag" ) )
{
//Sgt. Foley training Private, throw a grenade and take out those targets.
//Sgt. Foley training Private, let's go. Throw a grenade at the targets!
//Sgt. Foley training Toss a grenade down range to take out several targets at once.
level.foley dialogue_execute( "frag_nag_0" + nagNumber );
nagNumber++;
if ( nagNumber > 2 )
nagNumber = 0;
}
}
}
player_frag_usage_monitor()
{
level endon( "targets_hit_with_grenades" );
while( true )
{
level.player waittill_either( "grenade_pullback", "did_action_frag" );
flag_set( "player_just_threw_a_frag" );
wait( 5 );
flag_clear( "player_just_threw_a_frag" );
}
}
set_flag_when_hit_by_grenade( sFlagToSet )
{
level endon( sFlagToSet );
while( true )
{
self waittill ( "hit_with_grenade" );
if (!flag( sFlagToSet ) )
flag_set( sFlagToSet );
}
}
target_pop_up_continuously( sFlagToStop )
{
level endon( sFlagToStop );
while ( true )
{
self notify( "pop_up" );
self waittill ( "hit" );
wait( 1 );
}
}
//firing_range_frags_old()
//{
// if ( !flag( "frags_have_been_spawned" ) )
// thread spawn_frags();
//
// thread autosave_now( "frag_training" );
//
// /*-----------------------
// PICKUP SOME FRAGS
// -------------------------*/
// level.foley dialogue_execute( "Last but not least, you need to know how to toss a frag." );
//
// alreadyHadFrags = false;
//
// if ( !level.player GetWeaponAmmoStock( "fraggrenade" ) )
// {
// frags_glow();
// level.foley thread dialogue_execute( "Ramirez, pick up some frag grenades from the table." );
// registerObjective( "obj_frags", &"TRAINER_PICK_UP_THE_FRAG_GRENADES", getEnt( "frag_trigger", "script_noteworthy" ) );
// setObjectiveState( "obj_frags", "current" );
// }
// else
// {
// alreadyHadFrags = true;
// }
//
// while ( level.player GetWeaponAmmoStock( "fraggrenade" ) < 3 )
// wait ( 0.05 );
//
//
// /*-----------------------
// THROW A FRAG INTO THE SPOT...
// -------------------------*/
// level.foley thread dialogue_execute( "Toss a grenade into one of those mortar craters." );
// if ( alreadyHadFrags )
// {
// registerObjective( "obj_frags", &"TRAINER_THROW_A_GRENADE_INTO", getEnt( "firing_range", "targetname" ) );
// setObjectiveState( "obj_frags", "current" );
// }
// else
// {
// thread setObjectiveString( "obj_frags", &"TRAINER_THROW_A_GRENADE_INTO" );
// setObjectiveState( "obj_frags", "current" );
// }
//
// /*-----------------------
// WAITTILL FRAG SUCCESS
// -------------------------*/
//
// grenade_damage_triggers = getentarray( "grenade_damage_trigger", "targetname" );
// array_thread( grenade_damage_triggers,::frag_triggers_think, "player_has_thrown_frag_into_target" );
//
// thread keyHint( "frag", undefined, true );
// flag_wait( "player_has_thrown_frag_into_target" );
//
// clear_hints();
// setObjectiveState( "obj_frags", "done" );
// level.foley dialogue_execute( "Good." );
// flag_set( "firing_range_frags_done" );
//
//}
//nags_frag()
//{
// level endon( "player_has_thrown_frag_into_target" );
// while( !flag( "player_has_thrown_frag_into_target" ) )
// {
// clear_hints();
// thread keyHint( "frag", undefined, true );
// wait( 5 );
// }
//}
frag_triggers_think( sFlagToSetWhenComplete )
{
//self ==> the damage trigger
self enablegrenadetouchdamage();
while( true )
{
self waittill( "trigger" );
if ( !flag( sFlagToSetWhenComplete ) )
flag_set( sFlagToSetWhenComplete );
break;
}
}
frags_glow()
{
frags = getentarray( "frags", "script_noteworthy" );
array_thread( frags,::glow );
flag_wait( "player_picked_up_frags" );
array_thread( frags,::stopglow );
}
frags_glow_stop()
{
frags = getentarray( "frags", "script_noteworthy" );
array_thread( frags,::stopglow );
}
spawn_frags()
{
flag_set( "frags_have_been_spawned" );
frag_trigger = getent( "frag_trigger", "script_noteworthy" );
grenade_box = getent( "grenade_box", "targetname" );
grenade_box setmodel( "mil_grenade_box_opened" );
level.frags = getentarray( "frags", "script_noteworthy" );
level.fragsPickups = getentarray( "frags_pickup", "targetname" );
maxFrags = 4;
level endon( "firing_range_frags_done" );
while( true )
{
wait( .1 );
frag_trigger waittill( "trigger" );
if ( !level.player WorldPointInReticle_Circle( grenade_box.origin, 45, 400 ) )
continue;
if ( level.player GetWeaponAmmoStock( "fraggrenade" ) > 3 )
continue;
if ( !flag( "player_picked_up_frags" ) )
{
flag_set( "player_picked_up_frags" );
level.player giveWeapon( "fraggrenade" );
level.player SetWeaponAmmoStock( "fraggrenade", 0 );
frags_glow_stop();
}
currentPlayerFrags = level.player GetWeaponAmmoStock( "fraggrenade" );
fragsToHide = maxFrags - currentPlayerFrags;
if ( fragsToHide > 0 )
{
hide_frags_till_player_not_looking( fragsToHide );
level.player GiveMaxAmmo( "fraggrenade" );
level.player playsound( "grenade_pickup" );
}
}
}
hide_frags_till_player_not_looking( fragsToHide )
{
level endon( "firing_range_frags_done" );
validFragsToHide = [];
foreach( frag in level.fragsPickups )
{
if ( !isdefined( frag.hidden ) )
validFragsToHide[ validFragsToHide.size ] = frag;
}
//if we are already hiding all the frags, return;
if ( validFragsToHide.size == 0 )
return;
i = 0;
fragToHide = undefined;
hiddenFrags = [];
while( i < fragsToHide )
{
wait( 0.05 );
fragToHide = getclosest( level.player.origin, validFragsToHide );
if ( !isdefined( fragToHide ) )
continue;
validFragsToHide = array_remove( validFragsToHide, fragToHide );
fragToHide hide();
fragToHide.hidden = true;
hiddenFrags[ hiddenFrags.size ] = fragToHide;
i++;
}
thread show_me_when_player_not_looking_or_timeout( hiddenFrags, 3 );
}
show_me_when_player_not_looking_or_timeout( hiddenFrags, timeout )
{
level endon( "firing_range_frags_done" );
wait( .5 );
//don't bother until player on his last frag
while ( level.player GetWeaponAmmoStock( "fraggrenade" ) > 0 )
wait ( 0.05 );
start_time = gettime();
while( true )
{
wait( .5 );
if ( within_fov( level.player.origin, level.player getplayerangles(), level.firing_range_area.origin, level.cosine[ "45" ] ) )
break;
if ( gettime() >= start_time + timeout * 1000 )
break;
}
array_call( hiddenFrags,::show );
foreach( frag in hiddenFrags )
frag.hidden = undefined;
}
/****************************************************************************
OBJECTIVE TO THE PIT START
****************************************************************************/
AA_find_pit_init()
{
thread AA_find_the_pit_sequence();
flag_wait( "sidearm_complete" );
thread AA_pit_init();
}
go_to_pit_anims()
{
flag_wait( "firing_range_frags_done" );
flag_wait( "foley_done_talking_from_frag_training" );
level.foley.animnode notify( "stop_idle" );
level.traineeanimnode notify( "stop_idle" );
level.translatoranimnode notify( "stop_idle" );
//foley and crew regroup
level.foley.animnode thread anim_single_solo( level.foley, "training_intro_end" );
level.traineeanimnode thread anim_single_solo( level.trainee_01, "training_intro_end" );
level.translatoranimnode anim_single_solo( level.translator, "training_intro_end" );
//idle forever doing weapon demo
level.foley.animnode thread anim_loop_solo( level.foley, "training_intro_end_idle", "stop_idle" );
level.translatoranimnode thread anim_loop_solo( level.translator, "training_intro_end_idle", "stop_idle" );
level.traineeanimnode anim_loop_solo( level.trainee_01, "training_intro_end_idle", "stop_idle" );
}
AA_find_the_pit_sequence()
{
/*-----------------------
SIDEARM TRAINING SETUP
-------------------------*/
level.pitguy.isidling = true;
level.pitguygun show();
level.pitguy.animnode anim_first_frame( level.pitActors, "training_pit_sitting_welcome" );
level.pitguy.animnode anim_first_frame( level.pitcases, "training_pit_open_case" );
level.pitguy.animnode thread anim_loop( level.pitActors, "training_pit_sitting_idle", "stop_idle" );
//Sgt. Foley Good.
level.foley dialogue_execute( "train_fly_good" );
//Sgt. Foley Note that frags tend to roll on sloped surfaces. So think twice before tossing one up hill.
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_fragstendtoroll" );
level.foley dialogue_execute( "train_fly_fragstendtoroll" );
/*-----------------------
FOLEY STEPS AWAY
-------------------------*/
blocker_range = getent( "blocker_range", "targetname" );
blocker_range hide_entity();
thread go_to_pit_anims();
thread autosave_by_name( "find_the_pit" );
//Sgt. Foley Thanks for the help, Private Allen. Now get over to The Pit...Colonel Shepherd wants to see you run the course.
flag_wait( "notetrack_dialogue_foley_thanks_for_help" );
level.foley play_sound_on_entity( "train_fly_thanksforhelp" );
thread dialogue_ambient();
setSavedDvar( "objectiveAlpha", 1 );
registerObjective( "obj_course_locate", &"TRAINER_OBJ_GO_TO_THE_PIT", getEnt( "origin_sidearm_table_babystep_1", "targetname" ) );
setObjectiveState( "obj_course_locate", "current" );
flag_set( "obj_go_to_the_pit_given" );
delaythread ( 4, ::objective_hints, "obj_go_to_the_pit_done" );
//Sgt. Foley All right, who here wants to go first? Show me what you've learned so far.
flag_wait( "notetrack_dialogue_foley_who_go_first" );
level.translator delaythread( level.translatordelay,::dialogue_execute, "train_fly_gofirst" );
level.foley play_sound_on_entity( "train_fly_gofirst" );
flag_wait( "player_passing_barracks" );
flag_wait( "player_at_pit_stairs" );
setObjectiveLocation( "obj_course_locate", getent( "origin_sidearm_table", "targetname" ) );
/*-----------------------
SIDEARM TRAINING
-------------------------*/
flag_wait( "player_entering_course" );
flag_set( "obj_go_to_the_pit_done" );
wait( 0.05 );
clear_hints();
setObjectiveState( "obj_course_locate", "done" );
thread sideArm_Training();
}
pitguy_anims()
{
level.pitguy.animnode notify( "stop_idle" );
level.pitguy.animnode anim_single( level.pitActors, "training_pit_sitting_welcome" );
level.pitguy.animnode notify( "stop_idle" );
level.pitguy.animnode thread anim_loop( level.pitActors, "training_pit_sitting_idle", "stop_idle" );
flag_set( "dunn_finished_welcome_anim" );
}
sideArm_Training()
{
setSavedDvar( "objectiveAlpha", level.oldObjectiveAlpha );
thread autosave_by_name( "sidearm" );
thread pitguy_anims();
flag_wait( "dunn_dialogue_welcome_01" );
//Cpl. Dunn Hey Private. Welcome back to The Pit.
level.pitguy play_sound_on_entity( "train_cpd_welcomeback" );
flag_wait( "dunn_dialogue_welcome_02" );
//Cpl. Dunn I hear Colonel Shepherd wants to pull a shooter from our unit for some special op - he's up there in observation.
level.pitguy play_sound_on_entity( "train_cpd_specialop" );
alreadyHadPistol = true;
if ( !level.player HasWeapon( level.gunSidearm ) )
{
alreadyHadPistol = false;
registerObjective( "obj_sidearm", &"TRAINER_GET_A_PISTOL_FROM_THE", getEnt( "origin_sidearm_table", "targetname" ) );
setObjectiveState( "obj_sidearm", "current" );
//Cpl. Dunn Go ahead and grab a pistol.
level.pitguy dialogue_execute( "train_cpd_grabapistol" );
pickup_sidearm = getent( "pickup_sidearm", "targetname" );
if ( isdefined( pickup_sidearm ) )
pickup_sidearm glow();
}
while ( ! level.player HasWeapon( level.gunSidearm ) )
{
//NAG_HINT: Approach the table and hold [USE_BUTTON] to pick up a pistol.
wait .05;
}
if ( alreadyHadPistol == true )
{
registerObjective( "obj_sidearm", &"TRAINER_GET_A_PISTOL_FROM_THE", getEnt( "origin_course_01", "targetname" ) );
setObjectiveState( "obj_sidearm", "current" );
//Cpl. Dunn OK. So you already have your side arm.
//level.pitguy dialogue_execute( "train_cpd_alreadyhave" );
}
else
{
wait( 1 );
}
setObjectiveLocation( "obj_sidearm", getent( "origin_course_01", "targetname" ) );
setObjectiveString( "obj_sidearm", &"TRAINER_SWITCH_TO_YOUR_RIFLE" );
currentWeapon = level.player getCurrentWeapon();
if ( currentWeapon == level.gunSidearm )
{
//Cpl. Dunn Alright, try switching to your rifle
level.pitguy dialogue_execute( "train_cpd_switchtorifle" );
currentWeapon = level.player getCurrentWeapon();
if ( currentWeapon != level.gunPrimary )
thread keyHint( "primary" );
while ( level.player getCurrentWeapon() != level.gunPrimary )
{
thread keyHint( "primary" );
wait .05;
}
clear_hints();
//Cpl. Dunn Good. Switch to your sidearm again.
level.pitguy dialogue_execute( "train_cpd_switchtosidearm" );
if ( level.player getCurrentWeapon() != level.gunSidearm )
{
//NAG_HINT: Press [WEAPON_SWITCH] to switch to your pistol.
thread keyHint( "sidearm" );
//wait .05;
}
while ( level.player getCurrentWeapon() != level.gunSidearm )
{
wait .05;
clear_hints();
thread keyHint( "sidearm" );
}
clear_hints();
}
else
{
//Cpl. Dunn Do me a favor and try switching to your sidearm.
level.pitguy dialogue_execute( "train_cpd_tryswitching" );
if ( level.player getCurrentWeapon() != level.gunSidearm )
{
//NAG_HINT: Press [WEAPON_SWITCH] to switch to your pistol.
thread keyHint( "sidearm" );
//wait .05;
}
while ( level.player getCurrentWeapon() != level.gunSidearm )
{
clear_hints();
thread keyHint( "sidearm" );
wait .05;
}
clear_hints();
}
//Cpl. Dunn You see how switching to your pistol is always faster than reloading?
level.pitguy dialogue_execute( "train_cpd_alwaysfaster" );
setObjectiveState( "obj_sidearm", "done" );
flag_set ( "sidearm_complete" );
level notify ( "sideArmTraining_end" );
}
/****************************************************************************
CQB PIT COURSE START
****************************************************************************/
AA_pit_init()
{
thread AA_pit_sequence();
thread pit_cases_and_door();
}
AA_pit_sequence()
{
if ( !isdefined( level.pitguy.isidling ) )
{
level.pitguygun show();
level.pitguy.animnode anim_first_frame( level.pitActors, "training_pit_sitting_welcome" );
level.pitguy.animnode thread anim_loop( level.pitActors, "training_pit_sitting_idle", "stop_idle" );
wait( 3 );
}
/*-----------------------
PIT GUY OPENS CASE AND SHOWS MORE WEAPONRY
-------------------------*/
//Cpl. Dunn Smile for the cameras and don't miss.. Shepard and the rest of the brass are scouting for a shooter for some special op.
thread dunn_open_case_dialogue();
thread course_loop_think();
thread AI_delete_when_out_of_sight( level.patrolDudes, 256 );
flag_wait( "dunn_finished_welcome_anim" );
level.pitguy.animnode notify( "stop_idle" );
level.pitguy.animnode thread anim_single( level.pitcases, "training_pit_open_case" );
level.pitguy.animnode anim_single( level.pitActors, "training_pit_open_case" );
level.pitguy.animnode thread anim_loop( level.pitActors, "training_pit_stand_idle", "stop_idle" );
/*-----------------------
TELEPORT PIT GUY WHILE PLAYER IS RUNNING COURSE
-------------------------*/
flag_wait( "player_course_stairs2" );
level.pitguy.animnode notify( "stop_idle" );
level.pitguy.animnode = getent( "node_dunn_training_exit", "targetname" );
level.pitguy.animnode thread anim_loop( level.pitActors, "training_pit_stand_idle", "stop_idle" );
// level.pitguygun delete();
}
dunn_open_case_dialogue()
{
flag_wait( "dunn_notetrack_open_case_dialogue" );
//Cpl. Dunn Smile for the cameras and don't miss.. Shepard and the rest of the brass are scouting for a shooter for some special op.
level.pitguy play_sound_on_entity( "train_cpd_smileforcameras" );
flag_set( "dunn_finished_with_open_case_dialogue" );
}
spawn_pitguy()
{
level.pitguy = spawn_targetname( "pitguy", true );
level.pitguy gun_remove();
level.pitguy.animname = "dunn";
level.pitguygun = spawn( "script_model", ( 0, 0, 0 ) );
level.pitguygun setmodel( "viewmodel_desert_eagle" );
level.pitguygun.origin = level.pitguy.origin;
level.pitguygun hide();
level.pitguygun.animname = "pit_gun";
level.pitguygun assign_animtree();
level.pitguy.animnode = getent( "node_dunn_training", "targetname" );
level.pitActors = [];
level.pitActors[ 0 ] = level.pitguy;
level.pitActors[ 1 ] = level.pitguygun;
}
pit_cases_and_door()
{
/*-----------------------
PIT GUY OPENS CASE AND SHOWS MORE WEAPONRY
-------------------------*/
flag_wait( "case_flip_01" );
level.pit_case_01 playsound( "scn_trainer_case_open1" );
pit_weapons_case_01 = getentarray( "pit_weapons_case_01", "script_noteworthy" );
array_thread( pit_weapons_case_01,::weapons_show );
flag_wait( "case_flip_02" );
level.pit_case_02 playsound( "scn_trainer_case_open2" );
pit_weapons_case_02 = getentarray( "pit_weapons_case_02", "script_noteworthy" );
array_thread( pit_weapons_case_02,::weapons_show );
flag_wait( "button_press" );
thread autosave_by_name( "pit_course_start" );
level.gate_cqb_enter thread door_open();
flag_wait( "player_course_stairs2" );
/*-----------------------
MORE WEAPONRY ON TABLE BY THE TIME THE PLAYER GETS BACK
-------------------------*/
pit_weapons_table = getentarray( "pit_weapons_table", "script_noteworthy" );
array_thread( pit_weapons_table,::weapons_show );
}
course_loop_think()
{
level endon( "clear_course" );
level endon( "mission failed" );
numTimesPlayed = 0;
setdvar( "killhouse_too_slow", "0" );
level.first_time = true;
previous_time = 0;
previous_selection = "none";
clear_hints();
numberOfTimesRun = 0;
/*-----------------------
COURSE LOOPS
-------------------------*/
while( true )
{
if ( level.first_time )
{
// if ( ( !( level.player getCurrentWeapon() == "mp5" ) ) || ( level.player GetWeaponAmmoStock( "flash_grenade" ) < 4 ) )
// {
// //"Pick up that MP5 and four flashbangs." );
// level.price thread execDialog( "pickupmp5" );
// // Equip the MP5 and pick up 4 flashbangs.
// setObjectiveString( "obj_price", &"KILLHOUSE_EQUIP_THE_MP5_AND_PICK" );
// setObjectiveLocation( "obj_price", getent( "obj_flashes", "targetname" ) );
// }
}
else
{
// jump_off_trigger thread jumpoff_monitor();
//
// //"Replace any flash bangs you used."
// level.price execDialog( "replaceflash" );
// if ( !( level.player getCurrentWeapon() == "mp5" ) )
// {
// //"Equip your MP5."
// level.price execDialog( "equipmp5" );
// }
}
/*-----------------------
WAIT UNTILL PLAYER HAS FULL AMMO
-------------------------*/
//TODO
/*-----------------------
SPECIFIC DIALOGUE FOR FIRST-TIMERS
-------------------------*/
if ( level.first_time )
{
//level.price execDialog( "ropedeck" ); // On my go, I want you to rope down to the deck and rush to position 1.
//level.price execDialog( "stormstairs" ); // After that you will storm down the stairs to position 2.
//level.price execDialog( "hit3and4" ); // Then hit position 3 and 4 following my precise instructions at each position.
}
thread dialogue_nag_start_course( level.first_time );
/*-----------------------
COURSE OBJECTIVE
-------------------------*/
if( level.first_time )
{
level.objectiveRegroup = 0;
registerObjective( "obj_course", &"TRAINER_OBJ_COURSE", getEnt( "origin_course_01", "targetname" ) );
setObjectiveState( "obj_course", "current" );
}
/*-----------------------
RESET CQB COURSE AND OPEN DOOR
-------------------------*/
course_triggers_01 = getentarray( "course_triggers_01", "script_noteworthy" );
array_notify( course_triggers_01, "activate" );
/*-----------------------
COURSE START
-------------------------*/
flag_wait( "player_has_started_course" );
flag_clear( "dunn_finished_with_difficulty_selection_dialogue" );
setObjectiveLocation( "obj_course", getent( "origin_course_01", "targetname" ) );
if ( level.objectiveRegroup != 0 )
setObjectiveString( "obj_course", &"TRAINER_OBJ_COURSE" );
flag_clear( "melee_target_hit" );
level.targets_hit_with_melee = 0;
thread target_flag_management();
if( level.first_time )
{
thread dialogue_course_civilian_killed();
delaythread ( 3,::dialogue_ambient_pit_course );
}
level.recommendedDifficulty = undefined;
thread dialogue_course();
conversation_orgs_pit = getentarray( "conversation_orgs_pit", "targetname" );
org = getclosest( level.player.origin, conversation_orgs_pit );
if ( cointoss() )
{
//Ranger 3 Come on. Get some, Allen!
org delaythread( 3,::play_sound_in_space, "train_ar3_getsome" );
}
else if ( cointoss() )
{
//Ranger 4 Bring it, bitch!
org delaythread( 3,::play_sound_in_space, "train_ar4_bringit" );
}
else
{
//Ranger 5 Come on! Get some!
org delaythread( 3,::play_sound_in_space, "train_ar5_comeon" );
}
/*-----------------------
TOP OFF PLAYER WEAPONS
-------------------------*/
playerPrimaryWeapons = level.player GetWeaponsListPrimaries();
if ( playerPrimaryWeapons.size > 0 )
{
foreach ( weapon in playerPrimaryWeapons )
level.player givemaxammo( weapon );
}
level.targets_hit = 0;
level.friendlies_hit = 0;
if ( getdvarint( "killhouse_too_slow" ) >= 1 )
thread startTimer( level.timelimitMax );
else
thread startTimer( level.timelimitMin );
thread accuracy_bonus();
if ( isdefined( level.IW_deck ) )
level.IW_deck destroy();
setObjectiveLocation( "obj_course", getEnt( "origin_course_02", "targetname" ) );
flag_wait( "player_course_03a" );
setObjectiveLocation( "obj_course", getEnt( "origin_course_03", "targetname" ) );
/*-----------------------
MELEE TARGET
-------------------------*/
flag_wait( "player_course_stairs2" );
thread key_hint_till_flag_set( "melee", "melee_target_hit" );
flag_wait( "player_course_upstairs" );
level.gate_cqb_enter thread door_close();
level.gate_cqb_exit thread door_open();
flag_clear( "player_inside_course" );
course_end_blocker = getent( "course_end_blocker", "targetname" );
course_end_blocker hide_entity();
setObjectiveLocation( "obj_course", getEnt( "origin_course_03a", "targetname" ) );
flag_wait( "player_course_jumping_down" );
setObjectiveLocation( "obj_course", getEnt( "origin_course_05", "targetname" ) );
/*-----------------------
SPRINT TO FINISH
-------------------------*/
flag_wait_either( "player_course_end_02", "course_end_targets_dead" );
flag_wait( "player_course_end_03" );
flag_clear( "player_has_started_course" );
/*-----------------------
SPRINT LOGIC LOOP - MUST SPRINT TO EXIT
-------------------------*/
first_sprint_try = true;
iNag_didnt_sprint_number = 0;
iNag_sprint_number = 0;
while( true )
{
flag_wait( "player_standing_on_sprint_marker" );
flag_clear( "sprinted" );
thread player_sprint_monitor();
clear_hints();
/*-----------------------
SETUP SPRINT DETECTORS
-------------------------*/
notify_on_sprint();
thread flag_on_notify( "sprinted" );
//player must sprint
if ( level.xenon )// ghetto but PS3 requires "Press X" and 360 requires "Click X"
thread key_hint_till_flag_set( "sprint", "player_course_end" );
else
thread key_hint_till_flag_set( "sprint_pc", "player_course_end" );
if ( first_sprint_try )
{
//Cpl. Dunn Sprint to the exit! Clock's ticking!
thread radio_dialogue( "train_cpd_sprint" );
first_sprint_try = false;
}
else
{
setObjectiveLocation( "obj_course", getEnt( "origin_course_05", "targetname" ) );
level.gate_cqb_exit thread door_open( undefined, true );
thread exit_light_off();
//Cpl. Dunn Go! Sprint to the exit!
//Cpl. Dunn Move! Sprint, Private!
//Cpl. Dunn Sprint, Allen! Go! Go! Go!
//Cpl. Dunn Now sprint to the exit! Move! Move! Move!
thread radio_dialogue( "nag_sprint_0" + iNag_sprint_number );
iNag_sprint_number++;
if ( iNag_sprint_number > 3 )
iNag_sprint_number = 0;
}
flag_wait( "player_sprint_door_close" );
if ( !flag( "sprinted" ) )
{
/*-----------------------
PLAYER DIDN'T SPRINT
-------------------------*/
setObjectiveLocation( "obj_course", getEnt( "origin_course_sprint", "targetname" ) );
level.gate_cqb_exit thread door_close( undefined, true );
level.gate_cqb_exit thread play_sound_on_entity( "door_close_buzzer" );
thread exit_light_on();
//Cpl. Dunn You need to sprint to complete the course. Go back to the red circle and try again
//Cpl. Dunn You didn't sprint, Private. Go back to the red circle and sprint to the exit.
//Cpl. Dunn You need to sprint, Private. Go back to the red circle and sprint to the end.
//Cpl. Dunn You can't finish till you sprint, Allen. Go back to the red circle and sprint to the end.
thread radio_dialogue( "nag_didnt_sprint_0" + iNag_didnt_sprint_number );
thread killhouse_hint( &"TRAINER_TRY_SPRINT_AGAIN", undefined, true );
iNag_didnt_sprint_number++;
if ( iNag_didnt_sprint_number > 3 )
iNag_didnt_sprint_number = 0;
}
else
{
break;
}
}
//if ( !flag( "player_course_end" ) )
//thread second_sprint_hint();
/*-----------------------
COURSE END
-------------------------*/
flag_wait( "player_course_end" );
course_end_blocker = getent( "course_end_blocker", "targetname" );
course_end_blocker show_entity();
numberOfTimesRun++;
clear_hints();
thread reset_course_targets();
level.gate_cqb_exit thread door_close( "player_course_end_close_gate" );
//level notify ( "kill_sprint_hint" );
clear_hints();
flag_clear( "sprinted" );
level notify ( "test_cleared" );
final_time = killTimer( level.bestPitTime, false );
while( !isdefined( level.recommendedDifficulty ) )
wait( .1 );
selection = dialog_end_of_course( numberOfTimesRun );
if ( level.recommendedDifficulty == 1000 )
{
selection = undefined;
if ( level.targets_hit_with_melee > 10 )
{
//Cpl. Dunn You took out too many targets with your knife. Try again, this time, with bullets.
selection = "train_cpd_targetswithknife";
}
else if ( level.toomanycivilianskilled && level.basetimetooklongerthanminimum )
{
//Cpl. Dunn training Not good enough, Allen. You took too long and killed too many civilians. Try it again.
selection = "train_cpd_longandcivilians";
}
else if ( level.toomanytargetsmissed && level.basetimetooklongerthanminimum )
{
//Cpl. Dunn training Not good enough, Allen. You took too long and missed too many targets. Try it again.
selection = "train_cpd_longandtargets";
}
else if ( level.toomanytargetsmissed )
{
//Cpl. Dunn training Not good enough, Allen. You missed too many targets. Try it again.
selection = "train_cpd_targets";
}
else if ( level.toomanycivilianskilled )
{
//Cpl. Dunn training Not good enough, Allen. You killed too many civilians. Try it again.
selection = "train_cpd_civilians";
}
else
{
//Cpl. Dunn Too damn slow. You need to run it again, Private.
selection = "train_cpd_needtorunagain";
}
}
else
{
//player passed....upload score
level.player UploadTime( "LB_KILLHOUSE", final_time );
thread try_again();
}
level.pitguy dialogue_execute( selection );
previous_selection = selection;
previous_time = final_time;
level.gate_cqb_enter thread door_open();
/*-----------------------
DO IT AGAIN, OR EXIT?
-------------------------*/
if ( level.recommendedDifficulty != 1000 )
{
if ( !flag( "player_has_started_course" ) )
{
//player passed....give the option of trying again....or not
//Cpl. Dunn You can run the course again or regroup with the others by the main gate.
level.pitguy thread dialogue_execute( "train_cpd_runagain", "dunn_finished_with_difficulty_selection_dialogue" );
setObjectiveLocation( "obj_course", getent( "course_start", "targetname" ) );
setObjectiveString( "obj_course", &"TRAINER_OBJ_EXIT_THE_PIT" );
level.objectiveRegroup = 1;
}
}
else
{
setObjectiveLocation( "obj_course", getent( "origin_course_01", "targetname" ) );
}
flag_wait_either( "player_inside_course", "player_done_with_course" );
if( flag( "player_done_with_course" ) )
break;
level.first_time = false;
}
}
player_sprint_monitor()
{
level notify( "starting sprint monitor" );
level endon( "starting sprint monitor" );
level endon( "sprinted" );
level endon( "player_course_end" );
sprint_volume = getent( "sprint_volume", "targetname" );
while( true )
{
wait( 0.05 );
vel = level.player GetVelocity();
// figure out the length of the vector to get the speed (distance from world center = length)
velocity = Distance( ( vel[ 0 ], vel[ 1 ], 0 ), ( 0, 0, 0 ) ); // don't care about Z velocity
if ( ( isdefined( velocity ) ) && ( velocity > 250 ) && ( level.player istouching( sprint_volume ) ) )
{
flag_set( "sprinted" );
}
}
}
exit_light_on()
{
redlight_fx_org = GetStruct( "light_exit", "targetname" );
level.exitDoorLightEffect = PlayLoopedFX( getfx( "redlight_fx" ), 50, redlight_fx_org.origin, 2500 );
level.exitDoorLightEffect.dummy = spawn_tag_origin();
level.exitDoorLightEffect.dummy.origin = redlight_fx_org.origin;
playfxontag( getfx( "dlight_red" ), level.exitDoorLightEffect.dummy, "tag_origin" );
}
exit_light_off()
{
if ( isdefined( level.exitDoorLightEffect ) )
{
level.exitDoorLightEffect Delete();
level.exitDoorLightEffect.dummy delete();
}
}
get_global_fx( name )
{
fxName = level.global_fx[ name ];
return level._effect[ fxName ];
}
try_again()
{
level endon( "player_has_started_course" );
level notify( "try_again_thread" );
level endon( "try_again_thread" );
/*-----------------------
MENU POPUP FOR DIFFICULTY SELECTION
-------------------------*/
flag_wait_either( "player_entering_course", "player_course_looking_down_hall_to_exit" );
level.player freezecontrols( true );
setblur( 2, .1 );
wait( 1 );
//