IW4-Dump-Files/maps/favela.gsc

2139 lines
59 KiB
Plaintext
Raw Permalink Blame History

#include maps\_utility;
#include maps\_vehicle;
#include common_scripts\utility;
#include maps\_anim;
#include maps\favela_code;
PLAYER_SPRINT_SCALE = 1.4;
main()
{
// ammo crates are for SO only so remove them
array_call( getentarray( "ammo_crate_part", "targetname" ), ::delete );
array_call( getentarray( "ammo_crate_clip", "targetname" ), ::delete );
array_call( getentarray( "ammo_cache", "targetname" ), ::delete );
setDvarIfUninitialized( "favela_trailer", "0" );
setsaveddvar( "r_lightGridEnableTweaks", 1 );
setsaveddvar( "r_lightGridIntensity", 1.5 );
setsaveddvar( "r_lightGridContrast", 0 );
default_start( ::startStreet );
add_start( "street", ::startStreet );
add_start( "chase", ::startChase );
add_start( "favela", ::startFavela );
add_start( "torture", ::startTortureTrailer );
add_start( "soccer", ::startSoccer );
add_start( "hilltop", ::startHilltop );
add_start( "trailer1", ::trailer_talkers_1 );
add_start( "trailer2", ::trailer_talkers_2 );
add_start( "trailer3", ::trailer_talkers_3 );
add_start( "end", ::startEnd );
maps\createart\favela_fog::main();
maps\createart\favela_art::main();
maps\createfx\favela_audio::main();
maps\favela_precache::main();
maps\favela_fx::main();
maps\_drone_ai::init();
animscripts\dog\dog_init::initDogAnimations();
maps\_hiding_door_anims::main();
maps\_load::set_player_viewhand_model( "viewhands_player_tf141_favela" );
maps\_load::main();
maps\favela_anim::main();
maps\_compass::setupMiniMap( "compass_map_favela" );
thread maps\favela_amb::main();
level.ai_friendlyFireBlockDuration = getdvarfloat( "ai_friendlyFireBlockDuration" );
level.advanceToEnemyInterval = 30000; // how often AI will try to run directly to their enemy if the enemy is not visible
level.advanceToEnemyGroupMax = 1; // group size for AI running to their enemy
level.lastWallaTime = getTime();
level.physics_drop_models[ 0 ] = "trash_container_big2";
level.physics_drop_models[ 1 ] = "com_milk_carton";
level.physics_drop_models[ 2 ] = "com_bottle4";
level.physics_drop_models[ 3 ] = "trash_cup_tall3";
level.physics_drop_models[ 4 ] = "trash_plate1";
level.physics_drop_models[ 5 ] = "trash_can1";
level.physics_drop_models[ 6 ] = "trash_can2";
level.physics_drop_models[ 7 ] = "trash_can3";
level.physics_drop_models[ 8 ] = "trash_can4";
foreach( model in level.physics_drop_models )
precacheModel( model );
precacheString( &"FAVELA_OBJ_CATCH_RUNNER" );
precacheString( &"FAVELA_OBJ_REACH_TOP" );
precacheString( &"FAVELA_OBJ_CAPTURE" );
precacheString( &"FAVELA_KILLED_RUNNER" );
precacheString( &"FAVELA_RUNNER_GOT_AWAY" );
precacheString( &"FAVELA_ROJAS_KILLED" );
precacheShader( "black" );
precacheItem( "rpg_straight" );
precacheItem( "flash_grenade" );
precacheModel( "com_bike_animated" );
precacheModel( "curtain_torn01_animated" );
precacheModel( "machinery_car_battery" );
precacheModel( "vehicle_hummer_hula_girl" );
array_spawn_function_noteworthy( "delete_at_path_end", ::delete_ai_at_path_end );
array_spawn_function_noteworthy( "delete_at_path_end_no_choke", ::delete_ai_at_path_end_no_choke );
array_spawn_function_noteworthy( "seek_player", ::seek_player );
array_spawn_function_noteworthy( "dog_seek_player", ::dog_seek_player );
array_spawn_function_noteworthy( "delete_at_goal", ::delete_ai_at_goal );
array_spawn_function_noteworthy( "dont_see_player_no_choke", ::dont_see_player );
array_spawn_function_noteworthy( "ignore_and_delete_on_goal", ::ignore_and_delete_on_goal );
array_spawn_function_noteworthy( "ignore_and_delete_on_goal_nosight", ::ignore_and_delete_on_goal, true );
array_spawn_function_noteworthy( "window_smasher", ::window_smasher );
array_spawn_function_noteworthy( "ignored_until_goal", ::ignored_until_goal );
array_spawn_function_noteworthy( "desert_eagle_guy", ::desert_eagle_guy );
array_spawn_function_noteworthy( "faust", ::faust_spawn_func );
array_spawn_function_noteworthy( "civilian_driver", ::civilian_driver );
// spawners with script_parameters get processed on spawn
all_axis_spawners = getspawnerteamarray( "axis" );
script_parameter_spawners = [];
foreach( spawner in all_axis_spawners )
{
if ( !isdefined( spawner.script_parameters ) )
continue;
script_parameter_spawners[ script_parameter_spawners.size ] = spawner;
}
array_spawn_function( script_parameter_spawners, ::process_ai_script_parameters );
array_spawn_function( getSpawnerTeamArray( "neutral" ), ::civilian_flee_walla );
array_thread( getentarray( "play_sound", "targetname" ), ::play_sound_trigger );
array_thread( getentarray( "trigger_chance", "targetname" ), ::trigger_spawn_chance );
array_thread( getentarray( "physics_drop", "targetname" ), ::physics_drop );
array_thread( getentarray( "trigger_cleanup", "targetname" ), ::trigger_cleanup );
array_thread( getentarray( "potted_plant", "targetname" ), ::potted_plant );
array_thread( getentarray( "play_fx_trig", "targetname" ), ::play_fx_trig );
array_thread( getentarray( "retreat_trigger", "targetname" ), ::retreat_trigger );
array_thread( getentarray( "curtain_pulldown", "script_noteworthy" ), ::curtain_pulldown );
array_thread( getentarray( "curtain_pulldown_playerwait", "script_noteworthy" ), ::curtain_pulldown, true );
array_thread( getvehiclenodearray( "car_screech_node", "script_noteworthy" ), ::car_screech_node );
add_global_spawn_function( "axis", ::adjustAccuracy );
//flag_init( "all_friendlies_at_runner" );
flag_init( "favela_gate_dialog_done" );
flag_init( "car_getting_shot" );
flag_init( "driver_dead" );
flag_init( "player_is_ducking" );
flag_init( "favela_music" );
flag_init( "faust_music" );
flag_init( "opening_scene_started" );
flag_init( "favela_enemies_spawned" );
flag_init( "start_chase" );
flag_init( "block_alley" );
flag_init( "favela_move_friendlies" );
flag_init( "favela_civilians_fleeing" );
flag_init( "allow_meat_death" );
flag_init( "allow_royce_death" );
flag_init( "civilians_walla" );
flag_init( "torture_sequence_done" );
flag_init( "van_skid" );
flag_init( "makarov_alley_wounded" );
flag_init( "favela_civilians_alerted" );
flag_init( "favela_civilians_spawned" );
flag_init( "ending_sequence_ready" );
flag_init( "ending_sequence_started" );
flag_init( "ending_sequence_dialog" );
flag_init( "start_final_dialog" );
flag_init( "visionset_chase" );
flag_init( "visionset_torture" );
flag_init( "soap_exits_car" );
trigger_off( "favela_opening_civilians_spawn", "targetname" );
thread vision_chase();
thread vision_torture();
thread gag_fence_dog();
thread gag_civilian_window_1();
thread favela_opening_civilians();
thread favela_music();
thread upper_village_triggered_dialog();
thread upper_village_music();
thread random_favela_background_runners();
thread faust_appearance_1();
thread faust_appearance_2();
thread faust_appearance_3();
thread faust_appearance_4();
thread street_scenes();
thread chase();
thread forklift_blocker();
thread final_bend_dialog();
thread final_staircase_dialog();
thread ending_sequence();
skill = getDifficulty();
if ( skill != "hard" && skill != "fu" )
{
setsaveddvar( "ai_accuracy_attackerCountMax", 4 );
setsaveddvar( "ai_accuracy_attackerCountDecrease", 0.6 );
}
}
startStreet()
{
thread battlechatter_off( "allies" );
thread battlechatter_off( "axis" );
setSavedDvar( "compass", 0 );
setSavedDvar( "hud_showStance", 0 );
// start random city traffic
thread start_traffic_group( 3.5, "traffic_car_groupA_1", "traffic_car_groupA_2");
thread start_traffic_group( 5.0, "traffic_car_groupB_1", "traffic_car_groupB_2");
// spawn street civilians
array_thread( getentarray( "street_civilian", "targetname" ), ::spawn_ai, true );
delayThread( 8.0, ::bike_rider, "bike_path_1" );
delayThread( 13.0, ::bike_rider, "bike_path_2" );
thread opening_scene();
thread intro_music();
}
intro_music()
{
// start intro music for ride and chase, and ends the music if the runner is shot before the alley
thread music_play( "favela_intro" );
level waittill( "runner_shot" );
music_stop( 2.0 );
}
startChase()
{
thread battlechatter_off( "allies" );
thread battlechatter_off( "axis" );
movePlayerToStartPoint( "playerstart_chase" );
setSavedDvar( "player_sprintUnlimited", "1" );
setSavedDvar( "player_sprintSpeedScale", PLAYER_SPRINT_SCALE );
flag_set( "start_chase" );
flag_set( "visionset_chase" );
}
startTortureTrailer()
{
setDvar( "favela_trailer", 1 );
thread startFavela();
}
startFavela()
{
thread battlechatter_off( "allies" );
thread battlechatter_off( "axis" );
thread fade_to_black_alley( 0.2, 2.0, 2.5 );
level waittill( "black_screen_start" );
// Give flashbangs and grenades now that the chase is over
level.player giveWeapon( "fraggrenade" );
level.player setOffhandSecondaryClass( "flash" );
level.player giveWeapon( "flash_grenade" );
level notify( "stop_monitoring_makarov_damage" );
// delete any AI ( dead or alive ) that might be left over from before
thread delete_ai_during_blackscreen();
array_call( getCorpseArray(), ::delete );
if ( isdefined( level.runner ) )
level.runner delete();
flag_set( "visionset_torture" );
level delayThread( 1.2, ::torture_sequence );
movePlayerToStartPoint( "playerstart_favela" );
activate_trigger( "favela_vision", "script_noteworthy" );
flag_set( "civilians_walla" );
enablePlayerWeapons( false );
// Reenable destructibles to do bad places, was disabled for the chase
level.disable_destructible_bad_places = undefined;
level.player setStance( "stand" );
setSavedDvar( "player_sprintUnlimited", "0" );
setSavedDvar( "player_sprintSpeedScale", 1.5 );
assert( isdefined( level.ai_friendlyFireBlockDuration ) );
setSavedDvar( "ai_friendlyFireBlockDuration", level.ai_friendlyFireBlockDuration );
flag_clear( "player_near_stairs" );
// Block the alley with the forklift so player wont backtrack
flag_set( "block_alley" );
level waittill( "black_screen_finish" );
thread autosave_now();
thread timed_favela_autosaves();
favela_friendlies();
flag_clear( "give_favela_warning" );
trigger_on( "favela_opening_civilians_spawn", "targetname" );
getent( "favela_enter_player_clip", "targetname" ) delete(); // remove player clip brush that prevented the player from entering the favela prematurely.
wait 0.05;
// Make enemies talk more by modding battlechatter times
thread modify_battlechatter_times();
// Wait for torture sequence to end before going into favela
flag_wait( "favela_move_friendlies" );
flag_set( "favela_music" );
enablePlayerWeapons( true );
thread add_top_of_hill_objective();
thread favela_gate();
thread favela_warning();
thread favela_dialog();
thread soccer_dialog();
thread meat_dies();
thread royce_dies();
}
startSoccer()
{
add_top_of_hill_objective();
array_call( getentarray( "delete_for_start_soccer", "script_noteworthy" ), ::delete );
movePlayerToStartPoint( "playerstart_soccer" );
activate_trigger( "vision_shanty", "script_noteworthy" );
flag_set( "civilians_walla" );
}
startHilltop()
{
add_top_of_hill_objective();
movePlayerToStartPoint( "playerstart_hilltop" );
activate_trigger( "favela_hill", "script_noteworthy" );
flag_set( "civilians_walla" );
}
trailer_talkers_1()
{
spawn_talkers( "trailer_talkers_1" );
level.player set_ignoreme( true );
movePlayerToStartPoint( "trailer_talkers_1_player" );
}
trailer_talkers_2()
{
spawn_talkers( "trailer_talkers_2" );
level.player set_ignoreme( true );
movePlayerToStartPoint( "trailer_talkers_2_player" );
}
trailer_talkers_3()
{
spawn_talkers( "trailer_talkers_3" );
level.player set_ignoreme( true );
movePlayerToStartPoint( "trailer_talkers_3_player" );
}
spawn_talkers( targetname )
{
spawners = getentarray( targetname, "targetname" );
foreach( spawner in spawners )
{
guy = spawner spawn_ai( true );
guy set_ignoreall( true );
guy.goalradius = 16;
guy setGoalPos( guy.origin );
if ( !isdefined( spawner.animation ) )
continue;
guy.animname = "trailer";
guy thread anim_loop_solo( guy, spawner.animation );
}
}
startEnd()
{
add_top_of_hill_objective();
movePlayerToStartPoint( "playerstart_end" );
activate_trigger( "favela_vision", "script_noteworthy" );
}
favela_gate()
{
// Gate sequence gone, just some dialog now
thread favela_gate_dialog();
}
favela_gate_dialog()
{
// Wait for torture sequence to finish so we don't step on dialog
flag_wait( "torture_sequence_done" );
// Let's go.
level.royce anim_single_solo( level.royce, "favela_ryc_letsgo" );
// Wait for player to be somewhere nearby
flag_wait( "player_near_stairs" );
// Remember - there are civilians in the favela. Take clean shots, watch your background.
level.royce anim_single_solo( level.royce, "favela_ryc_watchyourbg" );
flag_set( "favela_gate_dialog_done" );
}
torture_sequence()
{
node = getent( "torture_node", "targetname" );
door = getent( "torture_door", "targetname" );
torture_enemy_spawner_targetname = "torture_enemy_spawner";
if ( getdvarint( "favela_trailer" ) > 0 )
torture_enemy_spawner_targetname = "torture_enemy_spawner_trailer";
guys[ 0 ] = spawn_targetname( torture_enemy_spawner_targetname );
guys[ 0 ].animname = "torture_enemy";
guys[ 1 ] = spawn_targetname( "torture_friendly_1_spawner" );
guys[ 1 ].animname = "torture_friend1";
guys[ 2 ] = spawn_targetname( "torture_friendly_2_spawner" );
guys[ 2 ].animname = "torture_friend2";
foreach( guy in guys )
{
guy set_ignoreme( true );
guy set_ignoreall( true );
}
jumper_cables = spawn_anim_model( "torture_cables", node.origin );
guys[ 3 ] = jumper_cables;
//chad - comment this out once the map has been recompiled
battery_origin = ( -527, -1043.5, 725 );
battery_angles = ( 0, 289.5, 0 );
car_battery = spawn( "script_model", battery_origin );
car_battery.angles = battery_angles;
car_battery setModel( "machinery_car_battery" );
//----
node anim_first_frame( guys, "torture" );
guys[ 2 ] thread torture_sequence_door( door );
guys[ 2 ] setLookAtEntity( level.player );
guys[ 0 ] thread play_sound_on_entity( "scn_favela_captive_in_chair" );
garagePos = guys[ 0 ].origin;
node anim_single( guys, "torture" );
array_call( guys, ::delete );
flag_set( "torture_sequence_done" );
flag_set( "favela_move_friendlies" );
thread play_sound_in_space( "scn_favela_garage_interior", garagePos );
}
torture_sequence_door( door )
{
finalDoorPos = door.origin;
startingDoorPos = door.origin + ( 0, 0, 45 );
door.origin = startingDoorPos;
flag_wait( "drop_door" );
door playsound( "scn_favela_garage_door" );
door moveTo( finalDoorPos, 1.3, 0.1, 0.0 );
}
opening_scene()
{
// open/close hotel doors for the sequence
thread hotel_doors();
// spawn player vehicle and put player inside
player_vehicle = spawn_vehicle_from_targetname_and_drive( "player_vehicle" );
assert( isdefined( player_vehicle ) );
player_vehicle hidepart( "TAG_GLASS_FRONT_D" );
player_vehicle hidepart( "TAG_BLOOD" );
player_vehicle thread car_anims();
player_vehicle thread car_driver_anims();
player_vehicle thread play_sound_on_entity( "scn_favela_driveup" );
thread player_rides_vehicle( player_vehicle );
// spawn van
van = spawn_vehicle_from_targetname_and_drive( "van" );
assert( isdefined( van ) );
van godon();
van thread van_skid_sound();
van.animname = "van";
van SetAnimTree();
// slow for intro screen - dont want to go too far while screen is black
player_vehicle Vehicle_SetSpeed( 3, 5.0, 5.0 );
van Vehicle_SetSpeed( 3, 5.0, 5.0 );
wait 4;
thread opening_scene_dialog();
player_vehicle resumeSpeed( 2.5 );
van resumeSpeed( 2.5 );
// wait for van to get into position
vehNode = getVehicleNode( "van_last_node", "script_noteworthy" );
vehNode waittill( "trigger" );
// get animation node
animNode = getent( "opening_scene_node", "targetname" );
// spawn actors ( actually just spawns drones )
makarov_spawner = getent( "makarov_spawner", "targetname" );
driver_spawner = getent( "opening_driver_spawner", "targetname" );
gunner1_spawner = getent( "opening_gunner1_spawner", "targetname" );
gunner2_spawner = getent( "opening_gunner2_spawner", "targetname" );
wait 1;
makarov = makarov_spawner spawn_ai( true );
makarov.animname = "makarov";
makarov thread magic_bullet_shield();
makarov.ignorerandombulletdamage = true;
makarov.grenadeawareness = 0;
driver = driver_spawner spawn_ai( true );
driver.animname = "driver";
driver thread opening_death();
driver thread blood_driver();
gunner1 = gunner1_spawner spawn_ai( true );
gunner1.animname = "gunner1";
gunner1 thread opening_death();
gunner1 thread blood_gunner1();
gunner2 = gunner2_spawner spawn_ai( true );
gunner2.animname = "gunner2";
gunner2 thread opening_death();
gunner2 thread blood_gunner2();
guys[ 0 ] = makarov;
guys[ 1 ] = driver;
guys[ 2 ] = gunner1;
guys[ 3 ] = gunner2;
street_clip = getent( "street_civilian_clip", "targetname" );
street_clip connectPaths();
street_clip delete();
flag_set( "opening_scene_started" );
van thread van_door_sounds();
van thread anim_single_solo( van, "door_open" );
animNode anim_single( guys, "opening_scene" );
level notify( "end_scene" );
thread stop_traffic();
// makarov shoots at player for a bit then flees
animNode thread anim_loop_solo( makarov, "opening_scene_shoot", "stop_shooting" );
thread break_windshield( player_vehicle );
makarov makarov_shoot_player( player_vehicle );
animNode notify( "stop_shooting" );
makarov anim_stopanimscripted();
// makarov runs around the corner and gets deleted
runner_first_node = getnode( "runner_first_node", "targetname" );
makarov.goalradius = 32;
makarov thread delete_ai_at_goal( true );
makarov set_ignoreall( true );
makarov setGoalNode( runner_first_node );
thread delayThread( 1.0, ::flag_set, "start_chase" );
player_vehicle thread play_sound_on_entity( "scn_favela_npc_door_open" );
wait 2;
// get player out of the vehicle
thread player_exits_vehicle( player_vehicle );
flag_set( "visionset_chase" );
}
player_rides_vehicle( vehicle )
{
level endon( "exiting_vehicle" );
enablePlayerWeapons( false );
MAX_ROTATE_ANG = 66;
// attach player to viewmodel rig for crouch movement
player_rig = spawn_anim_model( "player_rig" );
player_rig.origin = vehicle getTagOrigin( "tag_passenger" );
player_rig.angles = vehicle getTagAngles( "tag_passenger" );
player_rig linkTo( vehicle, "tag_passenger" );
player_rig hide();
player_rig thread player_dies_in_vehicle();
level.player playerLinkToDelta( player_rig, "tag_player", 1.0, MAX_ROTATE_ANG, MAX_ROTATE_ANG, 45, 20 );
level.player allowProne( false );
level.player allowCrouch( false );
level.player allowStand( true );
flag_clear( "player_is_ducking" );
level.player endon( "death" );
level.player setStance( "stand" );
player_rig thread anim_first_frame_solo( player_rig, "duck_down" );
notifyOnCommand( "go_crouch", "+movedown" );
notifyOnCommand( "go_crouch", "+prone" );
notifyOnCommand( "go_crouch", "+stance" );
notifyOnCommand( "go_crouch", "lowerstance" );
notifyOnCommand( "go_crouch", "togglecrouch" );
notifyOnCommand( "go_crouch", "toggleprone" );
notifyOnCommand( "go_crouch", "goprone" );
notifyOnCommand( "go_crouch", "gocrouch" );
notifyOnCommand( "go_stand", "+stance" );
notifyOnCommand( "go_stand", "raisestance" );
notifyOnCommand( "go_stand", "togglecrouch" );
notifyOnCommand( "go_stand", "toggleprone" );
notifyOnCommand( "go_stand", "+moveup" );
notifyOnCommand( "go_stand", "+gostand" );
for(;;)
{
level.player waittill( "go_crouch" );
flag_set( "player_is_ducking" );
level.player enableInvulnerability();
level.player lerpViewAngleClamp( 0.3, 0, 0, 25, 25, 25, 0 );
player_rig anim_single_solo( player_rig, "duck_down" );
player_rig thread anim_loop_solo( player_rig, "duck_down_idle", "stop_down_idle" );
level.player waittill( "go_stand" );
level.player lerpViewAngleClamp( 0.3, 0, 0, MAX_ROTATE_ANG, MAX_ROTATE_ANG, 45, 20 );
player_rig notify( "stop_down_idle" );
player_rig anim_single_solo( player_rig, "duck_up" );
flag_clear( "player_is_ducking" );
level.player disableInvulnerability();
}
}
player_dies_in_vehicle()
{
level endon( "exiting_vehicle" );
level.player waittill( "shot_next_frame" );
level.player lerpViewAngleClamp( 0, 0, 0, 0, 0, 0, 0 );
self anim_single_solo( self, "die" );
}
player_exits_vehicle( vehicle )
{
wait 1.2;
level notify( "exiting_vehicle" );
vehicle notify( "door_open" );
exit_point = getent( "player_vehicle_exit_point", "targetname" );
dummy = spawn( "script_model", level.player.origin );
dummy.angles = level.player.angles;
dummy setmodel( "tag_origin" );
level.player playerLinkTo( dummy, "tag_player", 1.0, 45, 45, 45, 20 );
MOVETIME = 1.5;
ACCEL = 0.3;
DECEL = 0.3;
dummy moveTo( exit_point.origin, MOVETIME, ACCEL, DECEL );
dummy rotateTo( exit_point.angles, MOVETIME, ACCEL, DECEL );
wait MOVETIME;
level.player unlink();
level.player disableInvulnerability();
enablePlayerWeapons( true );
level.player allowProne( true );
level.player allowCrouch( true );
level.player allowStand( true );
level.player setStance( "stand" );
setSavedDvar( "player_sprintUnlimited", "1" );
setSavedDvar( "player_sprintSpeedScale", PLAYER_SPRINT_SCALE );
}
van_skid_sound()
{
flag_wait( "van_skid" );
self thread play_sound_on_entity( "scn_favela_van_skid2stop" );
}
van_door_sounds()
{
self thread delayThread( 0.0, ::play_sound_on_entity, "scn_favela_van_door_open" );
self thread delayThread( 2.3, ::play_sound_on_entity, "scn_favela_van_driverdoor_open" );
self thread delayThread( 2.8, ::play_sound_on_entity, "scn_favela_van_door_close" );
self thread delayThread( 4.0, ::play_sound_on_entity, "scn_favela_van_driverdoor_close" );
}
opening_scene_dialog()
{
wait 2.0;
// Ghost, the plates are a match.
radio_dialogue( "favela_cmt_ready2move" );
// Copy. Any sign of Rojas's right hand man?
radio_dialogue( "favela_gst_good2go" );
// Negative. They've stopped twice already - no sign of him.
radio_dialogue( "favela_cmt_rogerthat" );
flag_wait( "van_in_position" );
thread autosave_now_silent();
wait 0.5;
// Wait, they've stopped again. Standby.
radio_dialogue( "favela_cmt_inposition" );
wait 2.5;
// Got a positive ID! Whoever these guys are, they're not happy to see him<69>
radio_dialogue( "favela_cmt_insight" );
wait 0.9;
// Ghost we have a situation here!
radio_dialogue( "favela_cmt_needhimalive" );
wait 0.2;
// Get down get down!!!
radio_dialogue( "favela_cmt_getdown" );
}
chase()
{
flag_wait( "start_chase" );
flag_clear( "runner_gets_away" );
setSavedDvar( "compass", 1 );
setSavedDvar( "hud_showStance", 1 );
setSavedDvar( "ai_friendlyFireBlockDuration", 0 );
thread autosave_now();
// disable badplaces on destructibles so that soap can run through the city without getting stuck, then set it back
level.disable_destructible_bad_places = true;
// spawn soap
level.soap = spawn_targetname( "soap_spawner", true );
level.soap set_ignoreall( true );
level.soap.usechokepoints = false;
level.soap.fixednode = false;
level.soap.disableBulletWhizbyReaction = true;
level.soap.a.disablePain = true;
level.soap.maxsightdistsqrd = 0;
level.soap.ignoresuppression = true;
level.soap.animname = "mactavish";
level.soap.pathRandomPercent = 0;
level.soap thread magic_bullet_shield();
chase_objective_location = getent( "chase_objective_location", "targetname" );
objective_add( 1, "current", &"FAVELA_OBJ_CATCH_RUNNER", chase_objective_location.origin );
waveNode = getnode( "soap_start_node", "targetname" );
waveNode anim_teleport_solo( level.soap, "run_and_wave" );
flag_set( "soap_exits_car" );
waveNode anim_single_solo( level.soap, "run_and_wave" );
thread chase_dialog();
level.soap thread control_run_speed();
// Wait for makarov street trigger and then spawn makarov
// He will run his path when he spawns
//trigger_wait( "makarov_street_spawn_trig", "targetname" );
makarov = spawn_targetname( "makarov_street_spawner", true );
makarov set_ignoreall( true );
makarov set_ignoreme( true );
makarov.disableBulletWhizbyReaction = true;
makarov.a.disablePain = true;
makarov.maxsightdistsqrd = 0;
makarov.ignoresuppression = true;
makarov.usechokepoints = false;
makarov.skipBloodPool = true;
makarov thread magic_bullet_shield();
makarov thread faust_assistant_kill_player_monitor();
makarov thread teleport_runner_for_takedown_1();
makarov thread teleport_runner_for_takedown_2();
makarov thread makarov_alley_fall();
makarov thread makarov_gets_away();
makarov thread player_doesnt_chase();
makarov thread makarov_check_player_distance();
objective_onentity( 1, level.soap, ( 0, 0, 70 ) );
}
makarov_check_player_distance()
{
// Player fails if you don't keep up with the runner
// Once you're told to take the shot you can't fail for getting too far away anymore
// He will get away and fail soon anyways if you don't shoot him so give the player some freedom to take him down here
level endon( "take_the_shot" );
self endon( "death" );
self endon( "runner_shot" );
MIN_DIST = 500;
MAX_DIST = 2500;
SPEED_MIN = 1.0;
SPEED_MAX = 1.6;
for(;;)
{
d = distance( level.player.origin, self.origin );
if ( d > MAX_DIST )
{
setdvar( "ui_deadquote", "@FAVELA_RUNNER_GOT_AWAY" );
maps\_utility::missionFailedWrapper();
return;
}
runSpeed = self.moveplaybackrate;
if ( d < MIN_DIST )
{
// player too close - run faster
runSpeed += 0.1;
}
else
{
// player farther away - run normal speed again
runSpeed -= 0.1;
}
self.moveplaybackrate = cap_value( runSpeed, SPEED_MIN, SPEED_MAX );
wait 0.1;
}
}
chase_dialog()
{
level endon( "runner_shot" );
// Ghost, our driver's dead! We're on foot! Meet us at the Hotel Rio and cut him off if you can!
level.soap dialogue_queue( "favela_cmt_driversdead" );
// Roger, I'm on my way!
radio_dialogue( "favela_gst_onmyway" );
flag_wait( "runner_in_alley" );
// He went into the alley - bloody hell he's fast!
radio_dialogue( "favela_gst_hesfast" );
// Non-lethal takedowns only! We need him alive!
level.soap dialogue_queue( "favela_cmt_nonlethal" );
flag_wait( "take_the_shot" );
thread legshot_pre_stinger();
// Roach - take the shot!! Go for his leg!!
level.soap dialogue_queue( "favela_cmt_takeshot" );
}
legshot_pre_stinger()
{
level endon( "runner_shot" );
wait 0.75;
thread music_stop( 0.25 );
level.player thread play_sound_on_entity( "favela_legshot_pre_stinger" );
}
teleport_runner_for_takedown_1()
{
// This makes sure he hasn't gotten too far down the alley when the player gets there.
// In the case that the player is really far behind they would have failed already for
// not keeping up so I dont really have to worry about that.
self endon( "death" );
trig = getent( "teleport_runner_1", "targetname" );
teleportLoc = getent( trig.target, "targetname" );
trig waittill( "trigger" );
// Only teleport him if he's gone around the corner out of sight
if ( !flag( "runner_in_alley" ) )
return;
self forceTeleport( teleportLoc.origin, teleportLoc.angles );
}
teleport_runner_for_takedown_2()
{
self endon( "death" );
trig = getent( "teleport_runner_2", "targetname" );
teleportLoc = getent( trig.target, "targetname" );
trig waittill( "trigger" );
// Only teleport him if he's gone around the corner out of sight
if ( !flag( "runner_in_alley2" ) )
return;
self forceTeleport( teleportLoc.origin, teleportLoc.angles );
}
makarov_alley_fall()
{
//level endon( "makarov_wounded_successfully" );
level endon( "stop_monitoring_makarov_damage" );
self set_generic_deathanim( "alley_death_fall" );
for(;;)
{
self waittill( "damage", damage, attacker, direction_vec, point, type );
// Only Soap and the player can damage him
if ( !isdefined( attacker ) )
continue;
if ( attacker != level.player && attacker != level.soap )
continue;
// If damage is only 1 ignore it. This happens when flashbangs and other things bounce off him
if ( damage <= 1 )
continue;
// If player uses grenades you fail
if ( !isdefined( type ) )
continue;
if ( issubstr( type, "GRENADE" ) )
{
self thread makarov_alley_killed( point );
return;
}
// Only non-lethal shots are allowed
if ( self was_shot_in_lethal_area() )
{
self thread makarov_alley_killed( point );
return;
}
self thread makarov_alley_wounded();
}
}
was_shot_in_lethal_area()
{
assert( isdefined( self ) );
if ( isdefined( self.disableLethalCheck ) )
return false;
if ( !isdefined( self.damagelocation ) )
return true;
switch( self.damagelocation )
{
case "none":
if ( flag( "makarov_alley_wounded" ) )
return false;
return true;
case "helmet":
case "head":
case "neck":
case "torso_upper":
case "torso_lower":
return true;
default:
return false;
}
}
makarov_alley_wounded()
{
level notify( "runner_shot" );
if ( flag( "makarov_alley_wounded" ) )
return;
flag_set( "makarov_alley_wounded" );
self thread makarov_alley_wounded_and_crawl();
wait 1.0;
level.soap thread anim_single_solo( level.soap, "favela_cmt_hesdown" );
wait 1.0;
level notify( "makarov_wounded_successfully" );
objective_State( 1, "done" );
thread startFavela();
}
makarov_alley_wounded_and_crawl()
{
self endon( "deleted" );
self endon( "death" );
if ( flag( "runner_disable_crawl" ) )
self clear_deathanim();
self stop_magic_bullet_shield();
level.runner = self;
level.runner thread play_sound_in_space( "scn_favela_death_crawl", level.runner.origin );
self.noDrop = true;
self kill();
}
makarov_alley_killed( point )
{
level notify( "runner_shot" );
if ( !flag( "makarov_alley_wounded" ) )
{
self clear_deathanim();
self stop_magic_bullet_shield();
self kill( point, level.player );
}
setdvar( "ui_deadquote", "@FAVELA_KILLED_RUNNER" );
maps\_utility::missionFailedWrapper();
}
makarov_gets_away()
{
self endon( "runner_shot" );
self waittill( "reached_path_end" );
setdvar( "ui_deadquote", "@FAVELA_RUNNER_GOT_AWAY" );
maps\_utility::missionFailedWrapper();
}
player_doesnt_chase()
{
self endon( "runner_shot" );
flag_wait( "runner_gets_away" );
setdvar( "ui_deadquote", "@FAVELA_RUNNER_GOT_AWAY" );
maps\_utility::missionFailedWrapper();
}
stop_sounds_during_black()
{
// Total hack to get sounds to stop playing. No good way to do this
X_LINE = -50;
ents = getentarray();
foreach( ent in ents )
{
if ( ent.origin[ 0 ] < X_LINE )
continue;
if ( !isdefined( ent.code_classname ) )
continue;
switch( ent.classname )
{
case "script_vehicle":
case "script_origin":
case "script_model":
case "script_struct":
ent notify( "stop_car_alarm" );
ent stopSounds();
break;
default:
break;
}
}
}
fade_to_black_alley( fadeInTime, fadeOutTime, duration )
{
setSavedDvar( "compass", 0 );
setSavedDvar( "hud_showStance", 0 );
stop_sounds_during_black();
level.player playLocalSound( "scn_favela_legshot_stinger" );
overlay = newHudElem();
overlay.x = 0;
overlay.y = 0;
overlay setshader( "black", 640, 480 );
overlay.alignX = "left";
overlay.alignY = "top";
overlay.horzAlign = "fullscreen";
overlay.vertAlign = "fullscreen";
overlay.alpha = 0;
if ( fadeInTime > 0 )
overlay fadeOverTime( fadeInTime );
overlay.alpha = 1;
wait fadeInTime;
wait 0.05;
level.player freezeControls( true );
level notify( "black_screen_start" );
wait duration;
level.player freezeControls( false );
level notify( "black_screen_finish" );
if ( fadeOutTime > 0 )
overlay fadeOverTime( fadeOutTime );
overlay.alpha = 0;
wait fadeOutTime;
setSavedDvar( "compass", 1 );
setSavedDvar( "hud_showStance", 1 );
overlay destroy();
}
hotel_doors()
{
rotationAmount = 110;
left = getent( "hotel_door_left", "targetname" );
right = getent( "hotel_door_right", "targetname" );
knobs = getentarray( "hotel_knob", "targetname" );
// Doors open
left rotateYaw( rotationAmount * -1, 0.05 );
right rotateYaw( rotationAmount, 0.05 );
array_call( knobs, ::hide );
flag_wait( "car_getting_shot" );
flag_wait( "player_is_ducking" );
// Doors close
left rotateYaw( rotationAmount, 0.05 );
right rotateYaw( rotationAmount * -1, 0.05 );
array_call( knobs, ::show );
}
break_windshield( vehicle )
{
flag_wait( "driver_dead" );
// break windshield on player vehicle
vehicle thread play_sound_on_tag( "scn_favela_car_glass_shatter", "TAG_GLASS_FRONT_D" );
playfxontag( getfx( "car_glass_interior" ), vehicle, "TAG_GLASS_FRONT_FX" );
vehicle showpart( "TAG_GLASS_FRONT_D" );
vehicle showpart( "TAG_BLOOD" );
vehicle hidepart( "TAG_GLASS_FRONT" );
if ( !isdefined( level.hula_girl ) )
return;
level.hula_girl unlink();
force = 150;
level.hula_girl physicsLaunchClient( level.hula_girl.origin + ( 0, 0, 5 ), ( 0, force, 0 ) );
}
driver_shot_in_head( driver )
{
//blood yessss!!!
playfxontag( getfx( "blood" ), driver, "J_Head" );
playfxontag( getfx( "blood_dashboard_splatter" ), driver, "J_Head" );
wait 0.1;
flag_set( "driver_dead" );
}
driver_falls_on_horn( driver )
{
alias = "scn_favela_merc_horn_loop";
driver thread play_loop_sound_on_entity( alias, ( 0, 0, 20 ) );
wait 60;
driver notify( "stop sound" + alias );
}
blood_gunner1()
{
wait 6.6;
playfxontag( getfx( "blood" ), self, "J_Hip_RI" );
wait 0.1;
playfxontag( getfx( "blood" ), self, "J_SpineLower" );
}
blood_gunner2()
{
wait 7.1;
playfxontag( getfx( "blood" ), self, "J_Hip_RI" );
wait 0.2;
playfxontag( getfx( "blood" ), self, "J_SpineLower" );
wait 1.2;
playfxontag( getfx( "blood" ), self, "J_Head" );
}
blood_driver()
{
wait 9.5;
playfxontag( getfx( "blood" ), self, "J_Shoulder_RI" );
}
makarov_shoot_player( vehicle )
{
self endon( "death" );
shots = 15;
shot_kill_start = 10;
shot_kill_stop = 15;
width = 29;
height = 8;
interval_min = 0.1;
interval_max = 0.3;
fireAnim = level.scr_anim[ self.animname ][ "stand_fire" ];
center = vehicle getTagOrigin( "tag_glass_front_fx" );
windowAng = vehicle getTagAngles( "tag_glass_front_fx" );
right = anglesToRight( windowAng );
up = anglesToUp( windowAng );
farLeft = center - ( right * width );
farRight = center + ( right * width );
top = center + ( up * height );
bottom = center - ( up * height );
//thread draw_line_for_time( self.origin, farLeft, 1, 0, 0, 10.0 );
//thread draw_line_for_time( self.origin, farRight, 1, 0, 0, 10.0 );
//thread draw_line_for_time( self.origin, top, 1, 0, 0, 10.0 );
//thread draw_line_for_time( self.origin, bottom, 1, 0, 0, 10.0 );
flag_set( "car_getting_shot" );
shootPoints = [];
for( i = 0 ; i < shots ; i++ )
{
rand_horizontal_offset = randomfloatrange( width * -1, width );
rand_vertical_offset = randomfloatrange( height * -1, height );
point = center;
point += right * rand_horizontal_offset;
point += up * rand_vertical_offset;
//thread draw_line_for_time( self.origin, point, 1, 1, 1, 10.0 );
shootPoints[ shootPoints.size ] = point;
}
for( i = 0 ; i < shots ; i++ )
{
self shoot( 100.0, shootPoints[ i ] );
fxOrigin = shootPoints[ i ];
forward = vectorNormalize( fxOrigin - self getTagOrigin( "tag_flash" ) );
playFX( getfx( "glass_exit" ), fxOrigin, forward );
if ( i >= shot_kill_start && i <= shot_kill_stop )
{
// this is a deadly bullet! Check that the player is crouching
if ( !flag( "player_is_ducking" ) )
self thread kill_player();
}
self setAnimKnobRestart( fireAnim, 1, .2, 1.0 );
wait randomfloatrange( interval_min, interval_max );
}
self clearAnim( fireAnim, 0 );
}
kill_player()
{
level.player notify( "shot_next_frame" );
wait 0.05;
level.player enableDeathShield( false );
level.player enableHealthShield( false );
level.player disableInvulnerability();
level.player doDamage( level.player.health + 50000, level.player getEye(), self );
wait 0.05;
if ( isalive( level.player ) )
level.player kill();
assert( !isAlive( level.player ) );
}
opening_death()
{
level waittill( "end_scene" );
self.allowdeath = true;
self.a.nodeath = true;
self.noragdoll = true;
self setContents( 0 );
self kill();
}
add_top_of_hill_objective()
{
originEnt = getent( "mission_objective_location", "targetname" );
objective_add( 2, "current", &"FAVELA_OBJ_REACH_TOP", originEnt.origin );
}
favela_friendlies()
{
level.meat = spawn_targetname( "meat_spawner", true );
level.meat thread magic_bullet_shield();
level.meat.animname = "meat";
level.royce = spawn_targetname( "royce_spawner", true );
level.royce thread magic_bullet_shield();
level.royce.animname = "royce";
}
favela_opening_civilians()
{
trigger_wait( "favela_opening_civilians_spawn", "targetname" );
spawners = getentarray( "favela_opening_civilian_spawner", "targetname" );
array_thread( spawners, ::favela_opening_civilians_think );
thread favela_civilians_scream();
flag_set( "favela_civilians_spawned" );
}
favela_opening_civilians_think()
{
// spawn the civilian
civilian = self spawn_ai( true );
civilian endon( "death" );
if ( !isdefined( level.favelaCivilians ) )
level.favelaCivilians = [];
level.favelaCivilians[ level.favelaCivilians.size ] = civilian;
wait 0.05;
civilian.alertlevel = "noncombat";
// Make walkers walk instead of do idle animations
if ( !isdefined( self.animation ) )
{
civilian thread delete_ai_at_path_end();
civilian.useChokePoints = false;
return;
}
// make a node
eNode = undefined;
if ( isdefined( self.script_linkto ) )
{
eNode = get_linked_ent();
}
else
{
eNode = spawn( "script_origin", self.origin );
eNode.angles = self.angles;
}
assert( isdefined( eNode ) );
// do idle as specified in editor
animScene = self.animation;
eNode thread anim_generic_loop( civilian, animScene, "stop_idle_anim" );
// wait for firefight to break out
civilian waittill( "combat" );
flag_set( "favela_civilians_fleeing" );
wait randomfloat( 1.5 );
// civilian stops looping idle
eNode notify( "stop_idle_anim" );
civilian notify( "stop_idle_anim" );
civilian stopAnimScripted();
// civilian runs away and gets deleted
civilian.useChokePoints = true;
node = getnode( "favela_civ_flee_node_opening", "targetname" );
civilian thread follow_path( node );
civilian thread delete_ai_at_path_end();
}
favela_civilians_scream()
{
soundEnt = getent( "favela_civilians_scream_ent", "targetname" );
soundEntEndPos = getent( soundEnt.target, "targetname" );
flag_wait( "favela_civilians_fleeing" );
soundEnt playSound( "scn_favela_civ_outofhere_screams" );
soundEnt moveTo( soundEntEndPos.origin, 6.0, 4.0, 2.0 );
}
favela_music()
{
flag_wait( "favela_music" );
level endon( "favela_music" );
thread favela_music_stop();
alias = "favela_tension";
time = musicLength( alias );
while( flag( "favela_music" ) )
{
thread music_play( alias );
wait time;
}
}
favela_music_stop()
{
flag_waitopen( "favela_music" );
music_stop( 3 );
}
upper_village_music()
{
flag_wait( "upper_village_music" );
level endon( "faust_appearance_1" );
// Roach - this is their territory and they know it well! Keep an eye open for ambush positions and check your corners!
radio_dialogue( "favela_cmt_theirterritory" );
alias = "favela_uppervillage_start";
time = musicLength( alias );
while( !flag( "faust_appearance_1" ) )
{
thread music_play( alias, 2.0 );
wait time;
}
}
faust_music()
{
level endon( "faust_music" );
thread faust_music_stop();
alias = "favela_moneyrun";
time = musicLength( alias );
while( flag( "faust_music" ) )
{
thread music_play( alias );
wait time;
}
}
faust_music_stop()
{
flag_waitopen( "faust_music" );
music_stop( 3 );
}
random_favela_background_runners()
{
level endon( "cleared_favela" );
spawners = getentarray( "random_favela_background_runner", "targetname" );
flag_wait( "favela_enemies_spawned" );
for(;;)
{
spawners = array_randomize( spawners );
foreach ( spawner in spawners )
{
if ( flag( "cleared_favela" ) )
return;
spawner.count = 1;
spawner thread spawn_ai( true );
wait randomintrange( 4, 8 );
}
}
}
faust_appearance_1()
{
flag_wait( "faust_appearance_1" );
thread autosave_by_name( "faust_appearance_1" );
thread faust_appearance_1_dialog();
faust = spawn_targetname( "faust_spawner_1", true );
faust thread objective_on_faust();
thread music_stop( 3.0 );
wait 3.2;
flag_set( "faust_music" );
thread faust_music();
}
objective_on_faust()
{
assert( isalive( self ) );
level notify( "objective_on_faust" );
level endon( "objective_on_faust" );
// put the objective marker on Faust
objective_onentity( 2, self, ( 0, 0, 70 ) );
objective_setpointertextoverride( 2, &"FAVELA_OBJ_CAPTURE" );
setsaveddvar( "objectiveFadeTooFar", 0.1 );
// wait until we delete Faust
self waittill( "death" );
// Marker back to top of hill
originEnt = getent( "mission_objective_location", "targetname" );
objective_position( 2, originEnt.origin );
setsaveddvar( "objectiveFadeTooFar", 25 );
}
faust_appearance_1_dialog()
{
// Roach! I've spotted Faust, he's making a run for it! He's headed your way!
radio_dialogue( "favela_cmt_spottedfaust" );
// And don't shoot him! We need him alive and unharmed!
radio_dialogue( "favela_cmt_unharmed" );
wait 5.0;
// Roach, we're going to cut him off at the summit, keep pushing him that way! Go! Go!
radio_dialogue( "favela_cmt_cutoff" );
}
faust_appearance_2()
{
flag_wait( "faust_appearance_2" );
faust = spawn_targetname( "faust_spawner_2", true );
faust thread objective_on_faust();
}
faust_appearance_3()
{
flag_wait( "faust_appearance_3" );
faust = spawn_targetname( "faust_spawner_3", true );
faust thread objective_on_faust();
thread faust_appearance_3_dialog();
}
faust_appearance_3_dialog()
{
level endon( "ending_sequence_dialog" );
// We've got eyes on Faust - wait! Shite! he's headed back towards you!
radio_dialogue( "favela_cmt_backtowards" );
if ( flag( "ending_sequence_dialog" ) )
return;
// Roach, keep pushing him up the hill! Don't let him double back!
radio_dialogue( "favela_cmt_doubleback" );
}
faust_appearance_4()
{
flag_wait( "faust_appearance_4" );
faust = spawn_targetname( "faust_spawner_4", true );
faust thread objective_on_faust();
}
street_scenes()
{
flag_wait( "start_street_sequences_1" );
thread street_scene_civilian_180_runaway();
thread street_scene_civilian_wounded_1();
thread street_scene_destruction();
}
street_scene_civilian_180_runaway()
{
spawner = getent( "civilian_180_runaway", "targetname" );
animNode = spawn( "script_origin", spawner.origin );
animNode.angles = spawner.angles;
animScene = spawner.animation;
runtoNode = getnode( spawner.target, "targetname" );
guy = spawner spawn_ai( true );
guy endon( "death" );
guy.allowdeath = true;
animNode anim_generic( guy, animScene );
guy.goalradius = 32;
guy thread delete_ai_at_goal();
guy setGoalNode( runtoNode );
}
street_scene_civilian_wounded_1()
{
wounded_spawner = getent( "wounded_guy_1", "targetname" );
helper_spawner = getent( "wounded_guy_helper_1", "targetname" );
woundedAnimScene = wounded_spawner.animation;
helperAnimScene = helper_spawner.animation;
animNode = wounded_spawner get_linked_ent();
runtoNode = getnode( helper_spawner.target, "targetname" );
wounded = wounded_spawner spawn_ai( true );
helper = helper_spawner spawn_ai( true );
wounded.a.nodeath = true;
animNode thread anim_generic_first_frame( wounded , woundedAnimScene );
animNode thread anim_generic_first_frame( helper , helperAnimScene );
helper endon( "death" );
// wait for player to hit the proximity trigger
trigger_wait( "wounded_guy_1_proximity", "targetname" );
animNode thread anim_generic( wounded , woundedAnimScene );
animNode anim_generic( helper , helperAnimScene );
// scene is over, put wounded guy back into first frame idle
animNode thread anim_generic_first_frame( wounded , woundedAnimScene );
// helper is done, he runs away now and gets deleted
helper.goalradius = 32;
helper thread delete_ai_at_goal();
helper setGoalNode( runtoNode );
}
street_scene_destruction()
{
//chad - disabled this because nobody really likes it? Try without it for now.
car1 = getent( "force_explosion_car_1", "script_noteworthy" );
car2 = getent( "force_explosion_car_2", "script_noteworthy" );
car3 = getent( "force_explosion_car_3", "script_noteworthy" );
thread delayThread( 0.0, ::street_scene_gunshots, car1.origin );
car1 thread delayThread( 1.8, ::destructible_force_explosion );
thread delayThread( 2.5, ::street_scene_gunshots, car2.origin );
car2 thread delayThread( 3.2, ::destructible_force_explosion );
thread delayThread( 4.0, ::street_scene_gunshots, car3.origin );
thread delayThread( 5.0, ::street_scene_gunshots, car3.origin );
car3 thread delayThread( 6.2, ::destructible_force_explosion );
}
street_scene_gunshots( org )
{
shots = randomintrange( 5, 10 );
for( i = 0 ; i < shots ; i++ )
{
thread play_sound_in_space( "weap_deserteagle_fire_npc", org );
wait randomfloatrange( 0.1, 0.3 );
}
}
favela_warning()
{
// Friendlies take up positions above the favela and wait for the player to approach
level.meat.goalradius = 32;
level.royce.goalradius = 32;
level.meat set_goal_node_targetname( "meat_first_node" );
level.royce set_goal_node_targetname( "royce_first_node" );
thread player_gives_favela_warning();
// Wait for other dialog to be done
flag_wait( "favela_gate_dialog_done" );
// Wait for player to approach
flag_wait( "give_favela_warning" );
animNode = getnode( "favela_warning_node", "targetname" );
if ( !flag( "favela_civilians_alerted" ) )
{
// Royce tells meat to give the warning
level.royce anim_single_solo( level.royce, "favela_ryc_warning" ); // Meat, give the civvies a fair warning.
level.meat thread anim_single_solo( level.meat, "favela_met_rogerthat" ); // Roger that.
// meat gives warning
animNode anim_reach_solo( level.meat, "favela_warning_jump" );
}
// make friendlies go to nodes at the bottom of the favela
level.meat thread set_goal_node_targetname( "favela_warning_guy_first_node" );
level.royce thread set_goal_node_targetname( "favela_other_guy_first_node" );
// friendlies are now on color node system
level.meat enable_ai_color();
level.royce enable_ai_color();
if ( !flag( "favela_civilians_alerted" ) )
{
animNode anim_single_solo( level.meat, "favela_warning_jump" );
animNode anim_single_solo( level.meat, "favela_warning_landing" );
}
// spawn favela enemies
flag_set( "favela_enemies_spawned" );
thread activate_trigger( "favela_spawn_trigger", "script_noteworthy", level.player );
thread battlechatter_on( "allies" );
thread battlechatter_on( "axis" );
}
player_gives_favela_warning()
{
flag_wait( "favela_civilians_spawned" );
thread player_gives_favela_warning_weapons();
thread player_gives_favela_warning_trigger();
}
player_gives_favela_warning_weapons()
{
level endon( "favela_civilians_alerted" );
level.player waittill_any( "grenade_fire", "weapon_fired" );
thread alert_favela_civilians();
}
player_gives_favela_warning_trigger()
{
level endon( "favela_civilians_alerted" );
flag_wait( "player_entered_favela" );
thread alert_favela_civilians();
}
alert_favela_civilians()
{
flag_set( "favela_civilians_alerted" );
wait 1.5;
foreach( civilian in level.favelaCivilians )
{
if ( isdefined( civilian ) )
civilian.alertlevel = "alert";
}
}
favela_dialog()
{
flag_wait( "favela_enemies_spawned" );
wait 7.0;
radio_dialogue( "favela_cmt_fullbattalion" ); // Bravo Six, be advised - we've engaged enemy militia at the lower village!
radio_dialogue( "favela_ryc_withyou" ); // Roach! I'm with you! Watch the rooftops! Go!
// wait for player to fight in a bit
flag_wait( "player_in_lower_favela_shanty" );
radio_dialogue( "favela_cmt_doingok" ); // Royce, gimme a sitrep, over!
radio_dialogue( "favela_ryc_nosign" ); // Lots of militia but no sign of Faust over here, over!
radio_dialogue( "favela_cmt_keepsearching" ); // Copy that! Keep searching! Let me know if you see him! Out!
wait 2.5;
radio_dialogue( "favela_ryc_moveup" ); // Roach! Move up! Let's go!
// allow meat to die now that dialog with him is over
flag_set( "allow_meat_death" );
}
soccer_dialog()
{
flag_wait( "cleared_favela" );
radio_dialogue( "favela_cmt_cuthimoff" ); // Roach - we've got Faust's location! He's headed west along the upper levels of the favela.
radio_dialogue( "favela_cmt_keepgoing" ); // We'll keep him from doubling back on our side - keep going and cut him off up top!
wait 1.0;
radio_dialogue( "favela_cmt_notime" ); // There's no time to wait for backup. You're gonna have to do this on your own. Good luck. Out.
}
meat_dies()
{
// wait until all dialog is done before killing him because he needs to say some lines before he dies
flag_wait( "allow_meat_death" );
flag_wait( "player_midway_through_lower_favela" );
// meat becomes vulnerable to die now. If he doens't die by the time we hit the next flag trigger then force kill him.
level.meat thread meat_dies_dialog();
level.meat stop_magic_bullet_shield();
wait 0.05;
level.meat.health = 1;
level.meat thread meat_force_death();
}
meat_force_death()
{
self endon( "death" );
flag_wait( "force_meat_death" );
magicBullet( "dragunov", ( -5427, -77, 1790 ), self getEye() );
wait 0.1;
self kill();
}
meat_dies_dialog()
{
self waittill( "death" );
// Meat is down! I repeat, Meat is down!
radio_dialogue( "favela_ryc_meatisdown" );
flag_set( "allow_royce_death" );
}
royce_dies()
{
// wait until meat is dead, and dialog is done about him dying, and player is most of the way through the lower favela
flag_wait( "force_meat_death" );
flag_wait( "allow_royce_death" );
// royce becomes vulnerable now. If he doesn't die by the time we hit the next flag trigger then force kill him.
level.royce thread royce_dies_dialog();
level.royce stop_magic_bullet_shield();
wait 0.05;
level.royce.health = 1;
level.royce thread royce_force_death();
}
royce_force_death()
{
self endon( "death" );
flag_wait( "force_kill_royce" );
magicBullet( "dragunov", ( -5427, -77, 1790 ), self getEye() );
wait 0.1;
self kill();
}
royce_dies_dialog()
{
self waittill( "death" );
withinView = false;
if ( isdefined( self ) && isdefined( self.origin ) )
withinView = level.player player_looking_at( self.origin, cos( 45 ) );
if ( !withinView )
radio_dialogue( "favela_ryc_imhit" ); // Roach! I'm down! Meat's dead! They're all over - (gunfire, angry shouting in Portuguese)
}
upper_village_triggered_dialog()
{
level endon( "faust_appearance_1" );
// Trigger
flag_wait( "dialog_watch_rooftops" );
radio_dialogue( "favela_cmt_watchrooftops" ); // Roach, watch the rooftops! We've had a few close calls with RPGs and machine guns positioned up high!
wait 4.0;
radio_dialogue( "favela_cmt_stilltracking" ); // Roach, we're taking heavy fire from militia here but I'm still tracking Faust! He's gone into a building to get something! Ghost, you see him?
radio_dialogue( "favela_gst_duffelbag" ); // Roger that, subject is now carrying a black duffel bag full of cash! Greedy bastard!
radio_dialogue( "favela_cmt_intercept" ); // Well that ought to slow him down! Roach, we're keeping him from doubling back! Keep moving to intercept! Go! Go!
wait 12;
radio_dialogue( "favela_cmt_yourside" ); // Keep going! Faust is still headed towards your side of the favela!
radio_dialogue( "favela_gst_pinyoudown" ); // Roach! Don't let the militia pin you down for too long! Use your flashbangs on them!
radio_dialogue( "favela_cmt_lostsightagain" ); // I've lost sight of him again! Ghost, talk to me!
radio_dialogue( "favela_gst_alleysbelow" ); // I'm onto him! He's trying to double back through the alleys below!
radio_dialogue( "favela_cmt_stayonhim" ); // Roger that! Stay on him!
wait 6;
// Trigger
flag_wait( "dialog_faust_through_market" );
radio_dialogue( "favela_gst_cuttingthru" ); // I've got a visual on Faust! He's cutting through the market!
radio_dialogue( "favela_cmt_headforrooftops" ); // Roger that! I'll head for the rooftops and try to cut him off on the right! He's going to have no choice but to head west!
wait 3.0;
radio_dialogue( "favela_gst_wayaround" ); // Bloody hell, I'm taking a lot of fire from the militia, I don't think I can track him through the market! I'm going to have to find another way around!
wait 6;
// Trigger
flag_wait( "dialog_faust_in_sights" );
radio_dialogue( "favela_gst_halfklick" ); // Be advised, I'm about half a klick east of the market, I can see Faust running across the rooftops on my right side!
radio_dialogue( "favela_cmt_eyeopen" ); // Roger that! Roach! We're corraling him closer to your side of the hill! Keep an eye open for Faust! He's still moving across the rooftops!
wait 8;
radio_dialogue( "favela_gst_legshot" ); // Sir, I've got Faust in my sights! I can go for a clean leg shot! We can end it here!
radio_dialogue( "favela_cmt_donotengage" ); // Negative! We can't risk it! Do not engage Faust!
radio_dialogue( "favela_gst_rogerthat2" ); // Bollocks! Roger that!
wait 12;
radio_dialogue( "favela_cmt_nowheretogo" ); // Roach! Keep moving uphill! I've cut him off! He's got nowhere to go but west over the rooftops into your area!
radio_dialogue( "favela_cmt_traphimuphere" ); // Roach! He knows the area well but we can trap him up here! Don't stop! Go! Go!
wait 12;
radio_dialogue( "favela_gst_jumpedfence" ); // He jumped the fence! I'm after him!!!
radio_dialogue( "favela_cmt_goingleft" ); // Roger that! I'm going around to the left!
wait 12;
radio_dialogue( "favela_cmt_closertoyourpart" );// Roach! He's getting closer to your part of the favela!! Keep moving! Go! Go!
}
final_bend_dialog()
{
level endon( "ending_sequence_dialog" );
level endon( "player_approaching_final_stairs" );
level endon( "stop_all_misc_dialog" );
flag_wait( "player_at_final_bend" );
radio_dialogue( "favela_cmt_motorcycle" ); // Ghost he's going for that motorcycle!
soundEnt = getent( "nohesnot_location", "targetname" );
soundEnt play_sound_in_space( "favela_gst_nohesnot" ); // (gunshots, explosion) No he's not.
radio_dialogue( "favela_cmt_dontshoothim" ); // Nice! He's breaking to the right again! Roach, if you see him, don't shoot him! I need him unharmed!
wait 0.3;
radio_dialogue( "favela_cmt_onthemove" ); // Roach! He's on the move and headed your way! Go! Go!
wait 4.0;
radio_dialogue( "favela_cmt_anotherfence" ); // Roach! He's jumped another fence and he's still headed towards your end of the favela! Keep moving up! Go! Go!
wait 4.0;
radio_dialogue( "favela_cmt_corraling" ); // Keep corraling him up the hill! We'll cut him off at the top!
wait 10;
radio_dialogue( "favela_gst_whereishe" ); // Where is he where is he?
wait 0.2;
radio_dialogue( "favela_cmt_slidingrooftops" ); // Got a visual! He's over there, sliding down the tin rooftops!
wait 0.2;
radio_dialogue( "favela_gst_anotherlegshot" ); // I've got another clear leg shot!
wait 0.2;
radio_dialogue( "favela_cmt_carryhimback" ); // Negative! Not unless you want to carry him back out with all this militia breathing down your neck! I need him unharmed!
}
final_staircase_dialog()
{
flag_wait( "player_approaching_final_stairs" );
if ( flag( "ending_sequence_dialog" ) )
return;
level endon( "ending_sequence_dialog" );
// Ghost, I'm going far right!
radio_dialogue( "favela_cmt_farright" );
// ( Ghost - Radio ) Roger that.
radio_dialogue( "favela_gst_rogerthat" );
}
ending_sequence()
{
trigger_wait( "ending_sequence", "targetname" );
thread ending_sequence_dialog();
thread battlechatter_off( "allies" );
thread battlechatter_off( "axis" );
node = getent( "ending_node", "targetname" );
soap = spawn_targetname( "ending_soap_spawner", true );
soap.animname = "mactavish";
soap set_ignoreme( true );
soap set_ignoreall( true );
soap thread magic_bullet_shield();
faust = spawn_targetname( "ending_faust_spawner", true );
faust.animname = "faust";
faust set_ignoreme( true );
faust set_ignoreall( true );
faust thread magic_bullet_shield();
faust thread faust_mission_fail();
faust thread objective_on_faust();
car = getent( "ending_car", "targetname" );
car useanimtree( level.scr_animtree[ "car" ] );
car.animname = "car";
// do first frame animation to set it up
guys[ 0 ] = soap;
guys[ 1 ] = faust;
guys[ 2 ] = car;
node anim_first_frame( guys, "ending_takedown" );
// wait for the player to be in the area and to look at the sequence, or timeout
flag_wait( "player_in_ending_area" );
faust waittill_player_lookat( 0.8, undefined, undefined, 7.0 );
// don't slomo the "no he's not" dialog
SoundSetTimeScaleFactor( "Music", 0 );
SoundSetTimeScaleFactor( "Menu", 0 );
SoundSetTimeScaleFactor( "Bulletimpact", 0 );
SoundSetTimeScaleFactor( "Voice", 0 );
SoundSetTimeScaleFactor( "effects2", 0 );
SoundSetTimeScaleFactor( "Mission", 0 );
SoundSetTimeScaleFactor( "Announcer", 0 );
SoundSetTimeScaleFactor( "local", 0 );
SoundSetTimeScaleFactor( "physics", 0 );
SoundSetTimeScaleFactor( "ambient", 0 );
SoundSetTimeScaleFactor( "auto", 0 );
SoundSetTimeScaleFactor( "Shellshock", 0 );
//flag_wait( "ending_sequence_ready" );
flag_set( "ending_sequence_started" );
thread ending_sequence_ghost();
// ending sequence happens
flag_clear( "faust_music" );
flag_clear( "favela_music" );
thread music_stop( 1.0 );
level.player thread play_sound_on_entity( "favela_moneyrun_endfall" );
node thread anim_single( guys, "ending_takedown" );
delayThread( 13.0, ::fade_out_level );
wait 5.2;
assert( isdefined( level.ghost ) );
level.ghost anim_single_solo( level.ghost, "favela_gst_sendchopper" );
wait 0.8;
level.ghost anim_single_solo( level.ghost, "favela_gst_skiesareclear" );
wait 1.0;
level.ghost thread anim_single_solo( level.ghost, "favela_gst_onourown" );
wait 4;
nextmission();
}
fade_out_level()
{
fadeInTime = 1.0;
setSavedDvar( "compass", 0 );
setSavedDvar( "hud_showStance", 0 );
overlay = newHudElem();
overlay.x = 0;
overlay.y = 0;
overlay setshader( "black", 640, 480 );
overlay.alignX = "left";
overlay.alignY = "top";
overlay.horzAlign = "fullscreen";
overlay.vertAlign = "fullscreen";
overlay.alpha = 0;
overlay fadeOverTime( fadeInTime );
overlay.alpha = 1;
wait fadeInTime;
level.player freezeControls( true );
enablePlayerWeapons( false );
}
ending_sequence_ghost()
{
level.ghost = spawn_targetname( "ending_ghost_spawner", true );
level.ghost.animname = "ghost";
level.ghost set_ignoreme( true );
level.ghost set_ignoreall( true );
level.ghost thread magic_bullet_shield();
}
ending_sequence_dialog()
{
flag_set( "ending_sequence_dialog" );
if ( !flag( "ending_sequence_started" ) )
{
// ( Ghost - Radio ) He's gonna get away!!
radio_dialogue( "favela_gst_getaway" );
}
//flag_set( "ending_sequence_ready" );
flag_wait( "ending_sequence_started" );
// No he's not.
radio_dialogue( "favela_cmt_nohesnot" );
flag_set( "start_final_dialog" );
}
ending_sequence_slowmo()
{
wait 0.15;
if ( !player_looking_at( self.origin, undefined, true ) )
return;
slomoLerpTime_in = 0.5;
slomoLerpTime_out = 0.65;
slomobreachplayerspeed = 0.1;
slomoSpeed = 0.2;
slomoDuration = 2.0;
level.player thread play_sound_on_entity( "slomo_whoosh" );
slowmo_start();
slowmo_setspeed_slow( slomoSpeed );
slowmo_setlerptime_in( slomoLerpTime_in );
slowmo_lerp_in();
level.player SetMoveSpeedScale( slomobreachplayerspeed );
wait slomoDuration * slomoSpeed;
level.player thread play_sound_on_entity( "slomo_whoosh" );
slowmo_setlerptime_out( slomoLerpTime_out );
slowmo_lerp_out();
slowmo_end();
level.player SetMoveSpeedScale( 1.0 );
wait 1;
objective_State( 2, "done" );
}