#using scripts\codescripts\struct; #using scripts\shared\array_shared; #using scripts\shared\compass; #using scripts\shared\math_shared; #using scripts\shared\util_shared; #using scripts\shared\exploder_shared; #using scripts\shared\scene_shared; #using scripts\shared\clientfield_shared; #using scripts\shared\lui_shared; #using scripts\mp\_load; #using scripts\mp\_util; #using scripts\mp\_destructible; #using scripts\mp\_nuketown_mannequin; #using scripts\mp\mp_nuketown_x_fx; #using scripts\mp\mp_nuketown_x_sound; #precache( "model", "p7_dest_ntx_mannequin_male_01_black" ); #precache( "model", "p7_dest_ntx_mannequin_male_02_black" ); #precache( "model", "p7_dest_ntx_mannequin_female_01_black" ); #precache( "model", "p7_dest_ntx_mannequin_female_02_black" ); #precache( "model", "p7_dest_ntx_mannequin_female_03_black" ); #precache( "string", "mp_nuketown_fs_endingmovie" ); //end game movie function autoexec init() { // Required for mannequins to find valid enemy positions. level._enableLastValidPosition = true; } function main() { clientfield::register( "scriptmover", "nuketown_population_ones", 1, 4, "int" ); clientfield::register( "scriptmover", "nuketown_population_tens", 1, 4, "int" ); clientfield::register( "world", "nuketown_endgame", 1, 1, "int" ); precache(); mp_nuketown_x_fx::main(); mp_nuketown_x_sound::main(); level.remotemissile_kill_z = ( ( -175 ) + ( 50 ) ); level.team_free_targeting = true; level.update_escort_robot_path = &update_escort_robot_path; load::main(); compass::setupMiniMap( "compass_map_mp_nuketown_x" ); // Set up the default range of the compass SetDvar( "compassmaxrange", "2100" ); // Spawn a radius trigger to disable escorting robot from upstairs level.levelescortDisable = []; //level.levelescortDisable[ level.levelescortDisable.size ] = Spawn( "trigger_radius", position, 0, radius, height ); level.levelescortDisable[ level.levelescortDisable.size ] = Spawn( "trigger_radius", ( 749 , 872 , -112.5 ), 0, 150, 128 ); level.levelescortDisable[ level.levelescortDisable.size ] = Spawn( "trigger_radius", ( 868 , 909.5 , -112.5 ), 0, 150, 128 ); level.levelescortDisable[ level.levelescortDisable.size ] = Spawn( "trigger_radius", ( 968 , 894.5 , -112.5 ), 0, 100, 128 ); level.levelescortDisable[ level.levelescortDisable.size ] = Spawn( "trigger_radius", ( 1009 , 902 , -112.5 ), 0, 100, 128 ); level.end_game_video = SpawnStruct(); level.end_game_video.name = "mp_nuketown_fs_endingmovie"; level.end_game_video.duration = 5; level.headless_mannequin_count = 0; level.limbless_mannequin_count = 0; level.destructible_callbacks[ "headless"] = &mannequin_headless; level.destructible_callbacks[ "right_arm_lower"] = &mannequin_right_arm_lower; level.destructible_callbacks[ "right_arm_upper"] = &mannequin_right_arm_upper; level.destructible_callbacks[ "left_arm_lower"] = &mannequin_left_arm_lower; level.destructible_callbacks[ "left_arm_upper"] = &mannequin_left_arm_upper; level thread tU3_disable_bad_robot_wallrun_nodes(); // Stockpile hub points level.cleanDepositPoints = Array ( ( 21.4622 , 133.075 , -65.875 ), ( 976.601 , 630.604 , -56.875 ), ( -787.35 , 508.411 , -59.875 ), ( 32.424 , 952.018 , -60.875 ) ); level thread nuked_mannequin_init(); level thread nuked_population_think(); /# level nuked_endgame_init(); #/ } function nuked_population_think() { popTensArr = getEntArray( "counter_tens" ,"targetname"); popOnesArr = getEntArray( "counter_ones" ,"targetname"); popTens = popTensArr[0]; popOnes = popOnesArr[0]; level.oldPopTensValue = 0; level.oldPopOnesValue = 0; while( 1 ) { players = GetPlayers(); actors = GetActorArray(); count = 0; foreach( player in players ) { if( IsAlive( player ) ) { count++; } } foreach( actor in actors ) { if( IsAlive( actor ) ) { count++; } } level.popTensValue = int( floor( count / 10 ) ); level.popOnesValue = count % 10; if( level.oldPopTensValue != level.popTensValue ) { popTens clientfield::set( "nuketown_population_tens", level.popTensValue ); } if( level.oldPopOnesValue != level.popOnesValue ) { popOnes clientfield::set( "nuketown_population_ones", level.popOnesValue ); } level.oldPopTensValue = level.popTensValue; level.oldPopOnesValue = level.popOnesValue; {wait(.05);}; } } function precache() { // DO ALL PRECACHING HERE } function nuked_endgame_init() { /# mapname = GetDvarString( "mapname" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug End Game Sequence/Start Sequence\" \"set level_notify nuked_end_sequence_start \"\n" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug End Game Sequence/Reset Sequence\" \"set level_notify nuked_end_sequence_reset \"\n" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug End Game Sequence/Test Movie\" \"set level_notify nuked_test_movie \"\n" ); level thread nuked_endgame_think(); #/ } function nuked_test_movie() { while( 1 ) { level waittill( "nuked_test_movie" ); if( isDefined( level.end_game_video ) ) { level lui::play_movie_with_timeout( level.end_game_video.name, "fullscreen", level.end_game_video.duration, true ); } } } function nuked_endgame_think() { level thread nuked_endgame_start(); level thread nuked_endgame_reset(); level thread nuked_test_movie(); } function nuked_endgame_start() { cameraStartArray = struct::get_array( "endgame_camera" ); cameraStart = cameraStartArray[0]; if( !isdefined( cameraStart ) ) { cameraStart = SpawnStruct(); cameraStart.origin = ( -200, -167, 15 ); cameraStart.angles = ( 0, -81, 0 ); } for ( ;; ) { camera = Spawn( "script_model", cameraStart.origin ); camera.angles = cameraStart.angles; camera SetModel( "tag_origin" ); level waittill( "nuked_end_sequence_start" ); hiddenEntities = GetEntArray( "hide_end_game_sequence", "script_noteworthy" ); foreach( hiddenEntity in hiddenEntities ) { hiddenEntity hide(); } clientfield::set( "nuketown_endgame", 1 ); /* SET UP CAMERA */ players = GetPlayers(); foreach ( player in players ) { player CameraSetPosition( camera ); player CameraSetLookAt(); player CameraActivate( true ); /* OVERRIDE ENDGAME DOF */ player setDepthOfField( 0, 128, 7000, 10000, 6, 1.8 ); } wait( 2 ); exploder::exploder( "nuketown_derez_explosion" ); level thread run_scene( "p7_fxanim_mp_nukex_derez_bridge_bundle" ); level thread run_scene( "p7_fxanim_mp_nukex_end_derezzing_tree_bundle" ); } } function nuked_endgame_reset() { for ( ;; ) { level waittill( "nuked_end_sequence_reset" ); hiddenEntities = GetEntArray( "hide_end_game_sequence", "script_noteworthy" ); foreach( hiddenEntity in hiddenEntities ) { hiddenEntity show(); } clientfield::set( "nuketown_endgame", 0 ); exploder::stop_exploder( "nuketown_derez_explosion" ); level thread init_scene( "p7_fxanim_mp_nukex_derez_bridge_bundle" ); level thread init_scene( "p7_fxanim_mp_nukex_end_derezzing_tree_bundle" ); } } function run_scene( str_scene ) { b_found = false; str_mode = ToLower( GetDvarString( "scene_menu_mode", "default" ) ); a_scenes = struct::get_array( str_scene, "scriptbundlename" ); foreach ( s_instance in a_scenes ) { if ( isdefined( s_instance ) ) { if ( !IsInArray( a_scenes, s_instance ) ) { b_found = true; s_instance thread scene::play( undefined, undefined, undefined, true, undefined, str_mode ); } } } if ( isdefined( level.active_scenes[ str_scene ] ) ) { foreach ( s_instance in level.active_scenes[ str_scene ] ) { b_found = true; s_instance thread scene::play( str_scene, undefined, undefined, true, undefined, str_mode ); } } } function init_scene( str_scene ) { str_mode = ToLower( GetDvarString( "scene_menu_mode", "default" ) ); b_found = false; a_scenes = struct::get_array( str_scene, "scriptbundlename" ); foreach ( s_instance in a_scenes ) { if ( isdefined( s_instance ) ) { b_found = true; s_instance thread scene::init( undefined, undefined, undefined, true ); } } if ( !b_found ) { level.scene_test_struct thread scene::init( str_scene, undefined, undefined, true ); } } function nuked_mannequin_init() { keep_count = 28; level.mannequin_count = 0; destructibles = GetEntArray( "destructible", "targetname" ); mannequins = nuked_mannequin_filter( destructibles ); if ( mannequins.size <= 0 ) { return; } ArrayRemoveValue( mannequins, undefined ); alreadyRemoved = 0; for ( i = 0; i < mannequins.size; i++ ) { if ( "p7_dest_ntx_mannequin_female_04_purple_ddef" == mannequins[i].destructibledef ) { collision = GetEnt( mannequins[i].target, "targetname" ); assert( IsDefined( collision ) ); collision delete(); mannequins[i] delete(); level.mannequin_count--; alreadyRemoved++; } if ( !isdefined( mannequins[i] ) ) continue; assert( IsDefined( mannequins[i].target ) ); // Per mscronce - we never want the mannequins below to spawn in those modes as they interfere if( ( level.gameType == "dem" ) || ( level.gameType == "dom" ) ) { if( mannequins[i].target == "pf1160_auto1" || mannequins[i].target == "pf1179_auto1" ) { collision = GetEnt( mannequins[i].target, "targetname" ); assert( IsDefined( collision ) ); collision delete(); mannequins[i] delete(); level.mannequin_count--; alreadyRemoved++; } } } level.mannequin_count = mannequins.size; remove_count = mannequins.size - keep_count - alreadyRemoved; remove_count = math::clamp( remove_count, 0, remove_count ); mannequins = array::randomize( mannequins ); for ( i = 0; i < mannequins.size; i++ ) { if ( !isdefined( mannequins[i] ) ) continue; assert( IsDefined( mannequins[i].target ) ); if ( i < remove_count ) { collision = GetEnt( mannequins[i].target, "targetname" ); assert( IsDefined( collision ) ); collision delete(); mannequins[i] delete(); level.mannequin_count--; } else { mannequins[i] DisconnectPaths(); } } ArrayRemoveValue( mannequins, undefined ); level.mannequins = mannequins; level waittill( "prematch_over" ); level.mannequin_time = GetTime(); debug_mannequin_init(); if ( GetDvarInt( "nuketown_mannequin", 0 ) ) { level thread _mannequin_constant_spawn( false ); } } function debug_mannequin_init() { level._mannequin_locations = []; level._mannequin_angles = []; destructibles = GetEntArray( "destructible", "targetname" ); mannequins = nuked_mannequin_filter( destructibles ); foreach( mannequin in mannequins ) { level._mannequin_locations[ level._mannequin_locations.size ] = mannequin.origin; level._mannequin_angles[ level._mannequin_angles.size ] = mannequin.angles; } /# mapname = GetDvarString( "mapname" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug Mannequin/Spawn AI Mannequins V1\" \"set level_notify mannequin_force_spawn_v1 \"\n" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug Mannequin/Spawn AI Mannequins V2\" \"set level_notify mannequin_force_spawn_v2 \"\n" ); AddDebugCommand( "devgui_cmd \"|" + mapname + "|/Debug Mannequin/Delete AI Mannequins\" \"set level_notify mannequin_force_cleanup \"\n" ); level thread debug_mannequin_spawn_v1(); level thread debug_mannequin_spawn_v2(); level thread debug_mannequin_cleanup(); #/ } function private _mannequin_delete_destructibles() { destructibles = GetEntArray( "destructible", "targetname" ); mannequins = nuked_mannequin_filter( destructibles ); foreach ( mannequin in mannequins ) { mannequin ConnectPaths(); collision = GetEnt( mannequin.target, "targetname" ); collision Delete(); mannequin Delete(); } } function private _mannequin_force_cleanup() { level notify ( "mannequin_ended" ); mannequins = GetAIArchetypeArray( "mannequin" ); foreach( mannequin in mannequins ) { mannequin Kill(); } } function private _mannequin_watch_end_spawn() { level notify ( "_mannequin_watch_end_spawn" ); level endon ( "_mannequin_watch_end_spawn" ); while( 1 ) { if( !mannequin_should_spawn() ) { _mannequin_force_cleanup(); return; } wait .05; } } function private _mannequin_force_spawn( weepingAngel ) { level endon ( "mannequin_ended" ); level thread _mannequin_watch_end_spawn(); if ( IsDefined( level._mannequin_locations ) ) { _mannequin_delete_destructibles(); for ( index = 0; index < level._mannequin_locations.size; index++ ) { origin = level._mannequin_locations[ index ]; angles = level._mannequin_angles[ index ]; gender = ( ( RandomInt( 2 ) ) ? "male" : "female" ); mannequin = NuketownMannequin::SpawnMannequin( origin, angles, gender, undefined, weepingAngel ); wait .05; } } if( weepingAngel ) { level thread NuketownMannequin::watch_player_looking(); } } function private _mannequin_constant_spawn( weepingAngel ) { level endon ( "mannequin_ended" ); _mannequin_force_spawn( weepingAngel ); while ( true && IsDefined( level._mannequin_locations ) ) { mannequins = GetAIArchetypeArray( "mannequin" ); if ( mannequins.size < level._mannequin_locations.size ) { index = RandomInt( level._mannequin_locations.size ); origin = level._mannequin_locations[ index ]; angles = level._mannequin_angles[ index ]; gender = ( ( RandomInt( 2 ) ) ? "male" : "female" ); mannequin = NuketownMannequin::SpawnMannequin( origin, angles, gender, undefined, weepingAngel ); } wait 0.1; } } function private debug_mannequin_spawn_v1() { /# while ( true ) { level waittill ( "mannequin_force_spawn_v1" ); _mannequin_force_cleanup(); _mannequin_force_spawn( false ); } #/ } function private debug_mannequin_spawn_v2() { /# while ( true ) { level waittill ( "mannequin_force_spawn_v2" ); _mannequin_force_cleanup(); _mannequin_force_spawn( true ); } #/ } function private debug_mannequin_cleanup() { /# while ( true ) { level waittill ( "mannequin_force_cleanup" ); _mannequin_force_cleanup(); } #/ } function nuked_mannequin_filter( destructibles ) { mannequins = []; for ( i = 0; i < destructibles.size; i++ ) { destructible = destructibles[i]; if ( IsSubStr( destructible.destructibledef, "male" ) ) { mannequins[ mannequins.size ] = destructible; level.mannequin_count++; } } return mannequins; } function mannequin_headless( notifyType, attacker, weapon ) { if ( GetTime() < level.mannequin_time + GetDvarInt( "mannequin_timelimit", 120 ) * 1000 ) { level.headless_mannequin_count++; if ( level.headless_mannequin_count == GetDvarInt( "mannequin_headless_count", 28 ) ) { level thread mannequin_activate_headless(); } } } function mannequin_valid_gamemode() { if ( !GetDvarInt( "nuketown_mannequin", 1 ) ) { return false; } if( SessionModeIsOnlineGame() && !SessionModeIsPrivateOnlineGame() ) { return false; } if ( util::IsPropHuntGametype() ) { return false; } return true; } function mannequin_should_spawn() { players = GetPlayers(); if( players.size > 12 ) { return false; } return true; } function mannequin_activate_headless() { wait( 1 ); // let the last destructible blow up if( !mannequin_valid_gamemode() ) { return; } level thread _mannequin_constant_spawn( false ); } function mannequin_left_arm_lower( notifyType, attacker, weapon ) { //mannequin_limbless( notifyType, attacker, weapon ); } function mannequin_left_arm_upper( notifyType, attacker, weapon ) { mannequin_limbless( notifyType, attacker, weapon ); } function mannequin_right_arm_lower( notifyType, attacker, weapon ) { //mannequin_limbless( notifyType, attacker, weapon ); } function mannequin_right_arm_upper( notifyType, attacker, weapon ) { mannequin_limbless( notifyType, attacker, weapon ); } function mannequin_limbless( notifyType, attacker, weapon ) { if ( GetTime() < level.mannequin_time + GetDvarInt( "mannequin_timelimit", 120 ) * 1000 ) { level.limbless_mannequin_count++; if ( level.limbless_mannequin_count == GetDvarInt( "mannequin_limbless_count", 28 * 2 ) ) { level thread mannequin_activate_limbless(); } } } function mannequin_activate_limbless() { wait( 1 ); // let the last destructible blow up if( !mannequin_valid_gamemode() ) { return; } level thread _mannequin_constant_spawn( true ); //util::set_lighting_state( 3 ); } // sjakatdar TU3 (11/12/2015) - Robot (G.I. Unit) gets stuck while wallrunning using following two traversal nodes. // There is definitely a logic issue, which I will debug further, but disabling these nodes for now. Hopefully, the real fix // will in checked in for TU4. function tU3_disable_bad_robot_wallrun_nodes() { // Disabling all wallrun end nodes, these cause GI Units to run off into space. nodes = GetNodesInRadius( (-765.225, 938.762, 7.377), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (-1158.760, 1070.650, 7.377), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (-926.372, -224.916, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (-1319.91, -93.028, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (918.81, -206.969, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (1313.93, -79.594, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (736.484, 925.845, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); nodes = GetNodesInRadius( (1131.5, 1053.22, 7.376), 30, 0, 10, "End" ); SetEnableNode( nodes[0], false ); } function update_escort_robot_path( &pathArray ) { ArrayInsert( pathArray, ( 929, 626, -56.875 ), 10 ); // fixes escort robot chosing to path around the "Vehicle Diagnostics" room if the door is blocked }