diff --git a/cfg/!start_client.bat b/cfg/!start_client.bat new file mode 100644 index 0000000..841daa5 --- /dev/null +++ b/cfg/!start_client.bat @@ -0,0 +1,14 @@ +@echo off + +:: Either put the batch in the Ghosts install dir, or change the value below to the Ghosts install dir +set GHOSTS_INSTALL=%~dp0 + +:: Remove this line if automatic updates on start should be disabled +start /W alterware-launcher.exe --update + +:://///////////////////////////////////////////////////////////////////// +:://You're done!! WARNING!!! Don't mess with anything below this line // +:://///////////////////////////////////////////////////////////////////// + +set GAME_EXE=iw6-mod.exe +start %GAME_EXE% diff --git a/cfg/!start_mp_server.bat b/cfg/!start_mp_server.bat new file mode 100644 index 0000000..d600d96 --- /dev/null +++ b/cfg/!start_mp_server.bat @@ -0,0 +1,22 @@ +@echo off + +set ServerFilename=server.cfg + +::///////////////////////////////////////////////////////////////////////////// +::// What port do you want the server to run on? // +::// You must port forward this port & allow it through your firewall // +::///////////////////////////////////////////////////////////////////////////// +set port=27016 + +:: Either put the batch in the Ghosts install dir, or change the value below to the Ghost install dir +set GHOSTS_INSTALL=%~dp0 + +:: Remove this line if automatic updates on start should be disabled +start /W alterware-launcher.exe --update + +:://///////////////////////////////////////////////////////////////////// +:://You're done!! WARNING!!! Don't mess with anything below this line // +:://///////////////////////////////////////////////////////////////////// + +set GAME_EXE=iw6-mod.exe +start %GAME_EXE% -dedicated +set net_port "%port%" +exec %ServerFilename% +map_rotate diff --git a/cfg/!start_zm_server.bat b/cfg/!start_zm_server.bat new file mode 100644 index 0000000..1ba952a --- /dev/null +++ b/cfg/!start_zm_server.bat @@ -0,0 +1,22 @@ +@echo off + +set ServerFilename=server_zm.cfg + +::///////////////////////////////////////////////////////////////////////////// +::// What port do you want the server to run on? // +::// You must port forward this port & allow it through your firewall // +::///////////////////////////////////////////////////////////////////////////// +set port=27016 + +:: Either put the batch in the Ghosts install dir, or change the value below to the Ghost install dir +set GHOSTS_INSTALL=%~dp0 + +:: Remove this line if automatic updates on start should be disabled +start /W alterware-launcher.exe --update + +:://///////////////////////////////////////////////////////////////////// +:://You're done!! WARNING!!! Don't mess with anything below this line // +:://///////////////////////////////////////////////////////////////////// + +set GAME_EXE=iw6-mod.exe +start %GAME_EXE% -dedicated +set zombiesMode 1 +set net_port "%port%" +exec %ServerFilename% +map_rotate diff --git a/data/common_scripts/utility.gsc b/data/common_scripts/utility.gsc new file mode 100644 index 0000000..4582dd6 --- /dev/null +++ b/data/common_scripts/utility.gsc @@ -0,0 +1,2853 @@ +// IW6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool + +noself_func( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( !isdefined( level.func ) ) + return; + + if ( !isdefined( level.func[var_0] ) ) + return; + + if ( !isdefined( var_1 ) ) + { + call [[ level.func[var_0] ]](); + return; + } + + if ( !isdefined( var_2 ) ) + { + call [[ level.func[var_0] ]]( var_1 ); + return; + } + + if ( !isdefined( var_3 ) ) + { + call [[ level.func[var_0] ]]( var_1, var_2 ); + return; + } + + if ( !isdefined( var_4 ) ) + { + call [[ level.func[var_0] ]]( var_1, var_2, var_3 ); + return; + } + + call [[ level.func[var_0] ]]( var_1, var_2, var_3, var_4 ); +} + +self_func( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( !isdefined( level.func[var_0] ) ) + return; + + if ( !isdefined( var_1 ) ) + { + self call [[ level.func[var_0] ]](); + return; + } + + if ( !isdefined( var_2 ) ) + { + self call [[ level.func[var_0] ]]( var_1 ); + return; + } + + if ( !isdefined( var_3 ) ) + { + self call [[ level.func[var_0] ]]( var_1, var_2 ); + return; + } + + if ( !isdefined( var_4 ) ) + { + self call [[ level.func[var_0] ]]( var_1, var_2, var_3 ); + return; + } + + self call [[ level.func[var_0] ]]( var_1, var_2, var_3, var_4 ); +} + +randomvector( var_0 ) +{ + return ( randomfloat( var_0 ) - var_0 * 0.5, randomfloat( var_0 ) - var_0 * 0.5, randomfloat( var_0 ) - var_0 * 0.5 ); +} + +randomvectorrange( var_0, var_1 ) +{ + var_2 = randomfloatrange( var_0, var_1 ); + + if ( randomint( 2 ) == 0 ) + var_2 = var_2 * -1; + + var_3 = randomfloatrange( var_0, var_1 ); + + if ( randomint( 2 ) == 0 ) + var_3 = var_3 * -1; + + var_4 = randomfloatrange( var_0, var_1 ); + + if ( randomint( 2 ) == 0 ) + var_4 = var_4 * -1; + + return ( var_2, var_3, var_4 ); +} + +sign( var_0 ) +{ + if ( var_0 >= 0 ) + return 1; + + return -1; +} + +mod( var_0, var_1 ) +{ + var_2 = int( var_0 / var_1 ); + + if ( var_0 * var_1 < 0 ) + var_2 = var_2 - 1; + + return var_0 - var_2 * var_1; +} + +track( var_0 ) +{ + if ( isdefined( self.current_target ) ) + { + if ( var_0 == self.current_target ) + return; + } + + self.current_target = var_0; +} + +get_enemy_team( var_0 ) +{ + var_1 = []; + var_1["axis"] = "allies"; + var_1["allies"] = "axis"; + return var_1[var_0]; +} + +clear_exception( var_0 ) +{ + self.exception[var_0] = anim.defaultexception; +} + +set_exception( var_0, var_1 ) +{ + self.exception[var_0] = var_1; +} + +set_all_exceptions( var_0 ) +{ + var_1 = getarraykeys( self.exception ); + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + self.exception[var_1[var_2]] = var_0; +} + +cointoss() +{ + return randomint( 100 ) >= 50; +} + +choose_from_weighted_array( var_0, var_1 ) +{ + var_2 = randomint( var_1[var_1.size - 1] + 1 ); + + for ( var_3 = 0; var_3 < var_1.size; var_3++ ) + { + if ( var_2 <= var_1[var_3] ) + return var_0[var_3]; + } +} + +get_cumulative_weights( var_0 ) +{ + var_1 = []; + var_2 = 0; + + for ( var_3 = 0; var_3 < var_0.size; var_3++ ) + { + var_2 = var_2 + var_0[var_3]; + var_1[var_3] = var_2; + } + + return var_1; +} + +waittill_string( var_0, var_1 ) +{ + if ( var_0 != "death" ) + self endon( "death" ); + + var_1 endon( "die" ); + self waittill( var_0 ); + var_1 notify( "returned", var_0 ); +} + +waittill_string_no_endon_death( var_0, var_1 ) +{ + var_1 endon( "die" ); + self waittill( var_0 ); + var_1 notify( "returned", var_0 ); +} + +waittill_multiple( var_0, var_1, var_2, var_3, var_4 ) +{ + self endon( "death" ); + var_5 = spawnstruct(); + var_5.threads = 0; + + if ( isdefined( var_0 ) ) + { + childthread waittill_string( var_0, var_5 ); + var_5.threads++; + } + + if ( isdefined( var_1 ) ) + { + childthread waittill_string( var_1, var_5 ); + var_5.threads++; + } + + if ( isdefined( var_2 ) ) + { + childthread waittill_string( var_2, var_5 ); + var_5.threads++; + } + + if ( isdefined( var_3 ) ) + { + childthread waittill_string( var_3, var_5 ); + var_5.threads++; + } + + if ( isdefined( var_4 ) ) + { + childthread waittill_string( var_4, var_5 ); + var_5.threads++; + } + + while ( var_5.threads ) + { + var_5 waittill( "returned" ); + var_5.threads--; + } + + var_5 notify( "die" ); +} + +waittill_multiple_ents( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) +{ + self endon( "death" ); + var_8 = spawnstruct(); + var_8.threads = 0; + + if ( isdefined( var_0 ) ) + { + var_0 childthread waittill_string( var_1, var_8 ); + var_8.threads++; + } + + if ( isdefined( var_2 ) ) + { + var_2 childthread waittill_string( var_3, var_8 ); + var_8.threads++; + } + + if ( isdefined( var_4 ) ) + { + var_4 childthread waittill_string( var_5, var_8 ); + var_8.threads++; + } + + if ( isdefined( var_6 ) ) + { + var_6 childthread waittill_string( var_7, var_8 ); + var_8.threads++; + } + + while ( var_8.threads ) + { + var_8 waittill( "returned" ); + var_8.threads--; + } + + var_8 notify( "die" ); +} + +waittill_any_return( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + if ( ( !isdefined( var_0 ) || var_0 != "death" ) && ( !isdefined( var_1 ) || var_1 != "death" ) && ( !isdefined( var_2 ) || var_2 != "death" ) && ( !isdefined( var_3 ) || var_3 != "death" ) && ( !isdefined( var_4 ) || var_4 != "death" ) && ( !isdefined( var_5 ) || var_5 != "death" ) ) + self endon( "death" ); + + var_6 = spawnstruct(); + + if ( isdefined( var_0 ) ) + childthread waittill_string( var_0, var_6 ); + + if ( isdefined( var_1 ) ) + childthread waittill_string( var_1, var_6 ); + + if ( isdefined( var_2 ) ) + childthread waittill_string( var_2, var_6 ); + + if ( isdefined( var_3 ) ) + childthread waittill_string( var_3, var_6 ); + + if ( isdefined( var_4 ) ) + childthread waittill_string( var_4, var_6 ); + + if ( isdefined( var_5 ) ) + childthread waittill_string( var_5, var_6 ); + + var_6 waittill( "returned", var_7 ); + var_6 notify( "die" ); + return var_7; +} + +waittill_any_return_no_endon_death( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + var_6 = spawnstruct(); + + if ( isdefined( var_0 ) ) + childthread waittill_string_no_endon_death( var_0, var_6 ); + + if ( isdefined( var_1 ) ) + childthread waittill_string_no_endon_death( var_1, var_6 ); + + if ( isdefined( var_2 ) ) + childthread waittill_string_no_endon_death( var_2, var_6 ); + + if ( isdefined( var_3 ) ) + childthread waittill_string_no_endon_death( var_3, var_6 ); + + if ( isdefined( var_4 ) ) + childthread waittill_string_no_endon_death( var_4, var_6 ); + + if ( isdefined( var_5 ) ) + childthread waittill_string_no_endon_death( var_5, var_6 ); + + var_6 waittill( "returned", var_7 ); + var_6 notify( "die" ); + return var_7; +} + +waittill_any_in_array_return( var_0 ) +{ + var_1 = spawnstruct(); + var_2 = 0; + + foreach ( var_4 in var_0 ) + { + childthread waittill_string( var_4, var_1 ); + + if ( var_4 == "death" ) + var_2 = 1; + } + + if ( !var_2 ) + self endon( "death" ); + + var_1 waittill( "returned", var_6 ); + var_1 notify( "die" ); + return var_6; +} + +waittill_any_in_array_return_no_endon_death( var_0 ) +{ + var_1 = spawnstruct(); + + foreach ( var_3 in var_0 ) + childthread waittill_string_no_endon_death( var_3, var_1 ); + + var_1 waittill( "returned", var_5 ); + var_1 notify( "die" ); + return var_5; +} + +waittill_any_in_array_or_timeout( var_0, var_1 ) +{ + var_2 = spawnstruct(); + var_3 = 0; + + foreach ( var_5 in var_0 ) + { + childthread waittill_string( var_5, var_2 ); + + if ( var_5 == "death" ) + var_3 = 1; + } + + if ( !var_3 ) + self endon( "death" ); + + var_2 childthread _timeout( var_1 ); + var_2 waittill( "returned", var_7 ); + var_2 notify( "die" ); + return var_7; +} + +waittill_any_in_array_or_timeout_no_endon_death( var_0, var_1 ) +{ + var_2 = spawnstruct(); + + foreach ( var_4 in var_0 ) + childthread waittill_string_no_endon_death( var_4, var_2 ); + + var_2 thread _timeout( var_1 ); + var_2 waittill( "returned", var_6 ); + var_2 notify( "die" ); + return var_6; +} + +waittill_any_timeout( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + if ( ( !isdefined( var_1 ) || var_1 != "death" ) && ( !isdefined( var_2 ) || var_2 != "death" ) && ( !isdefined( var_3 ) || var_3 != "death" ) && ( !isdefined( var_4 ) || var_4 != "death" ) && ( !isdefined( var_5 ) || var_5 != "death" ) && ( !isdefined( var_6 ) || var_6 != "death" ) ) + self endon( "death" ); + + var_7 = spawnstruct(); + + if ( isdefined( var_1 ) ) + childthread waittill_string( var_1, var_7 ); + + if ( isdefined( var_2 ) ) + childthread waittill_string( var_2, var_7 ); + + if ( isdefined( var_3 ) ) + childthread waittill_string( var_3, var_7 ); + + if ( isdefined( var_4 ) ) + childthread waittill_string( var_4, var_7 ); + + if ( isdefined( var_5 ) ) + childthread waittill_string( var_5, var_7 ); + + if ( isdefined( var_6 ) ) + childthread waittill_string( var_6, var_7 ); + + var_7 childthread _timeout( var_0 ); + var_7 waittill( "returned", var_8 ); + var_7 notify( "die" ); + return var_8; +} + +_timeout( var_0 ) +{ + self endon( "die" ); + wait( var_0 ); + self notify( "returned", "timeout" ); +} + +waittill_any_timeout_no_endon_death( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + var_6 = spawnstruct(); + + if ( isdefined( var_1 ) ) + childthread waittill_string_no_endon_death( var_1, var_6 ); + + if ( isdefined( var_2 ) ) + childthread waittill_string_no_endon_death( var_2, var_6 ); + + if ( isdefined( var_3 ) ) + childthread waittill_string_no_endon_death( var_3, var_6 ); + + if ( isdefined( var_4 ) ) + childthread waittill_string_no_endon_death( var_4, var_6 ); + + if ( isdefined( var_5 ) ) + childthread waittill_string_no_endon_death( var_5, var_6 ); + + var_6 childthread _timeout( var_0 ); + var_6 waittill( "returned", var_7 ); + var_6 notify( "die" ); + return var_7; +} + +waittill_any( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) +{ + if ( isdefined( var_1 ) ) + self endon( var_1 ); + + if ( isdefined( var_2 ) ) + self endon( var_2 ); + + if ( isdefined( var_3 ) ) + self endon( var_3 ); + + if ( isdefined( var_4 ) ) + self endon( var_4 ); + + if ( isdefined( var_5 ) ) + self endon( var_5 ); + + if ( isdefined( var_6 ) ) + self endon( var_6 ); + + if ( isdefined( var_7 ) ) + self endon( var_7 ); + + self waittill( var_0 ); +} + +waittill_any_ents( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13 ) +{ + if ( isdefined( var_2 ) && isdefined( var_3 ) ) + var_2 endon( var_3 ); + + if ( isdefined( var_4 ) && isdefined( var_5 ) ) + var_4 endon( var_5 ); + + if ( isdefined( var_6 ) && isdefined( var_7 ) ) + var_6 endon( var_7 ); + + if ( isdefined( var_8 ) && isdefined( var_9 ) ) + var_8 endon( var_9 ); + + if ( isdefined( var_10 ) && isdefined( var_11 ) ) + var_10 endon( var_11 ); + + if ( isdefined( var_12 ) && isdefined( var_13 ) ) + var_12 endon( var_13 ); + + var_0 waittill( var_1 ); +} + +isflashed() +{ + if ( !isdefined( self.flashendtime ) ) + return 0; + + return gettime() < self.flashendtime; +} + +flag_exist( var_0 ) +{ + return isdefined( level.flag[var_0] ); +} + +flag( var_0 ) +{ + return level.flag[var_0]; +} + +init_flags() +{ + level.flag = []; + level.flags_lock = []; + level.generic_index = 0; + + if ( !isdefined( level.sp_stat_tracking_func ) ) + level.sp_stat_tracking_func = ::empty_init_func; + + level.flag_struct = spawnstruct(); + level.flag_struct assign_unique_id(); +} + +flag_init( var_0 ) +{ + if ( !isdefined( level.flag ) ) + init_flags(); + + /# + if ( isdefined( level.first_frame ) && level.first_frame == -1 ) + assertex( !isdefined( level.flag[var_0] ), "Attempt to reinitialize existing message: " + var_0 ); + #/ + + level.flag[var_0] = 0; + + if ( !isdefined( level.trigger_flags ) ) + { + init_trigger_flags(); + level.trigger_flags[var_0] = []; + } + else if ( !isdefined( level.trigger_flags[var_0] ) ) + level.trigger_flags[var_0] = []; + + if ( issuffix( var_0, "aa_" ) ) + thread [[ level.sp_stat_tracking_func ]]( var_0 ); +} + +empty_init_func( var_0 ) +{ + +} + +issuffix( var_0, var_1 ) +{ + if ( var_1.size > var_0.size ) + return 0; + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + { + if ( var_0[var_2] != var_1[var_2] ) + return 0; + } + + return 1; +} + +flag_set( var_0, var_1 ) +{ +/# + assertex( isdefined( level.flag[var_0] ), "Attempted to set a flag before calling flag_init: " + var_0 ); +#/ + + level.flag[var_0] = 1; + set_trigger_flag_permissions( var_0 ); + + if ( isdefined( var_1 ) ) + level notify( var_0, var_1 ); + else + level notify( var_0 ); +} + +assign_unique_id() +{ + self.unique_id = "generic" + level.generic_index; + level.generic_index++; +} + +flag_wait( var_0 ) +{ + var_1 = undefined; + + while ( !flag( var_0 ) ) + { + var_1 = undefined; + level waittill( var_0, var_1 ); + } + + if ( isdefined( var_1 ) ) + return var_1; +} + +flag_clear( var_0 ) +{ + if ( !flag( var_0 ) ) + return; + + level.flag[var_0] = 0; + set_trigger_flag_permissions( var_0 ); + level notify( var_0 ); +} + +flag_waitopen( var_0 ) +{ + while ( flag( var_0 ) ) + level waittill( var_0 ); +} + +waittill_either( var_0, var_1 ) +{ + self endon( var_0 ); + self waittill( var_1 ); +} + +array_thread_amortized( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11 ) +{ + if ( !isdefined( var_3 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]](); + wait( var_2 ); + } + } + else + { + if ( !isdefined( var_4 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_5 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_6 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_7 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_8 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6, var_7 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_9 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6, var_7, var_8 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_10 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); + wait( var_2 ); + } + + return; + } + + if ( !isdefined( var_11 ) ) + { + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + wait( var_2 ); + } + + return; + } + + foreach ( var_13 in var_0 ) + { + var_13 thread [[ var_1 ]]( var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11 ); + wait( var_2 ); + } + } +} + +array_thread( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( !isdefined( var_2 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]](); + } + else + { + if ( !isdefined( var_3 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2 ); + + return; + } + + if ( !isdefined( var_4 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3 ); + + return; + } + + if ( !isdefined( var_5 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4 ); + + return; + } + + if ( !isdefined( var_6 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5 ); + + return; + } + + if ( !isdefined( var_7 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5, var_6 ); + + return; + } + + if ( !isdefined( var_8 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5, var_6, var_7 ); + + return; + } + + if ( !isdefined( var_9 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5, var_6, var_7, var_8 ); + + return; + } + + if ( !isdefined( var_10 ) ) + { + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); + + return; + } + + foreach ( var_12 in var_0 ) + var_12 thread [[ var_1 ]]( var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + } +} + +array_call( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( isdefined( var_4 ) ) + { + foreach ( var_6 in var_0 ) + var_6 call [[ var_1 ]]( var_2, var_3, var_4 ); + + return; + } + + if ( isdefined( var_3 ) ) + { + foreach ( var_6 in var_0 ) + var_6 call [[ var_1 ]]( var_2, var_3 ); + + return; + } + + if ( isdefined( var_2 ) ) + { + foreach ( var_6 in var_0 ) + var_6 call [[ var_1 ]]( var_2 ); + + return; + } + + foreach ( var_6 in var_0 ) + var_6 call [[ var_1 ]](); +} + +noself_array_call( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( isdefined( var_4 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2, var_3, var_4 ); + + return; + } + + if ( isdefined( var_3 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2, var_3 ); + + return; + } + + if ( isdefined( var_2 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2 ); + + return; + } + + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6 ); +} + +array_thread4( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + array_thread( var_0, var_1, var_2, var_3, var_4, var_5 ); +} + +array_thread5( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + array_thread( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ); +} + +trigger_on( var_0, var_1 ) +{ + if ( isdefined( var_0 ) && isdefined( var_1 ) ) + { + var_2 = getentarray( var_0, var_1 ); + array_thread( var_2, ::trigger_on_proc ); + } + else + trigger_on_proc(); +} + +trigger_on_proc() +{ + if ( isdefined( self.realorigin ) ) + self.origin = self.realorigin; + + self.trigger_off = undefined; +} + +trigger_off( var_0, var_1 ) +{ + if ( isdefined( var_0 ) && isdefined( var_1 ) ) + { + var_2 = getentarray( var_0, var_1 ); + array_thread( var_2, ::trigger_off_proc ); + } + else + trigger_off_proc(); +} + +trigger_off_proc() +{ + if ( !isdefined( self.realorigin ) ) + self.realorigin = self.origin; + + if ( self.origin == self.realorigin ) + self.origin = self.origin + ( 0, 0, -10000 ); + + self.trigger_off = 1; +} + +set_trigger_flag_permissions( var_0 ) +{ + if ( !isdefined( level.trigger_flags ) || !isdefined( level.trigger_flags[var_0] ) ) + return; + + level.trigger_flags[var_0] = array_removeundefined( level.trigger_flags[var_0] ); + array_thread( level.trigger_flags[var_0], ::update_trigger_based_on_flags ); +} + +update_trigger_based_on_flags() +{ + var_0 = 1; + + if ( isdefined( self.script_flag_true ) ) + { + var_0 = 0; + var_1 = create_flags_and_return_tokens( self.script_flag_true ); + + foreach ( var_3 in var_1 ) + { + if ( flag( var_3 ) ) + { + var_0 = 1; + break; + } + } + } + + var_5 = 1; + + if ( isdefined( self.script_flag_false ) ) + { + var_1 = create_flags_and_return_tokens( self.script_flag_false ); + + foreach ( var_3 in var_1 ) + { + if ( flag( var_3 ) ) + { + var_5 = 0; + break; + } + } + } + + [[ level.trigger_func[var_0 && var_5] ]](); +} + +create_flags_and_return_tokens( var_0 ) +{ + var_1 = strtok( var_0, " " ); + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + { + if ( !isdefined( level.flag[var_1[var_2]] ) ) + flag_init( var_1[var_2] ); + } + + return var_1; +} + +init_trigger_flags() +{ + level.trigger_flags = []; + level.trigger_func[1] = ::trigger_on; + level.trigger_func[0] = ::trigger_off; +} + +getstruct( var_0, var_1 ) +{ + var_2 = level.struct_class_names[var_1][var_0]; + + if ( !isdefined( var_2 ) ) + return undefined; + + if ( var_2.size > 1 ) + return undefined; + + return var_2[0]; +} + +getstructarray( var_0, var_1 ) +{ + var_2 = level.struct_class_names[var_1][var_0]; + + if ( !isdefined( var_2 ) ) + return []; + + return var_2; +} + +struct_class_init() +{ + level.struct_class_names = []; + level.struct_class_names["target"] = []; + level.struct_class_names["targetname"] = []; + level.struct_class_names["script_noteworthy"] = []; + level.struct_class_names["script_linkname"] = []; + + foreach ( var_1 in level.struct ) + { + if ( isdefined( var_1.targetname ) ) + { + if ( !isdefined( level.struct_class_names["targetname"][var_1.targetname] ) ) + level.struct_class_names["targetname"][var_1.targetname] = []; + + var_2 = level.struct_class_names["targetname"][var_1.targetname].size; + level.struct_class_names["targetname"][var_1.targetname][var_2] = var_1; + } + + if ( isdefined( var_1.target ) ) + { + if ( !isdefined( level.struct_class_names["target"][var_1.target] ) ) + level.struct_class_names["target"][var_1.target] = []; + + var_2 = level.struct_class_names["target"][var_1.target].size; + level.struct_class_names["target"][var_1.target][var_2] = var_1; + } + + if ( isdefined( var_1.script_noteworthy ) ) + { + if ( !isdefined( level.struct_class_names["script_noteworthy"][var_1.script_noteworthy] ) ) + level.struct_class_names["script_noteworthy"][var_1.script_noteworthy] = []; + + var_2 = level.struct_class_names["script_noteworthy"][var_1.script_noteworthy].size; + level.struct_class_names["script_noteworthy"][var_1.script_noteworthy][var_2] = var_1; + } + + if ( isdefined( var_1.script_linkname ) ) + { + if ( !isdefined( level.struct_class_names["script_linkname"][var_1.script_linkname] ) ) + level.struct_class_names["script_linkname"][var_1.script_linkname] = []; + + var_2 = level.struct_class_names["script_linkname"][var_1.script_linkname].size; + level.struct_class_names["script_linkname"][var_1.script_linkname][0] = var_1; + } + } +} + +fileprint_start( var_0 ) +{ + +} + +fileprint_map_start() +{ + +} + +fileprint_map_header( var_0 ) +{ + if ( !isdefined( var_0 ) ) + var_0 = 0; +} + +fileprint_map_keypairprint( var_0, var_1 ) +{ + +} + +fileprint_map_entity_start() +{ + +} + +fileprint_map_entity_end() +{ + +} + +fileprint_radiant_vec( var_0 ) +{ + +} + +array_remove( var_0, var_1 ) +{ + var_2 = []; + + foreach ( var_4 in var_0 ) + { + if ( var_4 != var_1 ) + var_2[var_2.size] = var_4; + } + + return var_2; +} + +array_remove_array( var_0, var_1 ) +{ + foreach ( var_3 in var_1 ) + var_0 = array_remove( var_0, var_3 ); + + return var_0; +} + +array_removeundefined( var_0 ) +{ + var_1 = []; + + foreach ( var_4, var_3 in var_0 ) + { + if ( !isdefined( var_3 ) ) + continue; + + var_1[var_1.size] = var_3; + } + + return var_1; +} + +array_remove_duplicates( var_0 ) +{ + var_1 = []; + + foreach ( var_3 in var_0 ) + { + if ( !isdefined( var_3 ) ) + continue; + + var_4 = 1; + + foreach ( var_6 in var_1 ) + { + if ( var_3 == var_6 ) + { + var_4 = 0; + break; + } + } + + if ( var_4 ) + var_1[var_1.size] = var_3; + } + + return var_1; +} + +array_levelthread( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( isdefined( var_4 ) ) + { + foreach ( var_6 in var_0 ) + thread [[ var_1 ]]( var_6, var_2, var_3, var_4 ); + + return; + } + + if ( isdefined( var_3 ) ) + { + foreach ( var_6 in var_0 ) + thread [[ var_1 ]]( var_6, var_2, var_3 ); + + return; + } + + if ( isdefined( var_2 ) ) + { + foreach ( var_6 in var_0 ) + thread [[ var_1 ]]( var_6, var_2 ); + + return; + } + + foreach ( var_6 in var_0 ) + thread [[ var_1 ]]( var_6 ); +} + +array_levelcall( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( isdefined( var_4 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2, var_3, var_4 ); + + return; + } + + if ( isdefined( var_3 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2, var_3 ); + + return; + } + + if ( isdefined( var_2 ) ) + { + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6, var_2 ); + + return; + } + + foreach ( var_6 in var_0 ) + call [[ var_1 ]]( var_6 ); +} + +add_to_array( var_0, var_1 ) +{ + if ( !isdefined( var_1 ) ) + return var_0; + + if ( !isdefined( var_0 ) ) + var_0[0] = var_1; + else + var_0[var_0.size] = var_1; + + return var_0; +} + +flag_assert( var_0 ) +{ + +} + +flag_wait_either( var_0, var_1 ) +{ + for (;;) + { + if ( flag( var_0 ) ) + return; + + if ( flag( var_1 ) ) + return; + + level waittill_either( var_0, var_1 ); + } +} + +flag_wait_either_return( var_0, var_1 ) +{ + for (;;) + { + if ( flag( var_0 ) ) + return var_0; + + if ( flag( var_1 ) ) + return var_1; + + var_2 = level waittill_any_return( var_0, var_1 ); + return var_2; + } +} + +flag_wait_any( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + var_6 = []; + + if ( isdefined( var_5 ) ) + { + var_6[var_6.size] = var_0; + var_6[var_6.size] = var_1; + var_6[var_6.size] = var_2; + var_6[var_6.size] = var_3; + var_6[var_6.size] = var_4; + var_6[var_6.size] = var_5; + } + else if ( isdefined( var_4 ) ) + { + var_6[var_6.size] = var_0; + var_6[var_6.size] = var_1; + var_6[var_6.size] = var_2; + var_6[var_6.size] = var_3; + var_6[var_6.size] = var_4; + } + else if ( isdefined( var_3 ) ) + { + var_6[var_6.size] = var_0; + var_6[var_6.size] = var_1; + var_6[var_6.size] = var_2; + var_6[var_6.size] = var_3; + } + else if ( isdefined( var_2 ) ) + { + var_6[var_6.size] = var_0; + var_6[var_6.size] = var_1; + var_6[var_6.size] = var_2; + } + else if ( isdefined( var_1 ) ) + { + flag_wait_either( var_0, var_1 ); + return; + } + else + return; + + for (;;) + { + for ( var_7 = 0; var_7 < var_6.size; var_7++ ) + { + if ( flag( var_6[var_7] ) ) + return; + } + + level waittill_any( var_0, var_1, var_2, var_3, var_4, var_5 ); + } +} + +flag_wait_any_return( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = []; + + if ( isdefined( var_4 ) ) + { + var_5[var_5.size] = var_0; + var_5[var_5.size] = var_1; + var_5[var_5.size] = var_2; + var_5[var_5.size] = var_3; + var_5[var_5.size] = var_4; + } + else if ( isdefined( var_3 ) ) + { + var_5[var_5.size] = var_0; + var_5[var_5.size] = var_1; + var_5[var_5.size] = var_2; + var_5[var_5.size] = var_3; + } + else if ( isdefined( var_2 ) ) + { + var_5[var_5.size] = var_0; + var_5[var_5.size] = var_1; + var_5[var_5.size] = var_2; + } + else if ( isdefined( var_1 ) ) + { + var_6 = flag_wait_either_return( var_0, var_1 ); + return var_6; + } + else + return; + + for (;;) + { + for ( var_7 = 0; var_7 < var_5.size; var_7++ ) + { + if ( flag( var_5[var_7] ) ) + return var_5[var_7]; + } + + var_6 = level waittill_any_return( var_0, var_1, var_2, var_3, var_4 ); + return var_6; + } +} + +flag_wait_all( var_0, var_1, var_2, var_3 ) +{ + if ( isdefined( var_0 ) ) + flag_wait( var_0 ); + + if ( isdefined( var_1 ) ) + flag_wait( var_1 ); + + if ( isdefined( var_2 ) ) + flag_wait( var_2 ); + + if ( isdefined( var_3 ) ) + flag_wait( var_3 ); +} + +flag_wait_or_timeout( var_0, var_1 ) +{ + var_2 = var_1 * 1000; + var_3 = gettime(); + + for (;;) + { + if ( flag( var_0 ) ) + break; + + if ( gettime() >= var_3 + var_2 ) + break; + + var_4 = var_2 - ( gettime() - var_3 ); + var_5 = var_4 / 1000; + wait_for_flag_or_time_elapses( var_0, var_5 ); + } +} + +flag_waitopen_or_timeout( var_0, var_1 ) +{ + var_2 = gettime(); + + for (;;) + { + if ( !flag( var_0 ) ) + break; + + if ( gettime() >= var_2 + var_1 * 1000 ) + break; + + wait_for_flag_or_time_elapses( var_0, var_1 ); + } +} + +wait_for_flag_or_time_elapses( var_0, var_1 ) +{ + level endon( var_0 ); + wait( var_1 ); +} + +delaycall( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + thread delaycall_proc( var_1, var_0, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); +} + +delaycall_proc( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( issp() ) + { + self endon( "death" ); + self endon( "stop_delay_call" ); + } + + wait( var_1 ); + + if ( isdefined( var_9 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); + else if ( isdefined( var_8 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4, var_5, var_6, var_7, var_8 ); + else if ( isdefined( var_7 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4, var_5, var_6, var_7 ); + else if ( isdefined( var_6 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4, var_5, var_6 ); + else if ( isdefined( var_5 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4, var_5 ); + else if ( isdefined( var_4 ) ) + self call [[ var_0 ]]( var_2, var_3, var_4 ); + else if ( isdefined( var_3 ) ) + self call [[ var_0 ]]( var_2, var_3 ); + else if ( isdefined( var_2 ) ) + self call [[ var_0 ]]( var_2 ); + else + self call [[ var_0 ]](); +} + +noself_delaycall( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + thread noself_delaycall_proc( var_1, var_0, var_2, var_3, var_4, var_5 ); +} + +noself_delaycall_proc( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + wait( var_1 ); + + if ( isdefined( var_5 ) ) + call [[ var_0 ]]( var_2, var_3, var_4, var_5 ); + else if ( isdefined( var_4 ) ) + call [[ var_0 ]]( var_2, var_3, var_4 ); + else if ( isdefined( var_3 ) ) + call [[ var_0 ]]( var_2, var_3 ); + else if ( isdefined( var_2 ) ) + call [[ var_0 ]]( var_2 ); + else + call [[ var_0 ]](); +} + +issp() +{ + if ( !isdefined( level.issp ) ) + level.issp = !string_starts_with( getdvar( "mapname" ), "mp_" ); + + return level.issp; +} + +issp_towerdefense() +{ + if ( !isdefined( level.issp_towerdefense ) ) + level.issp_towerdefense = string_starts_with( getdvar( "mapname" ), "so_td_" ); + + return level.issp_towerdefense; +} + +string_starts_with( var_0, var_1 ) +{ + if ( var_0.size < var_1.size ) + return 0; + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + { + if ( tolower( var_0[var_2] ) != tolower( var_1[var_2] ) ) + return 0; + } + + return 1; +} + +plot_points( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = var_0[0]; + + if ( !isdefined( var_1 ) ) + var_1 = 1; + + if ( !isdefined( var_2 ) ) + var_2 = 1; + + if ( !isdefined( var_3 ) ) + var_3 = 1; + + if ( !isdefined( var_4 ) ) + var_4 = 0.05; + + for ( var_6 = 1; var_6 < var_0.size; var_6++ ) + { + thread draw_line_for_time( var_5, var_0[var_6], var_1, var_2, var_3, var_4 ); + var_5 = var_0[var_6]; + } +} + +draw_line_for_time( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + var_5 = gettime() + var_5 * 1000; + + while ( gettime() < var_5 ) + wait 0.05; +} + +table_combine( var_0, var_1 ) +{ + var_2 = []; + + foreach ( var_5, var_4 in var_0 ) + var_2[var_5] = var_4; + + foreach ( var_5, var_4 in var_1 ) + var_2[var_5] = var_4; + + return var_2; +} + +array_combine( var_0, var_1 ) +{ + var_2 = []; + + foreach ( var_4 in var_0 ) + var_2[var_2.size] = var_4; + + foreach ( var_4 in var_1 ) + var_2[var_2.size] = var_4; + + return var_2; +} + +array_combine_non_integer_indices( var_0, var_1 ) +{ + var_2 = []; + + foreach ( var_5, var_4 in var_0 ) + var_2[var_5] = var_4; + + foreach ( var_5, var_4 in var_1 ) + var_2[var_5] = var_4; + + return var_2; +} + +array_randomize( var_0 ) +{ + for ( var_1 = 0; var_1 < var_0.size; var_1++ ) + { + var_2 = randomint( var_0.size ); + var_3 = var_0[var_1]; + var_0[var_1] = var_0[var_2]; + var_0[var_2] = var_3; + } + + return var_0; +} + +array_add( var_0, var_1 ) +{ + var_0[var_0.size] = var_1; + return var_0; +} + +array_insert( var_0, var_1, var_2 ) +{ + if ( var_2 == var_0.size ) + { + var_3 = var_0; + var_3[var_3.size] = var_1; + return var_3; + } + + var_3 = []; + var_4 = 0; + + for ( var_5 = 0; var_5 < var_0.size; var_5++ ) + { + if ( var_5 == var_2 ) + { + var_3[var_5] = var_1; + var_4 = 1; + } + + var_3[var_5 + var_4] = var_0[var_5]; + } + + return var_3; +} + +array_contains( var_0, var_1 ) +{ + if ( var_0.size <= 0 ) + return 0; + + foreach ( var_3 in var_0 ) + { + if ( var_3 == var_1 ) + return 1; + } + + return 0; +} + +array_find( var_0, var_1 ) +{ + foreach ( var_4, var_3 in var_0 ) + { + if ( var_3 == var_1 ) + return var_4; + } + + return undefined; +} + +flat_angle( var_0 ) +{ + var_1 = ( 0, var_0[1], 0 ); + return var_1; +} + +flat_origin( var_0 ) +{ + var_1 = ( var_0[0], var_0[1], 0 ); + return var_1; +} + +draw_arrow_time( var_0, var_1, var_2, var_3 ) +{ + level endon( "newpath" ); + var_4 = []; + var_5 = vectortoangles( var_0 - var_1 ); + var_6 = anglestoright( var_5 ); + var_7 = anglestoforward( var_5 ); + var_8 = anglestoup( var_5 ); + var_9 = distance( var_0, var_1 ); + var_10 = []; + var_11 = 0.1; + var_10[0] = var_0; + var_10[1] = var_0 + var_6 * ( var_9 * var_11 ) + var_7 * ( var_9 * -0.1 ); + var_10[2] = var_1; + var_10[3] = var_0 + var_6 * ( var_9 * ( -1 * var_11 ) ) + var_7 * ( var_9 * -0.1 ); + var_10[4] = var_0; + var_10[5] = var_0 + var_8 * ( var_9 * var_11 ) + var_7 * ( var_9 * -0.1 ); + var_10[6] = var_1; + var_10[7] = var_0 + var_8 * ( var_9 * ( -1 * var_11 ) ) + var_7 * ( var_9 * -0.1 ); + var_10[8] = var_0; + var_12 = var_2[0]; + var_13 = var_2[1]; + var_14 = var_2[2]; + plot_points( var_10, var_12, var_13, var_14, var_3 ); +} + +get_linked_ents() +{ + var_0 = []; + + if ( isdefined( self.script_linkto ) ) + { + var_1 = get_links(); + + foreach ( var_3 in var_1 ) + { + var_4 = getentarray( var_3, "script_linkname" ); + + if ( var_4.size > 0 ) + var_0 = array_combine( var_0, var_4 ); + } + } + + return var_0; +} + +get_linked_vehicle_nodes() +{ + var_0 = []; + + if ( isdefined( self.script_linkto ) ) + { + var_1 = get_links(); + + foreach ( var_3 in var_1 ) + { + var_4 = getvehiclenodearray( var_3, "script_linkname" ); + + if ( var_4.size > 0 ) + var_0 = array_combine( var_0, var_4 ); + } + } + + return var_0; +} + +get_linked_ent() +{ + var_0 = get_linked_ents(); + return var_0[0]; +} + +get_linked_vehicle_node() +{ + var_0 = get_linked_vehicle_nodes(); + return var_0[0]; +} + +get_links() +{ + return strtok( self.script_linkto, " " ); +} + +run_thread_on_targetname( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = getentarray( var_0, "targetname" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = getstructarray( var_0, "targetname" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = call [[ level.getnodearrayfunction ]]( var_0, "targetname" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = getvehiclenodearray( var_0, "targetname" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); +} + +run_thread_on_noteworthy( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = getentarray( var_0, "script_noteworthy" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = getstructarray( var_0, "script_noteworthy" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = call [[ level.getnodearrayfunction ]]( var_0, "script_noteworthy" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); + var_5 = getvehiclenodearray( var_0, "script_noteworthy" ); + array_thread( var_5, var_1, var_2, var_3, var_4 ); +} + +draw_arrow( var_0, var_1, var_2 ) +{ + level endon( "newpath" ); + var_3 = []; + var_4 = vectortoangles( var_0 - var_1 ); + var_5 = anglestoright( var_4 ); + var_6 = anglestoforward( var_4 ); + var_7 = distance( var_0, var_1 ); + var_8 = []; + var_9 = 0.05; + var_8[0] = var_0; + var_8[1] = var_0 + var_5 * ( var_7 * var_9 ) + var_6 * ( var_7 * -0.2 ); + var_8[2] = var_1; + var_8[3] = var_0 + var_5 * ( var_7 * ( -1 * var_9 ) ) + var_6 * ( var_7 * -0.2 ); + + for ( var_10 = 0; var_10 < 4; var_10++ ) + { + var_11 = var_10 + 1; + + if ( var_11 >= 4 ) + var_11 = 0; + } +} + +draw_entity_bounds( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( !isdefined( var_2 ) ) + var_2 = ( 0, 1, 0 ); + + if ( !isdefined( var_3 ) ) + var_3 = 0; + + if ( !isdefined( var_4 ) ) + var_4 = 0.05; + + if ( var_3 ) + var_5 = int( var_4 / 0.05 ); + else + var_5 = int( var_1 / 0.05 ); + + var_6 = []; + var_7 = []; + var_8 = gettime(); + + for ( var_9 = var_8 + var_1 * 1000; var_8 < var_9 && isdefined( var_0 ); var_8 = gettime() ) + { + var_6[0] = var_0 getpointinbounds( 1, 1, 1 ); + var_6[1] = var_0 getpointinbounds( 1, 1, -1 ); + var_6[2] = var_0 getpointinbounds( -1, 1, -1 ); + var_6[3] = var_0 getpointinbounds( -1, 1, 1 ); + var_7[0] = var_0 getpointinbounds( 1, -1, 1 ); + var_7[1] = var_0 getpointinbounds( 1, -1, -1 ); + var_7[2] = var_0 getpointinbounds( -1, -1, -1 ); + var_7[3] = var_0 getpointinbounds( -1, -1, 1 ); + + for ( var_10 = 0; var_10 < 4; var_10++ ) + { + var_11 = var_10 + 1; + + if ( var_11 == 4 ) + var_11 = 0; + } + + if ( !var_3 ) + return; + + wait( var_4 ); + } +} + +draw_volume( var_0, var_1, var_2, var_3, var_4 ) +{ + draw_entity_bounds( var_0, var_1, var_2, var_3, var_4 ); +} + +draw_trigger( var_0, var_1, var_2, var_3, var_4 ) +{ + draw_entity_bounds( var_0, var_1, var_2, var_3, var_4 ); +} + +getfx( var_0 ) +{ + return level._effect[var_0]; +} + +fxexists( var_0 ) +{ + return isdefined( level._effect[var_0] ); +} + +print_csv_asset( var_0, var_1 ) +{ + var_2 = var_1 + "," + var_0; + + if ( isdefined( level.csv_lines[var_2] ) ) + return; + + level.csv_lines[var_2] = 1; +} + +fileprint_csv_start( var_0 ) +{ + +} + +getlastweapon() +{ + return self.saved_lastweapon; +} + +playerunlimitedammothread() +{ + +} + +isusabilityenabled() +{ + return !self.disabledusability; +} + +_disableusability() +{ + if ( !isdefined( self.disabledusability ) ) + self.disabledusability = 0; + + self.disabledusability++; + self disableusability(); +} + +_enableusability() +{ + if ( !isdefined( self.disabledusability ) ) + self.disabledusability = 0; + else if ( self.disabledusability > 0 ) + { + self.disabledusability--; + + if ( self.disabledusability == 0 ) + self enableusability(); + } +} + +resetusability() +{ + self.disabledusability = 0; + self enableusability(); +} + +_disableweapon() +{ + if ( !isdefined( self.disabledweapon ) ) + self.disabledweapon = 0; + + self.disabledweapon++; + self disableweapons(); +} + +_enableweapon() +{ + if ( !isdefined( self.disabledweapon ) ) + self.disabledweapon = 0; + + self.disabledweapon--; + + if ( !self.disabledweapon ) + self enableweapons(); +} + +isweaponenabled() +{ + return !self.disabledweapon; +} + +_disableweaponswitch() +{ + if ( !isdefined( self.disabledweaponswitch ) ) + self.disabledweaponswitch = 0; + + self.disabledweaponswitch++; + self disableweaponswitch(); +} + +_enableweaponswitch() +{ + if ( !isdefined( self.disabledweaponswitch ) ) + self.disabledweaponswitch = 0; + + self.disabledweaponswitch--; + + if ( !self.disabledweaponswitch ) + self enableweaponswitch(); +} + +isweaponswitchenabled() +{ + return !self.disabledweaponswitch; +} + +_disableoffhandweapons() +{ + if ( !isdefined( self.disabledoffhandweapons ) ) + self.disabledoffhandweapons = 0; + + self.disabledoffhandweapons++; + self disableoffhandweapons(); +} + +_enableoffhandweapons() +{ + if ( !isdefined( self.disabledoffhandweapons ) ) + self.disabledoffhandweapons = 0; + + self.disabledoffhandweapons--; + + if ( !self.disabledoffhandweapons ) + self enableoffhandweapons(); +} + +isoffhandweaponenabled() +{ + return !self.disabledoffhandweapons; +} + +random( var_0 ) +{ + var_1 = []; + + foreach ( var_4, var_3 in var_0 ) + var_1[var_1.size] = var_3; + + if ( !var_1.size ) + return undefined; + + return var_1[randomint( var_1.size )]; +} + +random_weight_sorted( var_0 ) +{ + var_1 = []; + + foreach ( var_4, var_3 in var_0 ) + var_1[var_1.size] = var_3; + + if ( !var_1.size ) + return undefined; + + var_5 = randomint( var_1.size * var_1.size ); + return var_1[var_1.size - 1 - int( sqrt( var_5 ) )]; +} + +spawn_tag_origin() +{ + var_0 = spawn( "script_model", ( 0, 0, 0 ) ); + var_0 setmodel( "tag_origin" ); + var_0 hide(); + + if ( isdefined( self.origin ) ) + var_0.origin = self.origin; + + if ( isdefined( self.angles ) ) + var_0.angles = self.angles; + + return var_0; +} + +waittill_notify_or_timeout( var_0, var_1 ) +{ + self endon( var_0 ); + wait( var_1 ); +} + +waittill_notify_or_timeout_return( var_0, var_1 ) +{ + self endon( var_0 ); + wait( var_1 ); + return "timeout"; +} + +fileprint_launcher_start_file() +{ + level.fileprintlauncher_linecount = 0; + level.fileprint_launcher = 1; + fileprint_launcher( "GAMEPRINTSTARTFILE:" ); +} + +fileprint_launcher( var_0 ) +{ + level.fileprintlauncher_linecount++; + + if ( level.fileprintlauncher_linecount > 200 ) + { + wait 0.05; + level.fileprintlauncher_linecount = 0; + } +} + +fileprint_launcher_end_file( var_0, var_1 ) +{ + if ( !isdefined( var_1 ) ) + var_1 = 0; + + if ( var_1 ) + fileprint_launcher( "GAMEPRINTENDFILE:GAMEPRINTP4ENABLED:" + var_0 ); + else + fileprint_launcher( "GAMEPRINTENDFILE:" + var_0 ); + + var_2 = gettime() + 4000; + + while ( getdvarint( "LAUNCHER_PRINT_SUCCESS" ) == 0 && getdvar( "LAUNCHER_PRINT_FAIL" ) == "0" && gettime() < var_2 ) + wait 0.05; + + if ( !( gettime() < var_2 ) ) + { + iprintlnbold( "LAUNCHER_PRINT_FAIL:( TIMEOUT ): launcherconflict? restart launcher and try again? " ); + level.fileprint_launcher = undefined; + return 0; + } + + var_3 = getdvar( "LAUNCHER_PRINT_FAIL" ); + + if ( var_3 != "0" ) + { + iprintlnbold( "LAUNCHER_PRINT_FAIL:( " + var_3 + " ): launcherconflict? restart launcher and try again? " ); + level.fileprint_launcher = undefined; + return 0; + } + + level.fileprint_launcher = undefined; + return 1; +} + +launcher_write_clipboard( var_0 ) +{ + level.fileprintlauncher_linecount = 0; + fileprint_launcher( "LAUNCHER_CLIP:" + var_0 ); +} + +isdestructible() +{ + if ( !isdefined( self ) ) + return 0; + + return isdefined( self.destructible_type ); +} + +pauseeffect() +{ + common_scripts\_createfx::stop_fx_looper(); +} + +activate_individual_exploder() +{ + common_scripts\_exploder::activate_individual_exploder_proc(); +} + +waitframe() +{ + wait 0.05; +} + +get_target_ent( var_0 ) +{ + if ( !isdefined( var_0 ) ) + var_0 = self.target; + + var_1 = getent( var_0, "targetname" ); + + if ( isdefined( var_1 ) ) + return var_1; + + if ( issp() ) + { + var_1 = call [[ level.getnodefunction ]]( var_0, "targetname" ); + + if ( isdefined( var_1 ) ) + return var_1; + } + + var_1 = getstruct( var_0, "targetname" ); + + if ( isdefined( var_1 ) ) + return var_1; + + var_1 = getvehiclenode( var_0, "targetname" ); + + if ( isdefined( var_1 ) ) + return var_1; +} + +get_noteworthy_ent( var_0 ) +{ + var_1 = getent( var_0, "script_noteworthy" ); + + if ( isdefined( var_1 ) ) + return var_1; + + if ( issp() ) + { + var_1 = call [[ level.getnodefunction ]]( var_0, "script_noteworthy" ); + + if ( isdefined( var_1 ) ) + return var_1; + } + + var_1 = getstruct( var_0, "script_noteworthy" ); + + if ( isdefined( var_1 ) ) + return var_1; + + var_1 = getvehiclenode( var_0, "script_noteworthy" ); + + if ( isdefined( var_1 ) ) + return var_1; +} + +do_earthquake( var_0, var_1 ) +{ + var_2 = level.earthquake[var_0]; + earthquake( var_2["magnitude"], var_2["duration"], var_1, var_2["radius"] ); +} + +play_loopsound_in_space( var_0, var_1 ) +{ + var_2 = spawn( "script_origin", ( 0, 0, 0 ) ); + + if ( !isdefined( var_1 ) ) + var_1 = self.origin; + + var_2.origin = var_1; + var_2 playloopsound( var_0 ); + return var_2; +} + +play_sound_in_space_with_angles( var_0, var_1, var_2, var_3 ) +{ + var_4 = spawn( "script_origin", ( 0, 0, 1 ) ); + + if ( !isdefined( var_1 ) ) + var_1 = self.origin; + + var_4.origin = var_1; + var_4.angles = var_2; + + if ( issp() ) + { + if ( isdefined( var_3 ) && var_3 ) + var_4 playsoundasmaster( var_0, "sounddone" ); + else + var_4 playsound( var_0, "sounddone" ); + + var_4 waittill( "sounddone" ); + } + else if ( isdefined( var_3 ) && var_3 ) + var_4 playsoundasmaster( var_0 ); + else + var_4 playsound( var_0 ); + + var_4 delete(); +} + +play_sound_in_space( var_0, var_1, var_2 ) +{ + play_sound_in_space_with_angles( var_0, var_1, ( 0, 0, 0 ), var_2 ); +} + +loop_fx_sound( var_0, var_1, var_2, var_3, var_4 ) +{ + loop_fx_sound_with_angles( var_0, var_1, ( 0, 0, 0 ), var_2, var_3, var_4 ); +} + +loop_fx_sound_with_angles( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + if ( isdefined( var_3 ) && var_3 ) + { + if ( !isdefined( level.first_frame ) || level.first_frame == 1 ) + spawnloopingsound( var_0, var_1, var_2 ); + } + else + { + if ( level.createfx_enabled && isdefined( var_5.loopsound_ent ) ) + var_7 = var_5.loopsound_ent; + else + var_7 = spawn( "script_origin", ( 0, 0, 0 ) ); + + if ( isdefined( var_4 ) ) + { + thread loop_sound_delete( var_4, var_7 ); + self endon( var_4 ); + } + + var_7.origin = var_1; + var_7.angles = var_2; + var_7 playloopsound( var_0 ); + + if ( level.createfx_enabled ) + var_5.loopsound_ent = var_7; + else + var_7 willneverchange(); + } +} + +loop_fx_sound_interval( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + loop_fx_sound_interval_with_angles( var_0, var_1, ( 0, 0, 0 ), var_2, var_3, var_4, var_5 ); +} + +loop_fx_sound_interval_with_angles( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = spawn( "script_origin", ( 0, 0, 0 ) ); + + if ( isdefined( var_3 ) ) + { + thread loop_sound_delete( var_3, var_7 ); + self endon( var_3 ); + } + + var_7.origin = var_1; + var_7.angles = var_2; + + if ( var_5 >= var_6 ) + { + for (;;) + wait 0.05; + } + + if ( !soundexists( var_0 ) ) + { + for (;;) + wait 0.05; + } + + for (;;) + { + wait( randomfloatrange( var_5, var_6 ) ); + lock( "createfx_looper" ); + thread play_sound_in_space_with_angles( var_0, var_7.origin, var_7.angles, undefined ); + unlock( "createfx_looper" ); + } +} + +loop_sound_delete( var_0, var_1 ) +{ + var_1 endon( "death" ); + self waittill( var_0 ); + var_1 delete(); +} + +createloopeffect( var_0 ) +{ + var_1 = common_scripts\_createfx::createeffect( "loopfx", var_0 ); + var_1.v["delay"] = common_scripts\_createfx::getloopeffectdelaydefault(); + return var_1; +} + +createoneshoteffect( var_0 ) +{ + var_1 = common_scripts\_createfx::createeffect( "oneshotfx", var_0 ); + var_1.v["delay"] = common_scripts\_createfx::getoneshoteffectdelaydefault(); + return var_1; +} + +createexploder( var_0 ) +{ + var_1 = common_scripts\_createfx::createeffect( "exploder", var_0 ); + var_1.v["delay"] = common_scripts\_createfx::getexploderdelaydefault(); + var_1.v["exploder_type"] = "normal"; + return var_1; +} + +alphabetize( var_0 ) +{ + if ( var_0.size <= 1 ) + return var_0; + + var_1 = 0; + + for ( var_2 = var_0.size - 1; var_2 >= 1; var_2-- ) + { + var_3 = var_0[var_2]; + var_4 = var_2; + + for ( var_5 = 0; var_5 < var_2; var_5++ ) + { + var_6 = var_0[var_5]; + + if ( stricmp( var_6, var_3 ) > 0 ) + { + var_3 = var_6; + var_4 = var_5; + } + } + + if ( var_4 != var_2 ) + { + var_0[var_4] = var_0[var_2]; + var_0[var_2] = var_3; + } + } + + return var_0; +} + +is_later_in_alphabet( var_0, var_1 ) +{ + return stricmp( var_0, var_1 ) > 0; +} + +play_loop_sound_on_entity( var_0, var_1 ) +{ + var_2 = spawn( "script_origin", ( 0, 0, 0 ) ); + var_2 endon( "death" ); + thread delete_on_death( var_2 ); + + if ( isdefined( var_1 ) ) + { + var_2.origin = self.origin + var_1; + var_2.angles = self.angles; + var_2 linkto( self ); + } + else + { + var_2.origin = self.origin; + var_2.angles = self.angles; + var_2 linkto( self ); + } + + var_2 playloopsound( var_0 ); + self waittill( "stop sound" + var_0 ); + var_2 stoploopsound( var_0 ); + var_2 delete(); +} + +stop_loop_sound_on_entity( var_0 ) +{ + self notify( "stop sound" + var_0 ); +} + +delete_on_death( var_0 ) +{ + var_0 endon( "death" ); + self waittill( "death" ); + + if ( isdefined( var_0 ) ) + var_0 delete(); +} + +error( var_0 ) +{ + waitframe(); +} + +exploder( var_0, var_1, var_2 ) +{ + [[ level._fx.exploderfunction ]]( var_0, var_1, var_2 ); +} + +create_dvar( var_0, var_1 ) +{ + setdvarifuninitialized( var_0, var_1 ); +} + +void() +{ + +} + +tag_project( var_0, var_1 ) +{ + var_2 = self gettagorigin( var_0 ); + var_3 = self gettagangles( var_0 ); + var_4 = anglestoforward( var_3 ); + var_4 = vectornormalize( var_4 ) * var_1; + return var_2 + var_4; +} + +ter_op( var_0, var_1, var_2 ) +{ + if ( var_0 ) + return var_1; + + return var_2; +} + +create_lock( var_0, var_1 ) +{ + if ( !isdefined( var_1 ) ) + var_1 = 1; + + if ( !isdefined( level.lock ) ) + level.lock = []; + + var_2 = spawnstruct(); + var_2.max_count = var_1; + var_2.count = 0; + level.lock[var_0] = var_2; +} + +lock_exists( var_0 ) +{ + if ( !isdefined( level.lock ) ) + return 0; + + return isdefined( level.lock[var_0] ); +} + +lock( var_0 ) +{ + var_1 = level.lock[var_0]; + + while ( var_1.count >= var_1.max_count ) + var_1 waittill( "unlocked" ); + + var_1.count++; +} + +is_locked( var_0 ) +{ + var_1 = level.lock[var_0]; + return var_1.count > var_1.max_count; +} + +unlock_wait( var_0 ) +{ + thread unlock_thread( var_0 ); + wait 0.05; +} + +unlock( var_0 ) +{ + thread unlock_thread( var_0 ); +} + +unlock_thread( var_0 ) +{ + wait 0.05; + var_1 = level.lock[var_0]; + var_1.count--; + var_1 notify( "unlocked" ); +} + +get_template_level() +{ + var_0 = level.script; + + if ( isdefined( level.template_script ) ) + var_0 = level.template_script; + + return var_0; +} + +is_player_gamepad_enabled() +{ + if ( !level.console ) + { + var_0 = self usinggamepad(); + + if ( isdefined( var_0 ) ) + return var_0; + else + return 0; + } + + return 1; +} + +array_reverse( var_0 ) +{ + var_1 = []; + + for ( var_2 = var_0.size - 1; var_2 >= 0; var_2-- ) + var_1[var_1.size] = var_0[var_2]; + + return var_1; +} + +distance_2d_squared( var_0, var_1 ) +{ + return length2dsquared( var_0 - var_1 ); +} + +get_array_of_farthest( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + var_6 = get_array_of_closest( var_0, var_1, var_2, var_3, var_4, var_5 ); + var_6 = array_reverse( var_6 ); + return var_6; +} + +get_array_of_closest( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + if ( !isdefined( var_3 ) ) + var_3 = var_1.size; + + if ( !isdefined( var_2 ) ) + var_2 = []; + + var_6 = undefined; + + if ( isdefined( var_4 ) ) + var_6 = var_4 * var_4; + + var_7 = 0; + + if ( isdefined( var_5 ) ) + var_7 = var_5 * var_5; + + if ( var_2.size == 0 && var_3 >= var_1.size && var_7 == 0 && !isdefined( var_6 ) ) + return sortbydistance( var_1, var_0 ); + + var_8 = []; + + foreach ( var_10 in var_1 ) + { + var_11 = 0; + + foreach ( var_13 in var_2 ) + { + if ( var_10 == var_13 ) + { + var_11 = 1; + break; + } + } + + if ( var_11 ) + continue; + + var_15 = distancesquared( var_0, var_10.origin ); + + if ( isdefined( var_6 ) && var_15 > var_6 ) + continue; + + if ( var_15 < var_7 ) + continue; + + var_8[var_8.size] = var_10; + } + + var_8 = sortbydistance( var_8, var_0 ); + + if ( var_3 >= var_8.size ) + return var_8; + + var_17 = []; + + for ( var_18 = 0; var_18 < var_3; var_18++ ) + var_17[var_18] = var_8[var_18]; + + return var_17; +} + +drop_to_ground( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_1 ) ) + var_1 = 1500; + + if ( !isdefined( var_2 ) ) + var_2 = -12000; + + return physicstrace( var_0 + ( 0, 0, var_1 ), var_0 + ( 0, 0, var_2 ) ); +} + +add_destructible_type_function( var_0, var_1 ) +{ + if ( !isdefined( level.destructible_functions ) ) + level.destructible_functions = []; + + level.destructible_functions[var_0] = var_1; +} + +add_destructible_type_transient( var_0, var_1 ) +{ + if ( !isdefined( level.destructible_transient ) ) + level.destructible_transient = []; + + level.destructible_transient[var_0] = var_1; +} + +within_fov( var_0, var_1, var_2, var_3 ) +{ + var_4 = vectornormalize( var_2 - var_0 ); + var_5 = anglestoforward( var_1 ); + var_6 = vectordot( var_5, var_4 ); + return var_6 >= var_3; +} + +entity_path_disconnect_thread( var_0 ) +{ + self notify( "entity_path_disconnect_thread" ); + self endon( "entity_path_disconnect_thread" ); + self endon( "death" ); + level endon( "game_ended" ); + var_1 = 0; + self.forcedisconnectuntil = 0; + + for (;;) + { + var_2 = self.origin; + var_3 = waittill_any_timeout( var_0, "path_disconnect" ); + var_4 = 0; + var_5 = distancesquared( self.origin, var_2 ) > 0; + + if ( var_5 ) + var_4 = 1; + + if ( isdefined( var_3 ) && var_3 == "path_disconnect" ) + var_4 = 1; + + if ( gettime() < self.forcedisconnectuntil ) + var_4 = 1; + + foreach ( var_7 in level.characters ) + { + if ( isai( var_7 ) && distancesquared( self.origin, var_7.origin ) < 250000 ) + { + var_4 = 1; + self.forcedisconnectuntil = max( gettime() + 30000, self.forcedisconnectuntil ); + } + } + + if ( var_4 != var_1 || var_5 ) + { + if ( var_4 ) + self disconnectpaths(); + else + self connectpaths(); + + var_1 = var_4; + } + } +} + +make_entity_sentient_mp( var_0, var_1 ) +{ + if ( level.gametype == "aliens" && isdefined( level.aliens_make_entity_sentient_func ) ) + return self [[ level.aliens_make_entity_sentient_func ]]( var_0, var_1 ); + + if ( isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["bots_make_entity_sentient"] ) ) + return self [[ level.bot_funcs["bots_make_entity_sentient"] ]]( var_0, var_1 ); +} + +ai_3d_sighting_model( var_0 ) +{ + if ( isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["ai_3d_sighting_model"] ) ) + return self [[ level.bot_funcs["ai_3d_sighting_model"] ]]( var_0 ); +} + +set_basic_animated_model( var_0, var_1, var_2 ) +{ + if ( !isdefined( level.anim_prop_models ) ) + level.anim_prop_models = []; + + var_3 = tolower( getdvar( "mapname" ) ); + var_4 = 1; + + if ( string_starts_with( var_3, "mp_" ) ) + var_4 = 0; + + if ( var_4 ) + level.anim_prop_models[var_0]["basic"] = var_1; + else + level.anim_prop_models[var_0]["basic"] = var_2; +} + +getclosest( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_2 ) ) + var_2 = 500000; + + var_3 = undefined; + + foreach ( var_5 in var_1 ) + { + var_6 = distance( var_5.origin, var_0 ); + + if ( var_6 >= var_2 ) + continue; + + var_2 = var_6; + var_3 = var_5; + } + + return var_3; +} + +getfarthest( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_2 ) ) + var_2 = 500000; + + var_3 = 0; + var_4 = undefined; + + foreach ( var_6 in var_1 ) + { + var_7 = distance( var_6.origin, var_0 ); + + if ( var_7 <= var_3 || var_7 >= var_2 ) + continue; + + var_3 = var_7; + var_4 = var_6; + } + + return var_4; +} + +missile_settargetandflightmode( var_0, var_1, var_2 ) +{ + var_2 = ter_op( isdefined( var_2 ), var_2, ( 0, 0, 0 ) ); + self missile_settargetent( var_0, var_2 ); + + switch ( var_1 ) + { + case "direct": + self missile_setflightmodedirect(); + break; + case "top": + self missile_setflightmodetop(); + break; + } +} + +add_fx( var_0, var_1 ) +{ + if ( !isdefined( level._effect ) ) + level._effect = []; + + level._effect[var_0] = loadfx( var_1 ); +} + +array_sort_by_handler( var_0, var_1 ) +{ + for ( var_2 = 0; var_2 < var_0.size - 1; var_2++ ) + { + for ( var_3 = var_2 + 1; var_3 < var_0.size; var_3++ ) + { + if ( var_0[var_3] [[ var_1 ]]() < var_0[var_2] [[ var_1 ]]() ) + { + var_4 = var_0[var_3]; + var_0[var_3] = var_0[var_2]; + var_0[var_2] = var_4; + } + } + } + + return var_0; +} + +array_sort_with_func( var_0, var_1 ) +{ + for ( var_2 = 1; var_2 < var_0.size; var_2++ ) + { + var_3 = var_0[var_2]; + + for ( var_4 = var_2 - 1; var_4 >= 0 && ![[ var_1 ]]( var_0[var_4], var_3 ); var_4-- ) + var_0[var_4 + 1] = var_0[var_4]; + + var_0[var_4 + 1] = var_3; + } + + return var_0; +} diff --git a/data/dw/entitlement_config_tu14.info b/data/dw/entitlement_config_tu14.info new file mode 100644 index 0000000..1bae79a --- /dev/null +++ b/data/dw/entitlement_config_tu14.info @@ -0,0 +1,228 @@ +version 7 + +// Entitlement ID Ranges +// 0 - 299 ??? +// 300 - 399 Clan Entitlements +// 400 - 599 ??? +// 600 - 699 Clan War Entitlements +// 700 - 799 Generic Elite Entitlements + +// Number of keys to read from the key archive +keys_to_read 16 + +// unlocks in game - type, key index, bit, name, payload... +unlock 0 0 600 //clan wars demon_skull_p +unlock 0 1 601 //clan wars dead_ninja_p +unlock 0 2 602 //clan wars mummy_p +unlock 0 3 603 //clan wars skull_bow_p +unlock 0 4 604 //clan wars cyclops_skull_p +unlock 0 5 605 //clan wars dead_gnome_p +unlock 0 6 606 //clan wars gold_grill_p +unlock 0 7 607 //clan wars pirate_skull_p +unlock 0 8 608 //clan wars gargoyle_p +unlock 0 9 609 //clan wars vulture_p +unlock 0 10 610 //clan wars warrior_mask_p +unlock 0 11 611 //clan wars yeti_p +unlock 0 12 612 //clan wars dead_owl_p +unlock 0 13 613 //clan wars money_bags_p +unlock 0 14 614 //clan wars injured_octopus_p +unlock 0 15 615 //clan wars hotdog_p +unlock 0 16 616 //clan wars crab_p +unlock 0 17 617 //clan wars angry_robot_p +unlock 0 18 618 //clan wars triangle_dot_ret +unlock 0 19 619 //clan wars gold_chain_emb +unlock 0 20 620 //clan wars wing_emb +unlock 0 21 621 //clan wars brass_knuck_emb +unlock 0 22 622 //clan wars ninja_emb +unlock 0 25 623 //clan wars reaper head +unlock 0 26 624 //clan wars merc head +unlock 0 27 625 //clan wars body +unlock 0 28 460 //clan wars diamond division reticle +unlock 0 29 401 //clan wars diamond division camo +unlock 0 30 627 //clan wars diamond division assassin head +unlock 0 31 626 //clan wars diamond division savage head +unlock 0 32 628 //clan wars diamond division body + +unlock 3 0 700 //Download the mobile app +unlock 3 1 701 //Founder Skull + +unlock 3 4 500 //NEVERSOFT +unlock 3 3 501 //IW +unlock 3 5 502 //RAVEN +unlock 3 7 503 //HIGH_MOON +unlock 3 6 504 //BEACHHEAD + +unlock 13 0 209 //monster beast patch +unlock 13 2 210 //monster beast playercard +unlock 13 1 211 //monster viper patch +unlock 13 3 212 //monster viper playercard + +unlock 13 4 216 //riley / classic ghost head + +unlock 13 30 217 //watcher patch +unlock 13 31 213 //federation patch +unlock 13 32 215 //into the deep patch +unlock 13 33 214 //no man's land patch + +//Platform Unlocks +platform 200 255161 //team leader head +platform 201 255161 //team leader playercard +platform 202 255161 //team leader patch +platform 403 255161 //team leader camo +platform 451 255161 //team leader reticle + +platform 200 255160 //team leader head +platform 201 255160 //team leader playercard +platform 202 255160 //team leader patch +platform 403 255160 //team leader camo +platform 451 255160 //team leader reticle + +platform 206 255162 //insignia playercard +platform 205 255162 //insignia patch + +platform 216 255165 //classic ghost character + +platform 213 255167 //federation patch +platform 214 255168 //no mans land patch +platform 215 255169 //into the deep patch + +platform 207 255163 //digital hardened patch +platform 208 255163 //digital hardened playercard + +platform 217 255166 //Steam Patch - The Watcher + +platform 222 268100 //festive playercard +platform 221 268100 //festive patch +platform 410 268100 //festive camo +platform 453 268100 //festive reticle + +platform 550 268101 //wolf + +platform 551 277670 //extra slots + +platform 552 277671 // hero character - elias +platform 553 277672 // hero character - hesh +platform 554 277673 // hero character - merrick +platform 555 277674 // hero character - keegan +platform 556 277675 // hero character - price + +platform 557 281343 // Hazmat character +platform 558 281340 // Makarov Legend Pack +platform 559 281342 // Rorke Character +platform 560 281341 // Zakhaev Character + +platform 561 286632 // Soap Legend Pack +platform 562 286633 // Extinction Squad +platform 563 286634 // TF141 + +platform 490 277676 // Personalization pack 1 - Ducky +platform 491 277677 // Personalization pack 2 - Blood +platform 492 277678 // Personalization pack 3 - Inferno +platform 493 277679 // Personalization pack 4 - Kittens + +platform 494 281344 // Personalization pack 5 +platform 495 281345 // Personalization pack 6 +platform 496 281346 // Personalization pack 7 +platform 497 281347 // Personalization pack 8 +platform 498 286630 // Personalization pack 9 +platform 499 286631 // Personalization pack 10 + +platform 510 295430 // Personalization pack 11 +platform 511 295431 // Personalization pack 12 +platform 512 295432 // Personalization pack 13 +platform 513 295433 // Personalization pack 14 +platform 515 295434 // Personalization pack 15 +platform 516 295435 // Personalization pack 16 + +platform 517 295439 // Personalization pack 17 +platform 518 295440 // Personalization pack 18 +platform 519 301111 // Personalization pack 19 +platform 520 301112 // Personalization pack 20 +platform 521 301113 // Personalization pack 21 +platform 522 301114 // Personalization pack 22 +platform 523 301110 // Personalization pack Flags + +platform 564 295436 // Spectrum Character +platform 565 295437 // Astronaut Character +platform 566 295438 // Resistance Squad + +platform 567 309870 // Bluntforce Character +platform 568 309871 // Inferno Character +platform 569 309872 // Bling Character + +platform 480 259250 //dlc gun 1 +platform 480 301116 //dlc gun 1 +platform 481 259250 //dlc gun 1 +platform 481 301116 //dlc gun 1 + +platform 482 259251 //Ripper from Devastation +platform 482 255161 //Ripper from Season Pass +platform 482 301115 //Ripper from mDLC + +//Clan Entitlements - ID 300 - 399 - type, bit, entitlement id +clan 0 300 +clan 0 301 +clan 1 302 +clan 2 303 +clan 3 304 +clan 3 305 +clan 3 306 +clan 4 307 +clan 4 308 +clan 4 309 +clan 5 310 +clan 5 311 +clan 6 312 +clan 7 313 +clan 8 314 +clan 8 315 +clan 8 316 +clan 9 317 +clan 10 318 +clan 10 319 +clan 10 320 +clan 10 321 +clan 10 322 +clan 11 323 +clan 12 324 +clan 13 325 +clan 13 326 +clan 13 327 +clan 13 328 +clan 13 329 +clan 14 330 +clan 15 331 +clan 15 332 +clan 15 333 +clan 16 334 +clan 16 335 +clan 16 336 +clan 16 337 +clan 16 338 +clan 17 339 +clan 18 340 +clan 19 341 +clan 19 342 +clan 19 343 +clan 19 344 +clan 20 345 +clan 20 346 +clan 21 347 +clan 21 348 +clan 21 349 +clan 22 350 +clan 23 351 +clan 24 352 +clan 25 353 +clan 26 354 +clan 26 355 +clan 26 356 +clan 26 357 +clan 27 358 + +//Clan Level Challenges - type, required level, challenge id +clanlevelchallenge 23 ch_cam_clan_02 // Kiss of Death Camo + +//Clan War Challenges - type, key index, bit offset, challenge id +entitlementchallenge 0 18 ch_ret_clan // clan wars reticle - Triad +entitlementchallenge 0 24 ch_cam_clan_01 // clan wars camo - Body Count diff --git a/data/dw/mm.cfg b/data/dw/mm.cfg new file mode 100644 index 0000000..bbb75d7 --- /dev/null +++ b/data/dw/mm.cfg @@ -0,0 +1,2 @@ +VERSION 5 +XX 0 D100 0 P50 0 G5 4 F 6 H 8 P75 16 P100 16 S 24 P120 32 P150 40 P-1 10 M192 20 M48 \ No newline at end of file diff --git a/data/dw/newsfeed.txt b/data/dw/newsfeed.txt new file mode 100644 index 0000000..28de37c --- /dev/null +++ b/data/dw/newsfeed.txt @@ -0,0 +1,162 @@ +article 1 +header "FLAGS OF THE WORLD PACK" +body "Show your national pride with individual patches, playercards, and backgrounds for England, France, Germany, Italy, Spain, Mexico, USA, Brazil, Australia, Japan, UK, Russia, Netherlands, Portugal, Colombia, Argentina, Canada, Ireland, and Sweden. + +Plus, go international in any firefight with a unique reticle and flags of the world weapon camo. + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_flags.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack40 +localJPEGImage + +article 2 +header "CALL OF DUTY APP" +body "The Call of Duty App is everything you need to keep track of your Ghosts experience on the go. + +Get unique info on Clan Wars: A brand new game mode that connects directly to Call of Duty®: Ghosts multiplayer, where clans compete against each other for additional XP and in-game content. + +Communicate via the Rally Up and Clan Chat features, to keep in touch with your friends and Clan members." +type news +image img_sf_generic_news2 +imagewidth 320 +imageheight 320 + +article 3 +header "PLAY HOW YOU WANT WITH EXTRA LOADOUT SLOTS" +body "You can increase the number of loadout slots from 6 to 10, so you can take even more options into battle. Never get caught with the wrong gear and give yourself great flexibility by creating different loadouts for different situations. + +Top Tip - Set up different characters for different game modes, that way you can select the right man for the job. + +Another Top Tip - With all the extra loadouts, set up variations of your favorite loadout so you’re always ready for the unexpected. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_extra_slots.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack2 +localJPEGImage + +article 4 +header "DROP ZONE IS BACK!" +body "We are bringing this fan favorite mode from Call of Duty: Modern Warfare 3 to Call of Duty: Ghosts Multiplayer. + +Fight to take control of the Drop Zone marked with a red smoke grenade, a location where Care Packages are regularly delivered by air drops. + +This mode gives you multiple chances to change the game with awesome killstreaks like the Gryphon, Juggernaut, or the earth shattering Loki. + +Control the Drop Zone, collect killstreaks, and wreak havoc on the opposing team!" +type news +image img_squadmode_03 +imagewidth 320 +imageheight 176 + +article 5 +header "THE REAL ORIGINS OF EXTINCTION" +body "Find out the origins of the Extinction story by collecting hidden intel items in Episode 1: Nightfall. + +Find out the real story of Dr. Cross, Archer and discover more secrets from Project Nightfall. + +Episode 1: Nightfall is part of DLC 1: Onslaught, available now. + +Visit the in-game store to find out more." +type item +image bg_large_073 +imagewidth 320 +imageheight 320 +data dlc3 + +article 6 +header "NEW CUSTOMIZATION CONTENT" +body "New content is being released all the time. Personalize your look and your loadout with customization items. + +- Special Characters: Customize your look head-to-toe in Multiplayer, Squads and Extinction. + +- Personalization Packs: Uniquely themed weapon camo, reticle, patch, playercard and background. + +- Legend Packs: A Special Character and themed Personalization Pack for a legendary figure in Call of Duty lore. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_07.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack17 +localJPEGImage + +article 7 +header "NEW TO EXTINCTION - THE ARMORY" +body "Spend Teeth in the Armory to purchase upgrades for classes and equipment. + +Earn Teeth by completing Extinction missions. Bonus Teeth are awarded for completing with a relic, completing in Hardcore mode, or helping other players complete a mission for the first time. + +You can also earn teeth by killing aliens in both Extinction and Chaos Mode. + +Upgrades include the Weapon Specialist's Infinite Ammo Ability and the Medic's Energy Field, instantly heal and revive anyone within its perimeter!" +type news +image img_sf_extinction_armory +imagewidth 320 +imageheight 320 + +article 8 +header "CAN YOU SURVIVE THE CHAOS?" +body "Extinction's Chaos Mode is an all-new, adrenaline pumping game type that pits 1-4 players against a never ending alien onslaught. + +Keep the combo meter filled by damaging aliens, collecting weaponry or upgrades, and making use of your abilities. Combos provide players with an ever-expanding set of perks such as Fast Health Regen, Gas Mask, and Stopping Power. + +Special bonus drops provide new ability upgrades including the Tank Class Skill and the Venom-X that further your arsenal and overall score potential. + +The aliens are ready, are you?" +type news +image img_sf_extinction_chaos +imagewidth 320 +imageheight 320 + +article 9 +header "WHAT'S GOING ON WITH YOUR CLAN?" +body "Check out what your Clan is up to in-game via Clan Details inside the Barracks. See what's going on with other players' Clans by checking out View Clan when you select them in the lobby. + +Get even more details on your Clan via the Call of Duty App, available now on the App Store, Google Play and Windows Store. + +Not in a Clan? Create one now via the Barracks and invite your friends straight from the game." +type news +image img_squadmode_02 +imagewidth 320 +imageheight 176 + +article 10 +header "DRILL INSTRUCTOR VOICE PACK" +body "Multiplayer returns to boot camp with the all-new Drill Instructor Voice Pack voiced by the one and only R. Lee Ermey, aka The Gunny. + +Swap out your in-game alerts with ones that will get you back into top combat shape. + +Now, drop down and give me twenty! + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_drill_sergeant.jpg +imagewidth 320 +imageheight 160 +data dlc10 +localJPEGImage + +article 11 +header "TRY REINFORCE" +body "Reinforce is a new game mode where you annihilate the enemy team or capture points to win a match. + +You only respawn if a teammate captures a point, so be careful out there! + +This new game mode is now live in our Multiplayer playlist. + +Enjoy!" +type news +image bg_large_045 +imagewidth 320 +imageheight 320 \ No newline at end of file diff --git a/data/dw/playlists_tu14.aggr b/data/dw/playlists_tu14.aggr new file mode 100644 index 0000000..59d8f73 Binary files /dev/null and b/data/dw/playlists_tu14.aggr differ diff --git a/data/dw/social_tu14.cfg b/data/dw/social_tu14.cfg new file mode 100644 index 0000000..e5d1b14 --- /dev/null +++ b/data/dw/social_tu14.cfg @@ -0,0 +1,139 @@ +// Demonware offline additions. + +set netinfo_logging 0 + +set theater_active 1 +set prestige_shop_active 1 +set elite_clan_delay -1 +set elite_clan_division_icon_active 1 +set dw_presence_coop_join_active 1 +set dw_shared_presence_active 1 +set splitscreen_online_enabled 1 +set dw_leaderboard_write_active 1 +set matchdata_active 1 +set pm_gamesetup_mode_altmodes 1 +set pm_gamesetup_mode_altmodes_dropzone 1 +set pm_gamesetup_mode_altmodes_teamjug 1 +set pm_gamesetup_mode_altmodes_jug 1 +set pm_gamesetup_mode_altmodes_infected 1 +set pm_gamesetup_mode_altmodes_oneinthechamber 1 +set pm_gamesetup_mode_altmodes_mugger 1 +set pm_gamesetup_options_createdefaultclass 1 +set pm_gamesetup_options_customclassrestrictions 1 +set motd_store_link 0 +set livestreaming_active 0 +set screenshots_active 1 +set ca_intra_only 0 +set dc_lobbymerge 1 + +// DW Delay values +set facebook_active 0 +set facebook_friends_active 0 +set facebook_upload_video_active 0 +set facebook_upload_photo_active 0 +set facebook_delay -1 +set facebook_max_retry_time 30000 +set facebook_retry_step 1000 +set facebook_friends_max_retry_time 30000 +set facebook_friends_retry_step 1000 + +set entitlements_active 1 +set entitlements_delay -1 +set entitlements_config_file_max_retry_time 30000 +set entitlements_config_file_retry_step 1000 +set entitlements_key_archive_max_retry_time 30000 +set entitlements_key_archive_retry_step 1000 + +set enable_eliteCACDownload 0 +set elite_edl 0 +set elite_edl_xl 0 +set elite_clan_set_private_member_profile_max_retry_time 30000 + +set userGroup_active 1 +set elite_clan_active 0 +set elite_clan_remote_view_active 0 +set allow_online_squads 1 +set allow_cod_anywhere 0 + +set allow_secondscreen 1 +set allow_secondscreen_ingame_send 1 +set allow_secondscreen_ingame_recv 1 + +set dw_presence_active 1 +set dw_presence_put_delay 5000 +set dw_presence_put_rate 60000 +set dw_presence_get_delay 5000 +set dw_presence_get_rate 120000 +set dw_shared_presence_put_rate 300000 + +set iotd_active 1 +set igs_swp 1 +set igs_shp 1 +set igs_svp 1 +set igs_sve 1 +set igs_svs 1 +set igs_svr 1 +set igs_fo 1 +set igs_s1 1 +set igs_td 1 +set igs_sosp 1 +set igs_swap 1 +set igs_crossgame 1 +set igs_announcer 3 +set igs_smappacks 1 +set extendedLoadoutsEnable 1 +set extinction_map_selection_enabled 1 +set igs_sripper 1 + +set num_available_map_packs 4 + +set mm_skill_enforcement 0 + +// set dsping_dc_0 "101,New,40.54,-74.47,108.61.88.37:10000,108.61.89.108:40000" +// set dsping_dc_1 "102,Chi,41.88,-87.63,108.61.238.217:40000,108.61.238.138:40000" +// set dsping_dc_2 "103,Dal,32.78,-96.8,108.61.239.113:40000,108.61.239.173:40000" +// set dsping_dc_3 "104,Sea,47.61,-122.33,108.61.233.100:40000,108.61.233.106:40000" +// set dsping_dc_4 "105,Los,34.05,-118.24,108.61.234.129:40000,108.61.234.204:40000" +// set dsping_dc_5 "106,Atl,33.75,-84.39,108.61.236.152:40000,108.61.236.112:40000" +// set dsping_dc_6 "107,Ams,52.37,4.9,173.199.64.6:40000,173.199.109.10:40000" +// set dsping_dc_7 "108,Lon,51.51,-0.12,108.61.230.152:40000,108.61.230.145:40000" +// set dsping_dc_8 "109,Fra,50.11,8.68,195.122.135.238:40000,195.122.135.97:40000" +// set dsping_dc_9 "111,Tam,27.7,-82.58,4.79.145.189:40000,4.79.145.108:40000" +// set dsping_dc_10 "112,San,37.34,-121.89,108.61.235.100:40000,108.61.235.179:40000" +// set dsping_dc_11 "113,St.,38.63,-90.2,108.61.232.122:40000,108.61.232.110:40000" +// set dsping_dc_12 "115,Mon,45.51,-73.55,108.61.231.117:40000,108.61.231.106:40000" +// set dsping_dc_13 "119,Syd,-33.87,151.21,108.61.227.109:40000,108.61.227.115:40000" +// set dsping_dc_14 "121,Den,56.04,9.93,108.61.106.31:40000,108.61.106.30:40000" +// set dsping_dc_15 "124,Par,48.86,2.35,108.61.237.152:40000,108.61.237.150:40000" +// set dsping_dc_16 "125,Tok,35.69,139.69,173.199.82.235:40000,173.199.82.237:40000" +// set dsping_dc_17 "126,Mos,55.76,37.62,173.199.67.27:40000,173.199.67.29:40000" +// set dsping_dc_18 "127,War,52.23,21.01,173.199.83.227:40000,173.199.83.236:40000" +// set dsping_dc_19 "129,Mad,40.42,-3.7,93.93.65.202:40000,93.93.65.203:40000" +// set dsping_dc_20 "130,Sao,-23.55,-46.64,189.1.174.20:40000,189.1.174.184:40000" +// set dsping_dc_21 "131,Cap,-33.92,18.42,197.84.209.11:40000,197.84.209.12:40000" +// set dsping_dc_22 "132,Joh,-26.2,28.05,197.80.212.5:40000,197.80.212.7:40000" +// set dsping_dc_23 "133,Mil,45.47,9.19,95.141.40.109:40000,95.141.40.105:40000" + +set ds_serverConnectTimeout 2000 +set ds_serverAcquireTimeout 2000 +set ds_introRequestTimeout 2000 +set ds_serverListExpiryPeriod 60000 +set ds_serverAcquisitionPeriod 7000 + +// Social Feed Controls +set social_feed_news_active 1 +set social_feed_clans_active 1 +set social_feed_squads_active 1 +set social_feed_social_active 1 +set social_feed_motd_active 1 + +set extinction_cac_enabled 1 +set extinction_hardcore_enabled 1 +set extinction_intel_enabled 1 +set extinction_tokens_enabled 1 + +set past_title_data_active 1 +set past_title_data_read_failure_interval_hours 24 +set past_title_data_read_success_interval_hours 72 + +set live_voting_active 1 diff --git a/data/maps/mp/alien/_drill.gsc b/data/maps/mp/alien/_drill.gsc new file mode 100644 index 0000000..063a7a4 --- /dev/null +++ b/data/maps/mp/alien/_drill.gsc @@ -0,0 +1,1727 @@ +// IW6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool + +init_drill() +{ + common_scripts\utility::flag_init( "drill_detonated" ); + common_scripts\utility::flag_init( "drill_destroyed" ); + common_scripts\utility::flag_init( "drill_drilling" ); + level.drill_use_trig = getent( "drill_pickup_trig", "targetname" ); + + if ( isdefined( level.drill_use_trig ) ) + level.drill_use_trig.original_origin = level.drill_use_trig.origin; + + level.drill_id = 0; + level.drill_marker_id = 1; + level.drill = undefined; + level.drill_carrier = undefined; + init_fx(); + init_drill_drop_loc(); + thread drill_think(); + level thread drill_out_of_playable(); +} + +drill_out_of_playable() +{ + level endon( "game_ended" ); + var_0 = getentarray( "trigger_hurt", "classname" ); + + for (;;) + { + if ( !isdefined( level.drill ) ) + { + wait 0.5; + continue; + } + + foreach ( var_2 in var_0 ) + { + if ( !isdefined( var_2.script_noteworthy ) || var_2.script_noteworthy != "out_of_playable" ) + continue; + + if ( level.drill istouching( var_2 ) ) + { + level.drill delete(); + + assertex( isdefined( level.last_drill_pickup_origin ) && isdefined( level.last_drill_pickup_angles ), "Last drill pickup spot was not defined" ); + playfx( level._effect["alien_teleport"], level.last_drill_pickup_origin ); + playfx( level._effect["alien_teleport_dist"], level.last_drill_pickup_origin ); + drop_drill( level.last_drill_pickup_origin, level.last_drill_pickup_angles ); + + foreach ( var_4 in level.players ) + var_4 maps\mp\_utility::setlowermessage( "drill_overboard", &"ALIEN_COLLECTIBLES_DRILL_OUTOFPLAY", 4 ); + } + } + + wait 0.1; + } +} + +init_drill_drop_loc() +{ + level.drill_locs = []; + level.drill_locs = common_scripts\utility::getstructarray( "bomb_drop_loc", "targetname" ); +} + +init_fx() +{ + level._effect["drill_laser_contact"] = loadfx( "vfx/gameplay/alien/vfx_alien_drill_laser_contact" ); + level._effect["drill_laser"] = loadfx( "vfx/gameplay/alien/vfx_alien_drill_laser" ); + level._effect["stronghold_explode_med"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_sentry_gun_explosion" ); + level._effect["stronghold_explode_large"] = loadfx( "fx/explosions/aerial_explosion" ); + level._effect["alien_hive_explode"] = loadfx( "fx/explosions/alien_hive_explosion" ); + level.spawnglowmodel["friendly"] = "mil_emergency_flare_mp"; + level.spawnglow["friendly"] = loadfx( "fx/misc/flare_ambient_green" ); +} + +drill_think() +{ + level endon( "game_ended" ); + + while ( !isdefined( level.players ) || level.players.size < 1 ) + wait 0.05; + + level.drill_health_hardcore = 1250; + + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.drill_health_hardcore = 2000; + + level thread drill_threat_think(); + var_0 = ( 2822.27, -196, 524.068 ); + var_1 = common_scripts\utility::getstruct( "drill_loc", "targetname" ); + + if ( isdefined( var_1 ) ) + var_0 = var_1.origin; + + var_2 = ( 1.287, 0.995, -103.877 ); + + if ( isdefined( var_1 ) && isdefined( var_1.angles ) ) + var_2 = var_1.angles; + + level waittill( "spawn_intro_drill", var_3, var_4 ); + var_5 = 1; + + if ( isdefined( level.initial_drill_origin ) && isdefined( level.initial_drill_angles ) ) + { + var_0 = level.initial_drill_origin; + var_2 = level.initial_drill_angles; + var_5 = 0; + } + + if ( isdefined( var_3 ) && isdefined( var_4 ) ) + { + var_0 = var_3; + var_2 = var_4; + var_5 = 0; + } + + var_6 = undefined; + + for (;;) + { + spawn_drill_raw( "mp_laser_drill", var_0, var_2, var_6, var_5 ); + var_5 = 1; + level waittill( "new_drill", var_0, var_2, var_6 ); + assertex( isdefined( drop_loc ), "Drill dropped at invalid position" ); + + wait 0.05; + } +} + +drop_drill( var_0, var_1, var_2 ) +{ + level notify( "new_drill", var_0, var_1, var_2 ); +} + +spawn_drill_raw( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( !isdefined( var_4 ) ) + var_4 = 1; + + level.drill_carrier = undefined; + + if ( isdefined( level.drill ) ) + { + level.drill delete(); + level.drill = undefined; + } + + level.drill = spawn( "script_model", var_1 ); + level.drill setmodel( var_0 ); + level.drill set_drill_icon(); + level.drill.state = "idle"; + + if ( var_4 ) + level.drill thread angles_to_ground( var_1, var_2, ( 0, 0, -4 ) ); + else + level.drill.angles = var_2; + + if ( common_scripts\utility::flag_exist( "intro_sequence_complete" ) && !common_scripts\utility::flag( "intro_sequence_complete" ) ) + common_scripts\utility::flag_wait( "intro_sequence_complete" ); + + if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) ) + maps\mp\alien\_outline_proto::add_to_drill_preplant_watch_list( level.drill ); + + if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) ) + level.drill thread drill_pickup_listener( var_3 ); + + level notify( "drill_spawned" ); +} + +enable_alt_drill_pickup( var_0 ) +{ + assert( isdefined( level.drill_use_trig ) ); + level.drill_use_trig.origin = var_0.origin + ( 0, 0, 24 ); +} + +disable_alt_drill_pickup() +{ + assert( isdefined( level.drill_use_trig ) ); + level.drill_use_trig.origin = level.drill_use_trig.original_origin; +} + +drill_pickup_listener( var_0 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + level endon( "new_drill" ); + + if ( isdefined( level.drill_use_trig ) ) + var_1 = level.drill_use_trig; + else + var_1 = self; + + if ( !maps\mp\alien\_utility::is_true( level.prevent_drill_pickup ) ) + { + if ( isdefined( level.drill_use_trig ) ) + level.drill_use_trig enable_alt_drill_pickup( self ); + else + var_1 makeusable(); + } + + var_1 setcursorhint( "HINT_ACTIVATE" ); + var_1 sethintstring( &"ALIEN_COLLECTIBLES_PICKUP_BOMB" ); + + for (;;) + { + var_1 waittill( "trigger", var_2 ); + + if ( var_2 maps\mp\alien\_utility::is_holding_deployable() ) + { + var_2 maps\mp\_utility::setlowermessage( "cant_buy", &"ALIEN_COLLECTIBLES_PLAYER_HOLDING", 3 ); + continue; + } + + if ( var_2 getstance() == "prone" || var_2 getstance() == "crouch" ) + { + var_2 maps\mp\_utility::setlowermessage( "change_stance", &"ALIENS_PATCH_CHANGE_STANCE", 3 ); + continue; + } + + if ( maps\mp\alien\_utility::is_true( var_2.picking_up_item ) ) + continue; + + if ( maps\mp\alien\_utility::is_true( var_2.iscarrying ) ) + continue; + + var_2.has_special_weapon = 1; + var_2 common_scripts\utility::_disableusability(); + var_2 thread delayed_enable_usability(); + + if ( isplayer( var_2 ) ) + break; + } + + if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) ) + maps\mp\alien\_outline_proto::remove_from_drill_preplant_watch_list( level.drill ); + + if ( isdefined( level.drill_use_trig ) ) + level.drill_use_trig disable_alt_drill_pickup(); + + level notify( "drill_pickedup", var_2 ); + self playsound( "extinction_item_pickup" ); + level.drill_carrier = var_2; + level.last_drill_pickup_origin = common_scripts\utility::drop_to_ground( self.origin, 16, -32 ); + level.last_drill_pickup_angles = self.angles; + level.drill_carrier set_drill_icon( 1 ); + self.state = "carried"; + var_2 thread drop_drill_on_death(); + var_2 thread drop_drill_on_disconnect(); + var_2.lastweapon = var_2 getcurrentweapon(); + var_2 maps\mp\_utility::_giveweapon( "alienbomb_mp" ); + var_2 switchtoweapon( "alienbomb_mp" ); + var_2 disableweaponswitch(); + var_2 common_scripts\utility::_disableoffhandweapons(); + + if ( isdefined( var_0 ) ) + var_0 delete(); + + var_2 notify( "kill_spendhint" ); + var_2 notify( "dpad_cancel" ); + self delete(); +} + +delayed_enable_usability() +{ + self endon( "death" ); + self endon( "disconnect" ); + wait 1; + common_scripts\utility::_enableusability(); +} + +drop_drill_on_death() +{ + level endon( "game_ended" ); + level endon( "new_drill" ); + level endon( "drill_planted" ); + level endon( "drill_dropping" ); + self notify( "watching_drop_drill_on_death" ); + self endon( "watching_drop_drill_on_death" ); + common_scripts\utility::waittill_either( "death", "last_stand" ); + self takeweapon( "alienbomb_mp" ); + self enableweaponswitch(); + self switchtoweapon( self.lastweapon ); + common_scripts\utility::_enableoffhandweapons(); + level.drill_carrier = undefined; + var_0 = getgroundposition( self.last_death_pos + ( 0, 0, 4 ), 8 ); + var_1 = self.angles; + + if ( maps\mp\alien\_utility::is_true( self.kill_trigger_event_processed ) ) + { + var_2 = common_scripts\utility::getclosest( self.origin, level.killtriggerspawnlocs ); + var_0 = getgroundposition( var_2.origin + ( 0, 0, 4 ), 8 ); + + if ( !isdefined( var_2.angles ) ) + var_2.angles = ( 0, 0, 0 ); + + var_1 = var_2.angles; + } + + drop_drill( var_0, var_1 ); +} + +drop_drill_on_disconnect() +{ + level endon( "drill_dropping" ); + level endon( "game_ended" ); + self endon( "death" ); + self endon( "last_stand" ); + self waittill( "disconnect" ); + playfx( level._effect["alien_teleport"], level.last_drill_pickup_origin ); + playfx( level._effect["alien_teleport_dist"], level.last_drill_pickup_origin ); + drop_drill( level.last_drill_pickup_origin, level.last_drill_pickup_angles ); + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1 == self ) + continue; + + var_1 maps\mp\_utility::setlowermessage( "drill_overboard", &"ALIEN_COLLECTIBLES_DRILL_OUTOFPLAY", 4 ); + } +} + +teleport_drill( var_0 ) +{ + wait 5; + + if ( isdefined( level.drill ) && !isdefined( level.drill_carrier ) && distance( var_0, level.drill.origin ) > 1250 ) + { + var_0 = common_scripts\utility::drop_to_ground( var_0, 16, -64 ); + level.drill angles_to_ground( var_0, level.drill.angles, ( 0, 0, -4 ) ); + level.drill set_drill_icon(); + enable_alt_drill_pickup( level.drill ); + } +} + +drilling( var_0, var_1 ) +{ + if ( isdefined( level.set_drill_state_drilling_override ) ) + self thread [[ level.set_drill_state_drilling_override ]]( var_0, var_1 ); + else + { + self endon( "stop_listening" ); + self endon( "drill_complete" ); + thread set_drill_state_plant( var_0, var_1 ); + level.drill endon( "death" ); + level.drill.owner = var_1; + level.encounter_name = self.target; + level.drill.start_time = gettime(); + common_scripts\utility::flag_set( "drill_drilling" ); + level.drill common_scripts\utility::waittill_any_timeout( 5, "drill_finished_plant_anim" ); + init_drilling_parameters(); + level.drill.start_time = gettime(); + thread set_drill_state_run( var_1 ); + maps\mp\alien\_hive::hive_play_drill_planted_animations(); + level.drill waittill( "offline", var_2, var_3 ); + thread set_drill_state_offline(); + common_scripts\utility::flag_set( "drill_destroyed" ); + wait 2; + maps\mp\gametypes\aliens::alienendgame( "axis", maps\mp\alien\_hud::get_end_game_string_index( "drill_destroyed" ) ); + } +} + +set_drill_attack_setup() +{ + var_0 = []; + var_0["brute"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( 0, 1, 0 ), "alien_drill_attack_drill_F_enter", "alien_drill_attack_drill_F_loop", "alien_drill_attack_drill_F_exit", "attack_drill_front", "attack_drill" ); + var_0["brute"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_drill_attack_drill_R_enter", "alien_drill_attack_drill_R_loop", "alien_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" ); + var_0["brute"][2] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_drill_attack_drill_L_enter", "alien_drill_attack_drill_L_loop", "alien_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" ); + var_0["goon"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( 0, 1, 0 ), "alien_goon_drill_attack_drill_F_enter", "alien_goon_drill_attack_drill_F_loop", "alien_goon_drill_attack_drill_F_exit", "attack_drill_front", "attack_drill" ); + var_0["goon"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_goon_drill_attack_drill_R_enter", "alien_goon_drill_attack_drill_R_loop", "alien_goon_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" ); + var_0["goon"][2] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_goon_drill_attack_drill_L_enter", "alien_goon_drill_attack_drill_L_loop", "alien_goon_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" ); + var_1[0] = "offline"; + var_1[1] = "death"; + var_1[2] = "drill_complete"; + var_1[3] = "destroyed"; + maps\mp\alien\_utility::set_synch_attack_setup( var_0, 1, var_1, undefined, ::drill_synch_attack_play_anim, ::drill_synch_attack_play_anim, ::drill_synch_attack_exit, "drill" ); +} + +drill_synch_attack_play_anim( var_0 ) +{ + level.drill scriptmodelclearanim(); + level.drill scriptmodelplayanim( var_0 ); +} + +drill_synch_attack_exit( var_0, var_1 ) +{ + if ( isdefined( var_0 ) ) + { + level.drill scriptmodelclearanim(); + level.drill scriptmodelplayanim( var_0 ); + wait( var_1 ); + } + + if ( isalive( level.drill ) && !common_scripts\utility::flag( "drill_detonated" ) ) + { + level.drill scriptmodelclearanim(); + level.drill scriptmodelplayanim( "alien_drill_loop" ); + } +} + +use_alternate_drill() +{ + return 1; +} + +watch_to_repair( var_0 ) +{ + self endon( "drill_complete" ); + self endon( "death" ); + var_0 endon( "hive_dying" ); + wait 5.0; + self makeunusable(); + var_1 = 100; + var_2 = 1000; + var_3 = 4000; + var_4 = 2000; + + for (;;) + { + self makeunusable(); + + for (;;) + { + var_5 = ( self.health - 20000 ) / level.drill_health_hardcore; + + if ( var_5 < 0.75 ) + break; + + wait 1; + } + + self makeusable(); + + if ( isdefined( level.drill_repair ) ) + self sethintstring( level.drill_repair ); + else + self sethintstring( &"ALIEN_COLLECTIBLES_DRILL_REPAIR" ); + + self waittill( "trigger", var_6 ); + + if ( maps\mp\alien\_utility::is_true( var_6.iscarrying ) ) + continue; + + self sethintstring( "" ); + var_7 = level.players.size; + var_6.isrepairing = 1; + level notify( "dlc_vo_notify", "drill_repair", var_6 ); + var_8 = int( var_3 * var_6 maps\mp\alien\_perk_utility::perk_getdrilltimescalar() * var_6.drillspeedmodifier ); + + if ( var_7 > 1 ) + var_8 = int( ( var_3 + ( var_7 - 1 ) * var_4 ) * var_6 maps\mp\alien\_perk_utility::perk_getdrilltimescalar() * var_6.drillspeedmodifier ); + + var_9 = useholdthink( var_6, var_8 ); + + if ( !var_9 ) + { + var_6.isrepairing = 0; + continue; + } + + if ( isdefined( level.drill_sfx_lp ) ) + { + if ( isdefined( level.drill_overheat_lp_02 ) ) + level.drill_overheat_lp_02 stoploopsound(); + + if ( !var_0 maps\mp\alien\_utility::is_door() && !var_0 maps\mp\alien\_utility::is_door_hive() && level.script != "mp_alien_dlc3" ) + { + if ( level.script == "mp_alien_last" ) + level.drill_sfx_lp playloopsound( "alien_conduit_on_lp" ); + else + level.drill_sfx_lp playloopsound( "alien_laser_drill_lp" ); + } + } + + level notify( "dlc_vo_notify", "drill_repaired", var_6 ); + level notify( "drill_repaired" ); + var_6.isrepairing = 0; + var_0 thread drill_reset_bbprint( var_6 ); + var_6 maps\mp\alien\_persistence::give_player_currency( var_1 ); + self.health = level.drill_health_hardcore + 20000; + level.drill_last_health = level.drill_health_hardcore + 20000; + update_drill_health_hud(); + var_6.isrepairing = 0; + var_6 maps\mp\alien\_persistence::eog_player_update_stat( "drillrestarts", 1 ); + wait 1.0; + } +} + +set_drill_state_plant( var_0, var_1 ) +{ + if ( isdefined( level.drill ) ) + { + level.drill delete(); + level.drill = undefined; + } + + level.drill = spawn( "script_model", var_0 ); + level.drill setmodel( "mp_laser_drill" ); + level.drill.state = "planted"; + level.drill.angles = self.angles; + + if ( !maps\mp\alien\_utility::is_door() ) + level.drill set_drill_attack_setup(); + + if ( isdefined( level.drill_attack_setup_override ) ) + level.drill [[ level.drill_attack_setup_override ]](); + + var_2 = 150; + + if ( use_alternate_drill() ) + { + var_2 = level.drill_health_hardcore; + level.drill thread watch_to_repair( self ); + } + + level.drill.maxhealth = 20000 + var_2; + level.drill.health = int( 20000 + var_2 * var_1 maps\mp\alien\_perk_utility::perk_getdrillhealthscalar() ); + level.drill thread watch_drill_health_for_challenge(); + + if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) ) + maps\mp\alien\_outline_proto::add_to_outline_drill_watch_list( level.drill, 0 ); + + thread sfx_drill_plant(); + self.depth_marker = gettime(); + level thread maps\mp\alien\_music_and_dialog::playvoforbombplant( var_1 ); + destroy_drill_icon(); + + if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() ) + { + level.drill scriptmodelplayanim( "alien_drill_enter" ); + wait 4; + } + else + wait 0.5; + + level.drill notify( "drill_finished_plant_anim" ); +} + +watch_drill_health_for_challenge() +{ + self endon( "drill_complete" ); + self endon( "death" ); + + for (;;) + { + var_0 = ( level.drill.health - 20000 ) / level.drill_health_hardcore; + + if ( var_0 < 0.5 ) + { + maps\mp\alien\_challenge::update_challenge( "no_stuck_drill", 0 ); + break; + } + + wait 1; + } +} + +drill_threat_think() +{ + level endon( "game_ended" ); + var_0 = 1; + + for (;;) + { + if ( !isdefined( level.drill ) || !issentient( level.drill ) || !isalive( level.drill ) ) + { + wait( var_0 ); + continue; + } + + if ( use_alternate_drill() ) + { + self.drill.threatbias = -1000; + wait( var_0 ); + continue; + } + + var_1 = 0; + var_2 = 0; + + foreach ( var_4 in level.players ) + { + if ( isdefined( var_4 ) && isalive( var_4 ) ) + { + var_2++; + var_1 = var_1 + distance2d( var_4.origin, level.drill.origin ); + } + } + + if ( var_2 == 0 ) + { + level.drill.threatbias = int( -3000 ); + wait( var_0 ); + continue; + } + + var_6 = var_1 / max( 1, var_2 ); + + if ( var_6 < 1000 ) + level.drill.threatbias = int( -3000 ); + else if ( var_6 > 2500 ) + level.drill.threatbias = int( -1000 ); + else + { + var_7 = 1500; + var_8 = 2000; + var_9 = ( var_6 - 1000 ) / var_7; + var_10 = var_9 * var_8; + level.drill.threatbias = int( -3000 + var_10 ); + } + + wait( var_0 ); + } +} + +set_drill_state_run( var_0 ) +{ + if ( isdefined( level.set_drill_state_run_override ) ) + { + self thread [[ level.set_drill_state_run_override ]]( var_0 ); + return; + } + + self endon( "death" ); + self endon( "stop_listening" ); + level.drill.state = "online"; + level.drill notify( "online" ); + level.drill setcandamage( 1 ); + level.drill makeunusable(); + level.drill sethintstring( "" ); + var_1 = 150; + + if ( use_alternate_drill() ) + var_1 = level.drill_health_hardcore; + + level.drill.maxhealth = 20000 + var_1; + level.drill.health = int( 20000 + var_1 * level.drill.owner maps\mp\alien\_perk_utility::perk_getdrillhealthscalar() ); + level.drill.threatbias = -3000; + level.drill makeentitysentient( "allies" ); + level.drill setthreatbiasgroup( "drill" ); + update_drill_health_hud(); + + foreach ( var_3 in level.agentarray ) + { + if ( isdefined( var_3.wave_spawned ) && var_3.wave_spawned ) + var_3 getenemyinfo( level.drill ); + } + + var_5 = level.drill gettagangles( "tag_laser" ); + var_6 = anglestoforward( var_5 ); + var_7 = anglestoup( var_5 ); + var_8 = vectorcross( var_6, ( 0, 0, 1 ) ); + var_9 = level.drill gettagorigin( "tag_laser_end" ) - ( 0, 0, 16 ) + var_8 * 4 * -1 + var_6 * 1.0 * -1; + var_10 = level.drill gettagorigin( "tag_laser" ) - ( 0, 0, 8 ); + level.drill.fxent = spawnfx( level._effect["drill_laser_contact"], var_9 ); + level.drill.fxlaserent = spawnfx( level._effect["drill_laser"], var_10, var_6, var_7 ); + var_11 = maps\mp\alien\_utility::is_door() || maps\mp\alien\_utility::is_door_hive(); + thread sfx_drill_on( var_11 ); + + if ( maps\mp\alien\_utility::is_door() ) + { + level notify( "drill_start_door_fx" ); + level.drill scriptmodelplayanim( "alien_drill_open_door" ); + } + else if ( isdefined( level.custom_hive_logic ) ) + level [[ level.custom_hive_logic ]](); + else + { + triggerfx( level.drill.fxent ); + triggerfx( level.drill.fxlaserent ); + level.drill scriptmodelplayanim( "alien_drill_loop" ); + } + + thread handle_bomb_damage(); + self.depth_marker = gettime(); + thread monitor_drill_complete( self.depth ); + thread maps\mp\alien\_hive::hive_pain_monitor(); + thread maps\mp\alien\_hive::set_hive_icon( "waypoint_alien_defend" ); + destroy_drill_icon(); + maps\mp\alien\_hud::turn_on_drill_meter_hud( self.depth ); + level thread watch_drill_depth_for_vo( self.depth ); +} + +watch_drill_depth_for_vo( var_0 ) +{ + level endon( "drill_detonated" ); + level endon( "game_ended" ); + wait( var_0 / 2 ); + level thread maps\mp\alien\_music_and_dialog::playvofordrillhalfway(); +} + +monitor_drill_complete( var_0 ) +{ + self endon( "death" ); + self endon( "stop_listening" ); + level.drill endon( "offline" ); + + while ( self.layers.size > 0 ) + { + var_1 = self.layers[self.layers.size - 1]; + var_2 = self.layers.size == 1; + var_3 = var_0 - var_1; + + if ( var_2 ) + childthread maps\mp\alien\_music_and_dialog::playmusicbeforereachlayer( var_3 ); + + var_4 = "remaining_depth_to_layer is negative, "; + var_4 = var_4 + "[depth=" + var_0 + "][layer_depth=" + var_1 + "][layer index=" + ( self.layers.size - 1 ) + "]"; + var_4 = var_4 + "[hive.origin=" + self.origin + "]"; + common_scripts\utility::waittill_any_timeout( var_3, "force_drill_complete" ); + self.layer_completed++; + setomnvar( "ui_alien_drill_layer_completed", self.layer_completed ); + self.layers = common_scripts\utility::array_remove( self.layers, var_1 ); + var_0 = var_1; + reach_layer_earthquake(); + + if ( !maps\mp\alien\_utility::is_door() ) + reach_layer_spawn_event( var_2 ); + } + + self notify( "drill_complete" ); + level.drill notify( "drill_complete" ); + level.encounter_name = undefined; + common_scripts\utility::flag_clear( "drill_drilling" ); + common_scripts\utility::flag_set( "drill_detonated" ); + + foreach ( var_6 in level.players ) + { + if ( !isalive( var_6 ) || maps\mp\alien\_utility::is_true( var_6.isreviving ) || maps\mp\alien\_utility::is_true( var_6.being_revived ) ) + continue; + + var_6 setclientomnvar( "ui_securing_progress", 0 ); + var_6 setclientomnvar( "ui_securing", 0 ); + } + + setomnvar( "ui_alien_drill_state", 0 ); +} + +reach_layer_earthquake() +{ + var_0 = 0.4; + var_1 = 1.75; + + if ( maps\mp\alien\_utility::is_door() ) + var_0 = 0.15; + + thread maps\mp\alien\_hive::warn_all_players( var_1, var_0 ); +} + +reach_layer_spawn_event( var_0 ) +{ + if ( var_0 ) + return; + + var_1 = "reached_layer_" + self.layer_completed; + maps\mp\alien\_spawn_director::activate_spawn_event( var_1 ); +} + +init_drilling_parameters() +{ + if ( maps\mp\alien\_utility::is_door() ) + { + self.depth = 30; + self.total_depth = self.depth; + self.layer_completed = 0; + self.layers[0] = 0; + setomnvar( "ui_alien_drill_layers_table_line", 599 + level.current_cycle_num + 1 ); + setomnvar( "ui_alien_drill_layer_completed", self.layer_completed ); + } + else + { + var_0 = level.cycle_data.cycle_drill_layers[level.current_cycle_num + 1]; + self.depth = var_0[var_0.size - 1]; + self.total_depth = self.depth; + self.layer_completed = 0; + self.layers[0] = 0; + + for ( var_1 = 0; var_1 <= var_0.size - 2; var_1++ ) + self.layers[self.layers.size] = var_0[var_1]; + + setomnvar( "ui_alien_drill_layers_table_line", 599 + level.current_cycle_num + 1 ); + setomnvar( "ui_alien_drill_layer_completed", self.layer_completed ); + } +} + +set_drill_state_offline() +{ + self endon( "death" ); + self endon( "stop_listening" ); + level.drill.state = "offline"; + + if ( isdefined( level.drill.fxent ) ) + level.drill.fxent delete(); + + if ( isdefined( level.drill.fxlaserent ) ) + level.drill.fxlaserent delete(); + + if ( maps\mp\alien\_utility::is_door() ) + level notify( "drill_stop_door_fx" ); + + thread sfx_drill_offline(); + var_0 = ( gettime() - self.depth_marker ) / 1000; + self.depth = max( 0, self.depth - var_0 ); + level.drill scriptmodelplayanim( "alien_drill_operate_end" ); + wait 1.4; + level.drill scriptmodelplayanim( "alien_drill_nonoperate" ); + level.drill makeusable(); + level.drill setcursorhint( "HINT_ACTIVATE" ); + level.drill sethintstring( &"ALIEN_COLLECTIBLES_PLANT_BOMB" ); + level.drill setcandamage( 0 ); + level.drill freeentitysentient(); + maps\mp\alien\_hive::destroy_hive_icon(); + level.drill set_drill_icon(); + setomnvar( "ui_alien_drill_state", 2 ); +} + +handle_bomb_damage() +{ + self endon( "death" ); + self endon( "stop_listening" ); + level endon( "hives_cleared" ); + level.drill endon( "death" ); + level.drill endon( "offline" ); + var_0 = 0; + var_1 = gettime(); + level.drill_last_health = level.drill.health; + var_2 = 0; + var_3 = 0; + var_4 = 0; + + for (;;) + { + level.drill waittill( "damage", var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14 ); + + if ( isdefined( var_6 ) && isai( var_6 ) ) + level.drill_last_health = level.drill_last_health - var_5; + else if ( isdefined( var_14 ) && var_14 == "alien_minion_explosion" ) + level.drill_last_health = level.drill_last_health - var_5; + else + { + level.drill.health = level.drill_last_health; + continue; + } + + if ( isdefined( level.level_drill_damage_adjust_function ) ) + [[ level.level_drill_damage_adjust_function ]]( var_5, var_6, var_14 ); + + level.drill.health = level.drill_last_health; + maps\mp\alien\_gamescore::update_team_encounter_performance( maps\mp\alien\_gamescore::get_drill_score_component_name(), "drill_damage_taken", var_5 ); + maps\mp\alien\_alien_matchdata::inc_drill_heli_damages( var_5 ); + + if ( level.script == "mp_alien_last" ) + { + if ( isdefined( var_6 ) && ( !isdefined( var_6.team ) || var_6.team == "axis" ) ) + self playsound( "scn_dscnt_alien_pod_hit" ); + } + + if ( level.drill.health < 20000 ) + { + maps\mp\alien\_hud::update_drill_health( 0 ); + level.drill notify( "offline", var_6, var_5 ); + continue; + } + + if ( !isdefined( self.icon ) ) + continue; + + var_16 = ( level.drill.health - 20000 ) / 150; + var_16 = max( 0, min( 1, var_16 ) ); + var_17 = var_16 * var_16; + var_18 = var_17; + var_19 = var_18; + self.icon.color = ( 1, var_18, var_19 ); + + if ( use_alternate_drill() ) + { + var_20 = ( level.drill.health - 20000 ) / level.drill_health_hardcore; + update_drill_health_hud(); + + if ( var_20 <= 0.75 && !var_2 ) + { + if ( isdefined( level.drill_repair_hint ) ) + iprintlnbold( level.drill_repair_hint ); + else + iprintlnbold( &"ALIEN_COLLECTIBLES_DRILL_REPAIR_HINT" ); + + var_2 = 1; + } + else if ( var_20 <= 0.5 && !var_3 ) + { + if ( isdefined( level.drill_repair_hint ) ) + iprintlnbold( level.drill_repair_hint ); + else + iprintlnbold( &"ALIEN_COLLECTIBLES_DRILL_REPAIR_HINT" ); + + var_3 = 1; + } + else if ( var_20 <= 0.25 && !var_4 ) + { + if ( isdefined( level.drill_repair_hint_urgent ) ) + iprintlnbold( level.drill_repair_hint_urgent ); + else + iprintlnbold( &"ALIEN_COLLECTIBLES_REACT_DRILL" ); + + var_4 = 1; + } + + if ( var_20 <= 0.25 ) + thread sfx_overheat(); + + if ( var_20 < 0.5 && gettime() - var_1 > var_0 ) + level thread maps\mp\alien\_music_and_dialog::playvofordrillhot(); + else if ( gettime() - var_1 > var_0 ) + level thread maps\mp\alien\_music_and_dialog::playvofordrilldamaged(); + + var_1 = gettime(); + } + } +} + +sfx_overheat() +{ + if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() && level.script != "mp_alien_dlc3" ) + level.drill_sfx_lp stoploopsound( "alien_laser_drill_lp" ); + + if ( !isdefined( level.drill_overheat_lp_02 ) ) + { + level.drill_overheat_lp_02 = spawn( "script_origin", level.drill.origin ); + level.drill_overheat_lp_02 linkto( level.drill ); + + if ( level.script == "mp_alien_last" ) + { + level.drill_sfx_lp stoploopsound( "alien_conduit_on_lp" ); + level.drill_overheat_lp_02 playloopsound( "alien_conduit_damaged_lp" ); + return; + } + } + + if ( level.script == "mp_alien_dlc3" ) + level.drill_overheat_lp_02 playloopsound( "alien_drill_scanner_overheat_lp" ); + else + level.drill_overheat_lp_02 playloopsound( "alien_laser_drill_overheat_lp" ); +} + +drill_detonate() +{ + if ( isdefined( level.drill_detonate_override ) ) + { + self thread [[ level.drill_detonate_override ]](); + return; + } + + maps\mp\alien\_hive::destroy_hive_icon(); + self makeunusable(); + self sethintstring( "" ); + + if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) ) + maps\mp\alien\_outline_proto::remove_from_outline_drill_watch_list( level.drill ); + + if ( !maps\mp\alien\_utility::is_door() && !maps\mp\alien\_utility::is_door_hive() ) + { + thread sfx_drill_off( 0 ); + thread kill_sequence(); + } + + if ( isdefined( level.drill.fxent ) ) + level.drill.fxent delete(); + + if ( isdefined( level.drill.fxlaserent ) ) + level.drill.fxlaserent delete(); + + if ( maps\mp\alien\_utility::is_door() ) + level notify( "drill_stop_door_fx" ); + + level.drill scriptmodelclearanim(); + + if ( !maps\mp\alien\_utility::is_door() ) + { + level.drill scriptmodelplayanim( "alien_drill_end" ); + wait 3.8; + } + + if ( !isdefined( self.last_hive ) || !self.last_hive ) + { + var_0 = level.drill.origin + ( 0, 0, 8 ); + drop_drill( var_0, self.angles - ( 0, 90, 0 ) ); + } + + if ( maps\mp\alien\_utility::is_door() || maps\mp\alien\_utility::is_door_hive() ) + maps\mp\_utility::delaythread( 3, ::open_door ); + else + thread maps\mp\alien\_hive::delete_removables(); + + thread remove_spawner(); + thread fx_ents_playfx(); + maps\mp\alien\_hive::show_dead_hive_model(); + thread do_radius_damage(); + + if ( isdefined( self.last_hive ) && self.last_hive ) + { + common_scripts\utility::flag_set( "hives_cleared" ); + level thread detonate_drill_when_nuke_goes_off( self ); + } + + common_scripts\utility::flag_clear( "drill_detonated" ); + wait 8; + level thread maps\mp\alien\_music_and_dialog::playvoforbombdetonate( self ); +} + +do_radius_damage() +{ + var_0 = 300; + + foreach ( var_2 in self.scriptables ) + { + radiusdamage( var_2.origin, var_0, 0, 0, var_2 ); + common_scripts\utility::waitframe(); + } +} + +detonate_drill_when_nuke_goes_off( var_0 ) +{ + if ( isdefined( level.drill ) ) + { + level.drill setcandamage( 0 ); + level.drill freeentitysentient(); + level.drill makeunusable(); + } + + level waittill( "nuke_went_off" ); + wait 1.5; + var_1 = level._effect["stronghold_explode_med"]; + var_2 = var_0.origin; + + if ( isdefined( level.drill ) ) + var_2 = level.drill.origin; + + playfx( var_1, var_2 ); + + if ( isdefined( level.drill ) ) + { + level.drill_carrier = undefined; + level.drill delete(); + } +} + +kill_sequence() +{ + playfx( level._effect["stronghold_explode_large"], self.origin ); + + if ( !maps\mp\alien\_utility::is_door() ) + thread maps\mp\alien\_hive::sfx_destroy_hive(); + + if ( isalive( level.drill ) ) + { + foreach ( var_1 in self.scriptables ) + { + var_1 thread maps\mp\alien\_hive::hive_explode( 1 ); + common_scripts\utility::waitframe(); + } + } +} + +createuseent() +{ + var_0 = spawn( "script_origin", self.origin ); + var_0.curprogress = 0; + var_0.usetime = 0; + var_0.userate = 1; + var_0.inuse = 0; + var_0 thread deleteuseent( self ); + return var_0; +} + +deleteuseent( var_0 ) +{ + self endon( "death" ); + var_0 waittill( "death" ); + self delete(); +} + +cancel_repair_on_hive_death( var_0 ) +{ + var_0 endon( "disconnect" ); + self notify( "cancel_repair_on_hive_death" ); + self endon( "cancel_repair_on_hive_death" ); + level endon( "drill_repaired" ); + self waittill( "drill_complete" ); + + if ( isalive( var_0 ) ) + { + var_0 notify( "drill_repair_weapon_management" ); + + if ( var_0.disabledweapon > 0 ) + var_0 common_scripts\utility::_enableweapon(); + + if ( maps\mp\alien\_utility::is_true( var_0.hasprogressbar ) ) + var_0.hasprogressbar = 0; + + var_0.isrepairing = 0; + } +} + +useholdthink( var_0, var_1 ) +{ + thread cancel_repair_on_hive_death( var_0 ); + self.curprogress = 0; + self.inuse = 1; + self.userate = 1; + + if ( isdefined( var_1 ) ) + self.usetime = var_1; + else + self.usetime = 3000; + + if ( !var_0 maps\mp\alien\_perk_utility::has_perk( "perk_rigger", [ 0, 1, 2, 3, 4 ] ) ) + var_0 maps\mp\alien\_utility::disable_weapon_timeout( var_1 + 0.05, "drill_repair_weapon_management" ); + + var_0 thread personalusebar( self ); + var_0.hasprogressbar = 1; + var_2 = useholdthinkloop( var_0, self, 18496 ); + + if ( isalive( var_0 ) ) + { + var_0.hasprogressbar = 0; + + if ( !var_0 maps\mp\alien\_perk_utility::has_perk( "perk_rigger", [ 0, 1, 2, 3, 4 ] ) ) + var_0 maps\mp\alien\_utility::enable_weapon_wrapper( "drill_repair_weapon_management" ); + } + + if ( !isdefined( self ) ) + return 0; + + self.inuse = 0; + self.curprogress = 0; + return var_2; +} + +personalusebar( var_0 ) +{ + var_1 = 2; + + if ( level.script == "mp_alien_last" ) + var_1 = 7; + + self endon( "disconnect" ); + self setclientomnvar( "ui_securing", var_1 ); + var_2 = -1; + + while ( maps\mp\_utility::isreallyalive( self ) && isdefined( var_0 ) && var_0.inuse && !level.gameended ) + { + if ( var_2 != var_0.userate ) + { + if ( var_0.curprogress > var_0.usetime ) + var_0.curprogress = var_0.usetime; + } + + var_2 = var_0.userate; + self setclientomnvar( "ui_securing_progress", var_0.curprogress / var_0.usetime ); + wait 0.05; + } + + self setclientomnvar( "ui_securing_progress", 0 ); + self setclientomnvar( "ui_securing", 0 ); +} + +useholdthinkloop( var_0, var_1, var_2 ) +{ + while ( !level.gameended && isdefined( self ) && maps\mp\_utility::isreallyalive( var_0 ) && var_0 usebuttonpressed() && ( !isdefined( var_0.laststand ) || !var_0.laststand ) && self.curprogress < self.usetime ) + { + var_3 = ( self.health - 20000 ) / level.drill_health_hardcore; + + if ( var_3 <= 0 ) + return 0; + + if ( isdefined( var_1 ) && isdefined( var_2 ) ) + { + if ( distancesquared( var_0.origin, var_1.origin ) > var_2 ) + return 0; + } + + self.curprogress = self.curprogress + 50 * self.userate; + self.userate = 1; + + if ( self.curprogress >= self.usetime ) + return maps\mp\_utility::isreallyalive( var_0 ); + + wait 0.05; + } + + return 0; +} + +draw_line( var_0, var_1, var_2, var_3 ) +{ + if ( isdefined( var_3 ) ) + { + for ( var_4 = 0; var_4 < var_3; var_4++ ) + wait 0.05; + } + else + { + for (;;) + wait 0.05; + } +} + +angles_to_ground( var_0, var_1, var_2 ) +{ + var_3 = var_0 + ( 0, 0, 16 ); + var_4 = var_0 - ( 0, 0, 64 ); + var_5 = bullettrace( var_3, var_4, 0, self ); + var_6 = var_5["normal"] * -1; + var_7 = vectortoangles( var_6 ); + var_8 = vectortoangles( anglestoup( var_7 ) )[1] - vectortoangles( anglestoforward( var_1 ) )[1]; + var_9 = vectornormalize( var_6 ); + var_10 = vectornormalize( anglestoup( vectortoangles( var_6 ) ) ); + var_11 = vectornormalize( anglestoright( vectortoangles( var_6 ) ) ); + var_10 = rotatepointaroundvector( var_9, var_10, var_8 - 90 ); + var_11 = rotatepointaroundvector( var_9, var_11, var_8 - 90 ); + self.angles = axistoangles( var_10, var_11, var_9 ); + + if ( abs( self.angles[2] ) > 45 ) + self.angles = ( self.angles[0], self.angles[1], 0 ); + + if ( abs( self.angles[0] ) > 45 ) + self.angles = ( 0, self.angles[1], self.angles[2] ); + + self.origin = var_0 + var_2; +} + +watchbomb() +{ + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + + if ( self hasweapon( "alienbomb_mp" ) ) + { + self takeweapon( "alienbomb_mp" ); + self enableweaponswitch(); + } + + for (;;) + { + self waittill( "grenade_fire", var_0, var_1 ); + + if ( var_1 == "alienbomb" || var_1 == "alienbomb_mp" ) + { + var_0.owner = self; + var_0 setotherent( self ); + var_0.team = self.team; + var_0 thread watchbombstuck( self ); + } + } +} + +watchbombstuck( var_0 ) +{ + level endon( "game_ended" ); + var_0 endon( "death" ); + var_0 endon( "disconnect" ); + self hide(); + common_scripts\utility::waittill_any_timeout( 0.05, "missile_stuck" ); + var_1 = self aiphysicstrace( var_0.origin + ( 0, 0, 8 ), var_0.origin - ( 0, 0, 12 ), undefined, undefined, 1, 1 ); + + if ( var_1["fraction"] == 1 ) + { + var_0 takeweapon( "alienbomb_mp" ); + var_0 giveweapon( "alienbomb_mp" ); + var_0 setweaponammostock( "alienbomb_mp", var_0 getweaponammostock( "alienbomb_mp" ) + 1 ); + var_0 switchtoweapon( "alienbomb_mp" ); + self delete(); + return; + } + else + { + self.origin = var_1["position"]; + var_2 = var_1["entity"]; + } + + self.angles = self.angles * ( 0, 1, 1 ); + level notify( "drill_dropping" ); + + foreach ( var_4 in level.stronghold_hive_locs ) + { + if ( var_4 maps\mp\alien\_hive::is_blocker_hive() ) + continue; + + if ( !var_4 maps\mp\alien\_hive::dependent_hives_removed() ) + continue; + + if ( distance( var_4.origin, self.origin ) < 80 ) + { + var_4 notify( "trigger", var_0 ); + earthquake( 0.25, 0.5, self.origin, 128 ); + var_0 takeweapon( "alienbomb_mp" ); + + if ( !var_0 maps\mp\alien\_utility::has_special_weapon() ) + var_0 enableweaponswitch(); + + var_0 restore_last_weapon(); + var_0 common_scripts\utility::_enableoffhandweapons(); + self delete(); + return; + } + } + + if ( isdefined( level.watch_bomb_stuck_override ) ) + { + if ( [[ level.watch_bomb_stuck_override ]]( var_0 ) ) + return; + } + + drop_drill( self.origin, self.angles, self ); + earthquake( 0.25, 0.5, self.origin, 128 ); + var_0 takeweapon( "alienbomb_mp" ); + + if ( !var_0 maps\mp\alien\_utility::has_special_weapon() ) + var_0 enableweaponswitch(); + + var_0 restore_last_weapon(); + var_0 common_scripts\utility::_enableoffhandweapons(); + level thread maps\mp\alien\_outline_proto::update_drill_outline(); + self delete(); +} + +restore_last_weapon() +{ + if ( self.lastweapon != "aliendeployable_crate_marker_mp" ) + self switchtoweapon( self.lastweapon ); + else + self switchtoweapon( self getweaponslistprimaries()[0] ); +} + +player_carry_bomb_init() +{ + if ( !isdefined( self.carryicon ) ) + { + if ( level.splitscreen ) + { + self.carryicon = maps\mp\gametypes\_hud_util::createicon( "hud_suitcase_bomb", 33, 33 ); + self.carryicon maps\mp\gametypes\_hud_util::setpoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -50, -78 ); + } + else + { + self.carryicon = maps\mp\gametypes\_hud_util::createicon( "hud_suitcase_bomb", 50, 50 ); + self.carryicon maps\mp\gametypes\_hud_util::setpoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -50, -65 ); + } + + self.carryicon.hidewheninmenu = 1; + thread hidecarryiconongameend(); + } + + self.carryicon.alpha = 0; +} + +hidecarryiconongameend() +{ + self endon( "disconnect" ); + level waittill( "game_ended" ); + + if ( isdefined( self.carryicon ) ) + self.carryicon.alpha = 0; +} + +set_drill_icon( var_0 ) +{ + level notify( "new_bomb_icon" ); + destroy_drill_icon( self ); + + if ( !isdefined( var_0 ) || !var_0 ) + { + level.drill_icon = newhudelem(); + level.drill_icon setshader( "waypoint_alien_drill", 14, 14 ); + level.drill_icon.color = ( 1, 1, 1 ); + level.drill_icon setwaypoint( 1, 1 ); + level.drill_icon.sort = 1; + level.drill_icon.foreground = 1; + level.drill_icon.alpha = 0.5; + level.drill_icon.x = self.origin[0]; + level.drill_icon.y = self.origin[1]; + level.drill_icon.z = self.origin[2] + 72; + } + else + maps\mp\_entityheadicons::setheadicon( self.team, "waypoint_alien_drill", ( 0, 0, 72 ), 4, 4, undefined, undefined, undefined, 1, undefined, 0 ); +} + +destroy_drill_icon( var_0 ) +{ + if ( isdefined( level.drill_icon ) ) + level.drill_icon destroy(); + + if ( !isdefined( var_0 ) ) + return; + + remove_headicons_from_players(); +} + +remove_headicons_from_players() +{ + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.entityheadicons ) ) + { + foreach ( var_4, var_3 in var_1.entityheadicons ) + { + if ( !isdefined( var_3 ) ) + continue; + + var_3 destroy(); + } + } + } +} + +remove_spawner() +{ + if ( isdefined( self.script_linkto ) ) + maps\mp\alien\_spawn_director::remove_spawn_location( self.script_linkto ); +} + +fx_ents_playfx() +{ + foreach ( var_1 in self.fx_ents ) + { + playfx( level._effect["stronghold_explode_med"], var_1.origin ); + var_1 delete(); + } +} + +sfx_drill_plant() +{ + var_0 = get_drill_entity(); + var_0 playsound( "alien_laser_drill_plant" ); +} + +sfx_drill_on( var_0 ) +{ + wait 0.1; + var_1 = get_drill_entity(); + + if ( !isdefined( level.drill_sfx_lp ) ) + { + level.drill_sfx_lp = spawn( "script_origin", var_1.origin ); + level.drill_sfx_lp linkto( var_1 ); + } + + if ( !isdefined( level.drill_sfx_dist_lp ) ) + { + level.drill_sfx_dist_lp = spawn( "script_origin", var_1.origin ); + level.drill_sfx_dist_lp linkto( var_1 ); + } + + wait 0.1; + + if ( var_0 ) + { + wait 3.76; + + if ( isdefined( level.drill_sfx_lp ) ) + level.drill_sfx_lp playloopsound( "alien_laser_drill_door_lp" ); + + if ( isdefined( level.drill_sfx_dist_lp ) ) + level.drill_sfx_dist_lp playloopsound( "alien_laser_drill_door_dist_lp" ); + } + else + { + if ( isdefined( level.drill_sfx_lp ) ) + level.drill_sfx_lp playloopsound( "alien_laser_drill_lp" ); + + if ( isdefined( level.drill_sfx_dist_lp ) ) + level.drill_sfx_dist_lp playloopsound( "alien_laser_drill_dist_lp" ); + } +} + +sfx_drill_off( var_0 ) +{ + var_1 = get_drill_entity(); + var_2 = var_1.origin; + + if ( !var_0 ) + var_1 playsound( "alien_laser_drill_stop" ); + else + playsoundatpos( var_2, "alien_laser_drill_stop" ); + + if ( isdefined( level.drill_sfx_lp ) ) + level.drill_sfx_lp delete(); + + if ( isdefined( level.drill_sfx_dist_lp ) ) + level.drill_sfx_dist_lp delete(); + + if ( isdefined( level.drill_overheat_lp ) ) + level.drill_overheat_lp delete(); + + if ( isdefined( level.drill_overheat_lp_02 ) ) + level.drill_overheat_lp_02 delete(); + + if ( var_0 ) + { + wait 2.7; + playsoundatpos( var_2, "alien_laser_drill_door_open" ); + } +} + +sfx_drill_offline() +{ + var_0 = get_drill_entity(); + + if ( level.script == "mp_alien_dlc3" ) + level.drill playsound( "alien_drill_scanner_shutdown" ); + else + var_0 playsound( "alien_laser_drill_shutdown" ); + + if ( isdefined( level.drill_sfx_lp ) ) + level.drill_sfx_lp delete(); + + if ( isdefined( level.drill_sfx_dist_lp ) ) + level.drill_sfx_dist_lp delete(); + + if ( isdefined( level.drill_overheat_lp_02 ) ) + level.drill_overheat_lp_02 delete(); +} + +drill_plant_bbprint( var_0 ) +{ + drill_generic_bbprint( "aliendrillplant", var_0 ); +} + +drill_reset_bbprint( var_0 ) +{ + drill_generic_bbprint( "aliendrillreset", var_0 ); +} + +drill_generic_bbprint( var_0, var_1 ) +{ + var_2 = level.current_cycle_num; + var_3 = "unknown hive"; + + if ( isdefined( self.target ) ) + var_3 = self.target; + + var_4 = gettime() - level.starttime; + var_5 = "unknown player"; + + if ( isdefined( var_1.name ) ) + var_5 = var_1.name; + + var_6 = level.players.size; + var_7 = var_1 maps\mp\alien\_persistence::get_selected_perk_0(); + var_8 = var_1 maps\mp\alien\_persistence::get_perk_0_level(); + var_9 = var_1 maps\mp\alien\_persistence::get_selected_perk_1(); + var_10 = var_1 maps\mp\alien\_persistence::get_perk_1_level(); + var_11 = -1; + + if ( isdefined( level.drill ) && isdefined( level.drill.health ) && isdefined( level.drill_health_hardcore ) ) + var_11 = ( level.drill.health - 20000 ) / level.drill_health_hardcore; + + bbprint( var_0, "cyclenum %i hivename %s playtime %f drillhealth %f repairer %s repairerperk0 %s repairerperk1 %s repairerperk0level %s repairerperk1level %s playernum %i ", var_2, var_3, var_4, var_11, var_5, var_7, var_9, var_8, var_10, var_6 ); +} + +check_for_player_near_hive_with_drill() +{ + if ( maps\mp\alien\_utility::is_true( level.automatic_drill ) ) + return; + + self endon( "disconnect" ); + var_0 = 6400; + + for (;;) + { + while ( !common_scripts\utility::flag( "drill_drilling" ) ) + { + if ( isdefined( self.inlaststand ) && self.inlaststand || common_scripts\utility::flag( "drill_drilling" ) || isdefined( self.usingremote ) || maps\mp\alien\_utility::is_true( self.iscarrying ) ) + { + wait 0.05; + continue; + } + + foreach ( var_2 in level.stronghold_hive_locs ) + { + if ( var_2 maps\mp\alien\_hive::is_blocker_hive() ) + continue; + + if ( !var_2 maps\mp\alien\_hive::dependent_hives_removed() ) + continue; + + if ( distancesquared( var_2.origin, self.origin ) < var_0 ) + { + if ( !isdefined( level.drill_carrier ) || isdefined( level.drill_carrier ) && level.drill_carrier != self ) + { + maps\mp\_utility::setlowermessage( "need_drill", &"ALIEN_COLLECTIBLES_NEED_DRILL", undefined, 10 ); + + while ( player_should_see_drill_hint( var_2, var_0, 1 ) ) + wait 0.05; + + maps\mp\_utility::clearlowermessage( "need_drill" ); + continue; + } + + maps\mp\_utility::setlowermessage( "plant_drill", &"ALIEN_COLLECTIBLES_PLANT_BOMB", undefined, 10 ); + + while ( player_should_see_drill_hint( var_2, var_0, 0 ) ) + wait 0.05; + + maps\mp\_utility::clearlowermessage( "plant_drill" ); + } + } + + wait 0.05; + } + + common_scripts\utility::flag_waitopen( "drill_drilling" ); + } +} + +player_should_see_drill_hint( var_0, var_1, var_2 ) +{ + if ( distancesquared( var_0.origin, self.origin ) > var_1 ) + return 0; + + if ( common_scripts\utility::flag( "drill_drilling" ) ) + return 0; + + if ( self.inlaststand ) + return 0; + + if ( isdefined( self.usingremote ) ) + return 0; + + if ( maps\mp\alien\_utility::is_true( var_2 ) ) + return 1; + else if ( maps\mp\alien\_utility::is_true( self.iscarrying ) ) + return 0; + + return 1; +} + +get_drill_entity() +{ + if ( isdefined( level.drill.vehicle ) ) + return level.drill.vehicle; + else + return level.drill; +} + +open_door() +{ + level notify( "door_opening", self.target ); + + foreach ( var_1 in self.removeables ) + { + if ( isdefined( var_1 ) ) + { + if ( var_1.classname == "script_model" ) + { + var_1 thread slide_open(); + continue; + } + + if ( var_1.classname == "script_brushmodel" ) + var_1 connectpaths(); + + var_1 delete(); + } + } +} + +slide_open() +{ + if ( !isdefined( self.script_angles ) ) + self delete(); + else + self moveto( self.origin + self.script_angles, 1 ); +} + +wait_for_drill_plant() +{ + self endon( "stop_listening" ); + + for (;;) + { + self waittill( "trigger", var_0 ); + + if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) && ( !isdefined( level.drill_carrier ) || level.drill_carrier != var_0 ) ) + { + var_0 maps\mp\_utility::setlowermessage( "no_bomb", &"ALIEN_COLLECTIBLES_NO_BOMB", 5 ); + wait 0.05; + continue; + } + + if ( isplayer( var_0 ) ) + { + if ( !maps\mp\alien\_utility::is_true( level.automatic_drill ) ) + { + var_0 maps\mp\_utility::clearlowermessage( "go_plant" ); + var_0 takeweapon( "alienbomb_mp" ); + + if ( !var_0 maps\mp\alien\_utility::has_special_weapon() ) + var_0 enableweaponswitch(); + + if ( !isdefined( level.non_player_drill_plant_check ) || ![[ level.non_player_drill_plant_check ]]() ) + var_0 switchtoweapon( var_0.lastweapon ); + + self makeunusable(); + self sethintstring( "" ); + remove_headicons_from_players(); + } + + var_1 = 0.4; + var_2 = 1.75; + thread maps\mp\alien\_hive::warn_all_players( var_2, var_1 ); + var_0 maps\mp\alien\_persistence::eog_player_update_stat( "drillplants", 1 ); + level notify( "drill_planted", var_0, self ); + return var_0; + } + } +} + +update_drill_health_hud() +{ + var_0 = int( ( level.drill.health - 20000 ) / level.drill_health_hardcore * 100 ); + maps\mp\alien\_hud::update_drill_health( var_0 ); +} diff --git a/data/maps/mp/gametypes/_damage.gsc b/data/maps/mp/gametypes/_damage.gsc new file mode 100644 index 0000000..b7318f3 --- /dev/null +++ b/data/maps/mp/gametypes/_damage.gsc @@ -0,0 +1,3302 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +isswitchingteams() +{ + if ( isdefined( self.switching_teams ) ) + return 1; + + return 0; +} + +isteamswitchbalanced() +{ + var_0 = maps\mp\gametypes\_teams::countplayers(); + var_0[self.leaving_team]--; + var_0[self.joining_team]++; + return var_0[self.joining_team] - var_0[self.leaving_team] < 2; +} + +isfriendlyfire( var_0, var_1 ) +{ + if ( !level.teambased ) + return 0; + + if ( !isdefined( var_1 ) ) + return 0; + + if ( !isplayer( var_1 ) && !isdefined( var_1.team ) ) + return 0; + + if ( var_0.team != var_1.team ) + return 0; + + if ( var_0 == var_1 ) + return 0; + + return 1; +} + +killedself( var_0 ) +{ + if ( !isplayer( var_0 ) ) + return 0; + + if ( var_0 != self ) + return 0; + + return 1; +} + +handleteamchangedeath() +{ + if ( !level.teambased ) + return; + + if ( self.joining_team == "spectator" || !isteamswitchbalanced() ) + { + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + } + + if ( isdefined( level.onteamchangedeath ) ) + [[ level.onteamchangedeath ]]( self ); +} + +handleworlddeath( var_0, var_1, var_2, var_3 ) +{ + if ( !isdefined( var_0 ) ) + return; + + if ( !isdefined( var_0.team ) ) + { + handlesuicidedeath( var_2, var_3 ); + return; + } + + if ( level.teambased && var_0.team != self.team || !level.teambased ) + { + if ( isdefined( level.onnormaldeath ) && ( isplayer( var_0 ) || isagent( var_0 ) ) && var_0.team != "spectator" ) + [[ level.onnormaldeath ]]( self, var_0, var_1 ); + } +} + +handlesuicidedeath( var_0, var_1 ) +{ + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !maps\mp\_utility::matchmakinggame() ) + maps\mp\_utility::incplayerstat( "suicides", 1 ); + + var_2 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidepointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_2 ); + + if ( var_0 == "MOD_SUICIDE" && var_1 == "none" && isdefined( self.throwinggrenade ) ) + self.lastgrenadesuicidetime = gettime(); + + if ( isdefined( level.onsuicidedeath ) ) + [[ level.onsuicidedeath ]]( self ); + + if ( isdefined( self.friendlydamage ) ) + self iprintlnbold( &"MP_FRIENDLY_FIRE_WILL_NOT" ); +} + +handlefriendlyfiredeath( var_0 ) +{ + var_0 thread [[ level.onxpevent ]]( "teamkill" ); + var_0.pers["teamkills"] += 1.0; + var_0.teamkillsthisround++; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillpointloss" ) ) + { + var_1 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ); + maps\mp\gametypes\_gamescore::_setplayerscore( var_0, maps\mp\gametypes\_gamescore::_getplayerscore( var_0 ) - var_1 ); + } + + if ( level.maxallowedteamkills < 0 ) + return; + + if ( level.ingraceperiod ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else if ( var_0.pers["teamkills"] > 1 && maps\mp\_utility::gettimepassed() < level.graceperiod * 1000 + 8000 + var_0.pers["teamkills"] * 1000 ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else + var_2 = var_0 maps\mp\gametypes\_playerlogic::teamkilldelay(); + + if ( var_2 > 0 ) + { + var_0.pers["teamKillPunish"] = 1; + var_0 maps\mp\_utility::_suicide(); + } +} + +handlenormaldeath( var_0, var_1, var_2, var_3, var_4 ) +{ + var_1 thread maps\mp\_events::killedplayer( var_0, self, var_3, var_4 ); + + if ( var_4 == "MOD_HEAD_SHOT" ) + { + var_1 maps\mp\_utility::incpersstat( "headshots", 1 ); + var_1.headshots = var_1 maps\mp\_utility::getpersstat( "headshots" ); + var_1 maps\mp\_utility::incplayerstat( "headshots", 1 ); + + if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_1 playlocalsound( "bullet_impact_headshot_plr" ); + self playsound( "bullet_impact_headshot" ); + } + else if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_6 = var_1; + + if ( isdefined( var_1.commanding_bot ) ) + var_6 = var_1.commanding_bot; + + var_7 = 0; + + if ( issquadsmode() ) + var_7 = 1; + + var_6 maps\mp\_utility::incpersstat( "kills", 1, var_7 ); + var_6.kills = var_6 maps\mp\_utility::getpersstat( "kills" ); + var_6 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_6 maps\mp\gametypes\_persistence::statsetchild( "round", "kills", var_6.kills ); + var_6 maps\mp\_utility::incplayerstat( "kills", 1 ); + + if ( isflankkill( self, var_1 ) ) + { + var_6 maps\mp\_utility::incplayerstat( "flankkills", 1 ); + maps\mp\_utility::incplayerstat( "flankdeaths", 1 ); + } + + var_8 = var_1.pers["cur_kill_streak"]; + + if ( isalive( var_1 ) || var_1.streaktype == "support" ) + { + if ( var_4 == "MOD_MELEE" && !var_1 maps\mp\_utility::isjuggernaut() || var_1 maps\mp\_utility::killshouldaddtokillstreak( var_3 ) ) + var_1 registerkill( var_3, 1 ); + + var_1 maps\mp\_utility::setplayerstatifgreater( "killstreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\_utility::getpersstat( "longestStreak" ) ) + var_1 maps\mp\_utility::setpersstat( "longestStreak", var_1.pers["cur_kill_streak"] ); + } + + var_1.pers["cur_death_streak"] = 0; + var_1 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_5, var_3, var_4, undefined, self ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\gametypes\_persistence::statgetchild( "round", "killStreak" ) ) + var_1 maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1 maps\mp\_utility::rankingenabled() ) + { + if ( var_1.pers["cur_kill_streak"] > var_1.kill_streak ) + { + if ( !issquadsmode() ) + var_1 maps\mp\gametypes\_persistence::statset( "killStreak", var_1.pers["cur_kill_streak"] ); + + var_1.kill_streak = var_1.pers["cur_kill_streak"]; + } + } + + maps\mp\gametypes\_gamescore::giveplayerscore( "kill", var_1, self ); + var_9 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "deathpointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_9 ); + + if ( isdefined( level.ac130player ) && level.ac130player == var_1 ) + level notify( "ai_killed", self ); + + if ( isdefined( var_1.odin ) ) + level notify( "odin_killed_player", self ); + + level notify( "player_got_killstreak_" + var_1.pers["cur_kill_streak"], var_1 ); + var_1 notify( "got_killstreak", var_1.pers["cur_kill_streak"] ); + var_1 notify( "killed_enemy", self, var_3, var_4 ); + + if ( isdefined( self.motionsensormarkedby ) ) + { + if ( self.motionsensormarkedby != var_1 ) + self.motionsensormarkedby thread maps\mp\gametypes\_weapons::motionsensor_processtaggedassist( self ); + + self.motionsensormarkedby = undefined; + } + + if ( isdefined( level.onnormaldeath ) && var_1.pers["team"] != "spectator" ) + [[ level.onnormaldeath ]]( self, var_1, var_0 ); + + if ( !level.teambased ) + { + self.attackers = []; + return; + } + + level thread maps\mp\gametypes\_battlechatter_mp::saylocalsounddelayed( var_1, "kill", 0.75 ); + + if ( isdefined( self.lastattackedshieldplayer ) && isdefined( self.lastattackedshieldtime ) && self.lastattackedshieldplayer != var_1 ) + { + if ( gettime() - self.lastattackedshieldtime < 2500 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + else if ( isalive( self.lastattackedshieldplayer ) && gettime() - self.lastattackedshieldtime < 5000 ) + { + var_10 = vectornormalize( anglestoforward( self.angles ) ); + var_11 = vectornormalize( self.lastattackedshieldplayer.origin - self.origin ); + + if ( vectordot( var_11, var_10 ) > 0.925 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + } + } + + if ( isdefined( self.attackers ) ) + { + foreach ( var_13 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_13 ) ) ) + continue; + + if ( var_13 == var_1 ) + continue; + + if ( self == var_13 ) + continue; + + if ( isdefined( level.assists_disabled ) ) + continue; + + var_13 thread maps\mp\gametypes\_gamescore::processassist( self ); + + if ( var_13 maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + var_13.pers["assistsToKill"]++; + + if ( !( var_13.pers["assistsToKill"] % 2 ) ) + { + var_13 maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + var_13 registerkill( var_3, 0 ); + } + + continue; + } + + var_13.pers["assistsToKill"] = 0; + } + + self.attackers = []; + } +} + +isplayerweapon( var_0 ) +{ + if ( weaponclass( var_0 ) == "non-player" ) + return 0; + + if ( weaponclass( var_0 ) == "turret" ) + return 0; + + if ( weaponinventorytype( var_0 ) == "primary" || weaponinventorytype( var_0 ) == "altmode" ) + return 1; + + return 0; +} + +waitskipkillcambuttonduringdeathtimer() +{ + self endon( "disconnect" ); + self endon( "killcam_death_done_waiting" ); + self notifyonplayercommand( "death_respawn", "+usereload" ); + self notifyonplayercommand( "death_respawn", "+activate" ); + self waittill( "death_respawn" ); + self notify( "killcam_death_button_cancel" ); +} + +waitskipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "killcam_death_button_cancel" ); + wait(var_0); + self notify( "killcam_death_done_waiting" ); +} + +skipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + + if ( level.showingfinalkillcam ) + return 0; + + if ( !isai( self ) ) + { + thread waitskipkillcambuttonduringdeathtimer(); + thread waitskipkillcamduringdeathtimer( var_0 ); + var_1 = common_scripts\utility::waittill_any_return( "killcam_death_done_waiting", "killcam_death_button_cancel" ); + + if ( var_1 == "killcam_death_done_waiting" ) + return 0; + else + return 1; + } + + return 0; +} + +callback_playerkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + playerkilled_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, 0 ); +} + +queueshieldforremoval( var_0 ) +{ + var_1 = 5; + + if ( !isdefined( level.shieldtrasharray ) ) + level.shieldtrasharray = []; + + if ( level.shieldtrasharray.size >= var_1 ) + { + var_2 = level.shieldtrasharray.size - 1; + level.shieldtrasharray[0] delete(); + + for ( var_3 = 0; var_3 < var_2; var_3++ ) + level.shieldtrasharray[var_3] = level.shieldtrasharray[var_3 + 1]; + + level.shieldtrasharray[var_2] = undefined; + } + + level.shieldtrasharray[level.shieldtrasharray.size] = var_0; +} + +launchshield( var_0, var_1 ) +{ + if ( isdefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( isdefined( self.riotshieldmodel ) ) + maps\mp\_utility::riotshield_detach( 1 ); + else if ( isdefined( self.riotshieldmodelstowed ) ) + maps\mp\_utility::riotshield_detach( 0 ); + } +} + +playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_2 endon( "spawned" ); + var_2 notify( "killed_player" ); + var_2 maps\mp\gametypes\_playerlogic::resetuidvarsondeath(); + var_2.abilitychosen = 0; + var_2.perkoutlined = 0; + + if ( maps\mp\_utility::gamehasneutralcrateowner( level.gametype ) ) + { + if ( var_2 != var_1 && var_4 == "MOD_CRUSH" ) + { + var_0 = var_2; + var_1 = var_2; + var_4 = "MOD_SUICIDE"; + var_5 = "none"; + var_7 = "none"; + var_2.attackers = []; + } + } + + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + + if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( !isdefined( var_2.idflags ) ) + { + if ( var_4 == "MOD_SUICIDE" ) + var_2.idflags = 0; + else if ( var_4 == "MOD_GRENADE" ) + { + if ( ( issubstr( var_5, "frag_grenade" ) || issubstr( var_5, "thermobaric_grenade" ) || issubstr( var_5, "mortar_shell" ) ) && var_3 == 100000 ) + var_2.idflags = 0; + else if ( var_5 == "nuke_mp" ) + var_2.idflags = 0; + else if ( level.friendlyfire >= 2 ) + var_2.idflags = 0; + else + { + + } + } + } + + if ( isdefined( var_2.hasriotshieldequipped ) && var_2.hasriotshieldequipped ) + var_2 launchshield( var_3, var_4 ); + + var_2 maps\mp\_utility::riotshield_clear(); + maps\mp\gametypes\_weapons::recordtogglescopestates(); + + if ( !var_10 ) + { + if ( isdefined( var_2.endgame ) ) + maps\mp\_utility::restorebasevisionset( 2 ); + else + { + maps\mp\_utility::restorebasevisionset( 0 ); + var_2 thermalvisionoff(); + } + } + else + { + var_2.fauxdead = 1; + self notify( "death" ); + } + + if ( game["state"] == "postgame" ) + return; + + maps\mp\perks\_perks::updateactiveperks( var_0, var_1, var_2, var_3, var_4 ); + var_11 = 0; + + if ( !isplayer( var_0 ) && isdefined( var_0.primaryweapon ) ) + var_12 = var_0.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_12 = var_1 getcurrentprimaryweapon(); + else if ( issubstr( var_5, "alt_" ) ) + var_12 = getsubstr( var_5, 4, var_5.size ); + else + var_12 = undefined; + + if ( isdefined( var_2.uselaststandparams ) || isdefined( var_2.laststandparams ) && var_4 == "MOD_SUICIDE" ) + { + var_2 ensurelaststandparamsvalidity(); + var_2.uselaststandparams = undefined; + var_0 = var_2.laststandparams.einflictor; + var_1 = var_2.laststandparams.attacker; + var_3 = var_2.laststandparams.idamage; + var_4 = var_2.laststandparams.smeansofdeath; + var_5 = var_2.laststandparams.sweapon; + var_12 = var_2.laststandparams.sprimaryweapon; + var_6 = var_2.laststandparams.vdir; + var_7 = var_2.laststandparams.shitloc; + var_11 = ( gettime() - var_2.laststandparams.laststandstarttime ) / 1000; + var_2.laststandparams = undefined; + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + } + + if ( ( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) && isdefined( self.attackers ) ) + { + var_13 = undefined; + + foreach ( var_15 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_15 ) ) ) + continue; + + if ( !isdefined( var_2.attackerdata[var_15.guid].damage ) ) + continue; + + if ( var_15 == var_2 || level.teambased && var_15.team == var_2.team ) + continue; + + if ( var_2.attackerdata[var_15.guid].lasttimedamaged + 2500 < gettime() && ( var_1 != var_2 && ( isdefined( var_2.laststand ) && var_2.laststand ) ) ) + continue; + + if ( var_2.attackerdata[var_15.guid].damage > 1 && !isdefined( var_13 ) ) + { + var_13 = var_15; + continue; + } + + if ( isdefined( var_13 ) && var_2.attackerdata[var_15.guid].damage > var_2.attackerdata[var_13.guid].damage ) + var_13 = var_15; + } + + if ( isdefined( var_13 ) ) + { + var_1 = var_13; + var_1.assistedsuicide = 1; + var_5 = var_2.attackerdata[var_13.guid].weapon; + var_6 = var_2.attackerdata[var_13.guid].vdir; + var_7 = var_2.attackerdata[var_13.guid].shitloc; + var_8 = var_2.attackerdata[var_13.guid].psoffsettime; + var_4 = var_2.attackerdata[var_13.guid].smeansofdeath; + var_3 = var_2.attackerdata[var_13.guid].damage; + var_12 = var_2.attackerdata[var_13.guid].sprimaryweapon; + var_0 = var_1; + } + } + else if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( maps\mp\_utility::isheadshot( var_5, var_7, var_4, var_1 ) ) + var_4 = "MOD_HEAD_SHOT"; + else if ( !isdefined( var_2.nuked ) ) + { + if ( isdefined( level.custom_death_sound ) ) + [[ level.custom_death_sound ]]( var_2, var_4, var_0 ); + else if ( var_4 != "MOD_MELEE" ) + var_2 maps\mp\_utility::playdeathsound(); + } + + if ( isdefined( level.custom_death_effect ) ) + [[ level.custom_death_effect ]]( var_2, var_4, var_0 ); + + var_17 = isfriendlyfire( var_2, var_1 ); + + if ( isdefined( var_1 ) ) + { + if ( var_1.code_classname == "script_vehicle" && isdefined( var_1.owner ) ) + var_1 = var_1.owner; + + if ( var_1.code_classname == "misc_turret" && isdefined( var_1.owner ) ) + { + if ( isdefined( var_1.vehicle ) ) + var_1.vehicle notify( "killedPlayer", var_2 ); + + var_1 = var_1.owner; + } + + if ( isagent( var_1 ) ) + { + var_5 = "agent_mp"; + var_4 = "MOD_RIFLE_BULLET"; + + if ( isdefined( var_1.agent_type ) ) + { + if ( var_1.agent_type == "dog" ) + var_5 = "guard_dog_mp"; + else if ( var_1.agent_type == "squadmate" ) + var_5 = "agent_support_mp"; + else if ( var_1.agent_type == "pirate" ) + var_5 = "pirate_agent_mp"; + else if ( var_1.agent_type == "wolf" ) + var_5 = "killstreak_wolfpack_mp"; + else if ( var_1.agent_type == "beastmen" ) + var_5 = "beast_agent_mp"; + } + + if ( isdefined( var_1.owner ) ) + var_1 = var_1.owner; + } + + if ( var_1.code_classname == "script_model" && isdefined( var_1.owner ) ) + { + var_1 = var_1.owner; + + if ( !isfriendlyfire( var_2, var_1 ) && var_1 != var_2 ) + var_1 notify( "crushed_enemy" ); + } + } + + if ( var_4 != "MOD_SUICIDE" && ( maps\mp\_utility::isaigameparticipant( var_2 ) || maps\mp\_utility::isaigameparticipant( var_1 ) ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["get_attacker_ent"] ) ) + { + var_18 = [[ level.bot_funcs["get_attacker_ent"] ]]( var_1, var_0 ); + + if ( isdefined( var_18 ) ) + { + if ( maps\mp\_utility::isaigameparticipant( var_2 ) ) + var_2 botmemoryevent( "death", var_5, var_18.origin, var_2.origin, var_18 ); + + if ( maps\mp\_utility::isaigameparticipant( var_1 ) ) + { + var_19 = 1; + + if ( var_18.classname == "script_vehicle" && isdefined( var_18.helitype ) || var_18.classname == "rocket" || var_18.classname == "misc_turret" ) + var_19 = 0; + + if ( var_19 ) + var_1 botmemoryevent( "kill", var_5, var_18.origin, var_2.origin, var_2 ); + } + } + } + + var_2 maps\mp\gametypes\_weapons::dropscavengerfordeath( var_1 ); + var_2 [[ level.weapondropfunction ]]( var_1, var_4 ); + + if ( !var_10 ) + var_2 maps\mp\_utility::updatesessionstate( "dead", "hud_status_dead" ); + + var_20 = isdefined( var_2.fauxdead ) && var_2.fauxdead && isdefined( var_2.switching_teams ) && var_2.switching_teams; + + if ( !var_20 ) + var_2 maps\mp\gametypes\_playerlogic::removefromalivecount(); + + if ( !isdefined( var_2.switching_teams ) ) + { + var_21 = var_2; + + if ( isdefined( var_2.commanding_bot ) ) + var_21 = var_2.commanding_bot; + + if ( isdefined( level.ishorde ) ) + var_21.deaths++; + else + { + var_22 = 0; + + if ( issquadsmode() ) + var_22 = 1; + + var_21 maps\mp\_utility::incpersstat( "deaths", 1, var_22 ); + var_21.deaths = var_21 maps\mp\_utility::getpersstat( "deaths" ); + var_21 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_21 maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", var_21.deaths ); + var_21 maps\mp\_utility::incplayerstat( "deaths", 1 ); + } + } + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + var_1 checkkillsteal( var_2 ); + + obituary( var_2, var_1, var_5, var_4 ); + var_23 = 0; + var_24 = var_2 maps\mp\_matchdata::logplayerlife(); + var_2 logprintplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + var_2 maps\mp\_matchdata::logplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + + if ( isplayer( var_1 ) ) + { + if ( var_4 == "MOD_MELEE" ) + { + if ( maps\mp\gametypes\_weapons::isriotshield( var_5 ) ) + { + var_1 maps\mp\_utility::incplayerstat( "shieldkills", 1 ); + + if ( !maps\mp\_utility::matchmakinggame() ) + var_2 maps\mp\_utility::incplayerstat( "shielddeaths", 1 ); + } + else + var_1 maps\mp\_utility::incplayerstat( "knifekills", 1 ); + + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + } + } + + if ( var_2 isswitchingteams() ) + handleteamchangedeath(); + else if ( !isplayer( var_1 ) || isplayer( var_1 ) && var_4 == "MOD_FALLING" ) + { + handleworlddeath( var_1, var_24, var_4, var_7 ); + + if ( isagent( var_1 ) ) + var_23 = 1; + } + else if ( var_1 == var_2 ) + handlesuicidedeath( var_4, var_7 ); + else if ( var_17 ) + { + if ( !( isdefined( var_2.nuked ) || var_5 == "bomb_site_mp" ) ) + handlefriendlyfiredeath( var_1 ); + } + else + { + if ( var_4 == "MOD_GRENADE" && var_0 == var_1 ) + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + + var_23 = 1; + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["should_do_killcam"] ) ) + var_23 = var_2 [[ level.bot_funcs["should_do_killcam"] ]](); + + if ( isdefined( level.disable_killcam ) && level.disable_killcam ) + var_23 = 0; + + handlenormaldeath( var_24, var_1, var_0, var_5, var_4 ); + var_2 thread maps\mp\gametypes\_missions::playerkilled( var_0, var_1, var_3, var_4, var_5, var_12, var_7, var_1.modifiers ); + var_2.pers["cur_death_streak"]++; + + if ( isplayer( var_1 ) && var_2 maps\mp\_utility::isjuggernaut() ) + { + if ( isdefined( var_2.isjuggernautmaniac ) && var_2.isjuggernautmaniac ) + { + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_maniac", var_1 ); + + if ( var_4 == "MOD_MELEE" ) + var_1 maps\mp\gametypes\_missions::processchallenge( "ch_thisisaknife" ); + } + else if ( isdefined( var_2.isjuggernautlevelcustom ) && var_2.isjuggernautlevelcustom ) + var_1 thread maps\mp\_utility::teamplayercardsplash( level.mapcustomjuggkilledsplash, var_1 ); + else + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_juggernaut", var_1 ); + } + } + + var_25 = 0; + var_26 = undefined; + + if ( isdefined( self.previousprimary ) ) + { + var_25 = 1; + var_26 = self.previousprimary; + self.previousprimary = undefined; + } + + if ( isplayer( var_1 ) && var_1 != self && ( !level.teambased || level.teambased && self.team != var_1.team ) ) + { + if ( var_25 && isdefined( var_26 ) ) + var_27 = var_26; + else + var_27 = self.lastdroppableweapon; + + var_27 = maps\mp\_utility::weaponmap( var_27 ); + thread maps\mp\gametypes\_gamelogic::trackleaderboarddeathstats( var_27, var_4 ); + var_1 thread maps\mp\gametypes\_gamelogic::trackattackerleaderboarddeathstats( var_5, var_4 ); + } + + if ( isdefined( var_1 ) && isdefined( var_2 ) ) + bbprint( "kills", "attackername %s attackerteam %s attackerx %f attackery %f attackerz %f attackerweapon %s victimx %f victimy %f victimz %f victimname %s victimteam %s damage %i damagetype %s damagelocation %s attackerisbot %i victimisbot %i timesincespawn %f", var_1.name, var_1.team, var_1.origin[0], var_1.origin[1], var_1.origin[2], var_5, var_2.origin[0], var_2.origin[1], var_2.origin[2], var_2.name, var_2.team, var_3, var_4, var_7, isai( var_1 ), isai( var_2 ), ( gettime() - var_2.lastspawntime ) / 1000 ); + + var_2.wasswitchingteamsforonplayerkilled = undefined; + + if ( isdefined( var_2.switching_teams ) ) + var_2.wasswitchingteamsforonplayerkilled = 1; + + var_2 resetplayervariables(); + var_2.lastattacker = var_1; + var_2.lastdeathpos = var_2.origin; + var_2.deathtime = gettime(); + var_2.wantsafespawn = 0; + var_2.revived = 0; + var_2.sameshotdamage = 0; + + if ( maps\mp\killstreaks\_killstreaks::streaktyperesetsondeath( var_2.streaktype ) ) + var_2 maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + var_28 = undefined; + + if ( maps\mp\_utility::isrocketcorpse() ) + { + var_23 = 1; + var_10 = 0; + var_28 = self.killcament; + self waittill( "final_rocket_corpse_death" ); + } + else + { + if ( var_10 ) + { + var_23 = 0; + var_9 = var_2 playerforcedeathanim( var_0, var_4, var_5, var_7, var_6 ); + } + + var_2.body = var_2 cloneplayer( var_9 ); + var_2.body.targetname = "player_corpse"; + + if ( var_10 ) + var_2 playerhide(); + + if ( var_2 isonladder() || var_2 ismantling() || !var_2 isonground() || isdefined( var_2.nuked ) || isdefined( var_2.customdeath ) ) + { + var_29 = 0; + + if ( var_4 == "MOD_MELEE" ) + { + if ( isdefined( var_2.isplanting ) && var_2.isplanting || isdefined( var_2.nuked ) ) + var_29 = 1; + } + + if ( !var_29 ) + { + var_2.body startragdoll(); + var_2 notify( "start_instant_ragdoll", var_4, var_0 ); + } + } + + if ( !isdefined( var_2.switching_teams ) ) + { + if ( isdefined( var_1 ) && isplayer( var_1 ) && !var_1 maps\mp\_utility::_hasperk( "specialty_silentkill" ) ) + thread maps\mp\gametypes\_deathicons::adddeathicon( var_2.body, var_2, var_2.team, 5.0 ); + } + + thread delaystartragdoll( var_2.body, var_7, var_6, var_5, var_0, var_4 ); + } + + var_2 thread [[ level.onplayerkilled ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["on_killed"] ) ) + var_2 thread [[ level.bot_funcs["on_killed"] ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( maps\mp\_utility::isgameparticipant( var_1 ) ) + var_30 = var_1 getentitynumber(); + else + var_30 = -1; + + if ( !isdefined( var_28 ) ) + var_28 = var_2 getkillcamentity( var_1, var_0, var_5 ); + + var_31 = -1; + var_32 = 0; + + if ( isdefined( var_28 ) ) + { + var_31 = var_28 getentitynumber(); + var_32 = var_28.birthtime; + + if ( !isdefined( var_32 ) ) + var_32 = 0; + } + + if ( ( !isdefined( level.disable_killcam ) || !level.disable_killcam ) && var_4 != "MOD_SUICIDE" && !( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) ) + recordfinalkillcam( 5.0, var_2, var_1, var_30, var_0, var_31, var_32, var_5, var_11, var_8, var_4 ); + + var_2 setcommonplayerdata( "killCamHowKilled", 0 ); + + switch ( var_4 ) + { + case "MOD_HEAD_SHOT": + var_2 setcommonplayerdata( "killCamHowKilled", 1 ); + break; + default: + break; + } + + var_33 = undefined; + + if ( var_23 ) + { + var_2 maps\mp\gametypes\_killcam::prekillcamnotify( var_0, var_1 ); + + if ( isdefined( var_0 ) && isagent( var_0 ) ) + { + var_33 = spawnstruct(); + var_33.agent_type = var_0.agent_type; + var_33.lastspawntime = var_0.lastspawntime; + } + } + + if ( !var_10 ) + { + self.respawntimerstarttime = gettime() + 1000; + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + + if ( var_34 < 1 ) + var_34 = 1; + + var_2 thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( var_34 ); + wait 1.0; + + if ( var_23 ) + var_23 = !skipkillcamduringdeathtimer( 0.5 ); + + var_2 notify( "death_delay_finished" ); + } + + var_35 = ( gettime() - var_2.deathtime ) / 1000; + self.respawntimerstarttime = gettime(); + var_23 = var_23 && !var_2 maps\mp\gametypes\_battlebuddy::canbuddyspawn(); + + if ( !( isdefined( var_2.cancelkillcam ) && var_2.cancelkillcam ) && var_23 && level.killcam && game["state"] == "playing" && !var_2 maps\mp\_utility::isusingremote() && !level.showingfinalkillcam ) + { + var_36 = !( maps\mp\_utility::getgametypenumlives() && !var_2.pers["lives"] ); + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + var_37 = var_36 && var_34 <= 0; + + if ( !var_36 ) + { + var_34 = -1; + level notify( "player_eliminated", var_2 ); + } + + var_2 maps\mp\gametypes\_killcam::killcam( var_0, var_33, var_30, var_31, var_32, var_5, var_35 + var_11, var_8, var_34, maps\mp\gametypes\_gamelogic::timeuntilroundend(), var_1, var_2, var_4 ); + } + + if ( game["state"] != "playing" ) + { + if ( !level.showingfinalkillcam ) + { + var_2 maps\mp\_utility::updatesessionstate( "dead" ); + var_2 maps\mp\_utility::clearkillcamstate(); + } + + return; + } + + var_38 = maps\mp\_utility::getgametypenumlives(); + var_39 = self.pers["lives"]; + + if ( self == var_2 && isdefined( var_2.battlebuddy ) && maps\mp\_utility::isreallyalive( var_2.battlebuddy ) && ( !maps\mp\_utility::getgametypenumlives() || self.pers["lives"] ) && !var_2 maps\mp\_utility::isusingremote() ) + maps\mp\gametypes\_battlebuddy::waitforplayerrespawnchoice(); + + if ( maps\mp\_utility::isvalidclass( var_2.class ) ) + var_2 thread maps\mp\gametypes\_playerlogic::spawnclient(); +} + +checkforcebleedout() +{ + if ( level.diehardmode != 1 ) + return 0; + + if ( !maps\mp\_utility::getgametypenumlives() ) + return 0; + + if ( level.livescount[self.team] > 0 ) + return 0; + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1 == self ) + continue; + + if ( !var_1.inlaststand ) + return 0; + } + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1.inlaststand && var_1 != self ) + var_1 laststandbleedout( 0 ); + } + + return 1; +} + +checkkillsteal( var_0 ) +{ + if ( maps\mp\_utility::matchmakinggame() ) + return; + + var_1 = 0; + var_2 = undefined; + + if ( isdefined( var_0.attackerdata ) && var_0.attackerdata.size > 1 ) + { + foreach ( var_4 in var_0.attackerdata ) + { + if ( var_4.damage > var_1 ) + { + var_1 = var_4.damage; + var_2 = var_4.attackerent; + } + } + + if ( isdefined( var_2 ) && var_2 != self ) + maps\mp\_utility::incplayerstat( "killsteals", 1 ); + } +} + +initfinalkillcam() +{ + level.finalkillcam_delay = []; + level.finalkillcam_victim = []; + level.finalkillcam_attacker = []; + level.finalkillcam_attackernum = []; + level.finalkillcam_inflictor = []; + level.finalkillcam_inflictor_agent_type = []; + level.finalkillcam_inflictor_lastspawntime = []; + level.finalkillcam_killcamentityindex = []; + level.finalkillcam_killcamentitystarttime = []; + level.finalkillcam_sweapon = []; + level.finalkillcam_deathtimeoffset = []; + level.finalkillcam_psoffsettime = []; + level.finalkillcam_timerecorded = []; + level.finalkillcam_timegameended = []; + level.finalkillcam_smeansofdeath = []; + + if ( level.multiteambased ) + { + foreach ( var_1 in level.teamnamelist ) + { + level.finalkillcam_delay[var_1] = undefined; + level.finalkillcam_victim[var_1] = undefined; + level.finalkillcam_attacker[var_1] = undefined; + level.finalkillcam_attackernum[var_1] = undefined; + level.finalkillcam_inflictor[var_1] = undefined; + level.finalkillcam_inflictor_agent_type[var_1] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_1] = undefined; + level.finalkillcam_killcamentityindex[var_1] = undefined; + level.finalkillcam_killcamentitystarttime[var_1] = undefined; + level.finalkillcam_sweapon[var_1] = undefined; + level.finalkillcam_deathtimeoffset[var_1] = undefined; + level.finalkillcam_psoffsettime[var_1] = undefined; + level.finalkillcam_timerecorded[var_1] = undefined; + level.finalkillcam_timegameended[var_1] = undefined; + level.finalkillcam_smeansofdeath[var_1] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +recordfinalkillcam( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( level.teambased && isdefined( var_2.team ) ) + { + level.finalkillcam_delay[var_2.team] = var_0; + level.finalkillcam_victim[var_2.team] = var_1; + level.finalkillcam_attacker[var_2.team] = var_2; + level.finalkillcam_attackernum[var_2.team] = var_3; + level.finalkillcam_inflictor[var_2.team] = var_4; + level.finalkillcam_killcamentityindex[var_2.team] = var_5; + level.finalkillcam_killcamentitystarttime[var_2.team] = var_6; + level.finalkillcam_sweapon[var_2.team] = var_7; + level.finalkillcam_deathtimeoffset[var_2.team] = var_8; + level.finalkillcam_psoffsettime[var_2.team] = var_9; + level.finalkillcam_timerecorded[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath[var_2.team] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type[var_2.team] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type[var_2.team] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = undefined; + } + } + + level.finalkillcam_delay["none"] = var_0; + level.finalkillcam_victim["none"] = var_1; + level.finalkillcam_attacker["none"] = var_2; + level.finalkillcam_attackernum["none"] = var_3; + level.finalkillcam_inflictor["none"] = var_4; + level.finalkillcam_killcamentityindex["none"] = var_5; + level.finalkillcam_killcamentitystarttime["none"] = var_6; + level.finalkillcam_sweapon["none"] = var_7; + level.finalkillcam_deathtimeoffset["none"] = var_8; + level.finalkillcam_psoffsettime["none"] = var_9; + level.finalkillcam_timerecorded["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath["none"] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type["none"] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime["none"] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + } +} + +erasefinalkillcam() +{ + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + level.finalkillcam_delay[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_victim[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attacker[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attackernum[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_agent_type[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_lastspawntime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentityindex[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentitystarttime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_sweapon[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_deathtimeoffset[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_psoffsettime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timerecorded[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timegameended[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_smeansofdeath[level.teamnamelist[var_0]] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +dofinalkillcam() +{ + level waittill( "round_end_finished" ); + level.showingfinalkillcam = 1; + var_0 = "none"; + + if ( isdefined( level.finalkillcam_winner ) ) + var_0 = level.finalkillcam_winner; + + var_1 = level.finalkillcam_delay[var_0]; + var_2 = level.finalkillcam_victim[var_0]; + var_3 = level.finalkillcam_attacker[var_0]; + var_4 = level.finalkillcam_attackernum[var_0]; + var_5 = level.finalkillcam_inflictor[var_0]; + var_6 = level.finalkillcam_inflictor_agent_type[var_0]; + var_7 = level.finalkillcam_inflictor_lastspawntime[var_0]; + var_8 = level.finalkillcam_killcamentityindex[var_0]; + var_9 = level.finalkillcam_killcamentitystarttime[var_0]; + var_10 = level.finalkillcam_sweapon[var_0]; + var_11 = level.finalkillcam_deathtimeoffset[var_0]; + var_12 = level.finalkillcam_psoffsettime[var_0]; + var_13 = level.finalkillcam_timerecorded[var_0]; + var_14 = level.finalkillcam_timegameended[var_0]; + var_15 = level.finalkillcam_smeansofdeath[var_0]; + + if ( !isdefined( var_2 ) || !isdefined( var_3 ) ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + var_16 = 15; + var_17 = var_14 - var_13; + + if ( var_17 > var_16 ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + if ( isdefined( var_3 ) ) + { + var_3.finalkill = 1; + var_18 = "none"; + + if ( level.teambased ) + var_18 = var_3.team; + + if ( isdefined( level.finalkillcam_attacker[var_18] ) && level.finalkillcam_attacker[var_18] == var_3 ) + maps\mp\gametypes\_missions::processfinalkillchallenges( var_3, var_2 ); + } + + var_19 = spawnstruct(); + var_19.agent_type = var_6; + var_19.lastspawntime = var_7; + var_20 = ( gettime() - var_2.deathtime ) / 1000; + + foreach ( var_22 in level.players ) + { + var_22 maps\mp\_utility::restorebasevisionset( 0 ); + var_22.killcamentitylookat = var_2 getentitynumber(); + var_22 thread maps\mp\gametypes\_killcam::killcam( var_5, var_19, var_4, var_8, var_9, var_10, var_20 + var_11, var_12, 0, 12, var_3, var_2, var_15 ); + } + + wait 0.1; + + while ( anyplayersinkillcam() ) + wait 0.05; + + level notify( "final_killcam_done" ); + level.showingfinalkillcam = 0; +} + +anyplayersinkillcam() +{ + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.killcam ) ) + return 1; + } + + return 0; +} + +resetplayervariables() +{ + self.killedplayerscurrent = []; + self.ch_extremecrueltycomplete = 0; + self.switching_teams = undefined; + self.joining_team = undefined; + self.leaving_team = undefined; + self.pers["cur_kill_streak"] = 0; + self.pers["cur_kill_streak_for_nuke"] = 0; + maps\mp\gametypes\_gameobjects::detachusemodels(); +} + +getkillcamentity( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_1 ) || var_0 == var_1 && !isagent( var_0 ) ) + return undefined; + + switch ( var_2 ) + { + case "trophy_mp": + case "bomb_site_mp": + case "proximity_explosive_mp": + case "heli_pilot_turret_mp": + case "sentry_minigun_mp": + case "hashima_missiles_mp": + return var_1.killcament; + case "remote_tank_projectile_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + case "aamissile_projectile_mp": + if ( isdefined( var_1.vehicle_fired_from ) && isdefined( var_1.vehicle_fired_from.killcament ) ) + return var_1.vehicle_fired_from.killcament; + else if ( isdefined( var_1.vehicle_fired_from ) ) + return var_1.vehicle_fired_from; + + break; + case "sam_projectile_mp": + if ( isdefined( var_1.samturret ) && isdefined( var_1.samturret.killcament ) ) + return var_1.samturret.killcament; + + break; + case "ims_projectile_mp": + if ( isdefined( var_0 ) && isdefined( var_0.imskillcament ) ) + return var_0.imskillcament; + + break; + case "ball_drone_gun_mp": + case "ball_drone_projectile_mp": + if ( isplayer( var_0 ) && isdefined( var_0.balldrone ) && isdefined( var_0.balldrone.turret ) && isdefined( var_0.balldrone.turret.killcament ) ) + return var_0.balldrone.turret.killcament; + + break; + case "none": + case "artillery_mp": + if ( isdefined( var_1.targetname ) && var_1.targetname == "care_package" || isdefined( var_1.killcament ) && ( var_1.classname == "script_brushmodel" || var_1.classname == "trigger_multiple" || var_1.classname == "script_model" ) ) + return var_1.killcament; + + break; + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "remotemissile_projectile_mp": + case "ac130_25mm_mp": + case "osprey_player_minigun_mp": + case "ugv_turret_mp": + case "remote_turret_mp": + return undefined; + } + + if ( maps\mp\_utility::isdestructibleweapon( var_2 ) || maps\mp\_utility::isbombsiteweapon( var_2 ) ) + { + if ( isdefined( var_1.killcament ) && !var_0 attackerinremotekillstreak() ) + return var_1.killcament; + else + return undefined; + } + + return var_1; +} + +attackerinremotekillstreak() +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( level.ac130player ) && self == level.ac130player ) + return 1; + + if ( isdefined( level.chopper ) && isdefined( level.chopper.gunner ) && self == level.chopper.gunner ) + return 1; + + if ( isdefined( level.remote_mortar ) && isdefined( level.remote_mortar.owner ) && self == level.remote_mortar.owner ) + return 1; + + if ( isdefined( self.using_remote_turret ) && self.using_remote_turret ) + return 1; + + if ( isdefined( self.using_remote_tank ) && self.using_remote_tank ) + return 1; + else if ( isdefined( self.using_remote_a10 ) ) + return 1; + + return 0; +} + +hitlocdebug( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = []; + var_5[0] = 2; + var_5[1] = 3; + var_5[2] = 5; + var_5[3] = 7; + + if ( !getdvarint( "scr_hitloc_debug" ) ) + return; + + if ( !isdefined( var_0.hitlocinited ) ) + { + for ( var_6 = 0; var_6 < 6; var_6++ ) + var_0 setclientdvar( "ui_hitloc_" + var_6, "" ); + + var_0.hitlocinited = 1; + } + + if ( level.splitscreen || !isplayer( var_0 ) ) + return; + + var_7 = 6; + + if ( !isdefined( var_0.damageinfo ) ) + { + var_0.damageinfo = []; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_0.damageinfo[var_6] = spawnstruct(); + var_0.damageinfo[var_6].damage = 0; + var_0.damageinfo[var_6].hitloc = ""; + var_0.damageinfo[var_6].bp = 0; + var_0.damageinfo[var_6].jugg = 0; + var_0.damageinfo[var_6].colorindex = 0; + } + + var_0.damageinfocolorindex = 0; + var_0.damageinfovictim = undefined; + } + + for ( var_6 = var_7 - 1; var_6 > 0; var_6-- ) + { + var_0.damageinfo[var_6].damage = var_0.damageinfo[var_6 - 1].damage; + var_0.damageinfo[var_6].hitloc = var_0.damageinfo[var_6 - 1].hitloc; + var_0.damageinfo[var_6].bp = var_0.damageinfo[var_6 - 1].bp; + var_0.damageinfo[var_6].jugg = var_0.damageinfo[var_6 - 1].jugg; + var_0.damageinfo[var_6].colorindex = var_0.damageinfo[var_6 - 1].colorindex; + } + + var_0.damageinfo[0].damage = var_2; + var_0.damageinfo[0].hitloc = var_3; + var_0.damageinfo[0].bp = var_4 & level.idflags_penetration; + var_0.damageinfo[0].jugg = var_1 maps\mp\_utility::isjuggernaut(); + + if ( isdefined( var_0.damageinfovictim ) && var_0.damageinfovictim != var_1 ) + { + var_0.damageinfocolorindex++; + + if ( var_0.damageinfocolorindex == var_5.size ) + var_0.damageinfocolorindex = 0; + } + + var_0.damageinfovictim = var_1; + var_0.damageinfo[0].colorindex = var_0.damageinfocolorindex; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_8 = "^" + var_5[var_0.damageinfo[var_6].colorindex]; + + if ( var_0.damageinfo[var_6].hitloc != "" ) + { + var_9 = var_8 + var_0.damageinfo[var_6].hitloc; + + if ( var_0.damageinfo[var_6].bp ) + var_9 += " (BP)"; + + if ( var_0.damageinfo[var_6].jugg ) + var_9 += " (Jugg)"; + + var_0 setclientdvar( "ui_hitloc_" + var_6, var_9 ); + } + + var_0 setclientdvar( "ui_hitloc_damage_" + var_6, var_8 + var_0.damageinfo[var_6].damage ); + } +} + +giverecentshieldxp() +{ + self endon( "death" ); + self endon( "disconnect" ); + self notify( "giveRecentShieldXP" ); + self endon( "giveRecentShieldXP" ); + self.recentshieldxp++; + wait 20.0; + self.recentshieldxp = 0; +} + +updateinflictorstat( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_0.alreadyhit ) || !var_0.alreadyhit || !maps\mp\_utility::issinglehitweapon( var_2 ) ) + maps\mp\gametypes\_gamelogic::setinflictorstat( var_0, var_1, var_2 ); + + if ( isdefined( var_0 ) ) + var_0.alreadyhit = 1; +} + +callback_playerdamage_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + var_11 = getdvar( "g_gametype" ); + + if ( isdefined( var_5 ) && var_5 == "MOD_CRUSH" && isdefined( var_0 ) && isdefined( var_0.classname ) && var_0.classname == "script_vehicle" ) + return "crushed"; + + if ( !maps\mp\_utility::isreallyalive( var_2 ) ) + return "!isReallyAlive( victim )"; + + if ( var_6 == "hind_bomb_mp" || var_6 == "hind_missile_mp" ) + { + if ( isdefined( var_1 ) && var_2 == var_1 ) + return 0; + } + + if ( isdefined( var_1 ) && var_1.classname == "script_origin" && isdefined( var_1.type ) && var_1.type == "soft_landing" ) + return "soft_landing"; + + if ( var_6 == "killstreak_emp_mp" ) + return "sWeapon == killstreak_emp_mp"; + + if ( var_6 == "bouncingbetty_mp" && !maps\mp\gametypes\_weapons::minedamageheightpassed( var_0, var_2 ) ) + return "mineDamageHeightPassed"; + + if ( var_6 == "bouncingbetty_mp" && ( var_2 getstance() == "crouch" || var_2 getstance() == "prone" ) ) + var_3 = int( var_3 / 2 ); + + if ( var_6 == "emp_grenade_mp" && var_5 != "MOD_IMPACT" ) + var_2 notify( "emp_damage", var_1 ); + + if ( isdefined( level.hostmigrationtimer ) ) + return "level.hostMigrationTimer"; + + if ( var_5 == "MOD_FALLING" ) + var_2 thread emitfalldamage( var_3 ); + + if ( var_5 == "MOD_EXPLOSIVE_BULLET" && var_3 != 1 ) + { + var_3 *= getdvarfloat( "scr_explBulletMod" ); + var_3 = int( var_3 ); + } + + if ( isdefined( var_1 ) && var_1.classname == "worldspawn" ) + var_1 = undefined; + + if ( isdefined( var_1 ) && isdefined( var_1.gunner ) ) + var_1 = var_1.gunner; + + if ( isdefined( var_0 ) && isdefined( var_0.damagedby ) ) + var_1 = var_0.damagedby; + + var_12 = isdefined( var_1 ) && !isdefined( var_1.gunner ) && ( var_1.classname == "script_vehicle" || var_1.classname == "misc_turret" || var_1.classname == "script_model" ); + var_13 = maps\mp\_utility::attackerishittingteam( var_2, var_1 ); + var_14 = isdefined( var_1 ) && isdefined( var_0 ) && isdefined( var_2 ) && isplayer( var_1 ) && var_1 == var_0 && var_1 == var_2 && !isdefined( var_0.poison ); + + if ( var_14 ) + return "attackerIsInflictorVictim"; + + var_15 = 0.0; + + if ( var_4 & level.idflags_stun ) + { + var_15 = 0.0; + var_3 = 0.0; + } + else if ( var_9 == "shield" ) + { + if ( var_13 && level.friendlyfire == 0 ) + return "attackerIsHittingTeammate"; + + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" && !var_13 ) + { + if ( isplayer( var_1 ) ) + { + if ( isdefined( var_2.owner ) ) + var_2 = var_2.owner; + + var_1.lastattackedshieldplayer = var_2; + var_1.lastattackedshieldtime = gettime(); + } + + var_2 notify( "shield_blocked" ); + + if ( maps\mp\_utility::isenvironmentweapon( var_6 ) ) + var_16 = 25; + else + var_16 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.shielddamage += var_16; + + if ( !maps\mp\_utility::isenvironmentweapon( var_6 ) || common_scripts\utility::cointoss() ) + var_2.shieldbullethits++; + + if ( var_2.shieldbullethits >= level.riotshieldxpbullets ) + { + if ( self.recentshieldxp > 4 ) + var_17 = int( 50 / self.recentshieldxp ); + else + var_17 = 50; + + var_2 thread maps\mp\gametypes\_rank::giverankxp( "shield_damage", var_17 ); + var_2 thread giverecentshieldxp(); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_damage", var_2.shielddamage ); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_bullet_hits", var_2.shieldbullethits ); + var_2.shielddamage = 0; + var_2.shieldbullethits = 0; + } + } + + if ( var_4 & level.idflags_shield_explosive_impact ) + { + if ( !var_13 ) + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + + var_9 = "none"; + + if ( !( var_4 & level.idflags_shield_explosive_impact_huge ) ) + var_3 *= 0.0; + } + else if ( var_4 & level.idflags_shield_explosive_splash ) + { + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + var_9 = "none"; + } + else + return "hit shield"; + } + else if ( var_5 == "MOD_MELEE" && maps\mp\gametypes\_weapons::isriotshield( var_6 ) ) + { + if ( !( var_13 && level.friendlyfire == 0 ) ) + { + var_15 = 0.0; + var_2 stunplayer( 0.0 ); + } + } + + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + if ( !var_13 ) + { + if ( maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + + if ( maps\mp\_utility::isbulletdamage( var_5 ) && var_1 maps\mp\_utility::_hasperk( "specialty_deadeye" ) ) + var_1 maps\mp\perks\_perkfunctions::setdeadeyeinternal(); + + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9, var_0 ); + + if ( isplayer( var_1 ) && ( var_6 == "smoke_grenade_mp" || var_6 == "throwingknife_mp" ) ) + var_1 thread maps\mp\gametypes\_gamelogic::threadedsetweaponstatbyname( var_6, 1, "hits" ); + } + + if ( isdefined( level.modifyplayerdamage ) ) + var_3 = [[ level.modifyplayerdamage ]]( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + if ( !var_3 ) + return "!iDamage"; + + var_2.idflags = var_4; + var_2.idflagstime = gettime(); + + if ( game["state"] == "postgame" ) + return "game[ state ] == postgame"; + + if ( var_2.sessionteam == "spectator" ) + return "victim.sessionteam == spectator"; + + if ( isdefined( var_2.candocombat ) && !var_2.candocombat ) + return "!victim.canDoCombat"; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_1.candocombat ) && !var_1.candocombat ) + return "!eAttacker.canDoCombat"; + + if ( var_12 && var_13 ) + { + if ( var_5 == "MOD_CRUSH" ) + { + var_2 maps\mp\_utility::_suicide(); + return "suicide crush"; + } + + if ( !level.friendlyfire ) + return "!level.friendlyfire"; + } + + if ( isai( self ) ) + self [[ level.bot_funcs["on_damaged"] ]]( var_1, var_3, var_5, var_6, var_0, var_9 ); + + if ( !isdefined( var_8 ) ) + var_4 |= level.idflags_no_knockback; + + var_18 = 0; + + if ( var_2.health == var_2.maxhealth && ( !isdefined( var_2.laststand ) || !var_2.laststand ) || !isdefined( var_2.attackers ) && !isdefined( var_2.laststand ) ) + var_2 resetattackerlist_internal(); + + if ( maps\mp\_utility::isheadshot( var_6, var_9, var_5, var_1 ) ) + var_5 = "MOD_HEAD_SHOT"; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "onlyheadshots" ) ) + { + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" ) + return "getTweakableValue( game, onlyheadshots )"; + else if ( var_5 == "MOD_HEAD_SHOT" ) + { + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = 75; + else + var_3 = 150; + } + } + + if ( var_6 == "destructible_toy" && isdefined( var_0 ) ) + var_6 = "destructible_car"; + + if ( gettime() < var_2.spawntime + level.killstreakspawnshield ) + { + var_19 = int( max( var_2.health / 4, 1 ) ); + + if ( var_3 >= var_19 && maps\mp\_utility::iskillstreakweapon( var_6 ) && var_5 != "MOD_MELEE" ) + var_3 = var_19; + } + + if ( !( var_4 & level.idflags_no_protection ) ) + { + if ( !level.teambased && var_12 && isdefined( var_1.owner ) && var_1.owner == var_2 ) + { + if ( var_5 == "MOD_CRUSH" ) + var_2 maps\mp\_utility::_suicide(); + + return "ffa suicide"; + } + + if ( ( issubstr( var_5, "MOD_GRENADE" ) || issubstr( var_5, "MOD_EXPLOSIVE" ) || issubstr( var_5, "MOD_PROJECTILE" ) ) && isdefined( var_0 ) && isdefined( var_1 ) ) + { + if ( var_2 != var_1 && var_0.classname == "grenade" && var_2.lastspawntime + 3500 > gettime() && isdefined( var_2.lastspawnpoint ) && distance( var_0.origin, var_2.lastspawnpoint.origin ) < 500 ) + return "spawnkill grenade protection"; + + var_2.explosiveinfo = []; + var_2.explosiveinfo["damageTime"] = gettime(); + var_2.explosiveinfo["damageId"] = var_0 getentitynumber(); + var_2.explosiveinfo["returnToSender"] = 0; + var_2.explosiveinfo["counterKill"] = 0; + var_2.explosiveinfo["chainKill"] = 0; + var_2.explosiveinfo["cookedKill"] = 0; + var_2.explosiveinfo["throwbackKill"] = 0; + var_2.explosiveinfo["suicideGrenadeKill"] = 0; + var_2.explosiveinfo["weapon"] = var_6; + var_20 = issubstr( var_6, "frag_" ); + + if ( var_1 != var_2 ) + { + if ( ( issubstr( var_6, "c4_" ) || issubstr( var_6, "proximity_explosive_" ) || issubstr( var_6, "claymore_" ) ) && isdefined( var_0.owner ) ) + { + var_2.explosiveinfo["returnToSender"] = var_0.owner == var_2; + var_2.explosiveinfo["counterKill"] = isdefined( var_0.wasdamaged ); + var_2.explosiveinfo["chainKill"] = isdefined( var_0.waschained ); + var_2.explosiveinfo["bulletPenetrationKill"] = isdefined( var_0.wasdamagedfrombulletpenetration ); + var_2.explosiveinfo["cookedKill"] = 0; + } + + if ( isdefined( var_1.lastgrenadesuicidetime ) && var_1.lastgrenadesuicidetime >= gettime() - 50 && var_20 ) + var_2.explosiveinfo["suicideGrenadeKill"] = 1; + } + + if ( var_20 ) + { + var_2.explosiveinfo["cookedKill"] = isdefined( var_0.iscooked ); + var_2.explosiveinfo["throwbackKill"] = isdefined( var_0.threwback ); + } + + var_2.explosiveinfo["stickKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "enemy"; + var_2.explosiveinfo["stickFriendlyKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "friendly"; + + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( issubstr( var_5, "MOD_IMPACT" ) && var_6 == "iw6_rgm_mp" ) + { + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( isplayer( var_1 ) && isdefined( var_1.pers["participation"] ) ) + var_1.pers["participation"]++; + else if ( isplayer( var_1 ) ) + var_1.pers["participation"] = 1; + + var_21 = var_2.health / var_2.maxhealth; + + if ( var_13 ) + { + if ( !maps\mp\_utility::matchmakinggame() && isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "mostff", 1 ); + + if ( level.friendlyfire == 0 || !isplayer( var_1 ) && level.friendlyfire != 1 || var_6 == "bomb_site_mp" ) + { + if ( var_6 == "artillery_mp" || var_6 == "stealth_bomb_mp" ) + var_2 damageshellshockandrumble( var_0, var_6, var_5, var_3, var_4, var_1 ); + + return "friendly fire"; + } + else if ( level.friendlyfire == 1 ) + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + } + else if ( level.friendlyfire == 2 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_1.lastdamagewasfromenemy = 0; + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + else if ( level.friendlyfire == 3 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_2.lastdamagewasfromenemy = 0; + var_1.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + } + + var_18 = 1; + } + else + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + addattacker( var_2, var_1, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.owner ) && ( !isdefined( var_1.scrambled ) || !var_1.scrambled ) ) + addattacker( var_2, var_1.owner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + else if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.secondowner ) && isdefined( var_1.scrambled ) && var_1.scrambled ) + addattacker( var_2, var_1.secondowner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( var_5 == "MOD_EXPLOSIVE" || var_5 == "MOD_GRENADE_SPLASH" && var_3 < var_2.health ) + var_2 notify( "survived_explosion", var_1 ); + + if ( isdefined( var_1 ) ) + level.lastlegitimateattacker = var_1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) ) + var_1 thread maps\mp\gametypes\_weapons::checkhit( var_6, var_2 ); + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) && var_1 != var_2 ) + { + var_1 thread maps\mp\_events::damagedplayer( self, var_3, var_6 ); + var_2.attackerposition = var_1.origin; + } + else + var_2.attackerposition = undefined; + + if ( issubstr( var_5, "MOD_GRENADE" ) && isdefined( var_0.iscooked ) ) + var_2.wascooked = gettime(); + else + var_2.wascooked = undefined; + + var_2.lastdamagewasfromenemy = isdefined( var_1 ) && var_1 != var_2; + + if ( var_2.lastdamagewasfromenemy ) + { + var_22 = gettime(); + var_1.damagedplayers[var_2.guid] = var_22; + var_2.lastdamagedtime = var_22; + } + + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_pain", var_2 ); + + var_2 thread maps\mp\gametypes\_missions::playerdamaged( var_0, var_1, var_3, var_5, var_6, var_9 ); + } + + if ( var_12 && isdefined( var_1.gunner ) ) + var_23 = var_1.gunner; + else + var_23 = var_1; + + if ( isdefined( var_23 ) && var_23 != var_2 && var_3 > 0 && ( !isdefined( var_9 ) || var_9 != "shield" ) ) + { + var_24 = !maps\mp\_utility::isreallyalive( var_2 ) || isagent( var_2 ) && var_3 >= var_2.health; + + if ( var_4 & level.idflags_stun ) + var_25 = "stun"; + else if ( isexplosivedamagemod( var_5 ) && ( isdefined( var_2.thermodebuffed ) && var_2.thermodebuffed ) ) + var_25 = common_scripts\utility::ter_op( var_24, "thermodebuff_kill", "thermobaric_debuff" ); + else if ( isexplosivedamagemod( var_5 ) && var_2 maps\mp\_utility::_hasperk( "_specialty_blastshield" ) && !maps\mp\_utility::weaponignoresblastshield( var_6 ) ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkillblast", "hitblastshield" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_combathigh" ) ) + var_25 = "hitendgame"; + else if ( isdefined( var_2.lightarmorhp ) && var_5 != "MOD_HEAD_SHOT" && !maps\mp\_utility::isfmjdamage( var_6, var_5, var_1 ) ) + var_25 = "hitlightarmor"; + else if ( maps\mp\perks\_perkfunctions::hasheavyarmor( var_2 ) ) + var_25 = "hitlightarmor"; + else if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkilljugg", "hitjuggernaut" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_moreHealth" ) ) + var_25 = "hitmorehealth"; + else if ( var_23 maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + { + var_25 = common_scripts\utility::ter_op( var_24, "hitdeadeyekill", "hitcritical" ); + var_23 maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + } + else if ( !shouldweaponfeedback( var_6 ) ) + var_25 = "none"; + else + var_25 = common_scripts\utility::ter_op( var_24, "hitkill", "standard" ); + + var_23 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_25 ); + } + + maps\mp\gametypes\_gamelogic::sethasdonecombat( var_2, 1 ); + } + + if ( isdefined( var_1 ) && var_1 != var_2 && !var_18 ) + level.usestartspawns = 0; + + if ( var_3 > 10 && isdefined( var_0 ) && !var_2 maps\mp\_utility::isusingremote() && isplayer( var_2 ) ) + { + var_2 thread maps\mp\gametypes\_shellshock::bloodeffect( var_0.origin ); + + if ( isplayer( var_0 ) && var_5 == "MOD_MELEE" ) + var_0 thread maps\mp\gametypes\_shellshock::bloodmeleeeffect(); + } + + if ( var_2.sessionstate != "dead" ) + { + var_23 = var_2 getentitynumber(); + var_24 = var_2.name; + var_25 = var_2.pers["team"]; + var_26 = var_2.guid; + var_27 = ""; + + if ( isplayer( var_1 ) ) + { + var_28 = var_1 getentitynumber(); + var_29 = var_1.guid; + var_30 = var_1.name; + var_27 = var_1.pers["team"]; + } + else + { + var_28 = -1; + var_29 = ""; + var_30 = ""; + var_27 = "world"; + } + + logprint( "D;" + var_26 + ";" + var_23 + ";" + var_25 + ";" + var_24 + ";" + var_29 + ";" + var_28 + ";" + var_27 + ";" + var_30 + ";" + var_6 + ";" + var_3 + ";" + var_5 + ";" + var_9 + "\n" ); + } + + hitlocdebug( var_1, var_2, var_3, var_9, var_4 ); + + if ( isdefined( var_1 ) && var_1 != var_2 ) + { + if ( isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "damagedone", var_3 ); + + var_2 maps\mp\_utility::incplayerstat( "damagetaken", var_3 ); + } + + if ( isagent( self ) ) + self [[ maps\mp\agents\_agent_utility::agentfunc( "on_damaged_finished" ) ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + + return "finished"; +} + +shouldweaponfeedback( var_0 ) +{ + switch ( var_0 ) + { + case "artillery_mp": + case "stealth_bomb_mp": + return 0; + } + + return 1; +} + +checkvictimstutter( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( var_4 == "MOD_PISTOL_BULLET" || var_4 == "MOD_RIFLE_BULLET" || var_4 == "MOD_HEAD_SHOT" ) + { + if ( distance( var_0.origin, var_1.origin ) > 256 ) + return; + + var_5 = var_0 getvelocity(); + + if ( lengthsquared( var_5 ) < 10 ) + return; + + var_6 = maps\mp\_utility::findisfacing( var_0, var_1, 25 ); + + if ( var_6 ) + var_0 thread stutterstep(); + } +} + +stutterstep( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + self.instutter = 1; + self.movespeedscaler = 0.05; + maps\mp\gametypes\_weapons::updatemovespeedscale(); + wait 0.5; + self.movespeedscaler = 1; + + if ( maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.instutter = 0; +} + +addattacker( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( !isdefined( var_0.attackerdata ) ) + var_0.attackerdata = []; + + if ( !isdefined( var_0.attackerdata[var_1.guid] ) ) + { + var_0.attackers[var_1.guid] = var_1; + var_0.attackerdata[var_1.guid] = spawnstruct(); + var_0.attackerdata[var_1.guid].damage = 0; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].firsttimedamaged = gettime(); + } + + if ( maps\mp\gametypes\_weapons::isprimaryweapon( var_3 ) && !maps\mp\gametypes\_weapons::issidearm( var_3 ) ) + var_0.attackerdata[var_1.guid].isprimary = 1; + + var_0.attackerdata[var_1.guid].damage += var_4; + var_0.attackerdata[var_1.guid].weapon = var_3; + var_0.attackerdata[var_1.guid].vpoint = var_5; + var_0.attackerdata[var_1.guid].vdir = var_6; + var_0.attackerdata[var_1.guid].shitloc = var_7; + var_0.attackerdata[var_1.guid].psoffsettime = var_8; + var_0.attackerdata[var_1.guid].smeansofdeath = var_9; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].lasttimedamaged = gettime(); + + if ( isdefined( var_2 ) && !isplayer( var_2 ) && isdefined( var_2.primaryweapon ) ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_2.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_0.attackerdata[var_1.guid].sprimaryweapon = undefined; +} + +resetattackerlist( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + wait 1.75; + resetattackerlist_internal(); +} + +resetattackerlist_internal() +{ + self.attackers = []; + self.attackerdata = []; +} + +callback_playerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + var_10 = callback_playerdamage_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); +} + +finishplayerdamagewrapper( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( maps\mp\_utility::isusingremote() && var_2 >= self.health && !( var_3 & level.idflags_stun ) && allowfauxdeath() || maps\mp\_utility::isrocketcorpse() ) + { + if ( !isdefined( var_7 ) ) + var_7 = ( 0, 0, 0 ); + + if ( !isdefined( var_1 ) && !isdefined( var_0 ) ) + { + var_1 = self; + var_0 = var_1; + } + + playerkilled_internal( var_0, var_1, self, var_2, var_4, var_5, var_7, var_8, var_9, 0, 1 ); + } + else + { + if ( !callback_killingblow( var_0, var_1, var_2 - var_2 * var_10, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) ) + return; + + if ( !isalive( self ) ) + return; + + if ( isplayer( self ) ) + self finishplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + } + + if ( var_4 == "MOD_EXPLOSIVE_BULLET" && !maps\mp\_utility::is_aliens() ) + self shellshock( "damage_mp", getdvarfloat( "scr_csmode" ) ); + + damageshellshockandrumble( var_0, var_5, var_4, var_2, var_3, var_1 ); +} + +allowfauxdeath() +{ + if ( !isdefined( level.allowfauxdeath ) ) + level.allowfauxdeath = 1; + + return level.allowfauxdeath; +} + +callback_playerlaststand( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + var_9 = spawnstruct(); + var_9.einflictor = var_0; + var_9.attacker = var_1; + var_9.idamage = var_2; + var_9.attackerposition = var_1.origin; + + if ( var_1 == self ) + var_9.smeansofdeath = "MOD_SUICIDE"; + else + var_9.smeansofdeath = var_3; + + var_9.sweapon = var_4; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_9.sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_9.sprimaryweapon = undefined; + + var_9.vdir = var_5; + var_9.shitloc = var_6; + var_9.laststandstarttime = gettime(); + var_10 = maydolaststand( var_4, var_3, var_6 ); + + if ( isdefined( self.endgame ) ) + var_10 = 0; + + if ( level.teambased && isdefined( var_1.team ) && var_1.team == self.team ) + var_10 = 0; + + if ( level.diehardmode ) + { + if ( level.teamcount[self.team] <= 1 ) + var_10 = 0; + else if ( maps\mp\_utility::isteaminlaststand() ) + { + var_10 = 0; + maps\mp\_utility::killteaminlaststand( self.team ); + } + } + + if ( !var_10 ) + { + self.laststandparams = var_9; + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); + } + else + { + self.inlaststand = 1; + var_11 = spawnstruct(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + var_11.titletext = game["strings"]["final_stand"]; + var_11.iconname = "specialty_finalstand"; + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + var_11.titletext = game["strings"]["c4_death"]; + var_11.iconname = "specialty_c4death"; + } + else + { + var_11.titletext = game["strings"]["last_stand"]; + var_11.iconname = "specialty_finalstand"; + } + + var_11.glowcolor = ( 1, 0, 0 ); + var_11.sound = "mp_last_stand"; + var_11.duration = 2.0; + self.health = 1; + thread maps\mp\gametypes\_hud_message::notifymessage( var_11 ); + var_12 = "frag_grenade_mp"; + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_crawling", self ); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + self.laststandparams = var_9; + self.infinalstand = 1; + var_13 = self getweaponslistexclusives(); + + foreach ( var_15 in var_13 ) + self takeweapon( var_15 ); + + common_scripts\utility::_disableusability(); + thread enablelaststandweapons(); + thread laststandtimer( 20, 1 ); + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + self.previousprimary = self.lastdroppableweapon; + self.laststandparams = var_9; + self takeallweapons(); + self giveweapon( "c4death_mp", 0, 0 ); + self switchtoweapon( "c4death_mp" ); + common_scripts\utility::_disableusability(); + self.inc4death = 1; + thread laststandtimer( 20, 0 ); + thread detonateonuse(); + thread detonateondeath(); + } + else + { + if ( level.diehardmode ) + { + var_1 maps\mp\gametypes\_rank::giverankxp( "kill", 100, var_4, var_3 ); + self.laststandparams = var_9; + common_scripts\utility::_disableweapon(); + thread laststandtimer( 20, 0 ); + common_scripts\utility::_disableusability(); + return; + } + + self.laststandparams = var_9; + var_17 = undefined; + var_18 = self getweaponslistprimaries(); + + foreach ( var_15 in var_18 ) + { + if ( maps\mp\gametypes\_weapons::issidearm( var_15 ) ) + var_17 = var_15; + } + + if ( !isdefined( var_17 ) ) + { + var_17 = "iw6_p226_mp"; + maps\mp\_utility::_giveweapon( var_17 ); + } + + self givemaxammo( var_17 ); + self disableweaponswitch(); + common_scripts\utility::_disableusability(); + + if ( !maps\mp\_utility::_hasperk( "specialty_laststandoffhand" ) ) + self disableoffhandweapons(); + + self switchtoweapon( var_17 ); + thread laststandtimer( 10, 0 ); + } + } +} + +dieaftertime( var_0 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + wait(var_0); + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); +} + +detonateonuse() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "detonate" ); + self.uselaststandparams = 1; + c4deathdetonate(); +} + +detonateondeath() +{ + self endon( "detonate" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "death" ); + c4deathdetonate(); +} + +c4deathdetonate() +{ + self playsound( "detpack_explo_default" ); + radiusdamage( self.origin, 312, 100, 100, self ); + + if ( isalive( self ) ) + maps\mp\_utility::_suicide(); +} + +enablelaststandweapons() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + wait 0.3; + maps\mp\_utility::freezecontrolswrapper( 0 ); +} + +laststandtimer( var_0, var_1 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + level notify( "player_last_stand" ); + thread laststandwaittilldeath(); + self.laststand = 1; + + if ( !var_1 && ( !isdefined( self.inc4death ) || !self.inc4death ) ) + { + thread laststandallowsuicide(); + maps\mp\_utility::setlowermessage( "last_stand", &"PLATFORM_COWARDS_WAY_OUT", undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + thread laststandkeepoverlay(); + } + + if ( level.diehardmode == 1 && level.diehardmode != 2 ) + { + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + return; + } + else if ( level.diehardmode == 2 ) + { + thread laststandkeepoverlay(); + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + wait(var_0 / 3); + var_3.color = ( 1, 0.64, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + var_3.color = ( 1, 0, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + + while ( var_2.inuse ) + wait 0.05; + + wait 0.05; + thread laststandbleedout( var_1 ); + return; + } + + thread laststandkeepoverlay(); + wait(var_0); + thread laststandbleedout( var_1 ); +} + +maxhealthoverlay( var_0, var_1 ) +{ + self endon( "stop_maxHealthOverlay" ); + self endon( "revive" ); + self endon( "death" ); + + for (;;) + { + self.health -= 1; + self.maxhealth = var_0; + wait 0.05; + self.maxhealth = 50; + self.health += 1; + wait 0.5; + } +} + +laststandbleedout( var_0, var_1 ) +{ + if ( var_0 ) + { + self.laststand = undefined; + self.infinalstand = 0; + self notify( "revive" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + + if ( isdefined( var_1 ) ) + var_1 delete(); + } + else + { + self.uselaststandparams = 1; + self.beingrevived = 0; + maps\mp\_utility::_suicide(); + } +} + +laststandallowsuicide() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "game_ended" ); + self endon( "revive" ); + + for (;;) + { + if ( self usebuttonpressed() ) + { + var_0 = gettime(); + + while ( self usebuttonpressed() ) + { + wait 0.05; + + if ( gettime() - var_0 > 700 ) + break; + } + + if ( gettime() - var_0 > 700 ) + break; + } + + wait 0.05; + } + + thread laststandbleedout( 0 ); +} + +laststandkeepoverlay() +{ + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + + while ( !level.gameended ) + { + self.health = 2; + wait 0.05; + self.health = 1; + wait 0.5; + } + + self.health = self.maxhealth; +} + +laststandwaittilldeath() +{ + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + self waittill( "death" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + self.laststand = undefined; +} + +maydolaststand( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_TRIGGER_HURT" ) + return 0; + + if ( var_1 != "MOD_PISTOL_BULLET" && var_1 != "MOD_RIFLE_BULLET" && var_1 != "MOD_FALLING" && var_1 != "MOD_EXPLOSIVE_BULLET" ) + return 0; + + if ( var_1 == "MOD_IMPACT" && maps\mp\gametypes\_weapons::isthrowingknife( var_0 ) ) + return 0; + + if ( var_1 == "MOD_IMPACT" && ( var_0 == "m79_mp" || issubstr( var_0, "gl_" ) ) ) + return 0; + + if ( maps\mp\_utility::isheadshot( var_0, var_2, var_1 ) ) + return 0; + + if ( maps\mp\_utility::isusingremote() ) + return 0; + + return 1; +} + +ensurelaststandparamsvalidity() +{ + if ( !isdefined( self.laststandparams.attacker ) ) + self.laststandparams.attacker = self; +} + +gethitlocheight( var_0 ) +{ + switch ( var_0 ) + { + case "head": + case "helmet": + case "neck": + return 60; + case "gun": + case "torso_upper": + case "right_arm_upper": + case "left_arm_upper": + case "right_arm_lower": + case "left_arm_lower": + case "right_hand": + case "left_hand": + return 48; + case "torso_lower": + return 40; + case "right_leg_upper": + case "left_leg_upper": + return 32; + case "right_leg_lower": + case "left_leg_lower": + return 10; + case "right_foot": + case "left_foot": + return 5; + } + + return 48; +} + +delaystartragdoll( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + if ( isdefined( var_0 ) ) + { + var_6 = var_0 getcorpseanim(); + + if ( animhasnotetrack( var_6, "ignore_ragdoll" ) ) + return; + } + + if ( isdefined( level.noragdollents ) && level.noragdollents.size ) + { + foreach ( var_8 in level.noragdollents ) + { + if ( distancesquared( var_0.origin, var_8.origin ) < 65536 ) + return; + } + } + + wait 0.2; + + if ( !isdefined( var_0 ) ) + return; + + if ( var_0 isragdoll() ) + return; + + var_6 = var_0 getcorpseanim(); + var_10 = 0.35; + + if ( animhasnotetrack( var_6, "start_ragdoll" ) ) + { + var_11 = getnotetracktimes( var_6, "start_ragdoll" ); + + if ( isdefined( var_11 ) ) + var_10 = var_11[0]; + } + + var_12 = var_10 * getanimlength( var_6 ); + wait(var_12); + + if ( isdefined( var_0 ) ) + var_0 startragdoll(); +} + +getmostkilledby() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedby ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedby[var_4] <= var_1 ) + continue; + + var_1 = self.killedby[var_4]; + var_5 = var_4; + } + + return var_0; +} + +getmostkilled() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedplayers ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedplayers[var_4] <= var_1 ) + continue; + + var_1 = self.killedplayers[var_4]; + var_0 = var_4; + } + + return var_0; +} + +damageshellshockandrumble( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + thread maps\mp\gametypes\_weapons::onweapondamage( var_0, var_1, var_2, var_3, var_5 ); + + if ( !isai( self ) ) + self playrumbleonentity( "damage_heavy" ); +} + +revivesetup( var_0 ) +{ + var_1 = var_0.team; + self linkto( var_0, "tag_origin" ); + self.owner = var_0; + self.inuse = 0; + self makeusable(); + updateusablebyteam( var_1 ); + thread trackteamchanges( var_1 ); + thread revivetriggerthink( var_1 ); + thread deleteonreviveordeathordisconnect(); +} + +deleteonreviveordeathordisconnect() +{ + self endon( "death" ); + self.owner common_scripts\utility::waittill_any( "death", "disconnect" ); + self delete(); +} + +updateusablebyteam( var_0 ) +{ + foreach ( var_2 in level.players ) + { + if ( var_0 == var_2.team && var_2 != self.owner ) + { + self enableplayeruse( var_2 ); + continue; + } + + self disableplayeruse( var_2 ); + } +} + +trackteamchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "joined_team" ); + updateusablebyteam( var_0 ); + } +} + +tracklaststandchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "player_last_stand" ); + updateusablebyteam( var_0 ); + } +} + +revivetriggerthink( var_0 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "trigger", var_1 ); + self.owner.beingrevived = 1; + + if ( isdefined( var_1.beingrevived ) && var_1.beingrevived ) + { + self.owner.beingrevived = 0; + continue; + } + + self makeunusable(); + self.owner maps\mp\_utility::freezecontrolswrapper( 1 ); + var_2 = useholdthink( var_1 ); + self.owner.beingrevived = 0; + + if ( !isalive( self.owner ) ) + { + self delete(); + return; + } + + self.owner maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( var_2 ) + { + var_1 thread maps\mp\gametypes\_hud_message::splashnotifydelayed( "reviver", maps\mp\gametypes\_rank::getscoreinfovalue( "reviver" ) ); + var_1 thread maps\mp\gametypes\_rank::giverankxp( "reviver" ); + self.owner.laststand = undefined; + self.owner maps\mp\_utility::clearlowermessage( "last_stand" ); + self.owner.movespeedscaler = 1; + + if ( self.owner maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.owner.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + self.owner common_scripts\utility::_enableweapon(); + self.owner.maxhealth = 100; + self.owner maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.owner maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + self.owner maps\mp\_utility::giveperk( "specialty_pistoldeath", 0 ); + self.owner.beingrevived = 0; + self delete(); + return; + } + + self makeusable(); + updateusablebyteam( var_0 ); + } +} + +useholdthink( var_0, var_1 ) +{ + var_2 = 3000; + var_3 = spawn( "script_origin", self.origin ); + var_3 hide(); + var_0 playerlinkto( var_3 ); + var_0 playerlinkedoffsetenable(); + var_0 common_scripts\utility::_disableweapon(); + self.curprogress = 0; + self.inuse = 1; + self.userate = 0; + + if ( isdefined( var_1 ) ) + self.usetime = var_1; + else + self.usetime = var_2; + + var_4 = useholdthinkloop( var_0 ); + self.inuse = 0; + var_3 delete(); + + if ( isdefined( var_0 ) && maps\mp\_utility::isreallyalive( var_0 ) ) + { + var_0 unlink(); + var_0 common_scripts\utility::_enableweapon(); + } + + if ( isdefined( var_4 ) && var_4 ) + { + self.owner thread maps\mp\gametypes\_hud_message::playercardsplashnotify( "revived", var_0 ); + self.owner.inlaststand = 0; + return 1; + } + + return 0; +} + +useholdthinkloop( var_0 ) +{ + level endon( "game_ended" ); + self.owner endon( "death" ); + self.owner endon( "disconnect" ); + + while ( maps\mp\_utility::isreallyalive( var_0 ) && var_0 usebuttonpressed() && self.curprogress < self.usetime && ( !isdefined( var_0.laststand ) || !var_0.laststand ) ) + { + self.curprogress += 50 * self.userate; + self.userate = 1; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + + if ( self.curprogress >= self.usetime ) + { + self.inuse = 0; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return maps\mp\_utility::isreallyalive( var_0 ); + } + + wait 0.05; + } + + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return 0; +} + +callback_killingblow( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( isdefined( self.lastdamagewasfromenemy ) && self.lastdamagewasfromenemy && var_2 >= self.health && isdefined( self.combathigh ) && self.combathigh == "specialty_endgame" ) + { + maps\mp\_utility::giveperk( "specialty_endgame", 0 ); + return 0; + } + + return 1; +} + +emitfalldamage( var_0 ) +{ + physicsexplosionsphere( self.origin, 64, 64, 1 ); + var_1 = []; + + for ( var_2 = 0; var_2 < 360; var_2 += 30 ) + { + var_3 = cos( var_2 ) * 16; + var_4 = sin( var_2 ) * 16; + var_5 = bullettrace( self.origin + ( var_3, var_4, 4 ), self.origin + ( var_3, var_4, -6 ), 1, self ); + + if ( isdefined( var_5["entity"] ) && isdefined( var_5["entity"].targetname ) && ( var_5["entity"].targetname == "destructible_vehicle" || var_5["entity"].targetname == "destructible_toy" ) ) + var_1[var_1.size] = var_5["entity"]; + } + + if ( var_1.size ) + { + var_6 = spawn( "script_origin", self.origin ); + var_6 hide(); + var_6.type = "soft_landing"; + var_6.destructibles = var_1; + radiusdamage( self.origin, 64, 100, 100, var_6 ); + wait 0.1; + var_6 delete(); + } +} + +isflankkill( var_0, var_1 ) +{ + var_2 = anglestoforward( var_0.angles ); + var_2 = ( var_2[0], var_2[1], 0 ); + var_2 = vectornormalize( var_2 ); + var_3 = var_0.origin - var_1.origin; + var_3 = ( var_3[0], var_3[1], 0 ); + var_3 = vectornormalize( var_3 ); + var_4 = vectordot( var_2, var_3 ); + + if ( var_4 > 0 ) + return 1; + else + return 0; +} + +logprintplayerdeath( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = self getentitynumber(); + var_8 = self.name; + var_9 = self.team; + var_10 = self.guid; + + if ( isplayer( var_1 ) ) + { + var_11 = var_1.guid; + var_12 = var_1.name; + var_13 = var_1.team; + var_14 = var_1 getentitynumber(); + var_15 = var_1 getxuid() + "(" + var_12 + ")"; + } + else + { + var_11 = ""; + var_12 = ""; + var_13 = "world"; + var_14 = -1; + var_15 = "none"; + } + + logprint( "k;" + var_10 + ";" + var_7 + ";" + var_9 + ";" + var_8 + ";" + var_11 + ";" + var_14 + ";" + var_13 + ";" + var_12 + ";" + var_4 + ";" + var_2 + ";" + var_3 + ";" + var_6 + "\n" ); +} + +destroyonreviveentdeath( var_0 ) +{ + var_0 waittill( "death" ); + self destroy(); +} + +gamemodemodifyplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) +{ + if ( isdefined( var_1 ) && isplayer( var_1 ) && isalive( var_1 ) ) + { + if ( level.matchrules_damagemultiplier ) + var_2 *= level.matchrules_damagemultiplier; + + if ( level.matchrules_vampirism ) + var_1.health = int( min( float( var_1.maxhealth ), float( var_1.health + 20 ) ) ); + } + + return var_2; +} + +registerkill( var_0, var_1 ) +{ + thread maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.pers["cur_kill_streak"]++; + + if ( var_1 ) + self notify( "kill_streak_increased" ); + + var_2 = !maps\mp\_utility::iskillstreakweapon( var_0 ); + + if ( var_2 ) + self.pers["cur_kill_streak_for_nuke"]++; + + var_3 = 25; + + if ( maps\mp\_utility::_hasperk( "specialty_hardline" ) ) + var_3--; + + if ( var_2 && self.pers["cur_kill_streak_for_nuke"] == var_3 && !maps\mp\_utility::isanymlgmatch() ) + { + if ( !isdefined( level.supportnuke ) || level.supportnuke ) + giveultimatekillstreak( var_3 ); + } +} + +giveultimatekillstreak( var_0 ) +{ + thread maps\mp\killstreaks\_killstreaks::givekillstreak( "nuke", 0, 1, self ); + thread maps\mp\gametypes\_hud_message::killstreaksplashnotify( "nuke", var_0 ); +} + +monitordamage( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + if ( !isdefined( var_5 ) ) + var_5 = 0; + + self setcandamage( 1 ); + self.health = 999999; + self.maxhealth = var_0; + self.damagetaken = 0; + + if ( !isdefined( var_4 ) ) + var_4 = 0; + + for ( var_6 = 1; var_6; var_6 = monitordamageoneshot( var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16, var_1, var_2, var_3, var_4 ) ) + { + self waittill( "damage", var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16 ); + + if ( var_5 ) + self playrumbleonentity( "damage_light" ); + + if ( isdefined( self.helitype ) && self.helitype == "littlebird" ) + { + if ( !isdefined( self.attackers ) ) + self.attackers = []; + + var_17 = ""; + + if ( isdefined( var_8 ) && isplayer( var_8 ) ) + var_17 = var_8 maps\mp\_utility::getuniqueid(); + + if ( isdefined( self.attackers[var_17] ) ) + self.attackers[var_17] += var_7; + else + self.attackers[var_17] = var_7; + } + } +} + +monitordamageoneshot( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13 ) +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( var_1 ) && !maps\mp\_utility::isgameparticipant( var_1 ) && !isdefined( var_1.allowmonitoreddamage ) ) + return 1; + + if ( maps\mp\_utility::is_aliens() || isdefined( var_1 ) && !maps\mp\gametypes\_weapons::friendlyfirecheck( self.owner, var_1 ) ) + return 1; + + var_14 = var_0; + + if ( isdefined( var_9 ) ) + { + switch ( var_9 ) + { + case "flash_grenade_mp": + case "smoke_grenade_mp": + case "smoke_grenadejugg_mp": + case "concussion_grenade_mp": + return 1; + } + + if ( !isdefined( var_12 ) ) + var_12 = ::modifydamage; + + var_14 = [[ var_12 ]]( var_1, var_9, var_4, var_0 ); + } + + if ( var_14 < 0 ) + return 1; + + self.wasdamaged = 1; + self.damagetaken += var_14; + + if ( isdefined( var_8 ) && var_8 & level.idflags_penetration ) + self.wasdamagedfrombulletpenetration = 1; + + if ( var_13 ) + maps\mp\killstreaks\_killstreaks::killstreakhit( var_1, var_9, self ); + + if ( isdefined( var_1 ) ) + { + if ( isplayer( var_1 ) ) + { + if ( self.damagetaken >= self.maxhealth ) + var_10 = "hitkill"; + + var_1 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + else if ( isdefined( var_1.owner ) && isplayer( var_1.owner ) ) + var_1.owner maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + + if ( self.damagetaken >= self.maxhealth ) + { + self thread [[ var_11 ]]( var_1, var_9, var_4, var_0 ); + return 0; + } + + return 1; +} + +modifydamage( var_0, var_1, var_2, var_3 ) +{ + var_4 = var_3; + var_4 = handleempdamage( var_1, var_2, var_4 ); + var_4 = handlemissiledamage( var_1, var_2, var_4 ); + var_4 = handlegrenadedamage( var_1, var_2, var_4 ); + var_4 = handleapdamage( var_1, var_2, var_4, var_0 ); + return var_4; +} + +handlemissiledamage( var_0, var_1, var_2 ) +{ + var_3 = var_2; + + switch ( var_0 ) + { + case "bomb_site_mp": + case "iw6_maawschild_mp": + case "iw6_maawshoming_mp": + case "iw6_maaws_mp": + case "iw6_panzerfaust3_mp": + case "drone_hive_projectile_mp": + case "odin_projectile_large_rod_mp": + case "odin_projectile_small_rod_mp": + case "aamissile_projectile_mp": + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "maverick_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = self.maxhealth + 1; + break; + case "remote_tank_projectile_mp": + case "switch_blade_child_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + self.largeprojectiledamage = 0; + var_3 = self.maxhealth + 1; + break; + case "heli_pilot_turret_mp": + case "a10_30mm_turret_mp": + self.largeprojectiledamage = 0; + var_3 *= 2; + break; + case "sam_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = var_2; + break; + } + + return var_3; +} + +handlegrenadedamage( var_0, var_1, var_2 ) +{ + if ( isexplosivedamagemod( var_1 ) ) + { + switch ( var_0 ) + { + case "mortar_shell_mp": + case "c4_mp": + case "proximity_explosive_mp": + case "iw6_rgm_mp": + var_2 *= 3; + break; + case "frag_grenade_mp": + case "semtex_mp": + case "semtexproj_mp": + case "iw6_mk32_mp": + var_2 *= 4; + break; + default: + if ( maps\mp\_utility::isstrstart( var_0, "alt_" ) ) + var_2 *= 3; + + break; + } + } + + return var_2; +} + +handlemeleedamage( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_MELEE" ) + return self.maxhealth + 1; + + return var_2; +} + +handleempdamage( var_0, var_1, var_2 ) +{ + if ( var_0 == "emp_grenade_mp" && var_1 == "MOD_GRENADE_SPLASH" ) + { + self notify( "emp_damage", var_0.owner, 8.0 ); + return 0; + } + + return var_2; +} + +handleapdamage( var_0, var_1, var_2, var_3 ) +{ + if ( var_1 == "MOD_RIFLE_BULLET" || var_1 == "MOD_PISTOL_BULLET" ) + { + if ( var_3 maps\mp\_utility::_hasperk( "specialty_armorpiercing" ) || maps\mp\_utility::isfmjdamage( var_0, var_1, var_3 ) ) + return var_2 * level.armorpiercingmod; + } + + return var_2; +} + +onkillstreakkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = 0; + var_8 = undefined; + + if ( isdefined( var_0 ) && isdefined( self.owner ) ) + { + if ( isdefined( var_0.owner ) && isplayer( var_0.owner ) ) + var_0 = var_0.owner; + + if ( self.owner maps\mp\_utility::isenemy( var_0 ) ) + var_8 = var_0; + } + + if ( isdefined( var_8 ) ) + { + var_8 notify( "destroyed_killstreak", var_1 ); + var_9 = 100; + + if ( isdefined( var_4 ) ) + { + var_9 = maps\mp\gametypes\_rank::getscoreinfovalue( var_4 ); + var_8 thread maps\mp\gametypes\_rank::xpeventpopup( var_4 ); + } + + var_8 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_9, var_1, var_2 ); + + if ( isdefined( var_6 ) ) + thread maps\mp\_utility::teamplayercardsplash( var_6, var_8 ); + + thread maps\mp\gametypes\_missions::killstreakkilled( self.owner, self, undefined, var_8, var_3, var_2, var_1 ); + var_7 = 1; + } + + if ( isdefined( self.owner ) && isdefined( var_5 ) ) + self.owner thread maps\mp\_utility::leaderdialogonplayer( var_5, undefined, undefined, self.origin ); + + self notify( "death" ); + return var_7; +} diff --git a/data/maps/mp/gametypes/_gamelogic.gsc b/data/maps/mp/gametypes/_gamelogic.gsc new file mode 100644 index 0000000..359f60a --- /dev/null +++ b/data/maps/mp/gametypes/_gamelogic.gsc @@ -0,0 +1,2770 @@ +// IW6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool + +onforfeit( var_0 ) +{ + if ( isdefined( level.forfeitinprogress ) ) + return; + + level endon( "abort_forfeit" ); + level thread forfeitwaitforabort(); + level.forfeitinprogress = 1; + + if ( !level.teambased && level.players.size > 1 ) + wait 10; + else + wait 1.05; + + level.forfeit_aborted = 0; + var_1 = 20.0; + matchforfeittimer( var_1 ); + var_2 = &""; + + if ( !isdefined( var_0 ) ) + { + level.finalkillcam_winner = "none"; + var_2 = game["end_reason"]["players_forfeited"]; + var_3 = level.players[0]; + } + else if ( var_0 == "axis" ) + { + level.finalkillcam_winner = "axis"; + var_2 = game["end_reason"]["allies_forfeited"]; + var_3 = "axis"; + } + else if ( var_0 == "allies" ) + { + level.finalkillcam_winner = "allies"; + var_2 = game["end_reason"]["axis_forfeited"]; + var_3 = "allies"; + } + else if ( level.multiteambased && issubstr( var_0, "team_" ) ) + var_3 = var_0; + else + { + level.finalkillcam_winner = "none"; + var_3 = "tie"; + } + + level.forcedend = 1; + + if ( isplayer( var_3 ) ) + logstring( "forfeit, win: " + var_3 getxuid() + "(" + var_3.name + ")" ); + else + logstring( "forfeit, win: " + var_3 + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + + thread endgame( var_3, var_2 ); +} + +forfeitwaitforabort() +{ + level endon( "game_ended" ); + level waittill( "abort_forfeit" ); + level.forfeit_aborted = 1; + setomnvar( "ui_match_start_countdown", 0 ); +} + +matchforfeittimer_internal( var_0 ) +{ + waittillframeend; + level endon( "match_forfeit_timer_beginning" ); + + while ( var_0 > 0 && !level.gameended && !level.forfeit_aborted && !level.ingraceperiod ) + { + setomnvar( "ui_match_start_countdown", var_0 ); + var_0--; + maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( 1.0 ); + } + + setomnvar( "ui_match_start_countdown", 0 ); +} + +matchforfeittimer( var_0 ) +{ + level notify( "match_forfeit_timer_beginning" ); + var_1 = int( var_0 ); + setomnvar( "ui_match_start_text", "opponent_forfeiting_in" ); + matchforfeittimer_internal( var_1 ); +} + +default_ondeadevent( var_0 ) +{ + level.finalkillcam_winner = "none"; + + if ( var_0 == "allies" ) + { + iprintln( &"MP_GHOSTS_ELIMINATED" ); + logstring( "team eliminated, win: opfor, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + level.finalkillcam_winner = "axis"; + thread endgame( "axis", game["end_reason"]["allies_eliminated"] ); + } + else if ( var_0 == "axis" ) + { + iprintln( &"MP_FEDERATION_ELIMINATED" ); + logstring( "team eliminated, win: allies, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + level.finalkillcam_winner = "allies"; + thread endgame( "allies", game["end_reason"]["axis_eliminated"] ); + } + else + { + logstring( "tie, allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + level.finalkillcam_winner = "none"; + + if ( level.teambased ) + thread endgame( "tie", game["end_reason"]["tie"] ); + else + thread endgame( undefined, game["end_reason"]["tie"] ); + } +} + +default_ononeleftevent( var_0 ) +{ + if ( level.teambased ) + { + var_1 = maps\mp\_utility::getlastlivingplayer( var_0 ); + + if ( isdefined( var_1 ) ) + var_1 thread givelastonteamwarning(); + } + else + { + var_1 = maps\mp\_utility::getlastlivingplayer(); + logstring( "last one alive, win: " + var_1.name ); + level.finalkillcam_winner = "none"; + thread endgame( var_1, game["end_reason"]["enemies_eliminated"] ); + } + + return 1; +} + +default_ontimelimit() +{ + var_0 = undefined; + level.finalkillcam_winner = "none"; + + if ( level.teambased ) + { + if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] ) + var_0 = "tie"; + else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] ) + { + level.finalkillcam_winner = "axis"; + var_0 = "axis"; + } + else + { + level.finalkillcam_winner = "allies"; + var_0 = "allies"; + } + + logstring( "time limit, win: " + var_0 + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + } + else + { + var_0 = maps\mp\gametypes\_gamescore::gethighestscoringplayer(); + + if ( isdefined( var_0 ) ) + logstring( "time limit, win: " + var_0.name ); + else + logstring( "time limit, tie" ); + } + + thread endgame( var_0, game["end_reason"]["time_limit_reached"] ); +} + +default_onhalftime() +{ + var_0 = undefined; + level.finalkillcam_winner = "none"; + thread endgame( "halftime", game["end_reason"]["time_limit_reached"] ); +} + +forceend( var_0 ) +{ + if ( level.hostforcedend || level.forcedend ) + return; + + var_1 = undefined; + level.finalkillcam_winner = "none"; + + if ( level.teambased ) + { + if ( getdvarint( "squad_match" ) == 1 && isdefined( var_0 ) && var_0 == 2 ) + var_1 = "axis"; + else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] ) + var_1 = "tie"; + else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] ) + { + level.finalkillcam_winner = "axis"; + var_1 = "axis"; + } + else + { + level.finalkillcam_winner = "allies"; + var_1 = "allies"; + } + + logstring( "host ended game, win: " + var_1 + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + } + else + { + var_1 = maps\mp\gametypes\_gamescore::gethighestscoringplayer(); + + if ( isdefined( var_1 ) ) + logstring( "host ended game, win: " + var_1.name ); + else + logstring( "host ended game, tie" ); + } + + level.forcedend = 1; + level.hostforcedend = 1; + + if ( level.splitscreen ) + var_2 = game["end_reason"]["ended_game"]; + else + var_2 = game["end_reason"]["host_ended_game"]; + + if ( isdefined( var_0 ) && var_0 == 2 ) + var_2 = game["end_reason"]["allies_forfeited"]; + + level notify( "force_end" ); + thread endgame( var_1, var_2 ); +} + +onscorelimit() +{ + var_0 = game["end_reason"]["score_limit_reached"]; + var_1 = undefined; + level.finalkillcam_winner = "none"; + + if ( level.multiteambased ) + { + var_1 = maps\mp\gametypes\_gamescore::getwinningteam(); + + if ( var_1 == "none" ) + var_1 = "tie"; + } + else if ( level.teambased ) + { + if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] ) + var_1 = "tie"; + else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] ) + { + var_1 = "axis"; + level.finalkillcam_winner = "axis"; + } + else + { + var_1 = "allies"; + level.finalkillcam_winner = "allies"; + } + + logstring( "scorelimit, win: " + var_1 + ", allies: " + game["teamScores"]["allies"] + ", opfor: " + game["teamScores"]["axis"] ); + } + else + { + var_1 = maps\mp\gametypes\_gamescore::gethighestscoringplayer(); + + if ( isdefined( var_1 ) ) + logstring( "scorelimit, win: " + var_1.name ); + else + logstring( "scorelimit, tie" ); + } + + thread endgame( var_1, var_0 ); + return 1; +} + +updategameevents() +{ + if ( maps\mp\_utility::matchmakinggame() && !level.ingraceperiod && ( !isdefined( level.disableforfeit ) || !level.disableforfeit ) ) + { + if ( level.multiteambased ) + { + var_0 = 0; + var_1 = 0; + + for ( var_2 = 0; var_2 < level.teamnamelist.size; var_2++ ) + { + var_0 = var_0 + level.teamcount[level.teamnamelist[var_2]]; + + if ( level.teamcount[level.teamnamelist[var_2]] ) + var_1 = var_1 + 1; + } + + for ( var_2 = 0; var_2 < level.teamnamelist.size; var_2++ ) + { + if ( var_0 == level.teamcount[level.teamnamelist[var_2]] && game["state"] == "playing" ) + { + thread onforfeit( level.teamnamelist[var_2] ); + return; + } + } + + if ( var_1 > 1 ) + { + level.forfeitinprogress = undefined; + level notify( "abort_forfeit" ); + } + } + else if ( level.teambased ) + { + if ( level.teamcount["allies"] < 1 && level.teamcount["axis"] > 0 && game["state"] == "playing" ) + { + thread onforfeit( "axis" ); + return; + } + + if ( level.teamcount["axis"] < 1 && level.teamcount["allies"] > 0 && game["state"] == "playing" ) + { + thread onforfeit( "allies" ); + return; + } + + if ( level.teamcount["axis"] > 0 && level.teamcount["allies"] > 0 ) + { + level.forfeitinprogress = undefined; + level notify( "abort_forfeit" ); + } + } + else + { + if ( level.teamcount["allies"] + level.teamcount["axis"] == 1 && level.maxplayercount > 1 ) + { + thread onforfeit(); + return; + } + + if ( level.teamcount["axis"] + level.teamcount["allies"] > 1 ) + { + level.forfeitinprogress = undefined; + level notify( "abort_forfeit" ); + } + } + } + + if ( !maps\mp\_utility::getgametypenumlives() && ( !isdefined( level.disablespawning ) || !level.disablespawning ) ) + return; + + if ( !maps\mp\_utility::gamehasstarted() ) + return; + + if ( level.ingraceperiod ) + return; + + if ( level.multiteambased ) + return; + + if ( level.teambased ) + { + var_3["allies"] = level.livescount["allies"]; + var_3["axis"] = level.livescount["axis"]; + + if ( isdefined( level.disablespawning ) && level.disablespawning ) + { + var_3["allies"] = 0; + var_3["axis"] = 0; + } + + if ( !level.alivecount["allies"] && !level.alivecount["axis"] && !var_3["allies"] && !var_3["axis"] ) + return [[ level.ondeadevent ]]( "all" ); + + if ( !level.alivecount["allies"] && !var_3["allies"] ) + return [[ level.ondeadevent ]]( "allies" ); + + if ( !level.alivecount["axis"] && !var_3["axis"] ) + return [[ level.ondeadevent ]]( "axis" ); + + var_4 = level.alivecount["allies"] == 1 && !var_3["allies"]; + var_5 = level.alivecount["axis"] == 1 && !var_3["axis"]; + + if ( var_4 || var_5 ) + { + var_6 = undefined; + + if ( var_4 && !isdefined( level.onelefttime["allies"] ) ) + { + level.onelefttime["allies"] = gettime(); + var_7 = [[ level.ononeleftevent ]]( "allies" ); + + if ( isdefined( var_7 ) ) + { + if ( !isdefined( var_6 ) ) + var_6 = var_7; + + var_6 = var_6 || var_7; + } + } + + if ( var_5 && !isdefined( level.onelefttime["axis"] ) ) + { + level.onelefttime["axis"] = gettime(); + var_8 = [[ level.ononeleftevent ]]( "axis" ); + + if ( isdefined( var_8 ) ) + { + if ( !isdefined( var_6 ) ) + var_6 = var_8; + + var_6 = var_6 || var_8; + } + } + + return var_6; + return; + } + } + else + { + if ( !level.alivecount["allies"] && !level.alivecount["axis"] && ( !level.livescount["allies"] && !level.livescount["axis"] ) ) + return [[ level.ondeadevent ]]( "all" ); + + var_9 = maps\mp\_utility::getpotentiallivingplayers(); + + if ( var_9.size == 1 ) + return [[ level.ononeleftevent ]]( "all" ); + } +} + +waittillfinalkillcamdone() +{ + if ( !isdefined( level.finalkillcam_winner ) ) + return 0; + + level waittill( "final_killcam_done" ); + return 1; +} + +timelimitclock_intermission( var_0 ) +{ + setgameendtime( gettime() + int( var_0 * 1000 ) ); + var_1 = spawn( "script_origin", ( 0, 0, 0 ) ); + var_1 hide(); + + if ( var_0 >= 10.0 ) + wait( var_0 - 10.0 ); + + for (;;) + { + var_1 playsound( "ui_mp_timer_countdown" ); + wait 1.0; + } +} + +waitforplayers( var_0 ) +{ + var_1 = gettime(); + var_2 = var_1 + var_0 * 1000 - 200; + + if ( var_0 > 5 ) + var_3 = gettime() + getdvarint( "min_wait_for_players" ) * 1000; + else + var_3 = 0; + + var_4 = level.connectingplayers / 3; + + for (;;) + { + if ( isdefined( game["roundsPlayed"] ) && game["roundsPlayed"] ) + break; + + var_5 = level.maxplayercount; + var_6 = gettime(); + + if ( var_5 >= var_4 && var_6 > var_3 || var_6 > var_2 ) + break; + + wait 0.05; + } +} + +prematchperiod() +{ + level endon( "game_ended" ); + level.connectingplayers = getdvarint( "party_partyPlayerCountNum" ); + + if ( level.prematchperiod > 0 ) + matchstarttimerwaitforplayers(); + else + matchstarttimerskip(); + + foreach ( var_1 in level.players ) + { + var_1 maps\mp\_utility::freezecontrolswrapper( 0 ); + var_1 enableweapons(); + + if ( !isdefined( var_1.pers["team"] ) ) + continue; + + var_2 = var_1.pers["team"]; + var_3 = maps\mp\_utility::getobjectivehinttext( var_2 ); + + if ( !isdefined( var_3 ) || !var_1.hasspawned ) + continue; + + var_4 = 0; + + if ( game["defenders"] == var_2 ) + var_4 = 1; + + var_1 setclientomnvar( "ui_objective_text", var_4 ); + } + + if ( game["state"] != "playing" ) + return; +} + +graceperiod() +{ + level endon( "game_ended" ); + + if ( !isdefined( game["clientActive"] ) ) + { + while ( getactiveclientcount() == 0 ) + wait 0.05; + + game["clientActive"] = 1; + } + + while ( level.ingraceperiod > 0 ) + { + wait 1.0; + level.ingraceperiod--; + } + + level notify( "grace_period_ending" ); + wait 0.05; + maps\mp\_utility::gameflagset( "graceperiod_done" ); + level.ingraceperiod = 0; + + if ( game["state"] != "playing" ) + return; + + if ( maps\mp\_utility::getgametypenumlives() ) + { + var_0 = level.players; + + for ( var_1 = 0; var_1 < var_0.size; var_1++ ) + { + var_2 = var_0[var_1]; + + if ( !var_2.hasspawned && var_2.sessionteam != "spectator" && !isalive( var_2 ) ) + var_2.statusicon = "hud_status_dead"; + } + } + + level thread updategameevents(); +} + +sethasdonecombat( var_0, var_1 ) +{ + var_0.hasdonecombat = var_1; + var_2 = !isdefined( var_0.hasdoneanycombat ) || !var_0.hasdoneanycombat; + + if ( var_2 && var_1 ) + { + var_0.hasdoneanycombat = 1; + + if ( isdefined( var_0.pers["hasMatchLoss"] ) && var_0.pers["hasMatchLoss"] ) + return; + + if ( !maps\mp\_utility::is_aliens() ) + updatelossstats( var_0 ); + } +} + +updatewinstats( var_0 ) +{ + if ( !var_0 maps\mp\_utility::rankingenabled() ) + return; + + if ( !isdefined( var_0.hasdoneanycombat ) || !var_0.hasdoneanycombat ) + return; + + if ( !issquadsmode() ) + { + var_0 maps\mp\gametypes\_persistence::statadd( "losses", -1 ); + var_0 maps\mp\gametypes\_persistence::statadd( "wins", 1 ); + var_0 maps\mp\_utility::updatepersratio( "winLossRatio", "wins", "losses" ); + var_0 maps\mp\gametypes\_persistence::statadd( "currentWinStreak", 1 ); + var_1 = var_0 maps\mp\gametypes\_persistence::statget( "currentWinStreak" ); + + if ( var_1 > var_0 maps\mp\gametypes\_persistence::statget( "winStreak" ) ) + var_0 maps\mp\gametypes\_persistence::statset( "winStreak", var_1 ); + } + + var_0 maps\mp\gametypes\_persistence::statsetchild( "round", "win", 1 ); + var_0 maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 0 ); +} + +updatelossstats( var_0 ) +{ + if ( !var_0 maps\mp\_utility::rankingenabled() ) + return; + + if ( !isdefined( var_0.hasdoneanycombat ) || !var_0.hasdoneanycombat ) + return; + + var_0.pers["hasMatchLoss"] = 1; + + if ( !issquadsmode() ) + { + var_0 maps\mp\gametypes\_persistence::statadd( "losses", 1 ); + var_0 maps\mp\_utility::updatepersratio( "winLossRatio", "wins", "losses" ); + maps\mp\gametypes\_persistence::statadd( "gamesPlayed", 1 ); + } + + var_0 maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 1 ); +} + +updatetiestats( var_0 ) +{ + if ( !var_0 maps\mp\_utility::rankingenabled() ) + return; + + if ( !isdefined( var_0.hasdoneanycombat ) || !var_0.hasdoneanycombat ) + return; + + if ( !issquadsmode() ) + { + var_0 maps\mp\gametypes\_persistence::statadd( "losses", -1 ); + var_0 maps\mp\gametypes\_persistence::statadd( "ties", 1 ); + var_0 maps\mp\_utility::updatepersratio( "winLossRatio", "wins", "losses" ); + var_0 maps\mp\gametypes\_persistence::statset( "currentWinStreak", 0 ); + } + + var_0 maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 0 ); +} + +updatewinlossstats( var_0 ) +{ + if ( maps\mp\_utility::privatematch() ) + return; + + if ( !maps\mp\_utility::waslastround() ) + return; + + var_1 = level.players; + updateplayercombatstatus(); + + if ( !isdefined( var_0 ) || isdefined( var_0 ) && isstring( var_0 ) && var_0 == "tie" ) + { + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) ) + continue; + + if ( level.hostforcedend && var_3 ishost() ) + { + if ( !issquadsmode() ) + var_3 maps\mp\gametypes\_persistence::statset( "currentWinStreak", 0 ); + + continue; + } + + updatetiestats( var_3 ); + } + } + else if ( isplayer( var_0 ) ) + { + if ( level.hostforcedend && var_0 ishost() ) + { + if ( !issquadsmode() ) + var_0 maps\mp\gametypes\_persistence::statset( "currentWinStreak", 0 ); + + return; + } + + updatewinstats( var_0 ); + } + else if ( isstring( var_0 ) ) + { + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) ) + continue; + + if ( level.hostforcedend && var_3 ishost() ) + { + if ( !issquadsmode() ) + var_3 maps\mp\gametypes\_persistence::statset( "currentWinStreak", 0 ); + + continue; + } + + if ( var_0 == "tie" ) + { + updatetiestats( var_3 ); + continue; + } + + if ( var_3.pers["team"] == var_0 ) + { + updatewinstats( var_3 ); + continue; + } + + if ( !issquadsmode() ) + var_3 maps\mp\gametypes\_persistence::statset( "currentWinStreak", 0 ); + } + } +} + +updateplayercombatstatus() +{ + if ( level.gametype != "infect" ) + return; + + foreach ( var_1 in level.players ) + { + if ( var_1.sessionstate == "spectator" && !var_1.spectatekillcam ) + continue; + else if ( isdefined( var_1.hasdoneanycombat ) && var_1.hasdoneanycombat ) + continue; + else if ( var_1.team == "axis" ) + continue; + else + var_1 sethasdonecombat( var_1, 1 ); + } +} + +freezeplayerforroundend( var_0 ) +{ + self endon( "disconnect" ); + maps\mp\_utility::clearlowermessages(); + + if ( !isdefined( var_0 ) ) + var_0 = 0.05; + + wait( var_0 ); + maps\mp\_utility::freezecontrolswrapper( 1 ); +} + +updatematchbonusscores( var_0 ) +{ + if ( !game["timePassed"] ) + return; + + if ( !maps\mp\_utility::matchmakinggame() ) + return; + + if ( !maps\mp\_utility::gettimelimit() || level.forcedend ) + { + var_1 = maps\mp\_utility::gettimepassed() / 1000; + var_1 = min( var_1, 1200 ); + } + else + var_1 = maps\mp\_utility::gettimelimit() * 60; + + if ( level.teambased ) + { + if ( var_0 == "allies" ) + { + var_2 = "allies"; + var_3 = "axis"; + } + else if ( var_0 == "axis" ) + { + var_2 = "axis"; + var_3 = "allies"; + } + else + { + var_2 = "tie"; + var_3 = "tie"; + } + + if ( var_2 != "tie" ) + { + var_4 = maps\mp\gametypes\_rank::getscoreinfovalue( "win" ); + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "loss" ); + setwinningteam( var_2 ); + } + else + { + var_4 = maps\mp\gametypes\_rank::getscoreinfovalue( "tie" ); + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "tie" ); + } + + foreach ( var_7 in level.players ) + { + if ( isdefined( var_7.connectedpostgame ) ) + continue; + + if ( !var_7 maps\mp\_utility::rankingenabled() ) + continue; + + if ( var_7.timeplayed["total"] < 1 || var_7.pers["participation"] < 1 ) + { + var_7 thread maps\mp\gametypes\_rank::endgameupdate(); + continue; + } + + if ( level.hostforcedend && var_7 ishost() ) + continue; + + if ( !isdefined( var_7.hasdoneanycombat ) || !var_7.hasdoneanycombat ) + continue; + + var_8 = var_7 maps\mp\gametypes\_rank::getspm(); + + if ( var_2 == "tie" ) + { + var_9 = int( var_4 * ( var_1 / 60 * var_8 ) * ( var_7.timeplayed["total"] / var_1 ) ); + var_7 thread givematchbonus( "tie", var_9 ); + var_7.matchbonus = var_9; + continue; + } + + if ( isdefined( var_7.pers["team"] ) && var_7.pers["team"] == var_2 ) + { + var_9 = int( var_4 * ( var_1 / 60 * var_8 ) * ( var_7.timeplayed["total"] / var_1 ) ); + var_7 thread givematchbonus( "win", var_9 ); + var_7.matchbonus = var_9; + continue; + } + + if ( isdefined( var_7.pers["team"] ) && var_7.pers["team"] == var_3 ) + { + var_9 = int( var_5 * ( var_1 / 60 * var_8 ) * ( var_7.timeplayed["total"] / var_1 ) ); + var_7 thread givematchbonus( "loss", var_9 ); + var_7.matchbonus = var_9; + } + } + } + else + { + if ( isdefined( var_0 ) ) + { + var_4 = maps\mp\gametypes\_rank::getscoreinfovalue( "win" ); + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "loss" ); + } + else + { + var_4 = maps\mp\gametypes\_rank::getscoreinfovalue( "tie" ); + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "tie" ); + } + + foreach ( var_7 in level.players ) + { + if ( isdefined( var_7.connectedpostgame ) ) + continue; + + if ( var_7.timeplayed["total"] < 1 || var_7.pers["participation"] < 1 ) + { + var_7 thread maps\mp\gametypes\_rank::endgameupdate(); + continue; + } + + if ( !isdefined( var_7.hasdoneanycombat ) || !var_7.hasdoneanycombat ) + continue; + + var_8 = var_7 maps\mp\gametypes\_rank::getspm(); + var_12 = 0; + + for ( var_13 = 0; var_13 < min( level.placement["all"].size, 3 ); var_13++ ) + { + if ( level.placement["all"][var_13] != var_7 ) + continue; + + var_12 = 1; + } + + if ( var_12 ) + { + var_9 = int( var_4 * ( var_1 / 60 * var_8 ) * ( var_7.timeplayed["total"] / var_1 ) ); + var_7 thread givematchbonus( "win", var_9 ); + var_7.matchbonus = var_9; + continue; + } + + var_9 = int( var_5 * ( var_1 / 60 * var_8 ) * ( var_7.timeplayed["total"] / var_1 ) ); + var_7 thread givematchbonus( "loss", var_9 ); + var_7.matchbonus = var_9; + } + } +} + +givematchbonus( var_0, var_1 ) +{ + self endon( "disconnect" ); + level waittill( "give_match_bonus" ); + maps\mp\gametypes\_rank::giverankxp( var_0, var_1 ); + maps\mp\gametypes\_rank::endgameupdate(); +} + +setxenonranks( var_0 ) +{ + var_1 = level.players; + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + { + var_3 = var_1[var_2]; + + if ( !isdefined( var_3.score ) || !isdefined( var_3.pers["team"] ) ) + continue; + } + + for ( var_2 = 0; var_2 < var_1.size; var_2++ ) + { + var_3 = var_1[var_2]; + + if ( !isdefined( var_3.score ) || !isdefined( var_3.pers["team"] ) ) + continue; + + var_4 = var_3.score; + + if ( maps\mp\_utility::getminutespassed() ) + var_4 = var_3.score / maps\mp\_utility::getminutespassed(); + + setplayerteamrank( var_3, var_3.clientid, int( var_4 ) ); + } +} + +checktimelimit( var_0 ) +{ + if ( isdefined( level.timelimitoverride ) && level.timelimitoverride ) + return; + + if ( game["state"] != "playing" ) + { + setgameendtime( 0 ); + return; + } + + if ( maps\mp\_utility::gettimelimit() <= 0 ) + { + if ( isdefined( level.starttime ) ) + setgameendtime( level.starttime ); + else + setgameendtime( 0 ); + + return; + } + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) ) + { + setgameendtime( 0 ); + return; + } + + if ( !isdefined( level.starttime ) ) + return; + + if ( maps\mp\_utility::gettimepassedpercentage() > level.timepercentagecutoff ) + setnojiptime( 1 ); + + var_1 = gettimeremaining(); + setgameendtime( gettime() + int( var_1 ) ); + + if ( var_1 > 0 ) + return; + + [[ level.ontimelimit ]](); +} + +gettimeremaining() +{ + return maps\mp\_utility::gettimelimit() * 60 * 1000 - maps\mp\_utility::gettimepassed(); +} + +gettimeremainingpercentage() +{ + var_0 = maps\mp\_utility::gettimelimit() * 60 * 1000; + return ( var_0 - maps\mp\_utility::gettimepassed() ) / var_0; +} + +checkteamscorelimitsoon( var_0 ) +{ + if ( maps\mp\_utility::getwatcheddvar( "scorelimit" ) <= 0 || maps\mp\_utility::isobjectivebased() ) + return; + + if ( isdefined( level.scorelimitoverride ) && level.scorelimitoverride ) + return; + + if ( level.gametype == "conf" || level.gametype == "jugg" ) + return; + + if ( !level.teambased ) + return; + + if ( maps\mp\_utility::gettimepassed() < 60000 ) + return; + + var_1 = estimatedtimetillscorelimit( var_0 ); + + if ( var_1 < 2 ) + level notify( "match_ending_soon", "score" ); +} + +checkplayerscorelimitsoon() +{ + if ( maps\mp\_utility::getwatcheddvar( "scorelimit" ) <= 0 || maps\mp\_utility::isobjectivebased() ) + return; + + if ( level.teambased ) + return; + + if ( maps\mp\_utility::gettimepassed() < 60000 ) + return; + + var_0 = estimatedtimetillscorelimit(); + + if ( var_0 < 2 ) + level notify( "match_ending_soon", "score" ); +} + +checkscorelimit() +{ + if ( maps\mp\_utility::isobjectivebased() ) + return 0; + + if ( isdefined( level.scorelimitoverride ) && level.scorelimitoverride ) + return 0; + + if ( game["state"] != "playing" ) + return 0; + + if ( maps\mp\_utility::getwatcheddvar( "scorelimit" ) <= 0 ) + return 0; + + if ( level.teambased ) + { + var_0 = 0; + + for ( var_1 = 0; var_1 < level.teamnamelist.size; var_1++ ) + { + if ( game["teamScores"][level.teamnamelist[var_1]] >= maps\mp\_utility::getwatcheddvar( "scorelimit" ) ) + var_0 = 1; + } + + if ( !var_0 ) + return 0; + } + else + { + if ( !isplayer( self ) ) + return 0; + + if ( self.score < maps\mp\_utility::getwatcheddvar( "scorelimit" ) ) + return 0; + } + + return onscorelimit(); +} + +updategametypedvars() +{ + level endon( "game_ended" ); + + while ( game["state"] == "playing" ) + { + if ( isdefined( level.starttime ) ) + { + if ( gettimeremaining() < 3000 ) + { + wait 0.1; + continue; + } + } + + wait 1; + } +} + +matchstarttimerwaitforplayers() +{ + thread matchstarttimer( "match_starting_in", level.prematchperiod + level.prematchperiodend ); + waitforplayers( level.prematchperiod ); + + if ( level.prematchperiodend > 0 && !isdefined( level.hostmigrationtimer ) ) + { + var_0 = level.prematchperiodend; + + if ( maps\mp\_utility::isroundbased() && !maps\mp\_utility::isfirstround() || maps\mp\_utility::ismlgmatch() ) + var_0 = level.prematchperiod; + + matchstarttimer( "match_starting_in", var_0 ); + } +} + +matchstarttimer_internal( var_0 ) +{ + waittillframeend; + introvisionset(); + level endon( "match_start_timer_beginning" ); + + while ( var_0 > 0 && !level.gameended ) + { + setomnvar( "ui_match_start_countdown", var_0 ); + + if ( var_0 == 0 ) + visionsetnaked( "", 0 ); + + var_0--; + wait 1.0; + } + + setomnvar( "ui_match_start_countdown", 0 ); +} + +matchstarttimer( var_0, var_1 ) +{ + self notify( "matchStartTimer" ); + self endon( "matchStartTimer" ); + level notify( "match_start_timer_beginning" ); + var_2 = int( var_1 ); + + if ( var_2 >= 2 ) + { + setomnvar( "ui_match_start_text", var_0 ); + matchstarttimer_internal( var_2 ); + visionsetnaked( "", 3.0 ); + } + else + { + introvisionset(); + visionsetnaked( "", 1.0 ); + } +} + +introvisionset() +{ + if ( !isdefined( level.introvisionset ) ) + level.introvisionset = "mpIntro"; + + visionsetnaked( level.introvisionset, 0 ); +} + +matchstarttimerskip() +{ + visionsetnaked( "", 0 ); +} + +onroundswitch() +{ + if ( !isdefined( game["switchedsides"] ) ) + game["switchedsides"] = 0; + + if ( game["roundsWon"]["allies"] == maps\mp\_utility::getwatcheddvar( "winlimit" ) - 1 && game["roundsWon"]["axis"] == maps\mp\_utility::getwatcheddvar( "winlimit" ) - 1 ) + { + var_0 = getbetterteam(); + + if ( var_0 != game["defenders"] ) + { + game["switchedsides"] = !game["switchedsides"]; + level.switchedsides = 1; + } + else + level.switchedsides = undefined; + + level.halftimetype = "overtime"; + } + else + { + level.halftimetype = "halftime"; + game["switchedsides"] = !game["switchedsides"]; + level.switchedsides = 1; + } +} + +checkroundswitch() +{ + if ( !level.teambased ) + return 0; + + if ( !isdefined( level.roundswitch ) || !level.roundswitch ) + return 0; + + if ( game["roundsPlayed"] % level.roundswitch == 0 ) + { + onroundswitch(); + return 1; + } + + return 0; +} + +timeuntilroundend() +{ + if ( level.gameended ) + { + var_0 = ( gettime() - level.gameendtime ) / 1000; + var_1 = level.postroundtime - var_0; + + if ( var_1 < 0 ) + return 0; + + return var_1; + } + + if ( maps\mp\_utility::gettimelimit() <= 0 ) + return undefined; + + if ( !isdefined( level.starttime ) ) + return undefined; + + var_2 = maps\mp\_utility::gettimelimit(); + var_0 = ( gettime() - level.starttime ) / 1000; + var_1 = maps\mp\_utility::gettimelimit() * 60 - var_0; + + if ( isdefined( level.timepaused ) ) + var_1 = var_1 + level.timepaused; + + return var_1 + level.postroundtime; +} + +freegameplayhudelems() +{ + if ( isdefined( self.perkicon ) ) + { + if ( isdefined( self.perkicon[0] ) ) + { + self.perkicon[0] maps\mp\gametypes\_hud_util::destroyelem(); + self.perkname[0] maps\mp\gametypes\_hud_util::destroyelem(); + } + + if ( isdefined( self.perkicon[1] ) ) + { + self.perkicon[1] maps\mp\gametypes\_hud_util::destroyelem(); + self.perkname[1] maps\mp\gametypes\_hud_util::destroyelem(); + } + + if ( isdefined( self.perkicon[2] ) ) + { + self.perkicon[2] maps\mp\gametypes\_hud_util::destroyelem(); + self.perkname[2] maps\mp\gametypes\_hud_util::destroyelem(); + } + } + + self notify( "perks_hidden" ); + self.lowermessage maps\mp\gametypes\_hud_util::destroyelem(); + self.lowertimer maps\mp\gametypes\_hud_util::destroyelem(); + + if ( isdefined( self.proxbar ) ) + self.proxbar maps\mp\gametypes\_hud_util::destroyelem(); + + if ( isdefined( self.proxbartext ) ) + self.proxbartext maps\mp\gametypes\_hud_util::destroyelem(); +} + +gethostplayer() +{ + var_0 = getentarray( "player", "classname" ); + + for ( var_1 = 0; var_1 < var_0.size; var_1++ ) + { + if ( var_0[var_1] ishost() ) + return var_0[var_1]; + } +} + +hostidledout() +{ + var_0 = gethostplayer(); + + if ( isdefined( var_0 ) && !var_0.hasspawned && !isdefined( var_0.selectedclass ) ) + return 1; + + return 0; +} + +roundendwait( var_0, var_1 ) +{ + var_2 = 0; + + while ( !var_2 ) + { + var_3 = level.players; + var_2 = 1; + + foreach ( var_5 in var_3 ) + { + if ( !isdefined( var_5.doingsplash ) ) + continue; + + if ( !var_5 maps\mp\gametypes\_hud_message::isdoingsplash() ) + continue; + + var_2 = 0; + } + + wait 0.5; + } + + if ( !var_1 ) + { + wait( var_0 ); + level notify( "round_end_finished" ); + return; + } + + wait( var_0 / 2 ); + level notify( "give_match_bonus" ); + wait( var_0 / 2 ); + var_2 = 0; + + while ( !var_2 ) + { + var_3 = level.players; + var_2 = 1; + + foreach ( var_5 in var_3 ) + { + if ( !isdefined( var_5.doingsplash ) ) + continue; + + if ( !var_5 maps\mp\gametypes\_hud_message::isdoingsplash() ) + continue; + + var_2 = 0; + } + + wait 0.5; + } + + level notify( "round_end_finished" ); +} + +roundenddof( var_0 ) +{ + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); +} + +updatesquadvssquad() +{ + for (;;) + { + setnojiptime( 1 ); + wait 0.05; + } +} + +callback_startgametype() +{ + maps\mp\_load::main(); + maps\mp\_utility::levelflaginit( "round_over", 0 ); + maps\mp\_utility::levelflaginit( "game_over", 0 ); + maps\mp\_utility::levelflaginit( "block_notifies", 0 ); + maps\mp\_utility::levelflaginit( "post_game_level_event_active", 0 ); + level.prematchperiod = 0; + level.prematchperiodend = 0; + level.postgamenotifies = 0; + level.intermission = 0; + setdvar( "bg_compassShowEnemies", getdvar( "scr_game_forceuav" ) ); + + if ( maps\mp\_utility::matchmakinggame() ) + setdvar( "isMatchMakingGame", 1 ); + else + setdvar( "isMatchMakingGame", 0 ); + + if ( level.multiteambased ) + setdvar( "ui_numteams", level.numteams ); + + if ( !isdefined( game["gamestarted"] ) ) + { + game["clientid"] = 0; + game["truncated_killcams"] = 0; + + if ( !isdefined( game["attackers"] ) || !isdefined( game["defenders"] ) ) + thread common_scripts\utility::error( "No attackers or defenders team defined in level .gsc." ); + + if ( !isdefined( game["attackers"] ) ) + game["attackers"] = "allies"; + + if ( !isdefined( game["defenders"] ) ) + game["defenders"] = "axis"; + + if ( !isdefined( game["state"] ) ) + game["state"] = "playing"; + + game["allies"] = "ghosts"; + game["axis"] = "federation"; + game["strings"]["press_to_spawn"] = &"PLATFORM_PRESS_TO_SPAWN"; + game["strings"]["spawn_next_round"] = &"MP_SPAWN_NEXT_ROUND"; + game["strings"]["spawn_flag_wait"] = &"MP_SPAWN_FLAG_WAIT"; + game["strings"]["spawn_tag_wait"] = &"MP_SPAWN_TAG_WAIT"; + game["strings"]["waiting_to_spawn"] = &"MP_WAITING_TO_SPAWN"; + game["strings"]["waiting_to_safespawn"] = &"MP_WAITING_TO_SAFESPAWN"; + game["strings"]["match_starting"] = &"MP_MATCH_STARTING"; + game["strings"]["change_class"] = &"MP_CHANGE_CLASS_NEXT_SPAWN"; + game["strings"]["last_stand"] = &"MPUI_LAST_STAND"; + game["strings"]["final_stand"] = &"MPUI_FINAL_STAND"; + game["strings"]["c4_death"] = &"MPUI_C4_DEATH"; + game["strings"]["cowards_way"] = &"PLATFORM_COWARDS_WAY_OUT"; + game["colors"]["black"] = ( 0, 0, 0 ); + game["colors"]["white"] = ( 1, 1, 1 ); + game["colors"]["grey"] = ( 0.5, 0.5, 0.5 ); + game["colors"]["cyan"] = ( 0.35, 0.7, 0.9 ); + game["colors"]["orange"] = ( 0.9, 0.6, 0 ); + game["colors"]["blue"] = ( 0.2, 0.3, 0.7 ); + game["colors"]["red"] = ( 0.75, 0.25, 0.25 ); + game["colors"]["green"] = ( 0.25, 0.75, 0.25 ); + game["colors"]["yellow"] = ( 0.65, 0.65, 0 ); + game["strings"]["allies_name"] = maps\mp\gametypes\_teams::getteamname( "allies" ); + game["icons"]["allies"] = maps\mp\gametypes\_teams::getteamicon( "allies" ); + game["colors"]["allies"] = maps\mp\gametypes\_teams::getteamcolor( "allies" ); + game["strings"]["axis_name"] = maps\mp\gametypes\_teams::getteamname( "axis" ); + game["icons"]["axis"] = maps\mp\gametypes\_teams::getteamicon( "axis" ); + game["colors"]["axis"] = maps\mp\gametypes\_teams::getteamcolor( "axis" ); + + if ( game["colors"]["allies"] == game["colors"]["black"] ) + game["colors"]["allies"] = game["colors"]["grey"]; + + if ( game["colors"]["axis"] == game["colors"]["black"] ) + game["colors"]["axis"] = game["colors"]["grey"]; + + [[ level.onprecachegametype ]](); + setdvarifuninitialized( "min_wait_for_players", 5 ); + + if ( level.console ) + { + if ( !level.splitscreen ) + { + if ( maps\mp\_utility::ismlgmatch() || isdedicatedserver() ) + level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "graceperiod_comp" ); + else + level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "graceperiod" ); + + level.prematchperiodend = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "matchstarttime" ); + } + } + else + { + if ( maps\mp\_utility::ismlgmatch() || isdedicatedserver() ) + level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "playerwaittime_comp" ); + else + level.prematchperiod = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "playerwaittime" ); + + level.prematchperiodend = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "matchstarttime" ); + } + + setnojipscore( 0 ); + setnojiptime( 0 ); + + if ( getdvar( "squad_vs_squad" ) == "1" ) + thread updatesquadvssquad(); + } + else + { + setdvarifuninitialized( "min_wait_for_players", 5 ); + + if ( level.console ) + { + if ( !level.splitscreen ) + { + level.prematchperiod = 5; + level.prematchperiodend = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "matchstarttime" ); + } + } + else + { + level.prematchperiod = 5; + level.prematchperiodend = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "matchstarttime" ); + } + } + + if ( !isdefined( game["status"] ) ) + game["status"] = "normal"; + + setdvar( "ui_overtime", game["status"] == "overtime" ); + + if ( game["status"] != "overtime" && game["status"] != "halftime" ) + { + if ( !( isdefined( game["switchedsides"] ) && game["switchedsides"] == 1 && maps\mp\_utility::ismoddedroundgame() ) ) + { + game["teamScores"]["allies"] = 0; + game["teamScores"]["axis"] = 0; + } + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + game["teamScores"][level.teamnamelist[var_0]] = 0; + } + } + + if ( !isdefined( game["timePassed"] ) ) + game["timePassed"] = 0; + + if ( !isdefined( game["roundsPlayed"] ) ) + game["roundsPlayed"] = 0; + + if ( !isdefined( game["roundsWon"] ) ) + game["roundsWon"] = []; + + if ( level.teambased ) + { + if ( !isdefined( game["roundsWon"]["axis"] ) ) + game["roundsWon"]["axis"] = 0; + + if ( !isdefined( game["roundsWon"]["allies"] ) ) + game["roundsWon"]["allies"] = 0; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + if ( !isdefined( game["roundsWon"][level.teamnamelist[var_0]] ) ) + game["roundsWon"][level.teamnamelist[var_0]] = 0; + } + } + } + + level.gameended = 0; + level.forcedend = 0; + level.hostforcedend = 0; + + if ( !maps\mp\_utility::is_aliens() ) + level.hardcoremode = getdvarint( "g_hardcore" ); + + if ( level.hardcoremode ) + logstring( "game mode: hardcore" ); + + level.diehardmode = getdvarint( "scr_diehard" ); + + if ( !level.teambased ) + level.diehardmode = 0; + + if ( level.diehardmode ) + logstring( "game mode: diehard" ); + + level.killstreakrewards = getdvarint( "scr_game_hardpoints" ); + level.usestartspawns = 1; + level.objectivepointsmod = 1; + + if ( maps\mp\_utility::matchmakinggame() ) + level.maxallowedteamkills = 2; + else + level.maxallowedteamkills = -1; + + if ( !maps\mp\_utility::is_aliens() ) + { + thread maps\mp\gametypes\_healthoverlay::init(); + thread maps\mp\gametypes\_killcam::init(); + thread maps\mp\gametypes\_damage::initfinalkillcam(); + thread maps\mp\gametypes\_battlechatter_mp::init(); + thread maps\mp\gametypes\_music_and_dialog::init(); + } + + thread [[ level.intelinit ]](); + thread maps\mp\gametypes\_persistence::init(); + thread maps\mp\gametypes\_menus::init(); + thread maps\mp\gametypes\_hud::init(); + thread maps\mp\gametypes\_serversettings::init(); + thread maps\mp\gametypes\_teams::init(); + thread maps\mp\gametypes\_weapons::init(); + thread maps\mp\gametypes\_outline::init(); + thread maps\mp\gametypes\_shellshock::init(); + thread maps\mp\gametypes\_deathicons::init(); + thread maps\mp\gametypes\_damagefeedback::init(); + thread maps\mp\gametypes\_objpoints::init(); + thread maps\mp\gametypes\_gameobjects::init(); + thread maps\mp\gametypes\_spectating::init(); + thread maps\mp\gametypes\_spawnlogic::init(); + thread maps\mp\_matchdata::init(); + thread maps\mp\_awards::init(); + thread maps\mp\_areas::init(); + thread [[ level.killstreakinit ]](); + thread maps\mp\perks\_perks::init(); + thread maps\mp\_events::init(); + thread maps\mp\_defcon::init(); + thread [[ level.matcheventsinit ]](); + thread maps\mp\_zipline::init(); + + if ( level.teambased ) + thread maps\mp\gametypes\_friendicons::init(); + + thread maps\mp\gametypes\_hud_message::init(); + game["gamestarted"] = 1; + level.maxplayercount = 0; + level.wavedelay["allies"] = 0; + level.wavedelay["axis"] = 0; + level.lastwave["allies"] = 0; + level.lastwave["axis"] = 0; + level.waveplayerspawnindex["allies"] = 0; + level.waveplayerspawnindex["axis"] = 0; + level.aliveplayers["allies"] = []; + level.aliveplayers["axis"] = []; + level.activeplayers = []; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + level._wavedelay[level.teamnamelist[var_0]] = 0; + level._lastwave[level.teamnamelist[var_0]] = 0; + level._waveplayerspawnindex[level.teamnamelist[var_0]] = 0; + level._aliveplayers[level.teamnamelist[var_0]] = []; + } + } + + setdvar( "ui_scorelimit", 0 ); + setdvar( "ui_allow_teamchange", 1 ); + + if ( maps\mp\_utility::getgametypenumlives() ) + setdvar( "g_deadChat", 0 ); + else + setdvar( "g_deadChat", 1 ); + + var_1 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ); + + if ( var_1 ) + { + level.wavedelay["allies"] = var_1; + level.wavedelay["axis"] = var_1; + level.lastwave["allies"] = 0; + level.lastwave["axis"] = 0; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + level._wavedelay[level.teamnamelist[var_0]] = var_1; + level._lastwave[level.teamnamelist[var_0]] = 0; + } + } + + level thread wavespawntimer(); + } + + maps\mp\_utility::gameflaginit( "prematch_done", 0 ); + + if ( maps\mp\_utility::is_aliens() ) + level.graceperiod = 10; + else + level.graceperiod = 15; + + level.ingraceperiod = level.graceperiod; + maps\mp\_utility::gameflaginit( "graceperiod_done", 0 ); + level.roundenddelay = 4; + level.halftimeroundenddelay = 4; + level.noragdollents = getentarray( "noragdoll", "targetname" ); + + if ( level.teambased ) + { + maps\mp\gametypes\_gamescore::updateteamscore( "axis" ); + maps\mp\gametypes\_gamescore::updateteamscore( "allies" ); + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + maps\mp\gametypes\_gamescore::updateteamscore( level.teamnamelist[var_0] ); + } + } + else + thread maps\mp\gametypes\_gamescore::initialdmscoreupdate(); + + thread updateuiscorelimit(); + level notify( "update_scorelimit" ); + [[ level.onstartgametype ]](); + level.scorepercentagecutoff = getdvarint( "scr_" + level.gametype + "_score_percentage_cut_off", 80 ); + level.timepercentagecutoff = getdvarint( "scr_" + level.gametype + "_time_percentage_cut_off", 80 ); + + if ( !level.console && ( getdvar( "dedicated" ) == "dedicated LAN server" || getdvar( "dedicated" ) == "dedicated internet server" ) ) + thread verifydedicatedconfiguration(); + + thread startgame(); + level thread maps\mp\_utility::updatewatcheddvars(); + level thread timelimitthread(); + + if ( !maps\mp\_utility::is_aliens() ) + level thread maps\mp\gametypes\_damage::dofinalkillcam(); + else + monitoraliensfailed(); +} + +callback_codeendgame() +{ + endparty(); + + if ( !level.gameended ) + level thread forceend(); +} + +verifydedicatedconfiguration() +{ + for (;;) + { + if ( level.rankedmatch ) + exitlevel( 0 ); + + if ( !getdvarint( "xblive_privatematch" ) ) + exitlevel( 0 ); + + if ( getdvar( "dedicated" ) != "dedicated LAN server" && getdvar( "dedicated" ) != "dedicated internet server" ) + exitlevel( 0 ); + + wait 5; + } +} + +timelimitthread() +{ + level endon( "game_ended" ); + var_0 = maps\mp\_utility::gettimepassed(); + + while ( game["state"] == "playing" ) + { + thread checktimelimit( var_0 ); + var_0 = maps\mp\_utility::gettimepassed(); + + if ( isdefined( level.starttime ) ) + { + if ( gettimeremaining() < 3000 ) + { + wait 0.1; + continue; + } + } + + wait 1; + } +} + +updateuiscorelimit() +{ + for (;;) + { + level common_scripts\utility::waittill_either( "update_scorelimit", "update_winlimit" ); + + if ( !maps\mp\_utility::isroundbased() || !maps\mp\_utility::isobjectivebased() ) + { + setdvar( "ui_scorelimit", maps\mp\_utility::getwatcheddvar( "scorelimit" ) ); + thread checkscorelimit(); + continue; + } + + setdvar( "ui_scorelimit", maps\mp\_utility::getwatcheddvar( "winlimit" ) ); + } +} + +playtickingsound() +{ + self endon( "death" ); + self endon( "stop_ticking" ); + level endon( "game_ended" ); + var_0 = level.bombtimer; + + for (;;) + { + self playsound( "ui_mp_suitcasebomb_timer" ); + + if ( var_0 > 10 ) + { + var_0 = var_0 - 1; + wait 1; + } + else if ( var_0 > 4 ) + { + var_0 = var_0 - 0.5; + wait 0.5; + } + else if ( var_0 > 1 ) + { + var_0 = var_0 - 0.4; + wait 0.4; + } + else + { + var_0 = var_0 - 0.3; + wait 0.3; + } + + maps\mp\gametypes\_hostmigration::waittillhostmigrationdone(); + } +} + +stoptickingsound() +{ + self notify( "stop_ticking" ); +} + +timelimitclock() +{ + level endon( "game_ended" ); + wait 0.05; + var_0 = spawn( "script_origin", ( 0, 0, 0 ) ); + var_0 hide(); + + while ( game["state"] == "playing" ) + { + if ( !level.timerstopped && maps\mp\_utility::gettimelimit() ) + { + var_1 = gettimeremaining() / 1000; + var_2 = int( var_1 + 0.5 ); + + if ( var_2 >= 30 && var_2 <= 60 ) + level notify( "match_ending_soon", "time" ); + + if ( var_2 <= 10 || var_2 <= 30 && var_2 % 2 == 0 ) + { + level notify( "match_ending_very_soon" ); + + if ( var_2 == 0 ) + break; + + var_0 playsound( "ui_mp_timer_countdown" ); + } + + if ( var_1 - floor( var_1 ) >= 0.05 ) + wait( var_1 - floor( var_1 ) ); + } + + wait 1.0; + } +} + +gametimer() +{ + level endon( "game_ended" ); + level waittill( "prematch_over" ); + level.starttime = gettime(); + level.discardtime = 0; + + if ( isdefined( game["roundMillisecondsAlreadyPassed"] ) ) + { + level.starttime = level.starttime - game["roundMillisecondsAlreadyPassed"]; + game["roundMillisecondsAlreadyPassed"] = undefined; + } + + var_0 = gettime(); + + while ( game["state"] == "playing" ) + { + if ( !level.timerstopped ) + game["timePassed"] = game["timePassed"] + ( gettime() - var_0 ); + + var_0 = gettime(); + wait 1.0; + } +} + +updatetimerpausedness() +{ + var_0 = level.timerstoppedforgamemode || isdefined( level.hostmigrationtimer ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) ) + var_0 = 0; + + if ( !level.timerstopped && var_0 ) + { + level.timerstopped = 1; + level.timerpausetime = gettime(); + } + else if ( level.timerstopped && !var_0 ) + { + level.timerstopped = 0; + level.discardtime = level.discardtime + ( gettime() - level.timerpausetime ); + } +} + +pausetimer() +{ + level.timerstoppedforgamemode = 1; + updatetimerpausedness(); +} + +resumetimer() +{ + level.timerstoppedforgamemode = 0; + updatetimerpausedness(); +} + +startgame() +{ + thread gametimer(); + level.timerstopped = 0; + level.timerstoppedforgamemode = 0; + setomnvar( "ui_prematch_period", 1 ); + + if ( isdefined( level.customprematchperiod ) ) + [[ level.customprematchperiod ]](); + else + prematchperiod(); + + maps\mp\_utility::gameflagset( "prematch_done" ); + level notify( "prematch_over" ); + setomnvar( "ui_prematch_period", 0 ); + updatetimerpausedness(); + thread timelimitclock(); + thread graceperiod(); + + if ( !maps\mp\_utility::is_aliens() ) + thread maps\mp\gametypes\_missions::roundbegin(); +} + +wavespawntimer() +{ + level endon( "game_ended" ); + + while ( game["state"] == "playing" ) + { + var_0 = gettime(); + + if ( var_0 - level.lastwave["allies"] > level.wavedelay["allies"] * 1000 ) + { + level notify( "wave_respawn_allies" ); + level.lastwave["allies"] = var_0; + level.waveplayerspawnindex["allies"] = 0; + } + + if ( var_0 - level.lastwave["axis"] > level.wavedelay["axis"] * 1000 ) + { + level notify( "wave_respawn_axis" ); + level.lastwave["axis"] = var_0; + level.waveplayerspawnindex["axis"] = 0; + } + + if ( level.multiteambased ) + { + for ( var_1 = 0; var_1 < level.teamnamelist.size; var_1++ ) + { + if ( var_0 - level.lastwave[level.teamnamelist[var_1]] > level._wavedelay[level.teamnamelist[var_1]] * 1000 ) + { + var_2 = "wave_rewpawn_" + level.teamnamelist[var_1]; + level notify( var_2 ); + level.lastwave[level.teamnamelist[var_1]] = var_0; + level.waveplayerspawnindex[level.teamnamelist[var_1]] = 0; + } + } + } + + wait 0.05; + } +} + +getbetterteam() +{ + var_0["allies"] = 0; + var_0["axis"] = 0; + var_1["allies"] = 0; + var_1["axis"] = 0; + + foreach ( var_3 in level.players ) + { + var_4 = var_3.pers["team"]; + + if ( isdefined( var_4 ) && ( var_4 == "allies" || var_4 == "axis" ) ) + { + var_0[var_4] = var_0[var_4] + var_3.kills; + var_1[var_4] = var_1[var_4] + var_3.deaths; + } + } + + if ( var_0["allies"] > var_0["axis"] ) + return "allies"; + else if ( var_0["axis"] > var_0["allies"] ) + return "axis"; + + if ( var_1["allies"] < var_1["axis"] ) + return "allies"; + else if ( var_1["axis"] < var_1["allies"] ) + return "axis"; + + if ( randomint( 2 ) == 0 ) + return "allies"; + + return "axis"; +} + +rankedmatchupdates( var_0 ) +{ + if ( maps\mp\_utility::matchmakinggame() ) + { + setxenonranks(); + + if ( hostidledout() ) + { + level.hostforcedend = 1; + logstring( "host idled out" ); + endlobby(); + } + + updatematchbonusscores( var_0 ); + } + + updatewinlossstats( var_0 ); +} + +displayroundend( var_0, var_1 ) +{ + if ( maps\mp\_utility::ismoddedroundgame() ) + { + var_0 = "roundend"; + var_2 = game["music"]["allies_suspense"].size; + var_3 = game["music"]["axis_suspense"].size; + maps\mp\_utility::playsoundonplayers( game["music"]["allies_suspense"][randomint( var_2 )], "allies" ); + maps\mp\_utility::playsoundonplayers( game["music"]["axis_suspense"][randomint( var_3 )], "axis" ); + } + + foreach ( var_5 in level.players ) + { + if ( isdefined( var_5.connectedpostgame ) || var_5.pers["team"] == "spectator" && !var_5 ismlgspectator() ) + continue; + + if ( level.teambased ) + { + var_5 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( var_0, 1, var_1 ); + continue; + } + + var_5 thread maps\mp\gametypes\_hud_message::outcomenotify( var_0, var_1 ); + } + + if ( !maps\mp\_utility::waslastround() ) + level notify( "round_win", var_0 ); + + if ( maps\mp\_utility::waslastround() ) + roundendwait( level.roundenddelay, 0 ); + else + roundendwait( level.roundenddelay, 1 ); +} + +displaygameend( var_0, var_1 ) +{ + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) || var_3.pers["team"] == "spectator" && !var_3 ismlgspectator() ) + continue; + + if ( level.teambased ) + { + var_3 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( var_0, 0, var_1 ); + continue; + } + + var_3 thread maps\mp\gametypes\_hud_message::outcomenotify( var_0, var_1 ); + } + + level notify( "game_win", var_0 ); + roundendwait( level.postroundtime, 1 ); +} + +displayroundswitch() +{ + var_0 = level.halftimetype; + + if ( var_0 == "halftime" ) + { + if ( maps\mp\_utility::getwatcheddvar( "roundlimit" ) ) + { + if ( game["roundsPlayed"] * 2 == maps\mp\_utility::getwatcheddvar( "roundlimit" ) ) + var_0 = "halftime"; + else + var_0 = "intermission"; + } + else if ( maps\mp\_utility::getwatcheddvar( "winlimit" ) ) + { + if ( game["roundsPlayed"] == maps\mp\_utility::getwatcheddvar( "winlimit" ) - 1 ) + var_0 = "halftime"; + else + var_0 = "intermission"; + } + else + var_0 = "intermission"; + } + + level notify( "round_switch", var_0 ); + var_1 = 0; + + if ( isdefined( level.switchedsides ) ) + var_1 = game["end_reason"]["switching_sides"]; + + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) || var_3.pers["team"] == "spectator" && !var_3 ismlgspectator() ) + continue; + + var_3 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( var_0, 1, var_1 ); + } + + roundendwait( level.halftimeroundenddelay, 0 ); +} + +freezeallplayers( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) ) + var_0 = 0; + + foreach ( var_4 in level.players ) + { + var_4 thread freezeplayerforroundend( var_0 ); + var_4 thread roundenddof( 4.0 ); + var_4 freegameplayhudelems(); + } + + foreach ( var_7 in level.agentarray ) + var_7 maps\mp\_utility::freezecontrolswrapper( 1 ); +} + +endgameovertime( var_0, var_1 ) +{ + visionsetnaked( "mpOutro", 0.5 ); + setdvar( "bg_compassShowEnemies", 0 ); + freezeallplayers(); + level notify( "round_switch", "overtime" ); + + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) || var_3.pers["team"] == "spectator" && !var_3 ismlgspectator() ) + continue; + + if ( level.teambased ) + { + var_3 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( var_0, 0, var_1 ); + continue; + } + + var_3 thread maps\mp\gametypes\_hud_message::outcomenotify( var_0, var_1 ); + } + + roundendwait( level.roundenddelay, 0 ); + + if ( isdefined( level.finalkillcam_winner ) ) + { + level.finalkillcam_timegameended[level.finalkillcam_winner] = maps\mp\_utility::getsecondspassed(); + + foreach ( var_3 in level.players ) + var_3 notify( "reset_outcome" ); + + level notify( "game_cleanup" ); + waittillfinalkillcamdone(); + + foreach ( var_3 in level.players ) + { + if ( isdefined( var_3.connectedpostgame ) || var_3.pers["team"] == "spectator" && !var_3 ismlgspectator() ) + continue; + + if ( level.teambased ) + { + var_3 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( var_0, 0, var_1 ); + continue; + } + + var_3 thread maps\mp\gametypes\_hud_message::outcomenotify( var_0, var_1 ); + } + } + + game["status"] = "overtime"; + level notify( "restarting" ); + game["state"] = "playing"; + map_restart( 1 ); +} + +endgamehalftime() +{ + visionsetnaked( "mpOutro", 0.5 ); + setdvar( "bg_compassShowEnemies", 0 ); + game["switchedsides"] = !game["switchedsides"]; + level.switchedsides = undefined; + freezeallplayers(); + + foreach ( var_1 in level.players ) + var_1.pers["stats"] = var_1.stats; + + level notify( "round_switch", "halftime" ); + + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.connectedpostgame ) || var_1.pers["team"] == "spectator" && !var_1 ismlgspectator() ) + continue; + + var_1 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( "halftime", 1, game["end_reason"]["switching_sides"] ); + } + + roundendwait( level.roundenddelay, 0 ); + + if ( isdefined( level.finalkillcam_winner ) ) + { + level.finalkillcam_timegameended[level.finalkillcam_winner] = maps\mp\_utility::getsecondspassed(); + + foreach ( var_1 in level.players ) + var_1 notify( "reset_outcome" ); + + level notify( "game_cleanup" ); + waittillfinalkillcamdone(); + + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.connectedpostgame ) || var_1.pers["team"] == "spectator" && !var_1 ismlgspectator() ) + continue; + + var_1 thread maps\mp\gametypes\_hud_message::teamoutcomenotify( "halftime", 1, game["end_reason"]["switching_sides"] ); + } + } + + game["status"] = "halftime"; + level notify( "restarting" ); + game["state"] = "playing"; + setdvar( "ui_game_state", game["state"] ); + map_restart( 1 ); +} + +endgame( var_0, var_1, var_2 ) +{ + if ( maps\mp\_utility::is_aliens() ) + [[ level.endgame_alien ]]( var_0, var_1 ); + else + endgame_regularmp( var_0, var_1, var_2 ); +} + +endgame_regularmp( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_2 ) ) + var_2 = 0; + + if ( game["state"] == "postgame" || level.gameended && ( !isdefined( level.gtnw ) || !level.gtnw ) ) + return; + + setomnvar( "ui_pause_menu_show", 0 ); + game["state"] = "postgame"; + setdvar( "ui_game_state", "postgame" ); + level.gameendtime = gettime(); + level.gameended = 1; + level.ingraceperiod = 0; + level notify( "game_ended", var_0 ); + maps\mp\_utility::levelflagset( "game_over" ); + maps\mp\_utility::levelflagset( "block_notifies" ); + common_scripts\utility::waitframe(); + setgameendtime( 0 ); + var_3 = getmatchdata( "gameLength" ); + var_3 = var_3 + int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "gameLength", var_3 ); + maps\mp\gametypes\_playerlogic::printpredictedspawnpointcorrectness(); + + if ( isdefined( var_0 ) && isstring( var_0 ) && var_0 == "overtime" ) + { + level.finalkillcam_winner = "none"; + endgameovertime( var_0, var_1 ); + return; + } + + if ( isdefined( var_0 ) && isstring( var_0 ) && var_0 == "halftime" ) + { + level.finalkillcam_winner = "none"; + endgamehalftime(); + return; + } + + if ( isdefined( level.finalkillcam_winner ) ) + level.finalkillcam_timegameended[level.finalkillcam_winner] = maps\mp\_utility::getsecondspassed(); + + game["roundsPlayed"]++; + + if ( level.teambased ) + { + if ( var_0 == "axis" || var_0 == "allies" ) + game["roundsWon"][var_0]++; + + maps\mp\gametypes\_gamescore::updateteamscore( "axis" ); + maps\mp\gametypes\_gamescore::updateteamscore( "allies" ); + } + else if ( isdefined( var_0 ) && isplayer( var_0 ) ) + game["roundsWon"][var_0.guid]++; + + maps\mp\gametypes\_gamescore::updateplacement(); + rankedmatchupdates( var_0 ); + + foreach ( var_5 in level.players ) + { + var_5 setclientdvar( "ui_opensummary", 1 ); + + if ( maps\mp\_utility::wasonlyround() || maps\mp\_utility::waslastround() ) + var_5 maps\mp\killstreaks\_killstreaks::clearkillstreaks(); + } + + setdvar( "g_deadChat", 1 ); + setdvar( "ui_allow_teamchange", 0 ); + setdvar( "bg_compassShowEnemies", 0 ); + freezeallplayers( 1.0, "cg_fovScale", 1 ); + + if ( !var_2 ) + visionsetnaked( "mpOutro", 0.5 ); + + if ( !maps\mp\_utility::wasonlyround() && !var_2 ) + { + displayroundend( var_0, var_1 ); + + if ( isdefined( level.finalkillcam_winner ) ) + { + foreach ( var_5 in level.players ) + var_5 notify( "reset_outcome" ); + + level notify( "game_cleanup" ); + waittillfinalkillcamdone(); + } + + if ( !maps\mp\_utility::waslastround() ) + { + maps\mp\_utility::levelflagclear( "block_notifies" ); + + if ( checkroundswitch() ) + displayroundswitch(); + + foreach ( var_5 in level.players ) + var_5.pers["stats"] = var_5.stats; + + level notify( "restarting" ); + game["state"] = "playing"; + setdvar( "ui_game_state", "playing" ); + map_restart( 1 ); + return; + } + + if ( !level.forcedend ) + var_1 = updateroundendreasontext( var_0 ); + } + + if ( !isdefined( game["clientMatchDataDef"] ) ) + { + game["clientMatchDataDef"] = "mp/clientmatchdata.def"; + setclientmatchdatadef( game["clientMatchDataDef"] ); + } + + maps\mp\gametypes\_missions::roundend( var_0 ); + + if ( level.teambased && maps\mp\_utility::isroundbased() && level.gameended && !maps\mp\_utility::ismoddedroundgame() ) + { + if ( game["roundsWon"]["allies"] == game["roundsWon"]["axis"] ) + var_0 = "tie"; + else if ( game["roundsWon"]["axis"] > game["roundsWon"]["allies"] ) + { + level.finalkillcam_winner = "axis"; + var_0 = "axis"; + } + else + { + level.finalkillcam_winner = "allies"; + var_0 = "allies"; + } + } + + displaygameend( var_0, var_1 ); + + if ( isdefined( level.finalkillcam_winner ) && maps\mp\_utility::wasonlyround() ) + { + foreach ( var_5 in level.players ) + var_5 notify( "reset_outcome" ); + + level notify( "game_cleanup" ); + waittillfinalkillcamdone(); + } + + maps\mp\_utility::levelflagclear( "block_notifies" ); + level.intermission = 1; + level notify( "start_custom_ending" ); + level notify( "spawning_intermission" ); + + foreach ( var_5 in level.players ) + { + var_5 notify( "reset_outcome" ); + var_5 thread maps\mp\gametypes\_playerlogic::spawnintermission(); + } + + processlobbydata(); + wait 1.0; + checkforpersonalbests(); + + if ( level.teambased ) + { + if ( var_0 == "axis" || var_0 == "allies" ) + setmatchdata( "victor", var_0 ); + else + setmatchdata( "victor", "none" ); + + setmatchdata( "alliesScore", getteamscore( "allies" ) ); + setmatchdata( "axisScore", getteamscore( "axis" ) ); + } + else + setmatchdata( "victor", "none" ); + + foreach ( var_5 in level.players ) + { + var_5 setcommonplayerdata( "round", "endReasonTextIndex", var_1 ); + + if ( var_5 maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + var_5 maps\mp\_matchdata::logfinalstats(); + } + + setmatchdata( "host", level.hostname ); + + if ( maps\mp\_utility::matchmakinggame() ) + { + setmatchdata( "playlistVersion", getplaylistversion() ); + setmatchdata( "playlistID", getplaylistid() ); + setmatchdata( "isDedicated", isdedicatedserver() ); + } + + sendmatchdata(); + + foreach ( var_5 in level.players ) + var_5.pers["stats"] = var_5.stats; + + if ( !var_2 && !level.postgamenotifies ) + { + if ( !maps\mp\_utility::wasonlyround() ) + wait 6.0; + else + wait( min( 10.0, 4.0 + level.postgamenotifies ) ); + } + else + wait( min( 10.0, 4.0 + level.postgamenotifies ) ); + + maps\mp\_utility::levelflagwaitopen( "post_game_level_event_active" ); + setnojipscore( 0 ); + setnojiptime( 0 ); + level notify( "exitLevel_called" ); + exitlevel( 0 ); +} + +updateroundendreasontext( var_0 ) +{ + if ( !level.teambased ) + return 1; + + if ( maps\mp\_utility::ismoddedroundgame() ) + { + if ( maps\mp\_utility::hitscorelimit() ) + return game["end_reason"]["score_limit_reached"]; + + if ( maps\mp\_utility::hittimelimit() ) + return game["end_reason"]["time_limit_reached"]; + } + else if ( maps\mp\_utility::hitroundlimit() ) + return game["end_reason"]["round_limit_reached"]; + + if ( maps\mp\_utility::hitwinlimit() ) + return game["end_reason"]["score_limit_reached"]; + + return game["end_reason"]["objective_completed"]; +} + +estimatedtimetillscorelimit( var_0 ) +{ + var_1 = getscoreperminute( var_0 ); + var_2 = getscoreremaining( var_0 ); + var_3 = 999999; + + if ( var_1 ) + var_3 = var_2 / var_1; + + return var_3; +} + +getscoreperminute( var_0 ) +{ + var_1 = maps\mp\_utility::getwatcheddvar( "scorelimit" ); + var_2 = maps\mp\_utility::gettimelimit(); + var_3 = maps\mp\_utility::gettimepassed() / 60000 + 0.0001; + + if ( isplayer( self ) ) + var_4 = self.score / var_3; + else + var_4 = getteamscore( var_0 ) / var_3; + + return var_4; +} + +getscoreremaining( var_0 ) +{ + var_1 = maps\mp\_utility::getwatcheddvar( "scorelimit" ); + + if ( isplayer( self ) ) + var_2 = var_1 - self.score; + else + var_2 = var_1 - getteamscore( var_0 ); + + return var_2; +} + +givelastonteamwarning() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + maps\mp\_utility::waittillrecoveredhealth( 3 ); + thread maps\mp\_utility::teamplayercardsplash( "callout_lastteammemberalive", self, self.pers["team"] ); + + foreach ( var_1 in level.teamnamelist ) + { + if ( self.pers["team"] != var_1 ) + thread maps\mp\_utility::teamplayercardsplash( "callout_lastenemyalive", self, var_1 ); + } + + level notify( "last_alive", self ); +} + +processlobbydata() +{ + var_0 = 0; + + foreach ( var_2 in level.players ) + { + if ( !isdefined( var_2 ) ) + continue; + + var_2.clientmatchdataid = var_0; + var_0++; + + if ( level.ps3 && var_2.name.size > level.maxnamelength ) + { + var_3 = ""; + + for ( var_4 = 0; var_4 < level.maxnamelength - 3; var_4++ ) + var_3 = var_3 + var_2.name[var_4]; + + var_3 = var_3 + "..."; + } + else + var_3 = var_2.name; + + setclientmatchdata( "players", var_2.clientmatchdataid, "xuid", var_3 ); + var_2 setcommonplayerdata( "round", "clientMatchIndex", var_2.clientmatchdataid ); + } + + maps\mp\_awards::assignawards(); + maps\mp\_scoreboard::processlobbyscoreboards(); + sendclientmatchdata(); +} + +trackleaderboarddeathstats( var_0, var_1 ) +{ + thread threadedsetweaponstatbyname( var_0, 1, "deaths" ); +} + +trackattackerleaderboarddeathstats( var_0, var_1 ) +{ + if ( isdefined( self ) && isplayer( self ) ) + { + if ( var_1 != "MOD_FALLING" ) + { + if ( var_1 == "MOD_MELEE" && issubstr( var_0, "tactical" ) ) + { + maps\mp\_matchdata::logattachmentstat( "tactical", "kills", 1 ); + maps\mp\_matchdata::logattachmentstat( "tactical", "hits", 1 ); + maps\mp\gametypes\_persistence::incrementattachmentstat( "tactical", "kills", 1 ); + maps\mp\gametypes\_persistence::incrementattachmentstat( "tactical", "hits", 1 ); + return; + } + + if ( var_1 == "MOD_MELEE" && !maps\mp\gametypes\_weapons::isriotshield( var_0 ) && var_0 != "iw6_knifeonly_mp" && var_0 != "iw6_knifeonlyfast_mp" ) + { + maps\mp\_matchdata::logattachmentstat( "none", "kills", 1 ); + maps\mp\_matchdata::logattachmentstat( "none", "hits", 1 ); + maps\mp\gametypes\_persistence::incrementattachmentstat( "none", "kills", 1 ); + maps\mp\gametypes\_persistence::incrementattachmentstat( "none", "hits", 1 ); + return; + } + + thread threadedsetweaponstatbyname( var_0, 1, "kills" ); + } + + if ( var_1 == "MOD_HEAD_SHOT" ) + thread threadedsetweaponstatbyname( var_0, 1, "headShots" ); + } +} + +setweaponstat( var_0, var_1, var_2 ) +{ + if ( !var_1 ) + return; + + var_3 = maps\mp\_utility::getweaponclass( var_0 ); + + if ( var_3 == "killstreak" || var_3 == "other" && var_0 != "trophy_mp" ) + return; + + if ( maps\mp\_utility::isenvironmentweapon( var_0 ) ) + return; + + if ( var_3 == "weapon_grenade" || var_3 == "weapon_explosive" || var_0 == "trophy_mp" ) + { + var_4 = maps\mp\_utility::strip_suffix( var_0, "_mp" ); + maps\mp\gametypes\_persistence::incrementweaponstat( var_4, var_2, var_1 ); + maps\mp\_matchdata::logweaponstat( var_4, var_2, var_1 ); + return; + } + + if ( !isdefined( self.trackingweaponname ) ) + self.trackingweaponname = var_0; + + if ( var_0 != self.trackingweaponname ) + { + maps\mp\gametypes\_persistence::updateweaponbufferedstats(); + self.trackingweaponname = var_0; + } + + switch ( var_2 ) + { + case "shots": + self.trackingweaponshots++; + break; + case "hits": + self.trackingweaponhits++; + break; + case "headShots": + self.trackingweaponheadshots++; + break; + case "kills": + self.trackingweaponkills++; + break; + } + + if ( var_2 == "deaths" ) + { + var_5 = undefined; + var_6 = maps\mp\_utility::getbaseweaponname( var_0 ); + + if ( !maps\mp\_utility::iscacprimaryweapon( var_6 ) && !maps\mp\_utility::iscacsecondaryweapon( var_6 ) ) + return; + + var_7 = maps\mp\_utility::getweaponattachmentsbasenames( var_0 ); + maps\mp\gametypes\_persistence::incrementweaponstat( var_6, var_2, var_1 ); + maps\mp\_matchdata::logweaponstat( var_6, "deaths", var_1 ); + + foreach ( var_9 in var_7 ) + { + if ( var_9 == "scope" ) + continue; + + maps\mp\gametypes\_persistence::incrementattachmentstat( var_9, var_2, var_1 ); + maps\mp\_matchdata::logattachmentstat( var_9, var_2, var_1 ); + } + } +} + +setinflictorstat( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_1 ) ) + return; + + if ( !isdefined( var_0 ) ) + { + var_1 setweaponstat( var_2, 1, "hits" ); + return; + } + + if ( !isdefined( var_0.playeraffectedarray ) ) + var_0.playeraffectedarray = []; + + var_3 = 1; + + for ( var_4 = 0; var_4 < var_0.playeraffectedarray.size; var_4++ ) + { + if ( var_0.playeraffectedarray[var_4] == self ) + { + var_3 = 0; + break; + } + } + + if ( var_3 ) + { + var_0.playeraffectedarray[var_0.playeraffectedarray.size] = self; + var_1 setweaponstat( var_2, 1, "hits" ); + } +} + +threadedsetweaponstatbyname( var_0, var_1, var_2 ) +{ + self endon( "disconnect" ); + waittillframeend; + setweaponstat( var_0, var_1, var_2 ); +} + +checkforpersonalbests() +{ + foreach ( var_1 in level.players ) + { + if ( !isdefined( var_1 ) ) + continue; + + if ( var_1 maps\mp\_utility::rankingenabled() ) + { + var_2 = var_1 getcommonplayerdata( "round", "kills" ); + var_3 = var_1 getcommonplayerdata( "round", "deaths" ); + var_4 = var_1.pers["summary"]["xp"]; + var_5 = var_1 getrankedplayerdata( "bestKills" ); + var_6 = var_1 getrankedplayerdata( "mostDeaths" ); + var_7 = var_1 getrankedplayerdata( "mostXp" ); + + if ( var_2 > var_5 ) + var_1 setrankedplayerdata( "bestKills", var_2 ); + + if ( var_4 > var_7 ) + var_1 setrankedplayerdata( "mostXp", var_4 ); + + if ( var_3 > var_6 ) + var_1 setrankedplayerdata( "mostDeaths", var_3 ); + + if ( !maps\mp\_utility::is_aliens() ) + var_1 checkforbestweapon(); + + var_1 maps\mp\_matchdata::logplayerxp( var_4, "totalXp" ); + var_1 maps\mp\_matchdata::logplayerxp( var_1.pers["summary"]["score"], "scoreXp" ); + var_1 maps\mp\_matchdata::logplayerxp( var_1.pers["summary"]["operation"], "operationXp" ); + var_1 maps\mp\_matchdata::logplayerxp( var_1.pers["summary"]["challenge"], "challengeXp" ); + var_1 maps\mp\_matchdata::logplayerxp( var_1.pers["summary"]["match"], "matchXp" ); + var_1 maps\mp\_matchdata::logplayerxp( var_1.pers["summary"]["misc"], "miscXp" ); + } + + if ( isdefined( var_1.pers["confirmed"] ) ) + var_1 maps\mp\_matchdata::logkillsconfirmed(); + + if ( isdefined( var_1.pers["denied"] ) ) + var_1 maps\mp\_matchdata::logkillsdenied(); + } +} + +isvalidbestweapon( var_0 ) +{ + var_1 = maps\mp\_utility::getweaponclass( var_0 ); + return isdefined( var_0 ) && var_0 != "" && !maps\mp\_utility::iskillstreakweapon( var_0 ) && var_1 != "killstreak" && var_1 != "other"; +} + +checkforbestweapon() +{ + var_0 = maps\mp\_matchdata::buildbaseweaponlist(); + var_1 = ""; + var_2 = -1; + + for ( var_3 = 0; var_3 < var_0.size; var_3++ ) + { + var_4 = var_0[var_3]; + var_4 = maps\mp\_utility::getbaseweaponname( var_4 ); + + if ( isvalidbestweapon( var_4 ) ) + { + var_5 = self getrankedplayerdata( "weaponStats", var_4, "kills" ); + + if ( var_5 > var_2 ) + { + var_1 = var_4; + var_2 = var_5; + } + } + } + + var_6 = self getrankedplayerdata( "weaponStats", var_1, "shots" ); + var_7 = self getrankedplayerdata( "weaponStats", var_1, "headShots" ); + var_8 = self getrankedplayerdata( "weaponStats", var_1, "hits" ); + var_9 = self getrankedplayerdata( "weaponStats", var_1, "deaths" ); + var_10 = 0; + self setrankedplayerdata( "bestWeapon", "kills", var_2 ); + self setrankedplayerdata( "bestWeapon", "shots", var_6 ); + self setrankedplayerdata( "bestWeapon", "headShots", var_7 ); + self setrankedplayerdata( "bestWeapon", "hits", var_8 ); + self setrankedplayerdata( "bestWeapon", "deaths", var_9 ); + self setrankedplayerdata( "bestWeaponXP", var_10 ); + var_11 = int( tablelookup( "mp/statstable.csv", 4, var_1, 0 ) ); + self setrankedplayerdata( "bestWeaponIndex", var_11 ); +} + +monitoraliensfailed() +{ + level waittill( "round_end_finished" ); + level notify( "final_killcam_done" ); + level.forcedend = 1; + level thread endgame( "axis", game["end_reason"]["objective_failed"] ); +} diff --git a/data/maps/mp/gametypes/_menus.gsc b/data/maps/mp/gametypes/_menus.gsc new file mode 100644 index 0000000..13180b7 --- /dev/null +++ b/data/maps/mp/gametypes/_menus.gsc @@ -0,0 +1,727 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +init() +{ + if ( !isdefined( game["gamestarted"] ) ) + { + game["menu_team"] = "team_marinesopfor"; + + if ( level.multiteambased ) + game["menu_team"] = "team_mt_options"; + + if ( maps\mp\_utility::bot_is_fireteam_mode() ) + { + level.fireteam_menu = "class_commander_" + level.gametype; + game["menu_class"] = level.fireteam_menu; + game["menu_class_allies"] = level.fireteam_menu; + game["menu_class_axis"] = level.fireteam_menu; + } + else + { + game["menu_class"] = "class"; + game["menu_class_allies"] = "class_marines"; + game["menu_class_axis"] = "class_opfor"; + } + + game["menu_changeclass_allies"] = "changeclass_marines"; + game["menu_changeclass_axis"] = "changeclass_opfor"; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] = game["menu_class_allies"]; + game[var_2] = "changeclass_marines"; + } + } + + game["menu_changeclass"] = "changeclass"; + + if ( level.console ) + { + game["menu_controls"] = "ingame_controls"; + + if ( level.splitscreen ) + { + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] += "_splitscreen"; + game[var_2] += "_splitscreen"; + } + } + + game["menu_team"] += "_splitscreen"; + game["menu_class_allies"] += "_splitscreen"; + game["menu_class_axis"] += "_splitscreen"; + game["menu_changeclass_allies"] += "_splitscreen"; + game["menu_changeclass_axis"] += "_splitscreen"; + game["menu_controls"] += "_splitscreen"; + game["menu_changeclass_defaults_splitscreen"] = "changeclass_splitscreen_defaults"; + game["menu_changeclass_custom_splitscreen"] = "changeclass_splitscreen_custom"; + precachemenu( game["menu_changeclass_defaults_splitscreen"] ); + precachemenu( game["menu_changeclass_custom_splitscreen"] ); + } + + precachemenu( game["menu_controls"] ); + } + + precachemenu( game["menu_team"] ); + precachemenu( game["menu_class_allies"] ); + precachemenu( game["menu_class_axis"] ); + precachemenu( game["menu_changeclass"] ); + precachemenu( game["menu_changeclass_allies"] ); + precachemenu( game["menu_changeclass_axis"] ); + precachemenu( game["menu_class"] ); + precachestring( &"MP_HOST_ENDED_GAME" ); + precachestring( &"MP_HOST_ENDGAME_RESPONSE" ); + } + + level thread onplayerconnect(); +} + +onplayerconnect() +{ + for (;;) + { + level waittill( "connected", var_0 ); + var_0 thread watchforclasschange(); + var_0 thread watchforteamchange(); + var_0 thread watchforleavegame(); + var_0 thread connectedmenus(); + } +} + +connectedmenus() +{ + +} + +getclasschoice( var_0 ) +{ + if ( var_0 > 10 ) + { + if ( var_0 > 10 && var_0 < 17 ) + { + var_0 -= 10; + var_0 = "axis_recipe" + var_0; + } + else if ( var_0 > 16 && var_0 < 23 ) + { + var_0 -= 16; + var_0 = "allies_recipe" + var_0; + } + } + else + var_0 = "custom" + var_0; + + return var_0; +} + +watchforclasschange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "class_select" ) + continue; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) && self ismlgspectator() ) + { + self setclientomnvar( "ui_options_menu", 0 ); + continue; + } + + var_2 = isai( self ) || issubstr( self.name, "tcBot" ); + + if ( !var_2 ) + { + if ( !isai( self ) && "" + var_1 != "callback" ) + self setclientomnvar( "ui_loadout_selected", var_1 ); + } + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + continue; + + if ( !maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_3 = var_1 + 1; + var_3 = getclasschoice( var_3 ); + + if ( !isdefined( self.pers["class"] ) || var_3 == self.pers["class"] ) + continue; + + self.pers["class"] = var_3; + self.class = var_3; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else if ( isalive( self ) ) + self iprintlnbold( game["strings"]["change_class"] ); + } + + continue; + } + + menuclass( "callback" ); + } +} + +watchforleavegame() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "end_game" ) + continue; + + if ( maps\mp\_utility::is_aliens() ) + { + [[ level.forceendgame_alien ]](); + continue; + } + + level thread maps\mp\gametypes\_gamelogic::forceend( var_1 ); + } +} + +watchforteamchange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "team_select" ) + continue; + + if ( maps\mp\_utility::matchmakinggame() && !getdvarint( "force_ranking" ) ) + continue; + + if ( var_1 != 3 ) + thread showloadoutmenu(); + + if ( var_1 == 3 ) + { + self setclientomnvar( "ui_spectator_selected", 1 ); + self setclientomnvar( "ui_loadout_selected", -1 ); + self.spectating_actively = 1; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 1 ); + self.pers["mlgSpectator"] = 1; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + self setclientomnvar( "ui_options_menu", 2 ); + } + } + else + { + self setclientomnvar( "ui_spectator_selected", -1 ); + self.spectating_actively = 0; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 0 ); + self.pers["mlgSpectator"] = 0; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 0 ); + } + } + + self setclientomnvar( "ui_team_selected", var_1 ); + + if ( var_1 == 0 ) + var_1 = "axis"; + else if ( var_1 == 1 ) + var_1 = "allies"; + else if ( var_1 == 2 ) + var_1 = "random"; + else + var_1 = "spectator"; + + if ( isdefined( self.pers["team"] ) && var_1 == self.pers["team"] ) + { + self notify( "selected_same_team" ); + continue; + } + + self setclientomnvar( "ui_loadout_selected", -1 ); + + if ( var_1 == "axis" ) + { + thread setteam( "axis" ); + continue; + } + + if ( var_1 == "allies" ) + { + thread setteam( "allies" ); + continue; + } + + if ( var_1 == "random" ) + { + thread autoassign(); + continue; + } + + if ( var_1 == "spectator" ) + thread setspectator(); + } +} + +showloadoutmenu() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + common_scripts\utility::waittill_any( "joined_team", "selected_same_team" ); + self setclientomnvar( "ui_options_menu", 2 ); +} + +autoassign() +{ + if ( maps\mp\_utility::is_aliens() || level.gametype == "infect" ) + thread setteam( "allies" ); + else if ( ( getdvarint( "squad_match" ) == 1 || getdvarint( "squad_vs_squad" ) == 1 || getdvarint( "squad_use_hosts_squad" ) == 1 ) && isdefined( self.bot_team ) ) + thread setteam( self.bot_team ); + else if ( !isdefined( self.team ) ) + { + if ( self ismlgspectator() ) + thread setspectator(); + else if ( level.teamcount["axis"] < level.teamcount["allies"] ) + thread setteam( "axis" ); + else if ( level.teamcount["allies"] < level.teamcount["axis"] ) + thread setteam( "allies" ); + else if ( getteamscore( "allies" ) > getteamscore( "axis" ) ) + thread setteam( "axis" ); + else + thread setteam( "allies" ); + } + else + { + if ( self ismlgspectator() ) + { + thread setspectator(); + return; + } + + if ( level.teamcount["axis"] < level.teamcount["allies"] && self.team != "axis" ) + { + thread setteam( "axis" ); + return; + } + + if ( level.teamcount["allies"] < level.teamcount["axis"] && self.team != "allies" ) + { + thread setteam( "allies" ); + return; + } + + if ( level.teamcount["allies"] == level.teamcount["axis"] ) + { + if ( getteamscore( "allies" ) > getteamscore( "axis" ) && self.team != "axis" ) + thread setteam( "axis" ); + else if ( self.team != "allies" ) + thread setteam( "allies" ); + } + } +} + +setteam( var_0 ) +{ + self endon( "disconnect" ); + + if ( !isai( self ) && level.teambased && !maps\mp\gametypes\_teams::getjointeampermissions( var_0 ) ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + self.hasspawned = 0; + + if ( self.sessionstate == "playing" ) + { + self.switching_teams = 1; + self.joining_team = var_0; + self.leaving_team = self.pers["team"]; + } + + addtoteam( var_0 ); + + if ( self.sessionstate == "playing" ) + self suicide(); + + waitforclassselect(); + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self notify( "okToSpawn" ); +} + +setspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + self notify( "becameSpectator" ); + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +waitforclassselect() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self.waitingtoselectclass = 1; + + for (;;) + { + if ( level.gametype == "infect" ) + { + bypassclasschoice(); + break; + } + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self waittill( "luinotifyserver", var_0, var_1 ); + else + { + bypassclasschoice(); + break; + } + + if ( var_0 != "class_select" ) + continue; + + if ( self.team == "spectator" ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_1 += 1; + self.pers["class"] = getclasschoice( var_1 ); + self.class = getclasschoice( var_1 ); + } + + self.waitingtoselectclass = 0; + } + else + { + self.waitingtoselectclass = 0; + menuclass( "callback" ); + } + + break; + } +} + +beginclasschoice( var_0 ) +{ + var_1 = self.pers["team"]; + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + { + self setclientomnvar( "ui_options_menu", 2 ); + + if ( !self ismlgspectator() ) + waitforclassselect(); + + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self.connecttime = gettime(); + self notify( "okToSpawn" ); + } + else + thread bypassclasschoice(); + + if ( !isalive( self ) ) + thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( 0.1 ); +} + +bypassclasschoice() +{ + self.selectedclass = 1; + self.waitingtoselectclass = 0; + + if ( isdefined( level.bypassclasschoicefunc ) ) + { + var_0 = self [[ level.bypassclasschoicefunc ]](); + self.class = var_0; + } + else + self.class = "class0"; +} + +beginteamchoice() +{ + self setclientomnvar( "ui_options_menu", 1 ); +} + +showmainmenuforteam() +{ + var_0 = self.pers["team"]; + self openpopupmenu( game["menu_class_" + var_0] ); +} + +menuspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +menuclass( var_0 ) +{ + if ( var_0 == "demolitions_mp,0" && self getrankedplayerdata( "featureNew", "demolitions" ) ) + self setrankedplayerdata( "featureNew", "demolitions", 0 ); + + if ( var_0 == "sniper_mp,0" && self getrankedplayerdata( "featureNew", "sniper" ) ) + self setrankedplayerdata( "featureNew", "sniper", 0 ); + + var_1 = self.pers["team"]; + var_2 = maps\mp\gametypes\_class::getclasschoice( var_0 ); + var_3 = maps\mp\gametypes\_class::getweaponchoice( var_0 ); + + if ( var_2 == "restricted" ) + { + beginclasschoice(); + return; + } + + if ( isdefined( self.pers["class"] ) && self.pers["class"] == var_2 && ( isdefined( self.pers["primary"] ) && self.pers["primary"] == var_3 ) ) + return; + + if ( self.sessionstate == "playing" ) + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else + self iprintlnbold( game["strings"]["change_class"] ); + } + else + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); +} + +update_wargame_after_migration() +{ + foreach ( var_1 in level.players ) + { + if ( !isai( var_1 ) && var_1 ishost() ) + level.wargame_client = var_1; + } +} + +addtoteam( var_0, var_1, var_2 ) +{ + if ( isdefined( self.team ) ) + { + maps\mp\gametypes\_playerlogic::removefromteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::decrementalivecount( self.team ); + } + + self.pers["team"] = var_0; + self.team = var_0; + + if ( getdvar( "squad_vs_squad" ) == "1" ) + { + if ( !isai( self ) ) + { + if ( var_0 == "allies" ) + { + if ( !isdefined( level.squad_vs_squad_allies_client ) ) + level.squad_vs_squad_allies_client = self; + } + else if ( var_0 == "axis" ) + { + if ( !isdefined( level.squad_vs_squad_axis_client ) ) + level.squad_vs_squad_axis_client = self; + } + } + } + + if ( getdvar( "squad_match" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.squad_match_client ) ) + level.squad_match_client = self; + } + } + + if ( getdvar( "squad_use_hosts_squad" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.wargame_client ) ) + level.wargame_client = self; + } + } + + // session team is readonly in ranked matches if "teambased" is set on the playlist + if ( level.teambased ) + self.sessionteam = var_0; + else if ( var_0 == "spectator" ) + self.sessionteam = "spectator"; + else + self.sessionteam = "none"; + + if ( game["state"] != "postgame" ) + { + maps\mp\gametypes\_playerlogic::addtoteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::incrementalivecount( self.team ); + } + + maps\mp\_utility::updateobjectivetext(); + + if ( isdefined( var_1 ) && var_1 ) + waittillframeend; + + maps\mp\_utility::updatemainmenu(); + + if ( var_0 == "spectator" ) + { + self notify( "joined_spectators" ); + level notify( "joined_team", self ); + } + else + { + self notify( "joined_team" ); + level notify( "joined_team", self ); + } +} + +endrespawnnotify() +{ + self.waitingtospawn = 0; + self notify( "end_respawn" ); +} diff --git a/data/maps/mp/gametypes/_playerlogic.gsc b/data/maps/mp/gametypes/_playerlogic.gsc new file mode 100644 index 0000000..78b4997 --- /dev/null +++ b/data/maps/mp/gametypes/_playerlogic.gsc @@ -0,0 +1,1885 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +timeuntilwavespawn( var_0 ) +{ + if ( !self.hasspawned ) + return 0; + + var_1 = gettime() + var_0 * 1000; + var_2 = level.lastwave[self.pers["team"]]; + var_3 = level.wavedelay[self.pers["team"]] * 1000; + var_4 = ( var_1 - var_2 ) / var_3; + var_5 = ceil( var_4 ); + var_6 = var_2 + var_5 * var_3; + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_7 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + + if ( self.respawntimerstarttime < var_2 ) + return 0; + } + + if ( isdefined( self.wavespawnindex ) ) + var_6 += 50 * self.wavespawnindex; + + return ( var_6 - gettime() ) / 1000; +} + +teamkilldelay() +{ + var_0 = self.pers["teamkills"]; + + if ( level.maxallowedteamkills < 0 || var_0 <= level.maxallowedteamkills ) + return 0; + + var_1 = var_0 - level.maxallowedteamkills; + return maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillspawndelay" ) * var_1; +} + +timeuntilspawn( var_0 ) +{ + if ( level.ingraceperiod && !self.hasspawned || level.gameended ) + return 0; + + var_1 = 0; + + if ( self.hasspawned ) + { + var_2 = self [[ level.onrespawndelay ]](); + + if ( isdefined( var_2 ) ) + var_1 = var_2; + else + var_1 = getdvarint( "scr_" + level.gametype + "_playerrespawndelay" ); + + if ( var_0 && isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + var_1 += teamkilldelay(); + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_3 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + var_1 -= var_3; + + if ( var_1 < 0 ) + var_1 = 0; + } + + if ( isdefined( self.setspawnpoint ) ) + var_1 += level.tispawndelay; + } + + var_4 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_4 ) + return timeuntilwavespawn( var_1 ); + + return var_1; +} + +mayspawn() +{ + if ( maps\mp\_utility::getgametypenumlives() || isdefined( level.disablespawning ) ) + { + if ( isdefined( level.disablespawning ) && level.disablespawning ) + return 0; + + if ( isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + return 0; + + if ( self.pers["lives"] <= 0 && maps\mp\_utility::gamehasstarted() ) + return 0; + else if ( maps\mp\_utility::gamehasstarted() ) + { + if ( !level.ingraceperiod && !self.hasspawned && ( isdefined( level.allowlatecomers ) && !level.allowlatecomers ) ) + { + if ( isdefined( self.siegelatecomer ) && !self.siegelatecomer ) + return 1; + + return 0; + } + } + } + + return 1; +} + +spawnclient() +{ + self endon( "becameSpectator" ); + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + self waittill( "okToSpawn" ); + + if ( isdefined( self.addtoteam ) ) + { + maps\mp\gametypes\_menus::addtoteam( self.addtoteam ); + self.addtoteam = undefined; + } + + if ( !mayspawn() ) + { + wait 0.05; + var_0 = self.origin; + var_1 = self.angles; + self notify( "attempted_spawn" ); + var_2 = self.pers["teamKillPunish"]; + + if ( isdefined( var_2 ) && var_2 ) + { + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT" ); + + if ( !self.hasspawned && self.pers["teamkills"] <= level.maxallowedteamkills ) + self.pers["teamKillPunish"] = 0; + } + else if ( maps\mp\_utility::isroundbased() && !maps\mp\_utility::islastround() ) + { + if ( isdefined( self.tagavailable ) && self.tagavailable ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_tag_wait"] ); + else if ( level.gametype == "siege" ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_flag_wait"] ); + else + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_next_round"] ); + + thread removespawnmessageshortly( 3.0 ); + } + + if ( self.sessionstate != "spectator" ) + var_0 += ( 0, 0, 60 ); + + thread spawnspectator( var_0, var_1 ); + return; + } + + if ( self.waitingtospawn ) + return; + + self.waitingtospawn = 1; + waitandspawnclient(); + + if ( isdefined( self ) ) + self.waitingtospawn = 0; +} + +waitandspawnclient() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + level endon( "game_ended" ); + self notify( "attempted_spawn" ); + var_0 = 0; + var_1 = self.pers["teamKillPunish"]; + + if ( isdefined( var_1 ) && var_1 ) + { + var_2 = teamkilldelay(); + + if ( var_2 > 0 ) + { + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT", var_2, 1, 1 ); + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + var_0 = 1; + wait(var_2); + maps\mp\_utility::clearlowermessage( "friendly_fire" ); + self.respawntimerstarttime = gettime(); + } + + self.pers["teamKillPunish"] = 0; + } + else if ( !maps\mp\_utility::is_aliens() && teamkilldelay() ) + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + + if ( maps\mp\_utility::isusingremote() ) + { + self.spawningafterremotedeath = 1; + self.deathposition = self.origin; + self waittill( "stopped_using_remote" ); + } + + if ( !isdefined( self.wavespawnindex ) && isdefined( level.waveplayerspawnindex[self.team] ) ) + { + self.wavespawnindex = level.waveplayerspawnindex[self.team]; + level.waveplayerspawnindex[self.team]++; + } + + var_3 = timeuntilspawn( 0 ); + thread predictabouttospawnplayerovertime( var_3 ); + + if ( var_3 > 0 ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["waiting_to_spawn"], var_3, 1, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + maps\mp\_utility::waitfortimeornotify( var_3, "force_spawn" ); + self notify( "stop_wait_safe_spawn_button" ); + } + + if ( needsbuttontorespawn() ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["press_to_spawn"], undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + waitrespawnbutton(); + } + + self.waitingtospawn = 0; + maps\mp\_utility::clearlowermessage( "spawn_info" ); + self.wavespawnindex = undefined; + thread spawnplayer(); +} + +needsbuttontorespawn() +{ + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "forcerespawn" ) != 0 ) + return 0; + + if ( !self.hasspawned ) + return 0; + + var_0 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_0 ) + return 0; + + if ( self.wantsafespawn ) + return 0; + + return 1; +} + +waitrespawnbutton() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + + for (;;) + { + if ( self usebuttonpressed() ) + break; + + wait 0.05; + } +} + +removespawnmessageshortly( var_0 ) +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + waittillframeend; + self endon( "end_respawn" ); + wait(var_0); + maps\mp\_utility::clearlowermessage( "spawn_info" ); +} + +laststandrespawnplayer() +{ + self laststandrevive(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) && !level.diehardmode ) + maps\mp\_utility::_unsetperk( "specialty_finalstand" ); + + if ( level.diehardmode ) + self.headicon = ""; + + self setstance( "crouch" ); + self.revived = 1; + self notify( "revive" ); + + if ( isdefined( self.standardmaxhealth ) ) + self.maxhealth = self.standardmaxhealth; + + self.health = self.maxhealth; + common_scripts\utility::_enableusability(); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +getdeathspawnpoint() +{ + var_0 = spawn( "script_origin", self.origin ); + var_0 hide(); + var_0.angles = self.angles; + return var_0; +} + +showspawnnotifies() +{ + if ( isdefined( game["defcon"] ) ) + thread maps\mp\gametypes\_hud_message::defconsplashnotify( game["defcon"], 0 ); + + if ( !maps\mp\_utility::is_aliens() && maps\mp\_utility::isrested() ) + thread maps\mp\gametypes\_hud_message::splashnotify( "rested" ); +} + +predictabouttospawnplayerovertime( var_0 ) +{ + if ( !0 ) + return; + + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "used_predicted_spawnpoint" ); + self notify( "predicting_about_to_spawn_player" ); + self endon( "predicting_about_to_spawn_player" ); + + if ( var_0 <= 0 ) + return; + + if ( var_0 > 1.0 ) + wait(var_0 - 1.0); + + predictabouttospawnplayer(); + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + wait 0.4; + var_2 = self.predictedspawnpoint; + predictabouttospawnplayer(); + + if ( self.predictedspawnpoint != var_2 ) + { + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + } + } +} + +predictabouttospawnplayer() +{ + if ( timeuntilspawn( 1 ) > 1.0 ) + { + self.predictedspawnpoint = getspectatepoint(); + return; + } + + if ( isdefined( self.setspawnpoint ) ) + { + self.predictedspawnpoint = self.setspawnpoint; + return; + } + + var_0 = self [[ level.getspawnpoint ]](); + self.predictedspawnpoint = var_0; +} + +checkpredictedspawnpointcorrectness( var_0 ) +{ + self notify( "used_predicted_spawnpoint" ); + self.predictedspawnpoint = undefined; +} + +percentage( var_0, var_1 ) +{ + return var_0 + " (" + int( var_0 / var_1 * 100 ) + "%)"; +} + +printpredictedspawnpointcorrectness() +{ + +} + +getspawnorigin( var_0 ) +{ + if ( !positionwouldtelefrag( var_0.origin ) ) + return var_0.origin; + + if ( !isdefined( var_0.alternates ) ) + return var_0.origin; + + foreach ( var_2 in var_0.alternates ) + { + if ( !positionwouldtelefrag( var_2 ) ) + return var_2; + } + + return var_0.origin; +} + +tivalidationcheck() +{ + if ( !isdefined( self.setspawnpoint ) ) + return 0; + + var_0 = getentarray( "care_package", "targetname" ); + + foreach ( var_2 in var_0 ) + { + if ( distance( var_2.origin, self.setspawnpoint.playerspawnpos ) > 64 ) + continue; + + if ( isdefined( var_2.owner ) ) + maps\mp\gametypes\_hud_message::playercardsplashnotify( "destroyed_insertion", var_2.owner ); + + maps\mp\perks\_perkfunctions::deleteti( self.setspawnpoint ); + return 0; + } + + if ( !bullettracepassed( self.setspawnpoint.origin + ( 0, 0, 60 ), self.setspawnpoint.origin, 0, self.setspawnpoint ) ) + return 0; + + var_4 = self.setspawnpoint.origin + ( 0, 0, 1 ); + var_5 = playerphysicstrace( var_4, self.setspawnpoint.origin + ( 0, 0, -16 ) ); + + if ( var_4[2] == var_5[2] ) + return 0; + + return 1; +} + +spawningclientthisframereset() +{ + self notify( "spawningClientThisFrameReset" ); + self endon( "spawningClientThisFrameReset" ); + wait 0.05; + level.numplayerswaitingtospawn--; +} + +spawnplayer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "joined_spectators" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "started_spawnPlayer" ); + + if ( !isdefined( var_0 ) ) + var_0 = 0; + + var_1 = undefined; + self.ti_spawn = 0; + self setclientomnvar( "ui_options_menu", 0 ); + self setclientomnvar( "ui_hud_shake", 0 ); + self.lastkillsplash = undefined; + + if ( !level.ingraceperiod && !self.hasdonecombat ) + { + level.numplayerswaitingtospawn++; + + if ( level.numplayerswaitingtospawn > 1 ) + { + self.waitingtospawnamortize = 1; + wait(0.05 * ( level.numplayerswaitingtospawn - 1 )); + } + + thread spawningclientthisframereset(); + self.waitingtospawnamortize = 0; + } + + // // Returning false we use default character model and prevent a 5 second respawn delay. (Github issue #109) + if ( !self hasloadedcustomizationplayerview( self ) ) + self.waitingtospawnamortize = 0; + + if ( isdefined( self.forcespawnorigin ) ) + { + var_2 = self.forcespawnorigin; + self.forcespawnorigin = undefined; + + if ( isdefined( self.forcespawnangles ) ) + { + var_3 = self.forcespawnangles; + self.forcespawnangles = undefined; + } + else + var_3 = ( 0, randomfloatrange( 0, 360 ), 0 ); + } + else if ( isdefined( self.setspawnpoint ) && ( isdefined( self.setspawnpoint.notti ) || tivalidationcheck() ) ) + { + var_1 = self.setspawnpoint; + + if ( !isdefined( self.setspawnpoint.notti ) ) + { + self.ti_spawn = 1; + self playlocalsound( "tactical_spawn" ); + + if ( level.multiteambased ) + { + foreach ( var_5 in level.teamnamelist ) + { + if ( var_5 != self.team ) + self playsoundtoteam( "tactical_spawn", var_5 ); + } + } + else if ( level.teambased ) + self playsoundtoteam( "tactical_spawn", level.otherteam[self.team] ); + else + self playsound( "tactical_spawn" ); + } + + foreach ( var_8 in level.ugvs ) + { + if ( distancesquared( var_8.origin, var_1.playerspawnpos ) < 1024 ) + var_8 notify( "damage", 5000, var_8.owner, ( 0, 0, 0 ), ( 0, 0, 0 ), "MOD_EXPLOSIVE", "", "", "", undefined, "killstreak_emp_mp" ); + } + + var_2 = self.setspawnpoint.playerspawnpos; + var_3 = self.setspawnpoint.angles; + + if ( isdefined( self.setspawnpoint.enemytrigger ) ) + self.setspawnpoint.enemytrigger delete(); + + self.setspawnpoint delete(); + var_1 = undefined; + } + else if ( isdefined( self.isspawningonbattlebuddy ) && isdefined( self.battlebuddy ) ) + { + var_2 = undefined; + var_3 = undefined; + var_10 = maps\mp\gametypes\_battlebuddy::checkbuddyspawn(); + + if ( var_10.status == 0 ) + { + var_2 = var_10.origin; + var_3 = var_10.angles; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + maps\mp\gametypes\_battlebuddy::cleanupbuddyspawn(); + self setclientomnvar( "cam_scene_name", "battle_spawn" ); + self setclientomnvar( "cam_scene_lead", self.battlebuddy getentitynumber() ); + self setclientomnvar( "cam_scene_support", self getentitynumber() ); + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "allies" ) + { + while ( !isdefined( level.allieschopper ) ) + wait 0.1; + + var_2 = level.allieschopper.origin; + var_3 = level.allieschopper.angles; + self.firstspawn = 0; + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "axis" ) + { + while ( !isdefined( level.axischopper ) ) + wait 0.1; + + var_2 = level.axischopper.origin; + var_3 = level.axischopper.angles; + self.firstspawn = 0; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + setspawnvariables(); + var_11 = self.hasspawned; + self.fauxdead = undefined; + + if ( !var_0 ) + { + self.killsthislife = []; + self.killsthislifeperweapon = []; + maps\mp\_utility::updatesessionstate( "playing" ); + maps\mp\_utility::clearkillcamstate(); + self.cancelkillcam = undefined; + self.maxhealth = maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "maxhealth" ); + self.health = self.maxhealth; + self.friendlydamage = undefined; + self.hasspawned = 1; + self.spawntime = gettime(); + self.wasti = !isdefined( var_1 ); + self.afk = 0; + self.damagedplayers = []; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.clampedhealth = undefined; + self.shielddamage = 0; + self.shieldbullethits = 0; + self.recentshieldxp = 0; + } + + self.movespeedscaler = 1; + self.inlaststand = 0; + self.laststand = undefined; + self.infinalstand = undefined; + self.inc4death = undefined; + self.disabledweapon = 0; + self.disabledweaponswitch = 0; + self.disabledoffhandweapons = 0; + common_scripts\utility::resetusability(); + + if ( !var_0 ) + { + self.avoidkillstreakonspawntimer = 5.0; + + if ( !maps\mp\_utility::is_aliens() ) + { + var_12 = self.pers["lives"]; + + if ( var_12 == maps\mp\_utility::getgametypenumlives() ) + addtolivescount(); + + if ( var_12 ) + self.pers["lives"]--; + } + + addtoalivecount(); + + if ( !var_11 || maps\mp\_utility::gamehasstarted() || maps\mp\_utility::gamehasstarted() && level.ingraceperiod && self.hasdonecombat ) + removefromlivescount(); + + if ( !self.wasaliveatmatchstart ) + { + var_13 = 20; + + if ( maps\mp\_utility::gettimelimit() > 0 && var_13 < maps\mp\_utility::gettimelimit() * 60 / 4 ) + var_13 = maps\mp\_utility::gettimelimit() * 60 / 4; + + if ( level.ingraceperiod || maps\mp\_utility::gettimepassed() < var_13 * 1000 ) + self.wasaliveatmatchstart = 1; + } + } + + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); + + if ( level.console ) + self setclientdvar( "cg_fov", "65" ); + + resetuidvarsonspawn(); + + if ( isdefined( var_1 ) ) + { + maps\mp\gametypes\_spawnlogic::finalizespawnpointchoice( var_1 ); + var_2 = getspawnorigin( var_1 ); + var_3 = var_1.angles; + } + else if ( !isdefined( self.faux_spawn_infected ) ) + self.lastspawntime = gettime(); + + self.spawnpos = var_2; + self spawn( var_2, var_3 ); + + if ( var_0 && isdefined( self.faux_spawn_stance ) ) + { + self setstance( self.faux_spawn_stance ); + self.faux_spawn_stance = undefined; + } + + if ( isai( self ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + + [[ level.onspawnplayer ]](); + + if ( isdefined( var_1 ) ) + checkpredictedspawnpointcorrectness( var_1.origin ); + + if ( !var_0 ) + { + maps\mp\gametypes\_missions::playerspawned(); + + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["player_spawned"] ) ) + self [[ level.bot_funcs["player_spawned"] ]](); + + if ( !isai( self ) ) + thread watchforslide(); + } + + maps\mp\gametypes\_class::setclass( self.class ); + + if ( isdefined( level.custom_giveloadout ) ) + self [[ level.custom_giveloadout ]]( var_0 ); + else + maps\mp\gametypes\_class::giveloadout( self.team, self.class ); + + if ( isdefined( game["roundsPlayed"] ) && game["roundsPlayed"] > 0 ) + { + if ( !isdefined( self.classrefreshed ) || !self.classrefreshed ) + { + if ( isdefined( self.class_num ) ) + { + self setclientomnvar( "ui_loadout_selected", self.class_num ); + self.classrefreshed = 1; + } + } + } + + if ( getdvarint( "camera_thirdPerson" ) ) + maps\mp\_utility::setthirdpersondof( 1 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + else + maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) || !var_11 && game["state"] == "playing" ) + { + if ( !maps\mp\_utility::is_aliens() ) + { + if ( game["status"] == "overtime" ) + thread maps\mp\gametypes\_hud_message::oldnotifymessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, ( 1, 0, 0 ), "mp_last_stand" ); + } + + thread showspawnnotifies(); + } + + if ( maps\mp\_utility::getintproperty( "scr_showperksonspawn", 1 ) == 1 && game["state"] != "postgame" ) + { + if ( !maps\mp\_utility::is_aliens() ) + self setclientomnvar( "ui_spawn_abilities_show", 1 ); + } + + waittillframeend; + self.spawningafterremotedeath = undefined; + self notify( "spawned_player" ); + level notify( "player_spawned", self ); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +spawnspectator( var_0, var_1 ) +{ + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "joined_spectators" ); + in_spawnspectator( var_0, var_1 ); +} + +respawn_asspectator( var_0, var_1 ) +{ + in_spawnspectator( var_0, var_1 ); +} + +in_spawnspectator( var_0, var_1 ) +{ + setspawnvariables(); + var_2 = self.pers["team"]; + + if ( isdefined( var_2 ) && var_2 == "spectator" && !level.gameended ) + maps\mp\_utility::clearlowermessage( "spawn_info" ); + + maps\mp\_utility::updatesessionstate( "spectator" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + resetuidvarsonspectate(); + + if ( isdefined( var_2 ) && var_2 == "spectator" ) + self.statusicon = ""; + else + self.statusicon = "hud_status_dead"; + + maps\mp\gametypes\_spectating::setspectatepermissions(); + onspawnspectator( var_0, var_1 ); + + if ( level.teambased && !level.splitscreen && !self issplitscreenplayer() ) + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); +} + +getplayerfromclientnum( var_0 ) +{ + if ( var_0 < 0 ) + return undefined; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] getentitynumber() == var_0 ) + return level.players[var_1]; + } + + return undefined; +} + +onspawnspectator( var_0, var_1 ) +{ + if ( isdefined( var_0 ) && isdefined( var_1 ) ) + { + self setspectatedefaults( var_0, var_1 ); + self spawn( var_0, var_1 ); + checkpredictedspawnpointcorrectness( var_0 ); + return; + } + + var_2 = getspectatepoint(); + + if ( !maps\mp\_utility::is_aliens() ) + { + var_3 = getentarray( "mp_mlg_camera", "classname" ); + + if ( isdefined( var_3 ) && var_3.size ) + { + for ( var_4 = 0; var_4 < var_3.size && var_4 < 4; var_4++ ) + { + self setmlgcameradefaults( var_4, var_3[var_4].origin, var_3[var_4].angles ); + level.cameramapobjs[var_4].origin = var_3[var_4].origin; + level.cameramapobjs[var_4].angles = var_3[var_4].angles; + } + } + else if ( isdefined( level.camera3pos ) ) + { + var_5 = tolower( getdvar( "mapname" ) ); + + if ( var_5 == "mp_strikezone" && isdefined( level.teleport_zone_current ) && level.teleport_zone_current != "start" ) + { + self setmlgcameradefaults( 0, level.camera5pos, level.camera5ang ); + level.cameramapobjs[0].origin = level.camera5pos; + level.cameramapobjs[0].angles = level.camera5ang; + self setmlgcameradefaults( 1, level.camera6pos, level.camera6ang ); + level.cameramapobjs[1].origin = level.camera6pos; + level.cameramapobjs[1].angles = level.camera6ang; + self setmlgcameradefaults( 2, level.camera7pos, level.camera7ang ); + level.cameramapobjs[2].origin = level.camera7pos; + level.cameramapobjs[2].angles = level.camera7ang; + self setmlgcameradefaults( 3, level.camera8pos, level.camera8ang ); + level.cameramapobjs[3].origin = level.camera8pos; + level.cameramapobjs[3].angles = level.camera8ang; + } + else + { + self setmlgcameradefaults( 0, level.camera1pos, level.camera1ang ); + level.cameramapobjs[0].origin = level.camera1pos; + level.cameramapobjs[0].angles = level.camera1ang; + self setmlgcameradefaults( 1, level.camera2pos, level.camera2ang ); + level.cameramapobjs[1].origin = level.camera2pos; + level.cameramapobjs[1].angles = level.camera2ang; + self setmlgcameradefaults( 2, level.camera3pos, level.camera3ang ); + level.cameramapobjs[2].origin = level.camera3pos; + level.cameramapobjs[2].angles = level.camera3ang; + self setmlgcameradefaults( 3, level.camera4pos, level.camera4ang ); + level.cameramapobjs[3].origin = level.camera4pos; + level.cameramapobjs[3].angles = level.camera4ang; + } + } + else + { + for ( var_4 = 0; var_4 < 4; var_4++ ) + self setmlgcameradefaults( var_4, var_2.origin, var_2.angles ); + } + } + + self setspectatedefaults( var_2.origin, var_2.angles ); + self spawn( var_2.origin, var_2.angles ); + checkpredictedspawnpointcorrectness( var_2.origin ); +} + +getspectatepoint() +{ + var_0 = getentarray( "mp_global_intermission", "classname" ); + var_1 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_0 ); + return var_1; +} + +spawnintermission() +{ + self endon( "disconnect" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + var_0 = self.pers["postGameChallenges"]; + + if ( !maps\mp\_utility::is_aliens() && level.rankedmatch && ( self.postgamepromotion || isdefined( var_0 ) && var_0 ) ) + { + if ( self.postgamepromotion ) + self playlocalsound( "mp_level_up" ); + else if ( isdefined( var_0 ) ) + self playlocalsound( "mp_challenge_complete" ); + + if ( self.postgamepromotion > level.postgamenotifies ) + level.postgamenotifies = 1; + + if ( isdefined( var_0 ) && var_0 > level.postgamenotifies ) + level.postgamenotifies = var_0; + + var_1 = 7.0; + + if ( isdefined( var_0 ) ) + var_1 = 4.0 + min( var_0, 3 ); + + while ( var_1 ) + { + wait 0.25; + var_1 -= 0.25; + } + } + + if ( isdefined( level.finalkillcam_winner ) && level.finalkillcam_winner != "none" && isdefined( level.match_end_delay ) && maps\mp\_utility::waslastround() ) + wait(level.match_end_delay); + + maps\mp\_utility::updatesessionstate( "intermission" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_2 = getentarray( "mp_global_intermission", "classname" ); + var_2 = maps\mp\gametypes\_spawnscoring::checkdynamicspawns( var_2 ); + var_3 = var_2[0]; + + if ( !isdefined( level.custom_ending ) ) + { + self spawn( var_3.origin, var_3.angles ); + checkpredictedspawnpointcorrectness( var_3.origin ); + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); + } + else + level notify( "scoreboard_displaying" ); +} + +spawnendofgame() +{ + if ( 1 ) + { + if ( isdefined( level.custom_ending ) && maps\mp\_utility::waslastround() ) + level notify( "start_custom_ending" ); + + maps\mp\_utility::freezecontrolswrapper( 1 ); + spawnspectator(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + return; + } + + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + maps\mp\_utility::updatesessionstate( "dead" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_0 = getspectatepoint(); + spawnspectator( var_0.origin, var_0.angles ); + checkpredictedspawnpointcorrectness( var_0.origin ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); +} + +setspawnvariables() +{ + self stopshellshock(); + self stoprumble( "damage_heavy" ); + self.deathposition = undefined; +} + +notifyconnecting() +{ + waittillframeend; + + if ( isdefined( self ) ) + level notify( "connecting", self ); +} + +callback_playerdisconnect( var_0 ) +{ + if ( !isdefined( self.connected ) ) + return; + + var_1 = getmatchdata( "gameLength" ); + var_1 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "disconnectTime", var_1 ); + setmatchdata( "players", self.clientid, "disconnectReason", var_0 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::logfinalstats(); + + if ( isdefined( self.pers["confirmed"] ) ) + maps\mp\_matchdata::logkillsconfirmed(); + + if ( isdefined( self.pers["denied"] ) ) + maps\mp\_matchdata::logkillsdenied(); + + removeplayerondisconnect(); + maps\mp\gametypes\_spawnlogic::removefromparticipantsarray(); + maps\mp\gametypes\_spawnlogic::removefromcharactersarray(); + var_2 = self getentitynumber(); + + if ( !level.teambased ) + game["roundsWon"][self.guid] = undefined; + + if ( level.splitscreen ) + { + var_3 = level.players; + + if ( var_3.size <= 1 ) + level thread maps\mp\gametypes\_gamelogic::forceend(); + } + + if ( isdefined( self.score ) && isdefined( self.pers["team"] ) ) + { + var_4 = self.score; + + if ( maps\mp\_utility::getminutespassed() ) + var_4 = self.score / maps\mp\_utility::getminutespassed(); + + setplayerteamrank( self, self.clientid, int( var_4 ) ); + } + + var_5 = self getentitynumber(); + var_6 = self.guid; + logprint( "Q;" + var_6 + ";" + var_5 + ";" + self.name + "\n" ); + thread maps\mp\_events::disconnected(); + + if ( level.gameended ) + maps\mp\gametypes\_gamescore::removedisconnectedplayerfromplacement(); + + if ( isdefined( self.team ) ) + removefromteamcount(); + + if ( self.sessionstate == "playing" && !( isdefined( self.fauxdead ) && self.fauxdead ) ) + removefromalivecount( 1 ); + else if ( self.sessionstate == "spectator" || self.sessionstate == "dead" ) + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removeplayerondisconnect() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] == self ) + { + for ( var_0 = 1; var_1 < level.players.size - 1; var_1++ ) + level.players[var_1] = level.players[var_1 + 1]; + + level.players[var_1] = undefined; + break; + } + } +} + +initclientdvarssplitscreenspecific() +{ +} + +initclientdvars() +{ + setdvar( "cg_drawTalk", 1 ); + setdvar( "cg_drawCrosshair", 1 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 250 ); + + if ( level.hardcoremode ) + { + setdvar( "cg_drawTalk", 3 ); + setdvar( "cg_drawCrosshair", 0 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 0 ); + } + + if ( isdefined( level.alwaysdrawfriendlynames ) && level.alwaysdrawfriendlynames ) + setdvar( "cg_drawFriendlyNamesAlways", 1 ); + else + setdvar( "cg_drawFriendlyNamesAlways", 0 ); + + initclientdvarssplitscreenspecific(); + + self setclientdvar( "ui_altscene", 0 ); + + if ( getdvarint( "scr_hitloc_debug" ) ) + { + for ( var_0 = 0; var_0 < 6; var_0++ ) + self setclientdvar( "ui_hitloc_" + var_0, "" ); + + self.hitlocinited = 1; + } +} + +getlowestavailableclientid() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + foreach ( var_3 in level.players ) + { + if ( !isdefined( var_3 ) ) + continue; + + if ( var_3.clientid == var_1 ) + { + var_0 = 1; + break; + } + + var_0 = 0; + } + + if ( !var_0 ) + return var_1; + } +} + +setupsavedactionslots() +{ + self.saved_actionslotdata = []; + + for ( var_0 = 1; var_0 <= 4; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + + if ( !level.console ) + { + for ( var_0 = 5; var_0 <= 8; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + } +} + +callback_playerconnect() +{ + thread notifyconnecting(); + self.statusicon = "hud_status_connecting"; + self waittill( "begin" ); + self.statusicon = ""; + self.connecttime = undefined; + level notify( "connected", self ); + self.connected = 1; + + if ( self ishost() ) + level.player = self; + + if ( !level.splitscreen && !isdefined( self.pers["score"] ) ) + iprintln( &"MP_CONNECTED", self ); + + self.usingonlinedataoffline = self isusingonlinedataoffline(); + initclientdvars(); + + if ( !maps\mp\_utility::is_aliens() ) + initplayerstats(); + + if ( getdvar( "r_reflectionProbeGenerate" ) == "1" ) + level waittill( "eternity" ); + + self.guid = maps\mp\_utility::getuniqueid(); + var_0 = 0; + + if ( !isdefined( self.pers["clientid"] ) ) + { + if ( game["clientid"] >= 30 ) + self.pers["clientid"] = getlowestavailableclientid(); + else + self.pers["clientid"] = game["clientid"]; + + if ( game["clientid"] < 30 ) + game["clientid"]++; + + var_0 = 1; + } + + if ( var_0 ) + maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + self.clientid = self.pers["clientid"]; + self.pers["teamKillPunish"] = 0; + logprint( "J;" + self.guid + ";" + self getentitynumber() + ";" + self.name + "\n" ); + + if ( game["clientid"] <= 30 && game["clientid"] != getmatchdata( "playerCount" ) ) + { + var_1 = 0; + var_2 = 0; + + if ( !isai( self ) && maps\mp\_utility::matchmakinggame() ) + self registerparty( self.clientid ); + + setmatchdata( "playerCount", game["clientid"] ); + setmatchdata( "players", self.clientid, "playerID", "xuid", self getxuid() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDHigh", self getucdidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDLow", self getucdidlow() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDHigh", self getclanidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDLow", self getclanidlow() ); + setmatchdata( "players", self.clientid, "gamertag", self.name ); + var_2 = self getcommonplayerdata( "connectionIDChunkLow", 0 ); + var_1 = self getcommonplayerdata( "connectionIDChunkHigh", 0 ); + setmatchdata( "players", self.clientid, "connectionIDChunkLow", var_2 ); + setmatchdata( "players", self.clientid, "connectionIDChunkHigh", var_1 ); + setmatchclientip( self, self.clientid ); + var_3 = getmatchdata( "gameLength" ); + var_3 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "joinType", self getjointype() ); + setmatchdata( "players", self.clientid, "connectTime", var_3 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::loginitialstats(); + + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] || isai( self ) ) + var_4 = 1; + else + var_4 = 0; + + if ( maps\mp\_utility::matchmakinggame() && maps\mp\_utility::allowteamchoice() && !var_4 ) + setmatchdata( "players", self.clientid, "team", self.sessionteam ); + } + + if ( !level.teambased ) + game["roundsWon"][self.guid] = 0; + + self.leaderdialogqueue = []; + self.leaderdialoglocqueue = []; + self.leaderdialogactive = ""; + self.leaderdialoggroups = []; + self.leaderdialoggroup = ""; + + if ( !isdefined( self.pers["cur_kill_streak"] ) ) + self.pers["cur_kill_streak"] = 0; + + if ( !isdefined( self.pers["cur_death_streak"] ) ) + self.pers["cur_death_streak"] = 0; + + if ( !isdefined( self.pers["assistsToKill"] ) ) + self.pers["assistsToKill"] = 0; + + if ( !isdefined( self.pers["cur_kill_streak_for_nuke"] ) ) + self.pers["cur_kill_streak_for_nuke"] = 0; + + if ( !isdefined( self.pers["objectivePointStreak"] ) ) + self.pers["objectivePointStreak"] = 0; + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + self.kill_streak = maps\mp\gametypes\_persistence::statget( "killStreak" ); + + self.lastgrenadesuicidetime = -1; + self.teamkillsthisround = 0; + self.hasspawned = 0; + self.waitingtospawn = 0; + self.wantsafespawn = 0; + self.wasaliveatmatchstart = 0; + self.movespeedscaler = 1; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.issniper = 0; + + if ( !maps\mp\_utility::is_aliens() ) + setrestxpgoal(); + + setupsavedactionslots(); + thread maps\mp\_flashgrenades::monitorflash(); + resetuidvarsonconnect(); + waittillframeend; + level.players[level.players.size] = self; + maps\mp\gametypes\_spawnlogic::addtoparticipantsarray(); + maps\mp\gametypes\_spawnlogic::addtocharactersarray(); + + if ( level.teambased ) + self updatescores(); + + if ( game["state"] == "postgame" ) + { + self.connectedpostgame = 1; + spawnintermission(); + } + else + { + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["think"] ) ) + self thread [[ level.bot_funcs["think"] ]](); + + level endon( "game_ended" ); + + if ( isdefined( level.hostmigrationtimer ) ) + thread maps\mp\gametypes\_hostmigration::hostmigrationtimerthink(); + + if ( isdefined( level.onplayerconnectaudioinit ) ) + [[ level.onplayerconnectaudioinit ]](); + + if ( maps\mp\_utility::bot_is_fireteam_mode() && !isai( self ) ) + { + thread spawnspectator(); + self setclientomnvar( "ui_options_menu", 0 ); + } + else if ( !isdefined( self.pers["team"] ) ) + { + if ( maps\mp\_utility::matchmakinggame() && self.sessionteam != "none" ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( self.sessionteam ); + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + thread kickifdontspawn(); + return; + } + else if ( issquadsmode() && getdvarint( "onlinegame" ) == 0 && level.gametype != "horde" && isbot( self ) == 0 ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( "allies" ); + self setclientomnvar( "ui_options_menu", 2 ); + } + else if ( maps\mp\_utility::allowteamchoice() && isbot( self ) == 0 ) + { + maps\mp\gametypes\_menus::menuspectator(); + self setclientomnvar( "ui_options_menu", 1 ); + } + else + { + thread spawnspectator(); + maps\mp\gametypes\_menus::autoassign(); + + if ( maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + if ( maps\mp\_utility::matchmakinggame() ) + thread kickifdontspawn(); + + return; + } + } + else + { + maps\mp\gametypes\_menus::addtoteam( self.pers["team"], 1 ); + + if ( maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + thread spawnclient(); + return; + } + + thread spawnspectator(); + + if ( self.pers["team"] == "spectator" ) + { + if ( isdefined( self.pers["mlgSpectator"] ) && self.pers["mlgSpectator"] ) + { + self setmlgspectator( 1 ); + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + if ( maps\mp\_utility::allowteamchoice() ) + { + maps\mp\gametypes\_menus::beginteamchoice(); + return; + } + + self [[ level.autoassign ]](); + return; + return; + } + + maps\mp\gametypes\_menus::beginclasschoice(); + } + } +} + +callback_playermigrated() +{ + if ( isdefined( self.connected ) && self.connected ) + { + maps\mp\_utility::updateobjectivetext(); + maps\mp\_utility::updatemainmenu(); + + if ( level.teambased ) + self updatescores(); + } + + if ( self ishost() ) + initclientdvarssplitscreenspecific(); + + var_0 = 0; + + foreach ( var_2 in level.players ) + { + if ( !isdefined( var_2.pers["isBot"] ) || var_2.pers["isBot"] == 0 ) + var_0++; + } + + if ( !isdefined( self.pers["isBot"] ) || self.pers["isBot"] == 0 ) + { + level.hostmigrationreturnedplayercount++; + + if ( level.hostmigrationreturnedplayercount >= var_0 * 2 / 3 ) + level notify( "hostmigration_enoughplayers" ); + } +} + +addlevelstoexperience( var_0, var_1 ) +{ + var_2 = maps\mp\gametypes\_rank::getrankforxp( var_0 ); + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + var_2 += ( var_0 - var_3 ) / ( var_4 - var_3 ); + var_2 += var_1; + + if ( var_2 < 0 ) + { + var_2 = 0; + var_5 = 0.0; + } + else if ( var_2 >= level.maxrank + 1.0 ) + { + var_2 = level.maxrank; + var_5 = 1.0; + } + else + { + var_5 = var_2 - floor( var_2 ); + var_2 = int( floor( var_2 ) ); + } + + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + return int( var_5 * ( var_4 - var_3 ) ) + var_3; +} + +getrestxpcap( var_0 ) +{ + var_1 = getdvarfloat( "scr_restxp_cap" ); + return addlevelstoexperience( var_0, var_1 ); +} + +setrestxpgoal() +{ + if ( !maps\mp\_utility::rankingenabled() ) + return; + + if ( !getdvarint( "scr_restxp_enable" ) ) + { + self setrankedplayerdata( "restXPGoal", 0 ); + return; + } + + var_0 = self getrestedtime(); + var_1 = var_0 / 3600; + var_2 = self getrankedplayerdata( "experience" ); + var_3 = getdvarfloat( "scr_restxp_minRestTime" ); + var_4 = getdvarfloat( "scr_restxp_levelsPerDay" ) / 24.0; + var_5 = getrestxpcap( var_2 ); + var_6 = self getrankedplayerdata( "restXPGoal" ); + + if ( var_6 < var_2 ) + var_6 = var_2; + + var_7 = var_6; + var_8 = 0; + + if ( var_1 > var_3 ) + { + var_8 = var_4 * var_1; + var_6 = addlevelstoexperience( var_6, var_8 ); + } + + var_9 = ""; + + if ( var_6 >= var_5 ) + { + var_6 = var_5; + var_9 = " (hit cap)"; + } + + self setrankedplayerdata( "restXPGoal", var_6 ); +} + +forcespawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + wait 60.0; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + if ( !maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + self.pers["class"] = "CLASS_CUSTOM1"; + self.class = self.pers["class"]; + } + + thread spawnclient(); +} + +kickifdontspawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "attempted_spawn" ); + var_0 = getdvarfloat( "scr_kick_time", 90 ); + var_1 = getdvarfloat( "scr_kick_mintime", 45 ); + var_2 = getdvarfloat( "scr_kick_hosttime", 120 ); + var_3 = gettime(); + + if ( self ishost() ) + kickwait( var_2 ); + else + kickwait( var_0 ); + + var_4 = ( gettime() - var_3 ) / 1000; + + if ( var_4 < var_0 - 0.1 && var_4 < var_1 ) + return; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + kick( self getentitynumber(), "EXE_PLAYERKICKED_INACTIVE" ); + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +kickwait( var_0 ) +{ + level endon( "game_ended" ); + maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 ); +} + +initplayerstats() +{ + maps\mp\gametypes\_persistence::initbufferedstats(); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + + if ( !isdefined( self.pers["deaths"] ) ) + { + maps\mp\_utility::initpersstat( "deaths" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", 0 ); + } + + self.deaths = maps\mp\_utility::getpersstat( "deaths" ); + + if ( !isdefined( self.pers["score"] ) ) + { + maps\mp\_utility::initpersstat( "score" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "score", 0 ); + } + + self.score = maps\mp\_utility::getpersstat( "score" ); + + if ( !isdefined( self.pers["suicides"] ) ) + maps\mp\_utility::initpersstat( "suicides" ); + + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !isdefined( self.pers["kills"] ) ) + { + maps\mp\_utility::initpersstat( "kills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "kills", 0 ); + } + + self.kills = maps\mp\_utility::getpersstat( "kills" ); + + if ( !isdefined( self.pers["headshots"] ) ) + maps\mp\_utility::initpersstat( "headshots" ); + + self.headshots = maps\mp\_utility::getpersstat( "headshots" ); + + if ( !isdefined( self.pers["assists"] ) ) + { + maps\mp\_utility::initpersstat( "assists" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "assists", 0 ); + } + + self.assists = maps\mp\_utility::getpersstat( "assists" ); + + if ( !isdefined( self.pers["captures"] ) ) + { + maps\mp\_utility::initpersstat( "captures" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "captures", 0 ); + } + + self.captures = maps\mp\_utility::getpersstat( "captures" ); + + if ( !isdefined( self.pers["returns"] ) ) + { + maps\mp\_utility::initpersstat( "returns" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "returns", 0 ); + } + + self.returns = maps\mp\_utility::getpersstat( "returns" ); + + if ( !isdefined( self.pers["defends"] ) ) + { + maps\mp\_utility::initpersstat( "defends" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defends", 0 ); + } + + self.defends = maps\mp\_utility::getpersstat( "defends" ); + + if ( !isdefined( self.pers["plants"] ) ) + { + maps\mp\_utility::initpersstat( "plants" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "plants", 0 ); + } + + self.plants = maps\mp\_utility::getpersstat( "plants" ); + + if ( !isdefined( self.pers["defuses"] ) ) + { + maps\mp\_utility::initpersstat( "defuses" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defuses", 0 ); + } + + self.defuses = maps\mp\_utility::getpersstat( "defuses" ); + + if ( !isdefined( self.pers["destructions"] ) ) + { + maps\mp\_utility::initpersstat( "destructions" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "destructions", 0 ); + } + + self.destructions = maps\mp\_utility::getpersstat( "destructions" ); + + if ( !isdefined( self.pers["confirmed"] ) ) + { + maps\mp\_utility::initpersstat( "confirmed" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "confirmed", 0 ); + } + + self.confirmed = maps\mp\_utility::getpersstat( "confirmed" ); + + if ( !isdefined( self.pers["denied"] ) ) + { + maps\mp\_utility::initpersstat( "denied" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "denied", 0 ); + } + + self.denied = maps\mp\_utility::getpersstat( "denied" ); + + if ( !isdefined( self.pers["rescues"] ) ) + { + maps\mp\_utility::initpersstat( "rescues" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "rescues", 0 ); + } + + self.rescues = maps\mp\_utility::getpersstat( "rescues" ); + + if ( !isdefined( self.pers["killChains"] ) ) + { + maps\mp\_utility::initpersstat( "killChains" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killChains", 0 ); + } + + self.killchains = maps\mp\_utility::getpersstat( "killChains" ); + + if ( !isdefined( self.pers["killsAsSurvivor"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsSurvivor" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsSurvivor", 0 ); + } + + self.killsassurvivor = maps\mp\_utility::getpersstat( "killsAsSurvivor" ); + + if ( !isdefined( self.pers["killsAsInfected"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsInfected" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsInfected", 0 ); + } + + self.killsasinfected = maps\mp\_utility::getpersstat( "killsAsInfected" ); + + if ( !isdefined( self.pers["teamkills"] ) ) + maps\mp\_utility::initpersstat( "teamkills" ); + + if ( !isdefined( self.pers["extrascore0"] ) ) + maps\mp\_utility::initpersstat( "extrascore0" ); + + if ( !isdefined( self.pers["hordeKills"] ) ) + { + maps\mp\_utility::initpersstat( "hordeKills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardKills", 0 ); + } + + if ( !isdefined( self.pers["hordeRevives"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRevives" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardRevives", 0 ); + } + + if ( !isdefined( self.pers["hordeCrates"] ) ) + { + maps\mp\_utility::initpersstat( "hordeCrates" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardCrates", 0 ); + } + + if ( !isdefined( self.pers["hordeRound"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRound" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWave", 0 ); + } + + if ( !isdefined( self.pers["hordeWeapon"] ) ) + { + maps\mp\_utility::initpersstat( "hordeWeapon" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWeaponLevel", 0 ); + } + + if ( !isdefined( self.pers["teamKillPunish"] ) ) + self.pers["teamKillPunish"] = 0; + + maps\mp\_utility::initpersstat( "longestStreak" ); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "win", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "scoreboardType", "none" ); + maps\mp\gametypes\_persistence::statsetchildbuffered( "round", "timePlayed", 0 ); +} + +addtoteamcount() +{ + level.teamcount[self.team]++; + + if ( !isdefined( level.teamlist ) ) + level.teamlist = []; + + if ( !isdefined( level.teamlist[self.team] ) ) + level.teamlist[self.team] = []; + + level.teamlist[self.team][level.teamlist[self.team].size] = self; + maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removefromteamcount() +{ + level.teamcount[self.team]--; + + if ( isdefined( level.teamlist ) && isdefined( level.teamlist[self.team] ) ) + { + var_0 = []; + + foreach ( var_2 in level.teamlist[self.team] ) + { + if ( !isdefined( var_2 ) || var_2 == self ) + continue; + + var_0[var_0.size] = var_2; + } + + level.teamlist[self.team] = var_0; + } +} + +addtoalivecount() +{ + var_0 = self.team; + + if ( !( isdefined( self.alreadyaddedtoalivecount ) && self.alreadyaddedtoalivecount ) ) + { + level.hasspawned[var_0]++; + incrementalivecount( var_0 ); + } + + self.alreadyaddedtoalivecount = undefined; + + if ( level.alivecount["allies"] + level.alivecount["axis"] > level.maxplayercount ) + level.maxplayercount = level.alivecount["allies"] + level.alivecount["axis"]; +} + +incrementalivecount( var_0 ) +{ + level.alivecount[var_0]++; +} + +removefromalivecount( var_0 ) +{ + if ( maps\mp\_utility::is_aliens() ) + return; + + var_1 = self.team; + + if ( isdefined( self.switching_teams ) && self.switching_teams && isdefined( self.joining_team ) && self.joining_team == self.team ) + var_1 = self.leaving_team; + + if ( isdefined( var_0 ) ) + removeallfromlivescount(); + else if ( isdefined( self.switching_teams ) ) + self.pers["lives"]--; + + decrementalivecount( var_1 ); + return maps\mp\gametypes\_gamelogic::updategameevents(); +} + +decrementalivecount( var_0 ) +{ + level.alivecount[var_0]--; +} + +addtolivescount() +{ + level.livescount[self.team] += self.pers["lives"]; +} + +removefromlivescount() +{ + level.livescount[self.team]--; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +removeallfromlivescount() +{ + level.livescount[self.team] -= self.pers["lives"]; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +resetuidvarsonspawn() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonconnect() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonspectate() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsondeath() +{ + +} + +watchforslide() +{ + self endon( "death" ); + self endon( "disconnect" ); + + for (;;) + { + self waittill( "sprint_slide_begin" ); + self playfx( level._effect["slide_dust"], self geteye() ); + } +} diff --git a/data/maps/mp/gametypes/aliens.gsc b/data/maps/mp/gametypes/aliens.gsc new file mode 100644 index 0000000..c495020 --- /dev/null +++ b/data/maps/mp/gametypes/aliens.gsc @@ -0,0 +1,2171 @@ +// IW6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool + +main() +{ + if ( getdvar( "mapname" ) == "mp_background" ) + return; + + maps\mp\alien\_globallogic::init(); + maps\mp\gametypes\_callbacksetup::setupcallbacks(); + maps\mp\alien\_globallogic::setupcallbacks(); + level.customprematchperiod = ::alien_customprematchperiod; + + if ( isusingmatchrulesdata() ) + { + level.initializematchrules = ::initializematchrules; + [[ level.initializematchrules ]](); + level thread maps\mp\_utility::reinitializematchrulesonmigration(); + } + else + { + maps\mp\_utility::registerroundswitchdvar( level.gametype, 0, 0, 9 ); + maps\mp\_utility::registertimelimitdvar( level.gametype, 0 ); + maps\mp\_utility::registerscorelimitdvar( level.gametype, 500 ); + maps\mp\_utility::registerroundlimitdvar( level.gametype, 1 ); + maps\mp\_utility::registerwinlimitdvar( level.gametype, 1 ); + maps\mp\_utility::registernumlivesdvar( level.gametype, 0 ); + maps\mp\_utility::registerhalftimedvar( level.gametype, 0 ); + level.matchrules_damagemultiplier = 0; + level.matchrules_vampirism = 0; + level.prematchperiod = 0; + } + + if ( level.matchrules_damagemultiplier || level.matchrules_vampirism ) + level.modifyplayerdamage = maps\mp\gametypes\_damage::gamemodemodifyplayerdamage; + + level.teambased = 1; + level.getteamassignment = ::getteamassignment; + level.onprecachegametype = ::onprecachegametype; + level.killstreakinit = ::killstreakinit; + level.onstartgametype = ::onstartgametype; + level.onspawnplayer = ::onspawnplayer; + level.getspawnpoint = ::getspawnpoint; + level.endgame_alien = ::alienendgame; + level.forceendgame_alien = ::alienforceendgame; + level.onnormaldeath = maps\mp\alien\_death::onnormaldeath; + level.onplayerkilled = maps\mp\alien\_death::onplayerkilled; + level.ontimelimit = ::ontimelimit; + level.onxpevent = ::onxpevent; + level.bypassclasschoicefunc = ::bypassclasschoicefunc; + level.callbackplayerlaststand = maps\mp\alien\_laststand::callback_playerlaststandalien; + level.callbackplayerdamage = maps\mp\alien\_damage::callback_alienplayerdamage; + level.aliens_make_entity_sentient_func = ::alien_make_entity_sentient; + level.aliens_give_currency_func = maps\mp\alien\_persistence::give_player_currency; + level.exploimpactmod = 0.1; + level.shotgundamagemod = 0.1; + level.armorpiercingmod = 0.2; + level.custom_giveloadout = ::custom_giveloadout; + level.boxcapturethink_alien_func = ::boxcapturethink_alien_func; + level.regenhealthmod = 2; + level.damagefeedbacknosound = 1; + level.ischaosmode = getdvarint( "scr_chaos_mode", 0 ); + level.hardcoremode = getdvarint( "scr_aliens_hardcore" ); + level.ricochetdamage = getdvarint( "scr_aliens_ricochet" ); + level.infinitemode = getdvarint( "scr_aliens_infinite" ); + level.casualmode = getdvarint( "scr_aliens_casual" ); + level.playermeleestunregentime = 4000; + setdvarifuninitialized( "alien_cover_node_retreat", 0 ); + setdvarifuninitialized( "alien_retreat_towards_spawn", 1 ); + + if ( maps\mp\alien\_utility::is_hardcore_mode() ) + setomnvar( "ui_aliens_hardcore", 1 ); + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + { + setomnvar( "ui_alien_chaos", 1 ); + maps\mp\alien\_chaos::set_chaos_area(); + } + + if ( !isdefined( level.ricochetdamagemax ) ) + level.ricochetdamagemax = 25; + + level.getnodearrayfunction = ::getnodearray; + level.nodefiltertracestime = 0; + level.nodefiltertracesthisframe = 0; + level.maxalienattackerdifficultyvalue = 10.0; + setalienloadout(); + healthregeninit(); + maps\mp\agents\alien\_alien_anim_utils::initalienanims(); + level thread onplayerconnect(); + level thread maps\mp\alien\_music_and_dialog::init(); + level thread maps\mp\alien\_deployablebox_functions::specialammo_init(); + level thread maps\mp\alien\_deployablebox_functions::deployables_init(); + level thread maps\mp\alien\_autosentry_alien::init(); + maps\mp\alien\_outline_proto::outline_init(); + maps\mp\alien\_ffotd::init(); + common_scripts\utility::array_thread( getentarray( "misc_turret", "classname" ), maps\mp\alien\_trap::turret_monitoruse ); +} + +healthregeninit() +{ + level.healthregendisabled = 0; + level.healthregencap = getdvarfloat( "alien_playerHealthRegenCap", 1.0 ); +} + +getteamassignment() +{ + return "allies"; +} + +initializematchrules() +{ + maps\mp\_utility::setcommonrulesfrommatchrulesdata(); + setdynamicdvar( "scr_aliens_roundswitch", 0 ); + maps\mp\_utility::registerroundswitchdvar( "aliens", 0, 0, 9 ); + setdynamicdvar( "scr_aliens_roundlimit", 1 ); + maps\mp\_utility::registerroundlimitdvar( "aliens", 1 ); + setdynamicdvar( "scr_aliens_winlimit", 1 ); + maps\mp\_utility::registerwinlimitdvar( "aliens", 1 ); + setdynamicdvar( "scr_aliens_halftime", 0 ); + maps\mp\_utility::registerhalftimedvar( "aliens", 0 ); + setdynamicdvar( "scr_aliens_promode", 0 ); +} + +onprecachegametype() +{ + precachestring( &"ALIEN_COLLECTIBLES_SELF_REVIVED" ); + precachestring( &"ALIEN_COLLECTIBLES_PLANT_BOMB" ); + precachestring( &"ALIEN_COLLECTIBLES_NO_BOMB" ); + precachestring( &"ALIEN_COLLECTIBLES_GO_PLANT_BOMB" ); + precachestring( &"ALIEN_COLLECTIBLES_PICKUP_BOMB" ); + precachestring( &"ALIEN_COLLECTIBLES_REPAIR_DRILL" ); + precachestring( &"ALIEN_COLLECTIBLES_ACTIVATE_NUKE" ); + precachestring( &"ALIEN_COLLECTIBLES_COUNTDOWN_NUKE" ); + precachestring( &"ALIEN_COLLECTIBLES_DRILL_DESTROYED" ); + level._effect["alien_teleport"] = loadfx( "vfx/test/vfx_alien_teleport" ); + level._effect["alien_teleport_dist"] = loadfx( "vfx/test/vfx_alien_teleport_dist" ); + level._effect["Riotshield_fire"] = loadfx( "vfx/gameplay/alien/vfx_alien_on_fire" ); + level._effect["arcade_death"] = loadfx( "vfx/moments/alien/vfx_alien_arcade_death" ); + maps\mp\agents\alien\_alien_elite::load_queen_fx(); + maps\mp\agents\alien\_alien_spitter::load_spitter_fx(); + level._effect["drone_ground_spawn"] = loadfx( "vfx/gameplay/alien/vfx_alien_drone_ground_spawn" ); + level._effect["deployablebox_crate_destroy"] = loadfx( "vfx/test/vfx_alien_teleport" ); + maps\mp\agents\alien\_alien_minion::load_minion_fx(); + level._effect["bomb_impact"] = loadfx( "vfx/ambient/sparks/electrical_sparks" ); + level._effect["shield_impact"] = loadfx( "fx/impacts/large_metalhit_1" ); + level._effect["airdrop_crate_destroy"] = loadfx( "vfx/gameplay/mp/killstreaks/vfx_ims_explosion" ); + level._effect["melee_blood"] = loadfx( "vfx/gameplay/impacts/small/impact_alien_flesh_hit_b_fatal" ); + precacheturret( "turret_minigun_alien" ); + + if ( maps\mp\alien\_utility::alien_mode_has( "airdrop" ) ) + { + precachevehicle( "littlebird_alien" ); + precachevehicle( "nh90_alien" ); + precachempanim( "alien_drill_enter" ); + precachempanim( "alien_drill_loop" ); + precachempanim( "alien_drill_end" ); + precachempanim( "alien_drill_operate_enter" ); + precachempanim( "alien_drill_nonoperate" ); + precachempanim( "alien_drill_operate_end" ); + precachempanim( "alien_drill_attack_drill_F_enter" ); + precachempanim( "alien_drill_attack_drill_F_exit" ); + precachempanim( "alien_drill_attack_drill_F_loop" ); + precachempanim( "alien_drill_attack_drill_L_enter" ); + precachempanim( "alien_drill_attack_drill_L_exit" ); + precachempanim( "alien_drill_attack_drill_L_loop" ); + precachempanim( "alien_drill_attack_drill_R_enter" ); + precachempanim( "alien_drill_attack_drill_R_exit" ); + precachempanim( "alien_drill_attack_drill_R_loop" ); + precachempanim( "alien_goon_drill_attack_drill_F_enter" ); + precachempanim( "alien_goon_drill_attack_drill_F_loop" ); + precachempanim( "alien_goon_drill_attack_drill_F_exit" ); + precachempanim( "alien_goon_drill_attack_drill_R_enter" ); + precachempanim( "alien_goon_drill_attack_drill_R_loop" ); + precachempanim( "alien_goon_drill_attack_drill_R_exit" ); + precachempanim( "alien_goon_drill_attack_drill_L_enter" ); + precachempanim( "alien_goon_drill_attack_drill_L_loop" ); + precachempanim( "alien_goon_drill_attack_drill_L_exit" ); + precachempanim( "alien_sentry_attack_sentry_front_enter" ); + precachempanim( "alien_sentry_attack_sentry_front_exit" ); + precachempanim( "alien_sentry_attack_sentry_front_loop" ); + precachempanim( "alien_sentry_attack_sentry_side_r_enter" ); + precachempanim( "alien_sentry_attack_sentry_side_r_exit" ); + precachempanim( "alien_sentry_attack_sentry_side_r_loop" ); + precachempanim( "alien_sentry_attack_sentry_side_l_enter" ); + precachempanim( "alien_sentry_attack_sentry_side_l_exit" ); + precachempanim( "alien_sentry_attack_sentry_side_l_loop" ); + precachempanim( "alien_goon_sentry_attack_sentry_F_enter" ); + precachempanim( "alien_goon_sentry_attack_sentry_F_exit" ); + precachempanim( "alien_goon_sentry_attack_sentry_F_loop" ); + precachempanim( "alien_goon_sentry_attack_sentry_L_enter" ); + precachempanim( "alien_goon_sentry_attack_sentry_L_exit" ); + precachempanim( "alien_goon_sentry_attack_sentry_L_loop" ); + precachempanim( "alien_goon_sentry_attack_sentry_R_enter" ); + precachempanim( "alien_goon_sentry_attack_sentry_R_exit" ); + precachempanim( "alien_goon_sentry_attack_sentry_R_loop" ); + } + + if ( maps\mp\alien\_intro_sequence::intro_sequence_enabled() ) + maps\mp\alien\_intro_sequence::intro_sequence_precache(); +} + +onstartgametype() +{ + if ( isdefined( level.custom_onstartgametypefunc ) ) + [[ level.custom_onstartgametypefunc ]](); + + setnojiptime( 1 ); + setclientnamemode( "auto_change" ); + thread maps\mp\alien\_utility::mp_ents_clean_up(); + level.disableforfeit = 1; + level.damagelistsize = 20; + maps\mp\_utility::setobjectivetext( "allies", &"ALIEN_OBJECTIVES_ALIENS" ); + maps\mp\_utility::setobjectivetext( "axis", &"ALIEN_OBJECTIVES_ALIENS" ); + + if ( level.splitscreen ) + { + maps\mp\_utility::setobjectivescoretext( "allies", &"ALIEN_OBJECTIVES_ALIENS" ); + maps\mp\_utility::setobjectivescoretext( "axis", &"ALIEN_OBJECTIVES_ALIENS" ); + } + else + { + maps\mp\_utility::setobjectivescoretext( "allies", &"ALIEN_OBJECTIVES_ALIENS_SCORE" ); + maps\mp\_utility::setobjectivescoretext( "axis", &"ALIEN_OBJECTIVES_ALIENS_SCORE" ); + } + + maps\mp\_utility::setobjectivehinttext( "allies", &"ALIEN_OBJECTIVES_ALIENS_HINT" ); + maps\mp\_utility::setobjectivehinttext( "axis", &"ALIEN_OBJECTIVES_ALIENS_HINT" ); + maps\mp\alien\_persistence::bbdata_init(); + maps\mp\alien\_persistence::rank_init(); + maps\mp\alien\_persistence::register_eog_to_lb_playerdata_mapping(); + maps\mp\alien\_progression::main(); + init_threatbiasgroups(); + + if ( maps\mp\alien\_utility::alien_mode_has( "collectible" ) ) + maps\mp\alien\_collectibles::pre_load(); + + maps\mp\alien\_deployablebox_functions::pre_load(); + + if ( maps\mp\alien\_utility::alien_mode_has( "scenes" ) ) + maps\mp\alien\_spawnlogic::alien_scene_init(); + + maps\mp\alien\_alien_fx::main(); + maps\mp\alien\_spawnlogic::alien_health_per_player_init(); + initspawns(); + var_0[0] = level.gametype; + maps\mp\gametypes\_gameobjects::main( var_0 ); + level.current_cycle_num = 0; + level.num_hive_destroyed = 0; + level thread maps\mp\alien\_trap::traps_init(); + maps\mp\alien\_gamescore::init_gamescore(); + level.spitter_gas_cloud_count = 0; + level.gametweaks["spectatetype"].value = 1; + + if ( should_enable_pillage() ) + thread maps\mp\alien\_pillage::pillage_init(); + + if ( maps\mp\alien\_utility::alien_mode_has( "challenge" ) ) + maps\mp\alien\_challenge::init_challenge(); + + maps\mp\alien\_unlock::init_unlock(); + maps\mp\alien\_prestige::init_prestige(); + maps\mp\alien\_hud::init(); + level.lowermessagefont = "objective"; + + if ( level.splitscreen ) + level.lowertextfontsize = 1.35; + + if ( !level.console ) + level.lowertextfontsize = 1; + + level.teamtweaks["fftype"].value = 1; + maps\mp\alien\_death::kill_trigger_spawn_init(); + level thread handle_nondeterministic_entities(); + level thread maps\mp\alien\_trap::easter_egg_lodge_sign(); + level.xpscale = getdvarint( "scr_aliens_xpscale" ); + level.xpscale = min( level.xpscale, 4 ); + level.xpscale = max( level.xpscale, 0 ); + maps\mp\alien\_alien_matchdata::start_game_type(); + maps\mp\alien\_ffotd::onstartgametype(); + level thread run_encounters(); +} + +should_enable_pillage() +{ + if ( maps\mp\alien\_utility::is_chaos_mode() ) + return 0; + + return maps\mp\alien\_utility::alien_mode_has( "pillage" ); +} + +handle_nondeterministic_entities() +{ + wait 5; + handle_nondeterministic_entities_internal(); + level notify( "spawn_nondeterministic_entities" ); +} + +handle_nondeterministic_entities_internal() +{ + if ( maps\mp\alien\_utility::alien_mode_has( "collectible" ) ) + maps\mp\alien\_collectibles::post_load(); + + if ( !maps\mp\alien\_utility::alien_mode_has( "nogame" ) && maps\mp\alien\_utility::alien_mode_has( "wave" ) && maps\mp\alien\_spawnlogic::use_spawn_director() ) + { + maps\mp\alien\_hive::remove_unused_hives( level.removed_hives ); + level.removed_hives = undefined; + } + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_chaos::create_alien_eggs(); +} + +spawnallypet( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + wait 0.05; + var_6 = "wave " + var_0; + + for ( var_7 = 0; var_7 < var_1; var_7++ ) + { + var_8 = var_2; + + if ( var_6 == "wave elite" ) + { + var_9 = bullettrace( var_2 + ( 0, 0, 128 ), var_2 + ( 0, 0, -128 ), 0 ); + + if ( var_9["fraction"] == 0 || var_9["fraction"] == 1 ) + continue; + + var_8 = var_9["position"]; + } + + var_10 = var_4; + var_11 = var_8; + var_12 = addalienagent( "allies", var_11, var_10, var_6 ); + var_12.pet = 1; + var_12.owner = var_3; + var_12.petfollowdist = 1024; + var_12.threatbias = -800; + + if ( var_0 == "goon" ) + { + var_12.maxhealth = int( 100 * level.alien_health_per_player_scalar[level.players.size] ); + var_12.health = int( 100 * level.alien_health_per_player_scalar[level.players.size] ); + } + else if ( var_0 == "brute" ) + { + var_12.maxhealth = int( 200 * level.alien_health_per_player_scalar[level.players.size] ); + var_12.health = int( 200 * level.alien_health_per_player_scalar[level.players.size] ); + } + else if ( var_0 == "spitter" ) + { + var_12.maxhealth = int( 150 * level.alien_health_per_player_scalar[level.players.size] ); + var_12.health = int( 150 * level.alien_health_per_player_scalar[level.players.size] ); + } + else if ( var_0 == "locust" ) + { + var_12.maxhealth = int( 250 * level.alien_health_per_player_scalar[level.players.size] ); + var_12.health = int( 250 * level.alien_health_per_player_scalar[level.players.size] ); + } + else if ( var_0 == "elite" ) + { + var_12.maxhealth = int( 350 * level.alien_health_per_player_scalar[level.players.size] ); + var_12.health = int( 350 * level.alien_health_per_player_scalar[level.players.size] ); + } + + if ( maps\mp\alien\_utility::is_true( var_5 ) ) + { + var_12.maxhealth = int( var_12.maxhealth * 1.25 ); + var_12.health = int( var_12.maxhealth * 1.25 ); + } + + var_12 maps\mp\alien\_utility::set_alien_emissive( 0.5, 0.0 ); + + if ( var_3 maps\mp\alien\_persistence::is_upgrade_enabled( "master_scavenger_upgrade" ) ) + { + var_12.upgraded = 1; + maps\mp\alien\_outline_proto::enable_outline( var_12, 2, 0 ); + } + else + maps\mp\alien\_outline_proto::enable_outline( var_12, 3, 0 ); + + var_12 setscriptablepartstate( "body", "pet" ); + + if ( isdefined( self.entityheadicon ) ) + self.entityheadicon destroy(); + + var_12 thread ally_pet_time_out( var_5 ); + var_12 thread kill_alien_on_owner_disconnect( var_3 ); + } +} + +ally_pet_time_out( var_0 ) +{ + level endon( "game_ended" ); + self endon( "death" ); + var_1 = 180; + + if ( maps\mp\alien\_utility::is_true( var_0 ) ) + var_1 = var_1 * 1.25; + + wait( var_1 ); + playfx( level._effect["alien_minion_explode"], self.origin + ( 0, 0, 32 ) ); + self suicide(); +} + +kill_alien_on_owner_disconnect( var_0 ) +{ + self endon( "death" ); + var_0 waittill( "disconnect" ); + playfx( level._effect["alien_minion_explode"], self.origin + ( 0, 0, 32 ) ); + self suicide(); +} + +onplayerconnect() +{ + for (;;) + { + level waittill( "connected", var_0 ); + + if ( !isai( var_0 ) ) + { + if ( maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_chaos::chaos_onplayerconnect( var_0 ); + + var_0 maps\mp\alien\_alien_matchdata::on_player_connect(); + + if ( isdefined( var_0.connecttime ) ) + var_0.connect_time = var_0.connecttime; + else + var_0.connect_time = gettime(); + + var_0 maps\mp\alien\_prestige::init_player_prestige(); + var_0 maps\mp\alien\_persistence::player_persistence_init(); + var_0 thread maps\mp\alien\_utility::weapon_change_monitor(); + var_0 thread threat_bias_grouping(); + var_0 thread player_init_health_regen(); + var_0 maps\mp\alien\_hud::init_player_hud_onconnect(); + var_0 maps\mp\alien\_gamescore::init_player_score(); + var_0 thread maps\mp\alien\_progression::player_setup(); + var_0 maps\mp\alien\_achievement::init_player_achievement(); + var_0 maps\mp\alien\_unlock::init_player_unlock(); + var_0 thread maps\mp\alien\_persistence::play_time_monitor(); + var_0 initial_spawn_pos_override(); + + if ( !maps\mp\alien\_utility::is_casual_mode() ) + var_0 setclientomnvar( "allow_write_leaderboards", 1 ); + else + var_0 setclientomnvar( "allow_write_leaderboards", 0 ); + + if ( common_scripts\utility::flag_exist( "hives_cleared" ) && common_scripts\utility::flag( "hives_cleared" ) ) + { + var_0.threatbias = 100000; + var_0 thread maps\mp\alien\_persistence::set_game_state( "escaping" ); + } + else if ( !isdefined( level.cycle_count ) || level.cycle_count < 1 ) + var_0 thread maps\mp\alien\_persistence::set_game_state( "pregame" ); + else if ( isdefined( level.cycle_count ) && level.cycle_count == 1 ) + var_0 thread maps\mp\alien\_persistence::set_game_state( "prehive" ); + else + var_0 thread maps\mp\alien\_persistence::set_game_state( "progressing" ); + + if ( maps\mp\alien\_utility::alien_mode_has( "kill_resource" ) ) + var_0 thread player_init_assist_bonus(); + + var_1 = get_hotjoin_skill_points(); + + if ( var_1 > 0 ) + var_0 maps\mp\alien\_persistence::give_player_points( var_1 ); + + var_0 resetuidvarsonconnect(); + + if ( maps\mp\alien\_utility::alien_mode_has( "outline" ) ) + var_0 thread maps\mp\alien\_outline_proto::outline_monitor(); + + if ( maps\mp\alien\_utility::alien_mode_has( "challenge" ) ) + { + if ( maps\mp\alien\_challenge::current_challenge_exist() && maps\mp\alien\_utility::alien_mode_has( "challenge" ) ) + var_0 thread maps\mp\alien\_challenge::handle_challenge_hotjoin(); + } + + var_0 thread special_weapon_hints(); + var_0 thread enable_disable_usability_monitor(); + var_0 thread monitordisownkillstreaks(); + + if ( common_scripts\utility::flag_exist( "drill_drilling" ) ) + var_0 thread maps\mp\alien\_drill::check_for_player_near_hive_with_drill(); + + var_0 thread maps\mp\alien\_hud::intro_black_screen(); + + if ( maps\mp\alien\_utility::is_true( level.introscreen_done ) ) + var_0 thread player_hotjoin(); + + var_0 maps\mp\alien\_ffotd::onplayerconnect(); + } + } +} + +initial_spawn_pos_override() +{ + if ( isdefined( level.initial_spawn_loc_override_func ) ) + self [[ level.initial_spawn_loc_override_func ]](); +} + +get_hotjoin_skill_points() +{ + if ( isdefined( level.hotjoin_skill_points_fun ) ) + return [[ level.hotjoin_skill_points_fun ]](); + else + return default_hotjoin_skill_points(); +} + +default_hotjoin_skill_points() +{ + var_0 = 1; + + if ( maps\mp\alien\_utility::is_hardcore_mode() ) + var_1 = 0; + else + var_1 = max( 0, level.num_hive_destroyed - var_0 ); + + var_2 = maps\mp\alien\_challenge::get_num_challenge_completed(); + return var_1 + var_2; +} + +init_threatbiasgroups() +{ + createthreatbiasgroup( "players" ); + createthreatbiasgroup( "hive_heli" ); + createthreatbiasgroup( "other_aliens" ); + createthreatbiasgroup( "spitters" ); + createthreatbiasgroup( "dontattackdrill" ); + createthreatbiasgroup( "drill" ); + setthreatbias( "hive_heli", "spitters", 10000 ); + setignoremegroup( "hive_heli", "other_aliens" ); + setignoremegroup( "drill", "dontattackdrill" ); + setignoremegroup( "hive_heli", "dontattackdrill" ); +} + +threat_bias_grouping() +{ + level endon( "game_ended" ); + + while ( !threatbiasgroupexists( "players" ) ) + wait 0.05; + + self setthreatbiasgroup( "players" ); +} + +player_hotjoin() +{ + self endon( "disconnect" ); + self notify( "intro_done" ); + self waittill( "spawned" ); + self.pers["hotjoined"] = 1; + self.introscreen_overlay fadeovertime( 1 ); + wait 1; + self.introscreen_overlay destroy(); + var_0 = maps\mp\alien\_spawnlogic::get_alive_enemies(); + + if ( !isdefined( var_0 ) || var_0.size < 1 ) + return; + + foreach ( var_2 in var_0 ) + { + if ( isdefined( var_2 ) && maps\mp\alien\_utility::is_true( var_2.pet ) ) + maps\mp\alien\_outline_proto::enable_outline_for_player( var_2, self, 3, 0, "high" ); + } +} + +player_init_health_regen() +{ + self.healthregenmaxpercent = level.healthregencap; + self.regenspeed = 1; +} + +player_init_invulnerability() +{ + self.haveinvulnerabilityavailable = 1; +} + +player_init_damageshield() +{ + self.damageshieldexpiretime = gettime(); +} + +player_init_assist_bonus() +{ + self.leftover_assist_bonus = 0; +} + +onspawnplayer() +{ + self.pers["gamemodeLoadout"] = level.alien_loadout; + self.drillspeedmodifier = 1.0; + self.fireshield = 0; + self.isreviving = 0; + self.isrepairing = 0; + self.iscarrying = 0; + self.isboosted = undefined; + self.ishealthboosted = undefined; + self.burning = undefined; + self.shocked = undefined; + self.player_action_disabled = undefined; + + if ( maps\mp\alien\_perk_utility::has_perk( "perk_health" ) ) + { + self.maxhealth = maps\mp\alien\_perk_utility::perk_getmaxhealth(); + self.health = self.maxhealth; + } + + thread player_last_death_pos(); + thread alienplayerhealthhints(); + player_init_invulnerability(); + player_init_damageshield(); + maps\mp\alien\_laststand::player_init_laststand(); + + if ( maps\mp\alien\_persistence::is_upgrade_enabled( "shock_melee_upgrade" ) ) + thread melee_strength_timer(); + + if ( maps\mp\alien\_persistence::is_upgrade_enabled( "locker_key_upgrade" ) ) + { + var_0 = getdvar( "ui_mapname" ); + + if ( var_0 == "mp_alien_armory" || var_0 == "mp_alien_beacon" || var_0 == "mp_alien_dlc3" || var_0 == "mp_alien_last" ) + thread init_locker_key_upgrade(); + } + + if ( maps\mp\alien\_utility::alien_mode_has( "loot" ) ) + maps\mp\alien\_collectibles::player_loot_init(); + + if ( maps\mp\alien\_utility::alien_mode_has( "airdrop" ) ) + thread maps\mp\alien\_drill::watchbomb(); + + thread maps\mp\alien\_collectibles::watchthrowableitems(); + thread maps\mp\alien\_utility::trackriotshield(); + thread alienplayerhealthregen(); + thread alienplayerarmor(); + thread maps\mp\alien\_perkfunctions::watchcombatspeedscaler(); + self.threatbias = maps\mp\alien\_prestige::prestige_getthreatbiasscalar(); + resetuidvarsonspawn(); + thread maps\mp\alien\_trap::monitor_flare_use(); + thread watchdisconnectendgame(); + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_chaos::chaos_onspawnplayer( self ); + + if ( isdefined( level.custom_onspawnplayer_func ) ) + self [[ level.custom_onspawnplayer_func ]](); + + if ( isdefined( level.resetplayercraftingitemsonrespawn ) ) + self [[ level.resetplayercraftingitemsonrespawn ]](); + + if ( maps\mp\alien\_utility::has_pistols_only_relic_and_no_deployables() ) + thread maps\mp\alien\_collectibles::check_for_player_near_weapon(); + + thread maps\mp\alien\_utility::setup_class_nameplates(); + thread kick_for_inactivity(); + maps\mp\alien\_ffotd::onspawnplayer(); +} + +watchdisconnectendgame() +{ + level endon( "game_ended" ); + self waittill( "disconnect" ); + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + var_0 = maps\mp\alien\_chaos_laststand::chaos_gameshouldend( self ); + else + var_0 = maps\mp\alien\_laststand::gameshouldend( self ); + + if ( var_0 ) + level thread alienendgame( "axis", maps\mp\alien\_hud::get_end_game_string_index( "kia" ) ); +} + +kick_for_inactivity() +{ + level endon( "game_ended" ); + self endon( "disconnect" ); + var_0 = level.onlinegame && !getdvarint( "xblive_privatematch" ); + + if ( var_0 ) + { + var_1 = self getnormalizedmovement(); + var_2 = gettime(); + + for (;;) + { + wait 0.2; + var_3 = self getnormalizedmovement(); + + if ( var_3[0] == var_1[0] && var_3[1] == var_1[1] ) + { + if ( gettime() - var_2 > 300000 && level.players.size > 1 ) + kick( self getentitynumber(), "EXE_PLAYERKICKED_INACTIVE" ); + + continue; + } + + return; + } + } +} + +player_last_death_pos() +{ + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + self.last_death_pos = self.origin; + + for (;;) + { + self waittill( "damage" ); + self.last_death_pos = self.origin; + } +} + +alienplayerhealthhints() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + var_0 = 0.33; + var_0 = int( var_0 * 100 ) / 100; + var_1 = self.health / self.maxhealth; + + if ( isdefined( self.laststand ) && self.laststand ) + { + wait 0.05; + continue; + } + + if ( var_1 < var_0 ) + { + if ( has_healthpack() ) + { + + } + else + { + + } + } + + common_scripts\utility::waittill_any_timeout( 5, "health_regened", "damage" ); + waittillframeend; + } +} + +has_healthpack() +{ + if ( isdefined( self.has_health_pack ) && self.has_health_pack ) + return 1; + + return 0; +} + +ontimelimit() +{ + maps\mp\gametypes\_gamelogic::default_ontimelimit(); +} + +onxpevent( var_0 ) +{ + maps\mp\alien\_globallogic::onxpevent( var_0 ); +} + +getspawnpoint() +{ + var_0 = self.pers["team"]; + + if ( level.graceperiod && isdefined( level.alien_player_spawn_group ) ) + { + var_1 = [ "group0", "group1", "group2", "group3" ]; + var_1 = common_scripts\utility::array_randomize( var_1 ); + level.group = var_1[0]; + var_2 = level.group; + var_3 = maps\mp\gametypes\_spawnlogic::getspawnpointarray( "mp_alien_spawn_" + var_2 + "_start" ); + var_4 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_3 ); + } + else + { + var_3 = maps\mp\gametypes\_spawnlogic::getspawnpointarray( "mp_tdm_spawn_axis_start" ); + var_4 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_3 ); + } + + return var_4; +} + +initspawns() +{ + maps\mp\alien\_director::alien_attribute_table_init(); + + if ( maps\mp\alien\_utility::alien_mode_has( "wave" ) ) + { + maps\mp\alien\_spawnlogic::alien_wave_init(); + thread maps\mp\alien\_spawnlogic::setup_meteoroid_paths(); + maps\mp\alien\_spawnlogic::alien_lurker_init(); + } + + level.spawnmins = ( 0, 0, 0 ); + level.spawnmaxs = ( 0, 0, 0 ); + maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_tdm_spawn_axis_start" ); + + if ( isdefined( level.alien_player_spawn_group ) ) + { + maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_alien_spawn_group3_start" ); + maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_alien_spawn_group1_start" ); + maps\mp\gametypes\_spawnlogic::addstartspawnpoints( "mp_alien_spawn_group0_start" ); + } + + level.mapcenter = maps\mp\gametypes\_spawnlogic::findboxcenter( level.spawnmins, level.spawnmaxs ); + setmapcenter( level.mapcenter ); +} + +addalienagent( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = maps\mp\agents\_agent_common::connectnewagent( "alien", var_0 ); + + if ( isdefined( var_5 ) ) + var_5 thread [[ var_5 maps\mp\agents\_agent_utility::agentfunc( "spawn" ) ]]( var_1, var_2, var_3, var_4 ); + + return var_5; +} + +setalienloadout() +{ + level.alien_loadout["loadoutPrimary"] = "none"; + level.alien_loadout["loadoutPrimaryAttachment"] = "none"; + level.alien_loadout["loadoutPrimaryAttachment2"] = "none"; + level.alien_loadout["loadoutPrimaryBuff"] = "specialty_null"; + level.alien_loadout["loadoutPrimaryCamo"] = "none"; + level.alien_loadout["loadoutPrimaryReticle"] = "none"; + level.alien_loadout["loadoutSecondary"] = "iw6_alienp226"; + level.alien_loadout["loadoutSecondaryAttachment"] = "none"; + level.alien_loadout["loadoutSecondaryAttachment2"] = "none"; + level.alien_loadout["loadoutSecondaryBuff"] = "specialty_null"; + level.alien_loadout["loadoutSecondaryCamo"] = "none"; + level.alien_loadout["loadoutSecondaryReticle"] = "none"; + level.alien_loadout["loadoutEquipment"] = "none"; + level.alien_loadout["loadoutOffhand"] = "none"; + level.alien_loadout["loadoutPerk1"] = "specialty_pistoldeath"; + level.alien_loadout["loadoutPerk2"] = "specialty_null"; + level.alien_loadout["loadoutPerk3"] = "specialty_null"; + level.alien_loadout["loadoutJuggernaut"] = 0; +} + +pistol_ammo_regen( var_0 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + var_1 = self getweaponslistprimaries(); + + foreach ( var_3 in var_1 ) + { + var_4 = getweaponbasename( var_3 ); + + if ( var_4 == "iw6_alienp226_mp" || var_4 == "iw6_alienmagnum_mp" || var_4 == "iw6_alienm9a1_mp" || var_4 == "iw6_alienmp443_mp" ) + { + var_5 = weaponclipsize( var_3 ); + self setweaponammoclip( var_3, var_5 ); + } + } + + var_7 = 0.2; + + for (;;) + { + if ( maps\mp\alien\_perk_utility::perk_getpistolregen() == 1 ) + { + if ( maps\mp\alien\_utility::player_has_specialized_ammo( "iw6_alienp226" ) || maps\mp\alien\_utility::player_has_specialized_ammo( "iw6_alienmagnum" ) || maps\mp\alien\_utility::player_has_specialized_ammo( "iw6_alienm9a1" ) || maps\mp\alien\_utility::player_has_specialized_ammo( "iw6_alienmp443" ) ) + { + wait( var_7 ); + continue; + } + + var_1 = self getweaponslistprimaries(); + + foreach ( var_3 in var_1 ) + { + var_4 = getweaponbasename( var_3 ); + + if ( var_4 == "iw6_alienp226_mp" || var_4 == "iw6_alienmagnum_mp" || var_4 == "iw6_alienm9a1_mp" || var_4 == "iw6_alienmp443_mp" ) + { + var_9 = self getweaponammostock( var_3 ); + self setweaponammostock( var_3, var_9 + 1 ); + } + } + + wait( var_7 ); + } + + wait 0.05; + } +} + +bypassclasschoicefunc() +{ + return "gamemode"; +} + +alienplayerhealthregen() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + self endon( "joined_spectators" ); + self endon( "faux_spawn" ); + level endon( "game_ended" ); + thread maps\mp\alien\_music_and_dialog::alienplayerpainbreathingsound(); + + for (;;) + { + common_scripts\utility::waittill_any( "damage", "health_perk_upgrade" ); + + if ( !canregenhealth() ) + continue; + + var_0 = gethealthcap(); + var_1 = self.health / var_0; + thread healthregen( gettime(), var_1, var_0 ); + thread maps\mp\gametypes\_healthoverlay::breathingmanager( gettime(), var_1 ); + } +} + +alienplayerarmor() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + self endon( "joined_spectators" ); + self endon( "faux_spawn" ); + self endon( "game_ended" ); + + if ( !isdefined( self.bodyarmorhp ) ) + self.bodyarmorhp = 0; + + self setcoopplayerdata( "alienSession", "armor", 0 ); + var_0 = 0; + + for (;;) + { + common_scripts\utility::waittill_any( "player_damaged", "enable_armor" ); + + if ( !isdefined( self.bodyarmorhp ) ) + { + if ( var_0 > 0 ) + { + self setcoopplayerdata( "alienSession", "armor", 0 ); + var_0 = 0; + } + + continue; + } + + if ( var_0 != self.bodyarmorhp ) + { + var_1 = int( self.bodyarmorhp ); + self setcoopplayerdata( "alienSession", "armor", var_1 ); + var_0 = self.bodyarmorhp; + } + } +} + +gethealthcap() +{ + self.healthregenmaxpercent = 1.0; + var_0 = clamp( self.maxhealth * self.healthregenmaxpercent, 0, self.maxhealth ); + return int( var_0 ); +} + +canregenhealth() +{ + if ( isdefined( self.inlaststand ) && self.inlaststand ) + return 0; + + return 1; +} + +healthregen( var_0, var_1, var_2 ) +{ + self notify( "healthRegeneration" ); + self endon( "healthRegeneration" ); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + self endon( "joined_spectators" ); + level endon( "game_ended" ); + + if ( ishealthregendisabled() ) + return; + + var_3 = spawnstruct(); + getregendata( var_3 ); + wait( var_3.activatetime ); + + for (;;) + { + var_3 = spawnstruct(); + getregendata( var_3 ); + + if ( !maps\mp\alien\_utility::has_fragile_relic_and_is_sprinting() ) + { + if ( self.health < int( var_2 ) ) + { + if ( self.health + var_3.regenamount > int( var_2 ) ) + self.health = int( var_2 ); + else + self.health = self.health + var_3.regenamount; + } + else + break; + } + + wait( var_3.waittimebetweenregen ); + } + + self notify( "healed" ); + player_init_invulnerability(); + maps\mp\gametypes\_damage::resetattackerlist(); +} + +getregendata( var_0 ) +{ + self.prestigehealthregennerfscalar = maps\mp\alien\_prestige::prestige_getslowhealthregenscalar(); + + if ( self.prestigehealthregennerfscalar == 1.0 ) + { + if ( isdefined( self.ishealthboosted ) ) + { + var_0.activatetime = 2.25; + var_0.waittimebetweenregen = 0.2625; + var_0.regenamount = 1; + } + else if ( maps\mp\alien\_persistence::is_upgrade_enabled( "faster_health_regen_upgrade" ) ) + { + var_0.activatetime = 2.7; + var_0.waittimebetweenregen = 0.315; + var_0.regenamount = 1; + } + else + { + var_0.activatetime = 3.0; + var_0.waittimebetweenregen = 0.35; + var_0.regenamount = 1; + } + } + else + { + var_0.activatetime = 3.0 * self.prestigehealthregennerfscalar; + var_0.waittimebetweenregen = 0.35 * self.prestigehealthregennerfscalar; + var_0.regenamount = 1; + } +} + +ishealthregendisabled() +{ + return isdefined( level.healthregendisabled ) && level.healthregendisabled || isdefined( self.healthregendisabled ) && self.healthregendisabled; +} + +resetuidvarsonspawn() +{ + +} + +resetuidvarsonconnect() +{ + self setclientomnvar( "ui_alien_max_currency", self.maxcurrency ); + setdvar( "cg_drawCrosshairNames", 0 ); +} + +resetuidvarsonspectate() +{ + +} + +alien_make_entity_sentient( var_0, var_1 ) +{ + if ( should_make_entity_sentient() ) + { + if ( isdefined( var_1 ) ) + return self makeentitysentient( var_0, var_1 ); + else + return self makeentitysentient( var_0 ); + } +} + +should_make_entity_sentient() +{ + if ( isdefined( self.sentrytype ) ) + return 1; + + if ( isdefined( level.drill ) && self == level.drill ) + return 1; + + if ( isdefined( self.flaretype ) ) + return 1; + + return 0; +} + +custom_giveloadout( var_0 ) +{ + self takeallweapons(); + self.changingweapon = undefined; + self.loadoutprimaryattachments = []; + self.loadoutsecondaryattachments = []; + maps\mp\_utility::_setactionslot( 1, "" ); + maps\mp\_utility::_setactionslot( 2, "" ); + maps\mp\_utility::_setactionslot( 3, "altMode" ); + maps\mp\_utility::_setactionslot( 4, "" ); + + if ( !level.console ) + { + maps\mp\_utility::_setactionslot( 5, "" ); + maps\mp\_utility::_setactionslot( 6, "" ); + maps\mp\_utility::_setactionslot( 7, "" ); + } + + maps\mp\_utility::_clearperks(); + maps\mp\alien\_utility::_detachall(); + self.spawnperk = 0; + + if ( isdefined( self.headmodel ) ) + self.headmodel = undefined; + + set_player_character_model(); + var_1 = getplayermodelindex(); + var_2 = getplayerfoleytype( var_1 ); + self setclothtype( var_2 ); + maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.killstreaktype = "none"; + self.primaryweapon = "none"; + var_3 = self getcoopplayerdata( "alienPlayerLoadout", "perks", 1 ); + + switch ( var_3 ) + { + case "perk_pistol_p226_4": + case "perk_pistol_p226_3": + case "perk_pistol_p226_2": + case "perk_pistol_p226_1": + case "perk_pistol_p226": + self.default_starting_pistol = "iw6_alienp226_mp"; + break; + case "perk_pistol_magnum_4": + case "perk_pistol_magnum_3": + case "perk_pistol_magnum_2": + case "perk_pistol_magnum_1": + case "perk_pistol_magnum": + if ( maps\mp\alien\_persistence::is_upgrade_enabled( "magnum_acog_upgrade" ) ) + self.default_starting_pistol = "iw6_alienmagnum_mp_acogpistol_scope5"; + else + self.default_starting_pistol = "iw6_alienmagnum_mp"; + + break; + case "perk_pistol_m9a1_4": + case "perk_pistol_m9a1_3": + case "perk_pistol_m9a1_2": + case "perk_pistol_m9a1_1": + case "perk_pistol_m9a1": + self.default_starting_pistol = "iw6_alienm9a1_mp"; + break; + case "perk_pistol_mp443_4": + case "perk_pistol_mp443_3": + case "perk_pistol_mp443_2": + case "perk_pistol_mp443_1": + case "perk_pistol_mp443": + self.default_starting_pistol = "iw6_alienmp443_mp"; + break; + } + + self notify( "changed_kit" ); + self notify( "giveLoadout" ); + maps\mp\_utility::giveperk( "specialty_pistoldeath", 0 ); + self.movespeedscaler = maps\mp\alien\_prestige::prestige_getmoveslowscalar(); + + if ( self.movespeedscaler == 1.0 ) + maps\mp\_utility::giveperk( "specialty_sprintreload", 0 ); + + if ( maps\mp\alien\_prestige::prestige_getslowhealthregenscalar() == 1.0 ) + maps\mp\_utility::giveperk( "specialty_falldamage", 0 ); + + if ( isdefined( var_0 ) && var_0 ) + return; + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + self.default_starting_pistol = "iw6_alienp226_mp"; + + self giveweapon( self.default_starting_pistol ); + maps\mp\alien\_collectibles::scale_ammo_based_on_nerf( self.default_starting_pistol ); + + if ( issplitscreen() ) + thread wait_and_force_weapon_switch(); + else + self setspawnweapon( self.default_starting_pistol ); + + if ( should_give_starting_flare() ) + { + self setoffhandsecondaryclass( "flash" ); + self giveweapon( "alienflare_mp" ); + self setweaponammoclip( "alienflare_mp", 1 ); + } + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_chaos::chaos_custom_giveloadout( self ); +} + +getplayermodelindex() +{ + return self getcoopplayerdata( "coopSquadMembers", 0, "body" ); +} + +getplayerfoleytype( var_0 ) +{ + return tablelookup( "mp/cac/bodies.csv", 0, var_0, 5 ); +} + +wait_and_force_weapon_switch() +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + wait 0.5; + self setspawnweapon( self.default_starting_pistol ); +} + +set_player_character_model() +{ + thread setmodelfromcustomization(); + setvoprefix(); +} + +setcharactermodels( var_0, var_1, var_2 ) +{ + if ( isdefined( self.headmodel ) ) + self detach( self.headmodel ); + + self setmodel( var_0 ); + self setviewmodel( var_2 ); + self attach( var_1, "", 1 ); + self.headmodel = var_1; +} + +setmodelfromcustomization() +{ + wait 0.05; + var_0 = self getcustomizationbody(); + var_1 = self getcustomizationhead(); + var_2 = self getcustomizationviewmodel(); + setcharactermodels( var_0, var_1, var_2 ); +} + +setvoprefix() +{ + if ( !isdefined( level.cac_vo_male ) ) + level.cac_vo_male = common_scripts\utility::array_randomize( [ "p2_", "p4_", "p3_" ] ); + + if ( !isdefined( level.cac_vo_female ) ) + level.cac_vo_female = common_scripts\utility::array_randomize( [ "p1_" ] ); + + if ( !isdefined( level.male_index ) ) + level.male_index = 0; + + if ( !isdefined( level.female_index ) ) + level.female_index = 0; + + if ( !isdefined( self.vo_prefix ) ) + { + if ( self hasfemalecustomizationmodel() ) + { + if ( level.female_index < level.cac_vo_female.size ) + { + self.vo_prefix = level.cac_vo_female[level.female_index]; + level.female_index++; + } + else + { + level.female_index = 0; + self.vo_prefix = level.cac_vo_female[level.female_index]; + level.female_index++; + } + } + else if ( level.male_index < level.cac_vo_male.size ) + { + self.vo_prefix = level.cac_vo_male[level.male_index]; + level.male_index++; + } + else + { + level.male_index = 0; + self.vo_prefix = level.cac_vo_male[level.male_index]; + level.male_index++; + } + } +} + +boxcapturethink_alien_func( var_0 ) +{ + return var_0 maps\mp\alien\_utility::is_holding_deployable(); +} + +special_weapon_hints() +{ + self endon( "disconnect" ); + self.flare_tutorial_given = 0; + self.pet_tutorial_given = 0; + self.claymore_tutorial_given = 0; + self.betty_tutorial_given = 0; + self.deployable_tutorial_given = 0; + self.semtex_tutorial_given = 0; + self.mortar_tutorial_given = 0; + self.trophy_tutorial_given = 0; + self.soflam_tutorial_given = 0; + self.drill_tutorial_given = 0; + thread show_weapon_switch_hints(); + + for (;;) + { + var_0 = self getweaponslistall(); + + foreach ( var_2 in var_0 ) + { + if ( var_2 == "alienbetty_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "alienclaymore_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "alienflare_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "aliensemtex_mp" ) + { + if ( !maps\mp\alien\_utility::is_chaos_mode() ) + thread show_tutorial_text( var_2 ); + + continue; + } + + if ( var_2 == "alienthrowingknife_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "alienmortar_shell_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "alientrophy_mp" ) + { + thread show_tutorial_text( var_2 ); + continue; + } + + if ( var_2 == "alienbomb_mp" ) + thread show_tutorial_text( var_2 ); + } + + wait 1; + } +} + +show_weapon_switch_hints() +{ + self endon( "disconnect" ); + + for (;;) + { + self waittill( "weapon_change", var_0 ); + + if ( var_0 == "aliendeployable_crate_marker_mp" || var_0 == "aliensoflam_mp" ) + thread show_tutorial_text( var_0 ); + + if ( maps\mp\alien\_utility::is_true( self.hasriotshield ) || maps\mp\alien\_utility::is_true( self.hasriotshieldequipped ) ) + { + self setclientomnvar( "ui_alien_riotshield_equipped", 1 ); + wait 0.05; + + if ( !self.hasriotshieldequipped && self.hasriotshield ) + { + var_1 = maps\mp\alien\_utility::riotshieldname(); + + if ( !isdefined( var_1 ) ) + continue; + + var_2 = self getammocount( var_1 ); + self setclientomnvar( "ui_alien_riotshield_equipped", 2 ); + self setclientomnvar( "ui_alien_stowed_riotshield_ammo", var_2 ); + } + + continue; + } + + self setclientomnvar( "ui_alien_riotshield_equipped", -1 ); + } +} + +show_tutorial_text( var_0 ) +{ + self endon( "disconnect" ); + + switch ( var_0 ) + { + case "alienbetty_mp": + if ( !self.betty_tutorial_given ) + { + self.betty_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_BETTY", 3.5 ); + } + + break; + case "alienclaymore_mp": + if ( !self.claymore_tutorial_given ) + { + self.claymore_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_CLAYMORE", 3.5 ); + } + + break; + case "alienthrowingknife_mp": + if ( !self.pet_tutorial_given ) + { + self.pet_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_PET", 3.5 ); + } + + break; + case "alienflare_mp": + if ( !self.flare_tutorial_given ) + { + self.flare_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_FLARE", 3.5 ); + } + + break; + case "aliensemtex_mp": + if ( !self.semtex_tutorial_given ) + { + self.semtex_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_SEMTEX", 3.5 ); + } + + break; + case "alienmortar_shell_mp": + if ( !self.mortar_tutorial_given ) + { + self.mortar_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_MORTARSHELL", 3.5 ); + } + + break; + case "aliensoflam_mp": + if ( !self.soflam_tutorial_given ) + { + self.soflam_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_SOFLAM", 3.5 ); + } + + break; + case "alientrophy_mp": + if ( !self.trophy_tutorial_given ) + { + self.trophy_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "tutorial", &"ALIEN_COLLECTIBLES_TUTORIAL_TROPHY", 3.5 ); + } + + break; + case "alienbomb_mp": + if ( !self.drill_tutorial_given ) + { + self.drill_tutorial_given = 1; + maps\mp\_utility::setlowermessage( "go_plant", get_drill_tutorial_text(), 3.5 ); + return; + } + } +} + +get_drill_tutorial_text() +{ + if ( isdefined( level.drill_tutorial_text ) ) + return level.drill_tutorial_text; + + return &"ALIEN_COLLECTIBLES_GO_PLANT_BOMB"; +} + +enable_disable_usability_monitor() +{ + self endon( "disconnect" ); + + for (;;) + { + if ( maps\mp\alien\_utility::is_holding_deployable() ) + { + common_scripts\utility::_disableusability(); + + while ( maps\mp\alien\_utility::is_holding_deployable() ) + wait 0.05; + + common_scripts\utility::_enableusability(); + } + + wait 0.05; + } +} + +killstreakinit() +{ + maps\mp\killstreaks\_killstreaks::initkillstreakdata(); + level.killstreakfuncs = []; + level.killstreaksetupfuncs = []; + level.killstreakweapons = []; + thread maps\mp\killstreaks\_uav::init(); + thread maps\mp\killstreaks\_airstrike::init(); + thread maps\mp\killstreaks\_plane::init(); + thread maps\mp\killstreaks\_helicopter::init(); + thread maps\mp\alien\_nuke::init(); + thread maps\mp\killstreaks\_portableaoegenerator::init(); + thread maps\mp\killstreaks\_ims::init(); + thread maps\mp\killstreaks\_perkstreaks::init(); + thread maps\mp\killstreaks\_remoteuav::init(); + thread maps\mp\killstreaks\_juggernaut::init(); + thread maps\mp\killstreaks\_ball_drone::init(); + thread maps\mp\killstreaks\_vanguard::init(); + thread maps\mp\killstreaks\_dronehive::init(); + thread maps\mp\killstreaks\_air_superiority::init(); + level.teamemped["allies"] = 0; + level.teamemped["axis"] = 0; + level.killstreakweildweapons = []; + level.killstreakweildweapons["artillery_mp"] = "precision_airstrike"; + level.killstreakweildweapons["stealth_bomb_mp"] = "stealth_airstrike"; + level.killstreakweildweapons["pavelow_minigun_mp"] = "helicopter_flares"; + level.killstreakweildweapons["sentry_minigun_mp"] = "sentry"; + level.killstreakweildweapons["ac130_105mm_mp"] = "ac130"; + level.killstreakweildweapons["ac130_40mm_mp"] = "ac130"; + level.killstreakweildweapons["ac130_25mm_mp"] = "ac130"; + level.killstreakweildweapons["remotemissile_projectile_mp"] = "predator_missile"; + level.killstreakweildweapons["cobra_ffar_mp"] = "helicopter"; + level.killstreakweildweapons["hind_bomb_mp"] = "helicopter"; + level.killstreakweildweapons["cobra_20mm_mp"] = "helicopter"; + level.killstreakweildweapons["nuke_mp"] = "nuke"; + level.killstreakweildweapons["littlebird_guard_minigun_mp"] = "littlebird_support"; + level.killstreakweildweapons["osprey_minigun_mp"] = "escort_airdrop"; + level.killstreakweildweapons["remote_mortar_missile_mp"] = "remote_mortar"; + level.killstreakweildweapons["manned_littlebird_sniper_mp"] = "heli_sniper"; + level.killstreakweildweapons["iw5_mp412jugg_mp"] = "airdrop_juggernaut"; + level.killstreakweildweapons["mortar_shelljugg_mp"] = "airdrop_juggernaut"; + level.killstreakweildweapons["iw6_riotshieldjugg_mp"] = "airdrop_juggernaut_recon"; + level.killstreakweildweapons["iw5_usp45jugg_mp"] = "airdrop_juggernaut_recon"; + level.killstreakweildweapons["smoke_grenadejugg_mp"] = "airdrop_juggernaut_recon"; + level.killstreakweildweapons["iw6_knifeonlyjugg_mp"] = "airdrop_juggernaut_maniac"; + level.killstreakweildweapons["throwingknifejugg_mp"] = "airdrop_juggernaut_maniac"; + level.killstreakweildweapons["remote_turret_mp"] = "remote_mg_turret"; + level.killstreakweildweapons["osprey_player_minigun_mp"] = "osprey_gunner"; + level.killstreakweildweapons["deployable_vest_marker_mp"] = "deployable_vest"; + level.killstreakweildweapons["ugv_turret_mp"] = "remote_tank"; + level.killstreakweildweapons["ugv_gl_turret_mp"] = "remote_tank"; + level.killstreakweildweapons["remote_tank_projectile_mp"] = "vanguard"; + level.killstreakweildweapons["uav_remote_mp"] = "remote_uav"; + level.killstreakweildweapons["heli_pilot_turret_mp"] = "heli_pilot"; + level.killstreakweildweapons["lasedstrike_missile_mp"] = "lasedStrike"; + level.killstreakweildweapons["agent_mp"] = "agent"; + level.killstreakweildweapons["guard_dog_mp"] = "guard_dog"; + level.killstreakweildweapons["ims_projectile_mp"] = "ims"; + level.killstreakweildweapons["ball_drone_gun_mp"] = "ball_drone_backup"; + level.killstreakweildweapons["drone_hive_projectile_mp"] = "drone_hive"; + level.killstreakweildweapons["switch_blade_child_mp"] = "drone_hive"; + level.killstreakweildweapons["iw6_maaws_mp"] = "aa_launcher"; + level.killstreakweildweapons["killstreak_uplink_mp"] = "uplink"; + level.killstreakweildweapons["gas_strike_mp"] = "gas_airstrike"; + level.killstreakweildweapons["a10_30mm_mp"] = "a10_strafe"; + level.killstreakweildweapons["maverick_projectile_mp"] = "a10_strafe"; + level.killstreakweildweapons["odin_projectile_large_rod_mp"] = "odin_assault"; + level.killstreakweildweapons["odin_projectile_small_rod_mp"] = "odin_assault"; + level.killstreakweildweapons["iw5_barrettexp_mp_barrettscope"] = "heli_sniper"; + level.killstreakweildweapons["airdrop_marker_mp"] = "airdrop_assault"; + + if ( isdefined( level.mapcustomkillstreakfunc ) ) + [[ level.mapcustomkillstreakfunc ]](); + + level.killstreakrounddelay = maps\mp\_utility::getintproperty( "scr_game_killstreakdelay", 8 ); +} + +monitordisownkillstreaks() +{ + while ( isdefined( self ) ) + { + if ( maps\mp\_utility::bot_is_fireteam_mode() ) + self waittill( "disconnect" ); + else + common_scripts\utility::waittill_any( "disconnect", "joined_team", "joined_spectators" ); + + self notify( "killstreak_disowned" ); + } +} + +alienforceendgame() +{ + level thread alienendgame( "axis", maps\mp\alien\_hud::get_end_game_string_index( "host_end" ) ); +} + +alienendgame( var_0, var_1 ) +{ + var_2 = 11.0; + + if ( gamealreadyended() ) + return; + + game["state"] = "postgame"; + level.gameended = 1; + level.gameendtime = gettime(); + level.ingraceperiod = 0; + level notify( "game_ended", var_0 ); + common_scripts\utility::waitframe(); + maps\mp\_utility::levelflagset( "game_over" ); + maps\mp\_utility::levelflagset( "block_notifies" ); + setomnvar( "ui_pause_menu_show", 0 ); + setdvar( "ui_game_state", "postgame" ); + setdvar( "g_deadChat", 1 ); + setdvar( "ui_allow_teamchange", 0 ); + setdvar( "bg_compassShowEnemies", 0 ); + setdvar( "scr_gameended", 1 ); + setgameendtime( 0 ); + maps\mp\gametypes\_gamescore::updateteamscore( "axis" ); + maps\mp\gametypes\_gamescore::updateteamscore( "allies" ); + maps\mp\gametypes\_gamescore::updateplacement(); + maps\mp\gametypes\_gamelogic::freezeallplayers( 1.0, "cg_fovScale", 1 ); + + foreach ( var_4 in level.players ) + { + var_4 notify( "reset_outcome" ); + var_4.pers["stats"] = var_4.stats; + var_4 maps\mp\killstreaks\_killstreaks::clearkillstreaks(); + var_4.ignoreme = 1; + var_4 maps\mp\_utility::clearlowermessages(); + } + + foreach ( var_7 in level.agentarray ) + { + if ( isdefined( var_7.isactive ) && var_7.isactive ) + { + var_7.ignoreall = 1; + var_7 maps\mp\alien\_utility::enable_alien_scripted(); + } + } + + maps\mp\alien\_gamescore::calculate_players_total_end_game_score(); + level.intermission = 1; + + if ( isdefined( level.pre_end_game_display_func ) ) + [[ level.pre_end_game_display_func ]](); + + maps\mp\alien\_hud::displayaliengameend( var_0, var_1 ); + maps\mp\_utility::levelflagclear( "block_notifies" ); + level notify( "spawning_intermission" ); + var_9 = maps\mp\gametypes\_playerlogic::spawnintermission; + + if ( isdefined( level.custom_intermission_func ) ) + var_9 = level.custom_intermission_func; + + foreach ( var_4 in level.players ) + { + var_4 thread [[ var_9 ]](); + var_4 thread blackbox_endgame_score(); + var_4 setclientdvar( "ui_opensummary", 1 ); + var_4 setroundgamemode(); + } + + var_12 = get_end_condition( var_1 ); + var_13 = get_play_time(); + blackbox_endgame( var_12, var_13 ); + maps\mp\alien\_alien_matchdata::endgame( var_12, var_13 ); + + if ( isdefined( level.end_game_scoreboard_wait_time ) ) + var_2 = level.end_game_scoreboard_wait_time; + + wait( var_2 ); + setnojiptime( 0 ); + level notify( "exitLevel_called" ); + exitlevel( 0 ); +} + +gamealreadyended() +{ + return game["state"] == "postgame" || level.gameended; +} + +setroundgamemode() +{ + if ( !maps\mp\alien\_utility::is_chaos_mode() ) + self setcommonplayerdata( "round", "gameMode", "aliens" ); + else + self setcommonplayerdata( "round", "gameMode", "mugger" ); + + self setcommonplayerdata( "round", "map", tolower( getdvar( "mapname" ) ) ); +} + +blackbox_endgame_score() +{ + var_0 = -1; + + if ( isdefined( level.current_cycle_num ) ) + var_0 = level.current_cycle_num; + + var_1 = "unknown"; + + if ( isdefined( self.name ) ) + var_1 = self.name; + + var_2 = "unknown"; + + if ( isdefined( level.current_hive_name ) ) + var_2 = level.current_hive_name; + + var_3 = 0; + + if ( isdefined( self.end_game_score ) && isdefined( self.end_game_score["total_score"] ) ) + var_3 = self.end_game_score["total_score"]; + + var_4 = maps\mp\alien\_persistence::get_player_session_xp(); + bbprint( "alienfinalscore", "playername %s cyclenum %i hivename %s playerfinalscore %i playerxpearned %i ", var_1, var_0, var_2, var_3, var_4 ); +} + +blackbox_endgame( var_0, var_1 ) +{ + var_2 = -1; + + if ( isdefined( level.players[0] ) ) + var_2 = int( level.players[0] maps\mp\alien\_persistence::get_player_rank() ); + + var_3 = -1; + + if ( isdefined( level.players[1] ) ) + var_3 = int( level.players[1] maps\mp\alien\_persistence::get_player_rank() ); + + var_4 = -1; + + if ( isdefined( level.players[2] ) ) + var_4 = int( level.players[2] maps\mp\alien\_persistence::get_player_rank() ); + + var_5 = -1; + + if ( isdefined( level.players[3] ) ) + var_5 = int( level.players[3] maps\mp\alien\_persistence::get_player_rank() ); + + var_6 = 0; + + if ( isdefined( level.current_cycle_num ) ) + var_6 = level.current_cycle_num; + + var_7 = "unknown"; + + if ( isdefined( level.current_hive_name ) ) + var_7 = level.current_hive_name; + + var_8 = level.alienbbdata["times_downed"]; + var_9 = level.alienbbdata["times_died"]; + var_10 = level.alienbbdata["times_drill_stuck"]; + var_11 = level.alienbbdata["aliens_killed"]; + var_12 = level.alienbbdata["team_item_deployed"]; + var_13 = level.alienbbdata["team_item_used"]; + var_14 = level.alienbbdata["bullets_shot"]; + var_15 = level.alienbbdata["damage_taken"]; + var_16 = level.alienbbdata["damage_done"]; + var_17 = level.alienbbdata["traps_used"]; + bbprint( "alienendgame", "endcondition %s player0rank %i player1rank %i player2rank %i player3rank %i playtime %f hivescleared %i hivename %s timesdowned %i timesdied %i timesdrillstuck %i alienskilled %i teamitemused %i teamitemdeployed %i bulletsshot %i damagedone %i damagetaken %i trapsused %i ", var_0, var_2, var_3, var_4, var_5, var_1, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16, var_17 ); + + foreach ( var_20 in level.players ) + { + var_20 setcoopplayerdata( "alienSession", "team_shots", level.alienbbdata["bullets_shot"] ); + var_20 setcoopplayerdata( "alienSession", "team_kills", level.alienbbdata["aliens_killed"] ); + var_20 setcoopplayerdata( "alienSession", "team_hives", level.num_hive_destroyed ); + var_21 = int( var_20 getentitynumber() ); + var_22 = "EoGPlayer" + var_21; + + if ( isdefined( var_20.name ) ) + var_23 = var_20.name; + else + var_23 = "-error"; + + var_24 = gettime() - var_20.connect_time; + var_25 = var_20 getcoopplayerdata( var_22, "kills" ); + var_26 = var_20 getcoopplayerdata( var_22, "score" ); + var_27 = var_20 getcoopplayerdata( var_22, "assists" ); + var_28 = var_20 getcoopplayerdata( var_22, "revives" ); + var_29 = var_20 getcoopplayerdata( var_22, "drillrestarts" ); + var_30 = var_20 getcoopplayerdata( var_22, "deaths" ); + var_31 = var_20 getcoopplayerdata( var_22, "hivesdestroyed" ); + var_32 = var_20 getcoopplayerdata( var_22, "traps" ); + var_33 = var_20 getcoopplayerdata( var_22, "deployables" ); + var_34 = var_20 getcoopplayerdata( var_22, "deployablesused" ); + var_35 = var_20 getcoopplayerdata( var_22, "currencyspent" ); + var_36 = var_20 getcoopplayerdata( var_22, "currencytotal" ); + var_37 = "alienendgame_player" + var_21; + bbprint( var_37, "playername %s playerplaytime %f playerkills %i playerscore %i playerassists %i playerrevives %i playerdrillrestarts %i playerdeaths %i playerhives %i playertraps %i playertotalcurrency %i playercurrencyspent %i playerdeployables %i playerdeployablesused %i ", var_23, var_24, var_25, var_26, var_27, var_28, var_29, var_30, var_31, var_32, var_36, var_35, var_33, var_34 ); + } +} + +get_end_condition( var_0 ) +{ + switch ( var_0 ) + { + case 1: + return "all_escape"; + case 2: + return "some_escape"; + case 3: + return "fail_escape"; + case 8: + case 4: + return "drill destroyed"; + case 5: + return "died"; + case 6: + return "host_quit"; + case 7: + return "gas_fail"; + default: + } +} + +get_play_time() +{ + var_0 = 0; + + if ( isdefined( level.starttime ) ) + var_0 = gettime() - level.starttime; + + return var_0; +} + +alien_customprematchperiod() +{ + if ( !maps\mp\alien\_utility::is_true( level.introscreen_done ) ) + level.prematchperiod = 10; + + while ( level.players.size == 0 ) + wait 0.05; + + if ( !maps\mp\alien\_intro_sequence::intro_sequence_enabled() ) + { + var_0 = 3; + + if ( maps\mp\alien\_utility::is_chaos_mode() ) + var_0 = 6; + + wait( var_0 ); + level notify( "introscreen_over" ); + level.introscreen_done = 1; + level notify( "spawn_intro_drill" ); + + if ( maps\mp\alien\_utility::is_true( level.intermission ) ) + return; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + level.players[var_1] maps\mp\_utility::freezecontrolswrapper( 0 ); + level.players[var_1] enableweapons(); + + if ( !isdefined( level.players[var_1].pers["team"] ) ) + continue; + } + + return; + } + + if ( level.prematchperiod > 0 ) + { + var_2 = level wait_for_first_player_connect(); + + if ( maps\mp\alien\_intro_sequence::intro_sequence_enabled() ) + level thread maps\mp\alien\_intro_sequence::play_intro_sequence( var_2 ); + + level thread show_introscreen_text(); + + if ( isdefined( level.intro_dialogue_func ) ) + level thread [[ level.intro_dialogue_func ]](); + + wait( level.prematchperiod - 3 ); + + if ( isdefined( level.postintroscreenfunc ) ) + [[ level.postintroscreenfunc ]](); + + level notify( "introscreen_over" ); + level.introscreen_done = 1; + } + else + { + wait 1; + level notify( "introscreen_over" ); + } + + if ( maps\mp\alien\_utility::is_true( level.intermission ) ) + return; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + level.players[var_1] maps\mp\_utility::freezecontrolswrapper( 0 ); + level.players[var_1] enableweapons(); + + if ( !isdefined( level.players[var_1].pers["team"] ) ) + continue; + } +} + +wait_for_first_player_connect() +{ + var_0 = undefined; + + if ( level.players.size == 0 ) + level waittill( "connected", var_0 ); + else + var_0 = level.players[0]; + + return var_0; +} + +show_introscreen_text() +{ + wait 2; + var_0 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_1, 1 ); + wait 1; + var_1 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_2, 2 ); + wait 1; + var_2 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_3, 3 ); + wait 1; + var_3 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_4, 4 ); + level waittill( "introscreen_over" ); + var_0 fadeovertime( 3 ); + var_1 fadeovertime( 3 ); + var_2 fadeovertime( 3 ); + var_3 fadeovertime( 3 ); + wait 3.1; + var_0.alpha = 0; + var_1.alpha = 0; + var_2.alpha = 0; + var_3.alpha = 0; + var_0 destroy(); + var_1 destroy(); + var_2 destroy(); + var_3 destroy(); +} + +setup_blocker_hives( var_0 ) +{ + level.blocker_hives = var_0; +} + +setup_cycle_end_area_list( var_0 ) +{ + level.cycle_end_area_list = var_0; +} + +setup_last_hive( var_0 ) +{ + level.last_hive = var_0; +} + +register_encounter( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + if ( !isdefined( level.encounters ) ) + level.encounters = []; + + var_7 = spawnstruct(); + var_7.func = var_0; + + if ( isdefined( var_2 ) ) + var_7.hardcore_skill_point = var_2; + + if ( isdefined( var_1 ) ) + var_7.skill_point = var_1; + + if ( isdefined( var_3 ) ) + var_7.go_next_area = var_3; + + if ( isdefined( var_4 ) ) + var_7.skip_func = var_4; + + if ( isdefined( var_5 ) ) + var_7.pre_encounter_func = var_5; + + if ( isdefined( var_6 ) ) + var_7.force_end_func = var_6; + + level.encounters[level.encounters.size] = var_7; +} + +run_encounters() +{ + level endon( "game_ended" ); + + if ( isdefined( level.dlc_run_encounters_override ) ) + { + [[ level.dlc_run_encounters_override ]](); + return; + } + + if ( !isdefined( level.encounters ) ) + return; + + var_0 = is_start_point_enable(); + var_1 = 0; + var_2 = get_start_point_index( var_0 ); + + foreach ( var_4 in level.encounters ) + { + level.current_encounter_info = var_4; + + if ( should_run_pre_encounter_func( var_0, var_1, var_2 ) ) + [[ var_4.pre_encounter_func ]](); + + if ( should_skip_encounter( var_0, var_1, var_2 ) ) + { + [[ var_4.skip_func ]](); + + if ( isdefined( var_4.skill_point ) ) + inc_starting_skill_point( var_4.skill_point ); + + if ( maps\mp\alien\_utility::is_true( var_4.go_next_area ) ) + maps\mp\alien\_utility::inc_current_area_index(); + } + else + { + [[ var_4.func ]](); + + if ( !maps\mp\alien\_utility::is_hardcore_mode() ) + { + if ( isdefined( var_4.skill_point ) ) + give_players_points( var_4.skill_point ); + } + else if ( isdefined( var_4.hardcore_skill_point ) ) + give_players_points( var_4.hardcore_skill_point ); + + if ( maps\mp\alien\_utility::is_true( var_4.go_next_area ) ) + maps\mp\alien\_collectibles::advance_to_next_area(); + } + + var_1++; + } +} + +init_locker_key_upgrade() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + wait 5.0; + + if ( !isdefined( level.starting_locker_key_names ) ) + level.starting_locker_key_names = []; + + var_0 = self getxuid(); + + if ( maps\mp\alien\_utility::is_true( level.onlinegame ) ) + { + for ( var_1 = 0; var_1 < level.starting_locker_key_names.size; var_1++ ) + { + if ( level.starting_locker_key_names[var_1] == var_0 ) + return; + } + } + + level.starting_locker_key_names[level.starting_locker_key_names.size] = var_0; + self.locker_key = 1; + self setclientomnvar( "ui_alien_locker_key", 1 ); +} + +should_give_starting_flare() +{ + if ( !maps\mp\alien\_perk_utility::has_perk( "perk_health", [ 0, 1, 2, 3, 4 ] ) ) + return 0; + + if ( !isdefined( level.starting_flare_names ) ) + level.starting_flare_names = []; + + var_0 = self getxuid(); + + if ( maps\mp\alien\_utility::is_true( level.onlinegame ) ) + { + for ( var_1 = 0; var_1 < level.starting_flare_names.size; var_1++ ) + { + if ( level.starting_flare_names[var_1] == var_0 ) + return 0; + } + } + + level.starting_flare_names[level.starting_flare_names.size] = var_0; + return 1; +} + +is_start_point_enable() +{ + return 0; +} + +get_start_point_index( var_0 ) +{ + return 0; +} + +should_run_pre_encounter_func( var_0, var_1, var_2 ) +{ + return 0; +} + +should_skip_encounter( var_0, var_1, var_2 ) +{ + return 0; +} + +give_players_points( var_0 ) +{ + foreach ( var_2 in level.players ) + var_2 maps\mp\alien\_persistence::give_player_points( int( var_0 ) ); +} + +inc_starting_skill_point( var_0 ) +{ + +} + +melee_strength_timer() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + self.meleestrength = 1.0; + var_0 = 1; + self.meleestrength = 0; + var_1 = gettime(); + + for (;;) + { + var_2 = gettime(); + + if ( var_2 - var_1 >= level.playermeleestunregentime ) + self.meleestrength = 1.0; + else + self.meleestrength = 0; + + if ( self meleebuttonpressed() && !self isreloading() && !self usebuttonpressed() ) + { + var_1 = gettime(); + + if ( var_0 == 1 ) + var_0 = 0; + } + else if ( !self meleebuttonpressed() ) + var_0 = 1; + else + var_0 = 0; + + wait 0.05; + } +} diff --git a/data/maps/mp/mp_alien_beacon.gsc b/data/maps/mp/mp_alien_beacon.gsc new file mode 100644 index 0000000..dd22215 --- /dev/null +++ b/data/maps/mp/mp_alien_beacon.gsc @@ -0,0 +1,3154 @@ +// IW6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool + +main() +{ + level.customprematchperiod = ::beacon_customprematchperiod; + level.additional_boss_weapon = ::spawn_weapon_in_boss_area; + level thread setintermissioncam(); + level.prematchperiod = 13; + level.icargohives = 0; + level.extinction_episode = 2; + level.introscreen_line_1 = &"MP_ALIEN_BEACON_INTRO_LINE_1"; + level.introscreen_line_2 = &"MP_ALIEN_BEACON_INTRO_LINE_2"; + level.introscreen_line_3 = &"MP_ALIEN_BEACON_INTRO_LINE_3"; + level.introscreen_line_4 = &"MP_ALIEN_BEACON_INTRO_LINE_4"; + common_scripts\utility::flag_init( "players_on_top_deck" ); + common_scripts\utility::flag_init( "tp_to_kraken_on_spawn" ); + common_scripts\utility::flag_init( "stop_tp_to_well_deck" ); + maps\mp\alien\_utility::alien_mode_enable( "kill_resource", "challenge", "wave", "airdrop", "lurker", "collectible", "loot", "pillage", "outline", "scenes" ); + level thread maps\mp\alien\_crafting::init(); + level thread maps\mp\alien\_crafting_traps::init(); + level.ricochetdamagemax = 25; + level.hardcore_spawn_multiplier = 1.0; + level.hardcore_damage_scalar = 1.0; + level.hardcore_health_scalar = 1.0; + level.hardcore_reward_scalar = 1.0; + level.hardcore_score_scalar = 1.25; + level.casual_spawn_multiplier = 1.0; + level.casual_damage_scalar = 0.45; + level.casual_health_scalar = 0.45; + level.casual_reward_scalar = 1.0; + level.casual_score_scalar = 0.5; + var_0 = [ "well_deck", "hallway_1", "cargo", "front_boat", "heli_pad" ]; + setdvar( "sm_sunSampleSizeNear", 0.25 ); + maps\mp\alien\_utility::alien_area_init( var_0 ); + level.include_default_challenges = 1; + level.challenge_registration_func = maps\mp\alien\mp_alien_beacon_challenges::register_beacon_challenges; + level.challenge_scalar_func = maps\mp\alien\mp_alien_beacon_challenges::beacon_challenge_scalar_func; + level.custom_death_challenge_func = maps\mp\alien\mp_alien_beacon_challenges::beacon_death_challenge_func; + level.custom_damage_challenge_func = maps\mp\alien\mp_alien_beacon_challenges::beacon_damage_challenge_func; + level.include_default_achievements = 1; + level.include_default_unlocks = 1; + level.escape_cycle = 21; + level.custom_pillageinitfunc = ::mp_alien_beacon_pillage_init; + level.create_attackable_ent_override_func = ::mp_alien_beacon_attackable_ent_override; + level.drill_attack_setup_override = ::mp_alien_beacon_drill_attack_override; + level.weapon_stats_override_name_func = ::beacon_weapon_stats_update_name; + level.get_custom_cycle_func = ::pre_hive; + level.achievement_registration_func = maps\mp\alien\_achievement_dlc2::register_achievements_dlc2; + level.update_alien_kill_achievements_func = maps\mp\alien\_achievement_dlc2::update_alien_kill_achievements_dlc2; + level.update_achievement_hypno_trap_func = maps\mp\alien\_achievement_dlc2::update_hypno_trap_rhino; + level.update_achievement_craft_items_func = maps\mp\alien\_achievement_dlc2::update_craft_all_items_achievement; + level.skip_radius_damage_on_puddles = 1; + level.adjust_spawnlocation_func = ::beacon_adjust_spawnlocation; + level.custom_alien_death_func = maps\mp\alien\_death::general_alien_custom_death; + level.custom_cangive_weapon_func = ::beacon_cangive_weapon_handler_func; + level.custom_give_weapon_func = ::beacon_give_weapon_handler_func; + level.hive_icon_override = ::beacon_hive_icon_override_func; + level.give_randombox_item_check = ::beacon_randombox_item_check; + level.hypno_trap_func = maps\mp\alien\_crafting_traps::tryuseplaceable; + level.tesla_trap_func = maps\mp\alien\_crafting_traps::tryuseplaceable; + maps\mp\alien\_alien_maaws::alien_maaws_init(); + maps\mp\alien\_pillage_locker::locker_pillage_functions_init(); + level.level_locker_weapon_pickup_string_func = ::beacon_locker_weapon_pickup_string_func; + level.cac_vo_male = common_scripts\utility::array_randomize( [ "p6_", "p5_" ] ); + level.cac_vo_female = common_scripts\utility::array_randomize( [ "p8_", "p7_" ] ); + level.custom_onspawnplayer_func = ::mp_alien_beacon_onspawnplayer_func; + level.initial_spawn_loc_override_func = ::beacon_player_initial_spawn_loc_override; + level.enter_area_func = ::beacon_enter_area_func; + level.leave_area_func = ::beacon_leave_area_func; + level.watch_bomb_stuck_override = ::beacon_watch_bomb_stuck_override; + level.get_alien_model_func = ::beacon_get_alien_model; + level.level_specific_vo_callouts = ::beacon_specific_vo_callouts; + level.non_player_drill_plant_check = ::beacon_non_player_drill_plant_check; + level.non_player_drill_plant = 0; + level.intel_table = "mp/alien/alien_beacon_intel.csv"; + level.randombox_table = "mp/alien/beacon_deployable_randombox.csv"; + level maps\mp\alien\mp_alien_beacon_turret::beacon_turret_init(); + level thread maps\mp\mp_alien_beacon_fx::ship_camera_tilting(); + set_spawn_table(); + set_container_spawn_table(); + set_alien_definition_table(); + level.alien_collectibles_table = "mp/alien/collectibles_beacon.csv"; + level.spawn_node_info_table = "mp/alien/beacon_spawn_node_info.csv"; + level.alien_challenge_table = "mp/alien/mp_alien_beacon_challenges.csv"; + + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.base_player_count_multiplier = 1; + else + level.base_player_count_multiplier = 0.49; + + level.additional_player_count_multiplier = 0.17; + level.waypoint_dist_override = 2500; + maps\mp\mp_alien_beacon_precache::main(); + maps\createart\mp_alien_beacon_art::main(); + maps\mp\mp_alien_beacon_fx::main(); + init_level_flags(); + level.hintprecachefunc = ::beacon_hint_precache; + maps\mp\alien\_beacon_weapon::init(); + maps\mp\_load::main(); + game["thermal_vision"] = "mp_alien_beacon_thermal"; + visionsetthermal( game["thermal_vision"] ); + game["thermal_vision_trinity"] = "mp_alien_thermal_trinity"; + setdvar( "sm_sunShadowScale", "0.5" ); + maps\mp\_utility::setdvar_cg_ng( "r_specularColorScale", 4.0, 6.0 ); + maps\mp\_compass::setupminimap( "compass_map_mp_alien_beacon" ); + var_1 = 20000; + var_2 = 40000; + var_3 = 70000; + var_4 = 240000; + maps\mp\alien\_persistence::register_lb_escape_rank( [ 0, var_1, var_2, var_3, var_4 ] ); + var_5 = [ "mini_lung_00" ]; + maps\mp\alien\_utility::add_hive_dependencies( "well_deck_2", var_5 ); + var_6 = [ "well_deck_2" ]; + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_4", var_6 ); + maps\mp\alien\_utility::add_hive_dependencies( "well_deck_3", var_6 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_6", var_6 ); + var_7 = [ "door_hive_4" ]; + maps\mp\alien\_utility::add_hive_dependencies( "well_deck_3", var_7 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_6", var_7 ); + var_8 = [ "well_deck_3" ]; + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_6", var_8 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_7", var_8 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_8", var_8 ); + var_9 = [ "door_hive_6" ]; + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_mini_1", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_mini_2", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_mini_3", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_mini_4", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_main", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_7", var_9 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_8", var_9 ); + var_10 = [ "top_deck_mini_1", "top_deck_mini_2", "top_deck_mini_3" ]; + maps\mp\alien\_utility::add_hive_dependencies( "lab_mini_1", var_10 ); + maps\mp\alien\_utility::add_hive_dependencies( "lab_mini_2", var_10 ); + maps\mp\alien\_utility::add_hive_dependencies( "lab_mini_3", var_10 ); + maps\mp\alien\_utility::add_hive_dependencies( "lab_mini_4", var_10 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_10", var_10 ); + var_11 = [ "cargo_area_mini_2" ]; + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_mini_3", var_11 ); + var_12 = [ "cargo_area_main" ]; + maps\mp\alien\_utility::add_hive_dependencies( "top_deck_mini_3", var_12 ); + maps\mp\alien\_utility::add_hive_dependencies( "top_deck_mini_1", var_12 ); + maps\mp\alien\_utility::add_hive_dependencies( "top_deck_mini_2", var_12 ); + maps\mp\alien\_utility::add_hive_dependencies( "door_hive_9", var_12 ); + var_13 = [ "cargo_area_mini_1", "cargo_area_mini_2", "cargo_area_mini_3", "cargo_area_mini_4" ]; + maps\mp\alien\_utility::add_hive_dependencies( "cargo_area_main", var_13 ); + game["attackers"] = "allies"; + game["defenders"] = "axis"; + game["allies_outfit"] = "woodland"; + var_14 = []; + var_15 = [ 8 ]; + maps\mp\gametypes\aliens::setup_cycle_end_area_list( var_15 ); + maps\mp\gametypes\aliens::setup_blocker_hives( var_14 ); + maps\mp\gametypes\aliens::setup_last_hive( "bomblocation_14" ); + init_seeder(); + register_encounter(); + maps\mp\mp_alien_beacon_vignettes::main(); + + if ( !maps\mp\alien\_utility::is_chaos_mode() ) + init_container_spawn(); + + maps\mp\alien\_pillage_intel::create_intel_spots(); + level thread maps\mp\alien\mp_alien_beacon_turret::set_up_remote_turrets(); + thread maps\mp\alien\_alien_class_skills_main::main(); + level thread beacon_intro_drill(); + level thread beacon_door_encounter_logic(); + level thread player_death_trigger_monitor(); + level thread crane_walls_hide(); + level.ammoincompatibleweaponslist = []; + level.ammoincompatibleweaponslist[0] = "iw5_alienriotshield_mp"; + level.ammoincompatibleweaponslist[1] = "iw5_alienriotshield1_mp"; + level.ammoincompatibleweaponslist[2] = "iw5_alienriotshield2_mp"; + level.ammoincompatibleweaponslist[3] = "iw5_alienriotshield3_mp"; + level.ammoincompatibleweaponslist[4] = "iw5_alienriotshield4_mp"; + level.ammoincompatibleweaponslist[5] = "iw6_alienminigun_mp"; + level.ammoincompatibleweaponslist[6] = "iw6_alienminigun1_mp"; + level.ammoincompatibleweaponslist[7] = "iw6_alienminigun2_mp"; + level.ammoincompatibleweaponslist[8] = "iw6_alienminigun3_mp"; + level.ammoincompatibleweaponslist[9] = "iw6_alienminigun4_mp"; + level.ammoincompatibleweaponslist[10] = "iw6_alienmk32_mp"; + level.ammoincompatibleweaponslist[11] = "iw6_alienmk321_mp"; + level.ammoincompatibleweaponslist[12] = "iw6_alienmk322_mp"; + level.ammoincompatibleweaponslist[13] = "iw6_alienmk323_mp"; + level.ammoincompatibleweaponslist[14] = "iw6_alienmk324_mp"; + level.ammoincompatibleweaponslist[15] = "iw6_aliendlc11_mp"; + level.ammoincompatibleweaponslist[16] = "iw6_aliendlc11li_mp"; + level.ammoincompatibleweaponslist[17] = "iw6_aliendlc11sp_mp"; + level.ammoincompatibleweaponslist[18] = "iw6_aliendlc11fi_mp"; + thread beacon_intro_music(); + level thread setup_beacon_offhands(); + level thread fix_bad_drill_spots(); + level thread maps\mp\alien\_music_and_dialog_dlc::remove_drill_vo_once_complete(); + level thread cleanup_strings(); +} + +fix_bad_drill_spots() +{ + level endon( "game_ended" ); + level waittill( "spawn_nondeterministic_entities" ); + var_0 = getent( "player64x64x256", "targetname" ); + + if ( isdefined( var_0 ) ) + { + var_0 moveto( ( -347.4, 2044.1, 1033.04 ), 0.05 ); + var_0.angles = ( 0, 0, 0 ); + } + + var_1 = getent( "clip64x64x64", "targetname" ); + + if ( isdefined( var_1 ) ) + { + var_1 moveto( ( -811.5, -2114.5, 75 ), 0.05 ); + var_1.angles = ( 0, 0, 0 ); + } + + var_2 = getent( "monsterjplayerclip512x8x256", "targetname" ); + + if ( isdefined( var_2 ) ) + { + var_2.origin = ( -856, 3590, 1152 ); + var_2.angles = ( 0, 270, 0 ); + } + + var_3 = getent( "clip64x64x128", "targetname" ); + + if ( isdefined( var_3 ) ) + { + var_3.origin = ( 276, 6176, 1152 ); + var_3.angles = ( 0, 0, 0 ); + } + + var_4 = getent( "player512x512x8", "targetname" ); + + if ( isdefined( var_4 ) ) + { + var_4.origin = ( 752, 3398, 64 ); + var_4.angles = ( 270, 180, 180 ); + var_5 = spawn( "script_model", ( 842, 3218, 440 ) ); + var_5 clonebrushmodeltoscriptmodel( var_4 ); + var_5.origin = ( 842, 3218, 440 ); + var_5.angles = ( 270, 180, 180 ); + } + + var_6 = getent( "monsterplayer512x512x8", "targetname" ); + + if ( isdefined( var_6 ) ) + { + var_6.origin = ( 1098, 3046, 440 ); + var_6.angles = ( 270, 270, -180 ); + var_7 = spawn( "script_model", ( 891, 3038, 184 ) ); + var_7 setmodel( "tool_cabinet_02_iw6" ); + var_7.angles = ( 0, 180, 0 ); + } +} + +cleanup_strings() +{ + var_0 = 5.0; + wait( var_0 ); + var_1 = getarraykeys( game["dialog"] ); + + foreach ( var_3 in var_1 ) + { + if ( game["dialog"][var_3] == "enemy_null" || game["dialog"][var_3] == "friendly_null" || game["dialog"][var_3] == "null" ) + game["dialog"][var_3] = undefined; + } + + game["dialog"] = common_scripts\utility::array_removeundefined( game["dialog"] ); +} + +setup_beacon_offhands() +{ + while ( !isdefined( level.offhand_explosives ) ) + wait 1; + + level.offhand_explosives = common_scripts\utility::array_add( level.offhand_explosives, "iw6_aliendlc22_mp" ); + level.offhand_secondaries = common_scripts\utility::array_add( level.offhand_secondaries, "iw6_aliendlc21_mp" ); +} + +beacon_intro_drill() +{ + level waittill( "spawn_beacon_drill", var_0, var_1 ); + level notify( "spawn_intro_drill", var_0, var_1 ); + common_scripts\utility::flag_set( "intro_sequence_complete" ); +} + +waypoint_after_drill_picked_up() +{ + level waittill( "drill_pickedup" ); + level thread place_waypoint_on_blocker_door(); +} + +place_waypoint_on_blocker_door() +{ + var_0 = ( -40, 874, 340 ); + var_1 = "waypoint_alien_blocker"; + var_2 = 14; + var_3 = 14; + var_4 = 0.75; + var_5 = var_0 + ( 0, 0, 4 ); + var_6 = maps\mp\alien\_hud::make_waypoint( var_1, var_2, var_3, var_4, var_5 ); + + for (;;) + { + level waittill( "drill_planted" ); + + if ( level.current_hive_name == "cargo_area_main" ) + break; + else + { + var_6.alpha = 0; + level waittill( "drill_pickedup" ); + var_6.alpha = 0.75; + } + } + + var_6 destroy(); +} + +use_drillbot_door( var_0, var_1 ) +{ + var_2 = var_1.script_angles; + + if ( isdefined( var_0 ) ) + var_2 = var_2 * -1; + + var_1 moveto( var_1.origin + var_2, 2 ); + playsoundatpos( var_1.origin, "scn_drillbot_door" ); +} + +spawn_beacon_cargo_drillbot() +{ + var_0 = getvehiclenode( "cargo_drillbot_start", "targetname" ); + level.drill_vehicle = spawnvehicle( "vehicle_drill_bot", "drill", "mp_alien_drill_bot", var_0.origin, var_0.angles ); + level.drill_vehicle.team = "allies"; + level.drill_vehicle.health = 1000000; + level.drill_vehicle makevehiclesolidcapsule( 1, 1, 1 ); + level.drill_headlight_fx = spawn( "script_model", level.drill_vehicle.origin + ( 0, 0, 30 ) + vector_multiply( anglestoforward( level.drill_vehicle.angles ), 10 ) ); + level.drill_headlight_fx.angles = ( 0, 90, 0 ); + level.drill_headlight_fx setmodel( "tag_origin" ); + wait 0.5; + playfxontag( level._effect["bot_headlight"], level.drill_headlight_fx, "tag_origin" ); + level.drill_headlight_fx linkto( level.drill_vehicle ); + var_1 = "waypoint_alien_blocker"; + var_2 = 14; + var_3 = 14; + var_4 = 0.75; + var_5 = level.drill_vehicle.origin + ( 0, 0, 40 ); + + foreach ( var_7 in level.players ) + maps\mp\alien\_outline_proto::enable_outline_for_player( level.drill_vehicle, var_7, 3, 0, "high" ); + + level.drillbot_waypoint_icon = maps\mp\alien\_hud::make_waypoint( var_1, var_2, var_3, var_4, var_5 ); +} + +vector_multiply( var_0, var_1 ) +{ + return ( var_0[0] * var_1, var_0[1] * var_1, var_0[2] * var_1 ); +} + +beacon_watch_bomb_stuck_override( var_0 ) +{ + if ( maps\mp\alien\_utility::is_true( var_0.on_container ) && maps\mp\alien\_utility::is_true( level.all_players_on_container ) ) + { + level thread link_drill_to_container( var_0 ); + return 1; + } + + if ( !isdefined( level.drill_vehicle ) || !maps\mp\alien\_utility::is_true( level.drillbot_door_open ) ) + return 0; + + if ( distancesquared( var_0.origin, level.drill_vehicle.origin ) < 6400 && !isdefined( level.drillbot_event_finished ) ) + { + level thread cargo_drillbot_logic( var_0 ); + return 1; + } + + return 0; +} + +link_drill_to_container( var_0 ) +{ + var_0 takeweapon( "alienbomb_mp" ); + var_0 enableweaponswitch(); + maps\mp\alien\_drill::drop_drill( var_0.origin + ( 0, 0, 4 ), ( 0, 0, 0 ) ); + earthquake( 0.25, 0.5, var_0.origin, 128 ); + level.drill_linked_to_container = 1; + wait 0.1; + var_1 = getentarray( "move_container", "targetname" ); + level.drill linkto( var_1[0] ); + level.drill makeunusable(); + + if ( isdefined( level.drill_icon ) ) + level.drill_icon.alpha = 0; + + var_0 maps\mp\alien\_drill::restore_last_weapon(); + var_0 common_scripts\utility::_enableoffhandweapons(); + level waittill( "beacon_starting_topdeck" ); + level.drill makeusable(); + level.drill unlink(); + level.drill_linked_to_container = undefined; + + foreach ( var_3 in level.players ) + var_3.on_container = undefined; + + if ( isdefined( level.drill_icon ) ) + { + level.drill_icon.x = level.drill.origin[0]; + level.drill_icon.y = level.drill.origin[1]; + level.drill_icon.z = level.drill.origin[2] + 72; + level.drill_icon.alpha = 0.5; + } +} + +cargo_drillbot_logic( var_0 ) +{ + level notify( "drillbot_used" ); + clear_drillbot_lowermessage(); + + if ( isdefined( level.drillbot_waypoint_icon ) ) + level.drillbot_waypoint_icon destroy(); + + var_0 takeweapon( "alienbomb_mp" ); + level.drill_vehicle playsoundonmovingent( "scn_drillbot_attach" ); + var_0 enableweaponswitch(); + var_1 = level.drill_vehicle gettagorigin( "tag_turret_attach" ); + level.prevent_drill_pickup = 1; + maps\mp\alien\_drill::drop_drill( var_1, ( 0, 0, 0 ) ); + earthquake( 0.25, 0.5, var_0.origin, 128 ); + var_0 maps\mp\alien\_drill::restore_last_weapon(); + var_0 common_scripts\utility::_enableoffhandweapons(); + wait 0.1; + level.prevent_drill_pickup = undefined; + level.drill linkto( level.drill_vehicle, "tag_turret_attach", ( 0, 0, 0 ), ( 0, 0, 0 ) ); + level.drill makeunusable(); + var_2 = undefined; + + foreach ( var_4 in level.stronghold_hive_locs ) + { + if ( isdefined( var_4.target ) && var_4.target == "cargo_area_mini_3" ) + { + var_2 = var_4; + break; + } + } + + var_2 maps\mp\alien\_hive::disable_other_strongholds(); + + if ( isdefined( var_2.icon ) ) + var_2.icon destroy(); + + wait_for_player_to_activate_platform(); + level.non_player_drill_plant = 1; + use_drillbot_door( 1, getent( "cargo_bot_entrance_door", "targetname" ) ); + send_bot_to_hive_and_drill( var_0 ); + var_6 = common_scripts\utility::getclosest( level.drill_vehicle.origin, getvehiclenodearray( "drill_path", "targetname" ) ); + level.drill_vehicle attachpath( var_6 ); + level.drill_vehicle startpath(); + level.drill_vehicle playsoundonmovingent( "scn_drillbot_move02" ); + level.drill_vehicle vehicle_setspeed( 5, 1, 1 ); + level.drill_vehicle waittill( "reached_end_node" ); + var_7 = undefined; + use_drillbot_door( var_7, getent( "cargo_bot_exit_door", "targetname" ) ); + level.drill makeusable(); + + foreach ( var_9 in level.players ) + maps\mp\alien\_outline_proto::disable_outline_for_player( level.drill_vehicle, var_9 ); + + level.drill_headlight_fx delete(); + level.drillbot_event_finished = 1; + level.non_player_drill_plant = 0; + level.drill maps\mp\alien\_drill::set_drill_icon(); +} + +send_bot_to_hive_and_drill( var_0 ) +{ + if ( isdefined( level.drill_icon ) ) + level.drill_icon destroy(); + + var_1 = getvehiclenode( "cargo_drillbot_start", "targetname" ); + level.drill_vehicle attachpath( var_1 ); + level.drill_vehicle startpath(); + level.drill_vehicle playsoundonmovingent( "scn_drillbot_move01" ); + level.drill_vehicle vehicle_setspeed( 5, 1, 1 ); + level.drill_icon_draw_dist_override = 10000; + level.drill_vehicle waittill( "reached_end_node" ); + var_2 = undefined; + + foreach ( var_4 in level.stronghold_hive_locs ) + { + if ( isdefined( var_4.target ) && var_4.target == "cargo_area_mini_3" ) + { + var_2 = var_4; + break; + } + } + + if ( !isdefined( var_0 ) || !isalive( var_0 ) ) + { + var_6 = maps\mp\alien\_utility::get_array_of_valid_players(); + var_0 = var_6[0]; + } + + level.drill_carrier = var_0; + var_2 notify( "trigger", var_0 ); + common_scripts\utility::flag_wait( "drill_detonated" ); + level.drill_icon_draw_dist_override = undefined; + wait 8; + level.drill makeunusable(); + level.drill linkto( level.drill_vehicle, "tag_turret_attach", ( 0, 0, -2 ), ( 0, 0, 0 ) ); + + if ( isdefined( level.drill_icon ) ) + level.drill_icon destroy(); +} + +wait_for_player_to_activate_platform() +{ + var_0 = getent( "bot_switch", "targetname" ); + maps\mp\alien\_outline_proto::add_to_outline_watch_list( var_0, 0 ); + var_1 = "waypoint_alien_blocker"; + var_2 = 14; + var_3 = 14; + var_4 = 0.75; + var_5 = var_0.origin + ( 0, 0, 40 ); + var_6 = maps\mp\alien\_hud::make_waypoint( var_1, var_2, var_3, var_4, var_5 ); + var_0 makeusable(); + var_0 sethintstring( &"MP_ALIEN_BEACON_ACTIVATE_BOT" ); + var_0 waittill( "trigger", var_7 ); + playsoundatpos( var_0.origin + ( 0, 0, 40 ), "scn_drillbot_activate" ); + maps\mp\alien\_outline_proto::remove_from_outline_watch_list( var_0 ); + var_0 makeunusable(); + var_6 destroy(); +} + +clear_drillbot_lowermessage() +{ + foreach ( var_1 in level.players ) + var_1 maps\mp\_utility::clearlowermessage( "bot_drill" ); +} + +check_for_player_near_bot_with_drill() +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "drillbot_used" ); + + if ( maps\mp\alien\_utility::is_true( level.drillbot_event_finished ) ) + return; + + var_0 = 6400; + + while ( !isdefined( level.drill_vehicle ) ) + wait 1; + + for (;;) + { + while ( !common_scripts\utility::flag( "drill_drilling" ) ) + { + if ( isdefined( self.inlaststand ) && self.inlaststand || common_scripts\utility::flag( "drill_drilling" ) || isdefined( self.usingremote ) || maps\mp\alien\_utility::is_true( self.iscarrying ) ) + { + wait 0.05; + continue; + } + + if ( distancesquared( level.drill_vehicle.origin, self.origin ) < var_0 ) + { + if ( !isdefined( level.drill_carrier ) || isdefined( level.drill_carrier ) && level.drill_carrier != self ) + { + maps\mp\_utility::setlowermessage( "bot_drill", &"MP_ALIEN_BEACON_PLACE_DRILL", undefined, 10 ); + + while ( player_should_see_drillbot_hint( level.drill_vehicle, var_0, 1 ) ) + wait 0.05; + + maps\mp\_utility::clearlowermessage( "bot_drill" ); + } + else + { + maps\mp\_utility::setlowermessage( "bot_drill", &"MP_ALIEN_BEACON_DRILL_ONBOT", undefined, 10 ); + + while ( player_should_see_drillbot_hint( level.drill_vehicle, var_0, 0 ) ) + wait 0.05; + + maps\mp\_utility::clearlowermessage( "bot_drill" ); + } + } + + wait 0.05; + } + + common_scripts\utility::flag_waitopen( "drill_drilling" ); + } +} + +player_should_see_drillbot_hint( var_0, var_1, var_2 ) +{ + if ( distancesquared( var_0.origin, self.origin ) > var_1 ) + return 0; + + if ( common_scripts\utility::flag( "drill_drilling" ) ) + return 0; + + if ( self.inlaststand ) + return 0; + + if ( isdefined( self.usingremote ) ) + return 0; + + if ( maps\mp\alien\_utility::is_true( var_2 ) ) + return 1; + else if ( maps\mp\alien\_utility::is_true( self.iscarrying ) ) + return 0; + + return 1; +} + +register_encounter() +{ + if ( maps\mp\alien\_utility::is_chaos_mode() ) + { + maps\mp\gametypes\aliens::register_encounter( ::chaos_init, undefined, undefined, undefined, ::chaos_init, maps\mp\alien\_globallogic::blank ); + maps\mp\gametypes\aliens::register_encounter( maps\mp\alien\_chaos::chaos, undefined, undefined, undefined, maps\mp\alien\_chaos::chaos, maps\mp\alien\_globallogic::blank ); + return; + } + + maps\mp\gametypes\aliens::register_encounter( ::encounter_init, undefined, undefined, undefined, ::encounter_init, maps\mp\alien\_globallogic::blank ); + maps\mp\gametypes\aliens::register_encounter( ::mp_alien_beacon_intro_ride, 1, undefined, undefined, ::skip_hive_give_abilities, ::jump_to_well_deck_1, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::hives_2_custom, 1, undefined, 1, maps\mp\alien\_hive::skip_hive, ::jump_to_well_deck_2, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::hives_3_custom, 1, undefined, 1, maps\mp\alien\_hive::skip_hive, ::jump_to_mini_boss, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::first_cargo_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_cargo_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::cargo_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_cargo_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::cargo_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_cargo_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::cargo_hive, 1, undefined, 1, maps\mp\alien\_hive::skip_hive, ::jump_to_cargo_blocker, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::top_deck_hive_01, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_top_deck, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::final_deck_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_top_deck, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::first_lab_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_lab_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::second_lab_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_lab_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::third_lab_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_lab_area, maps\mp\alien\_hive::beat_regular_hive ); + maps\mp\gametypes\aliens::register_encounter( ::mp_alien_beacon_top_deck_hive, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_lab_blocker ); + maps\mp\gametypes\aliens::register_encounter( ::mp_alien_beacon_boss_encounter, 1, undefined, undefined, maps\mp\alien\_hive::skip_hive, ::jump_to_boss_area ); +} + +encounter_init() +{ + var_0 = getent( "drill_pickup_trig", "targetname" ); + + if ( isdefined( var_0 ) ) + var_0 delete(); + + maps\mp\alien\_drill::init_drill(); + maps\mp\alien\_hive::init_hives(); + maps\mp\alien\_gamescore::init_eog_score_components( [ "hive" ] ); + maps\mp\alien\_gamescore_beacon::init_beacon_eog_score_components( [ "kraken", "item_crafting", "side_area", "relics" ] ); + maps\mp\alien\_gamescore::init_encounter_score_components( [ "challenge", "drill", "team", "team_blocker", "personal", "personal_blocker" ] ); + maps\mp\alien\_gamescore_beacon::init_beacon_encounter_score_components( [ "item_crafting", "side_area", "gas", "kraken", "kraken_personal", "kraken_team", "tentacle_bonus", "progression_door" ] ); + level.progression_doors = [ "door_hive_4", "door_hive_6" ]; + level thread fix_cargo_leftovers(); +} + +init_seeder() +{ + maps\mp\agents\alien\_alien_seeder::seeder_level_init(); + level.dlc_alien_init_override_func = ::beacon_alien_init_override; + level.dlc_melee_override_func = ::beacon_alien_melee_override; + level.dlc_alien_death_override_func = ::beacon_alien_death_override; + level.dlc_get_non_agent_enemies = ::beacon_get_non_agent_enemies; +} + +beacon_alien_init_override() +{ + if ( maps\mp\alien\_utility::get_alien_type() == "seeder" ) + maps\mp\agents\alien\_alien_seeder::seeder_init(); +} + +beacon_alien_melee_override( var_0 ) +{ + if ( self.melee_type == "seeder_spit" ) + maps\mp\agents\alien\_alien_seeder::seeder_spit_attack( var_0 ); +} + +beacon_alien_death_override( var_0 ) +{ + if ( maps\mp\alien\_utility::get_alien_type() == "seeder" ) + maps\mp\agents\alien\_alien_seeder::seeder_death( var_0 ); +} + +beacon_get_non_agent_enemies() +{ + var_0 = []; + + if ( isdefined( level.seeder_active_turrets ) ) + { + foreach ( var_2 in level.seeder_active_turrets ) + { + if ( !isdefined( var_2.pet ) ) + var_0 = common_scripts\utility::array_add( var_0, var_2 ); + } + + return var_0; + } + + return []; +} + +beacon_hint_precache() +{ + var_0 = []; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_PROPANE_TANK"] = &"ALIEN_PICKUPS_BEACON_PICKUP_PROPANE_TANK"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_VKS"] = &"ALIEN_PICKUPS_BEACON_PICKUP_VKS"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_FP6"] = &"ALIEN_PICKUPS_BEACON_PICKUP_FP6"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_RGM"] = &"ALIEN_PICKUPS_BEACON_PICKUP_RGM"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_PP19"] = &"ALIEN_PICKUPS_BEACON_PICKUP_PP19"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_CBJMS"] = &"ALIEN_PICKUPS_BEACON_PICKUP_CBJMS"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_MAUL"] = &"ALIEN_PICKUPS_BEACON_PICKUP_MAUL"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_MICROTAR"] = &"ALIEN_PICKUPS_BEACON_PICKUP_MICROTAR"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_KAC"] = &"ALIEN_PICKUPS_BEACON_PICKUP_KAC"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_PANZERFAUST"] = &"ALIEN_PICKUPS_BEACON_PICKUP_PANZERFAUST"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_G28"] = &"ALIEN_PICKUPS_BEACON_PICKUP_G28"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_HONEYBADGER"] = &"ALIEN_PICKUPS_BEACON_PICKUP_HONEYBADGER"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_RGM"] = &"ALIEN_PICKUPS_BEACON_PICKUP_RGM"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_ARX_160"] = &"ALIEN_PICKUPS_BEACON_PICKUP_ARX_160"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_LSAT"] = &"ALIEN_PICKUPS_BEACON_PICKUP_LSAT"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_SVU"] = &"ALIEN_PICKUPS_BEACON_PICKUP_SVU"; + var_0["ALIEN_PICKUPS_BEACON_PICKUP_RIPPER"] = &"ALIEN_PICKUPS_BEACON_PICKUP_RIPPER"; + return var_0; +} + +mp_alien_beacon_pillage_init() +{ + level.pillageinfo = spawnstruct(); + level.pillageinfo.alienattachment_model = "weapon_alien_muzzlebreak"; + level.pillageinfo.default_use_time = 1000; + level.pillageinfo.money_stack = "pb_money_stack_01"; + level.pillageinfo.attachment_model = "has_spotter_scope"; + level.pillageinfo.maxammo_model = "mil_ammo_case_1_open"; + level.pillageinfo.flare_model = "mil_emergency_flare_mp"; + level.pillageinfo.clip_model = "weapon_baseweapon_clip"; + level.pillageinfo.leash_model = "weapon_knife_iw6"; + level.pillageinfo.trophy_model = "mp_trophy_system_folded_iw6"; + level.pillageinfo.ui_searching = 1; + level.pillageinfo.easy_attachment = 30; + level.pillageinfo.easy_clip = 15; + level.pillageinfo.easy_money = 20; + level.pillageinfo.easy_explosive = 16; + level.pillageinfo.easy_specialammo = 17; + level.pillageinfo.easy_locker_key = 1; + level.pillageinfo.easy_intel = 1; + level.pillageinfo.medium_attachment = 35; + level.pillageinfo.medium_explosive = 16; + level.pillageinfo.medium_money = 20; + level.pillageinfo.medium_specialammo = 20; + level.pillageinfo.medium_clip = 7; + level.pillageinfo.medium_locker_key = 1; + level.pillageinfo.medium_intel = 1; + level.pillageinfo.hard_attachment = 25; + level.pillageinfo.hard_maxammo = 25; + level.pillageinfo.hard_specialammo = 19; + level.pillageinfo.hard_money = 25; + level.pillageinfo.hard_locker_key = 5; + level.pillageinfo.hard_intel = 1; + level.crafting_item_table = "mp/alien/crafting_items.csv"; + level.crafting_table_item_index = 0; + level.crafting_table_item_ref = 1; + level.crafting_table_item_name = 2; + level.crafting_table_item_icon = 3; + level.max_crafting_items = 3; + level.crafting_model = "weapon_baseweapon_clip"; + level.get_hintstring_for_pillaged_item_func = ::beacon_get_hintstring_for_pillaged_item_func; + level.get_hintstring_for_item_pickup_func = ::beacon_get_hintstring_for_item_pickup_func; + level.custom_build_pillageitem_array_func = ::beacon_build_pillageitem_array_func; + relocate_bad_pillage_spots(); +} + +relocate_bad_pillage_spots() +{ + var_0 = common_scripts\utility::getstructarray( "lab_crafting_pillage", "targetname" ); + + foreach ( var_2 in var_0 ) + { + if ( var_2.origin == ( -1034, 5744.2, 1214 ) ) + { + var_2.origin = ( -1034.5, 5686.2, 1156 ); + var_2.angles = ( 0, 313, 0 ); + } + } +} + +mp_alien_beacon_onspawnplayer_func() +{ + thread maps\mp\alien\_alien_class_skills_main::assign_skills(); + thread maps\mp\alien\_music_and_dialog_dlc::dlc_vo_init_on_player_spawn(); + thread maps\mp\alien\_pillage_intel::intel_on_player_connect(); + thread maps\mp\alien\_beacon_weapon::special_gun_watcher(); + thread check_for_player_near_bot_with_drill(); + var_0 = self; + thread maps\mp\alien\_achievement::eggallfoundforpack( 1 ); + level notify( "boat_spawn", var_0 ); + + if ( common_scripts\utility::flag_exist( "boat_ride_over" ) && !common_scripts\utility::flag( "boat_ride_over" ) ) + var_0 thread boat_intro_on_connect( var_0, level.players.size ); +} + +tp_to_well_deck() +{ + var_0 = []; + var_0[1] = ( -132, -3142, -100 ); + var_0[2] = ( -232, -3142, -100 ); + var_0[3] = ( -332, -3142, -100 ); + var_0[4] = ( -432, -3142, -100 ); + var_1 = 0; + + while ( var_1 == 0 && self.origin[1] < -4500 ) + { + foreach ( var_3 in var_0 ) + { + if ( canspawn( var_3 ) && !positionwouldtelefrag( var_3 ) ) + { + if ( !isdefined( self.teleport_overlay ) ) + { + thread teleport_black_screen(); + wait 1; + } + + if ( canspawn( var_3 ) && !positionwouldtelefrag( var_3 ) ) + { + teleport_player_to_spot( var_3 ); + var_1 = 1; + break; + } + else + continue; + } + } + + wait 0.1; + } +} + +freeze_connected_player_controls() +{ + level endon( "introscreen_over" ); + wait 1; + + while ( !common_scripts\utility::flag( "intro_sequence_complete" ) ) + { + level waittill( "connected", var_0 ); + var_0 thread freeze_controls_load(); + } +} + +freeze_controls_load() +{ + maps\mp\_utility::freezecontrolswrapper( 1 ); + self disableweapons(); + level waittill( "introscreen_over" ); + maps\mp\_utility::freezecontrolswrapper( 0 ); + self enableweapons(); +} + +skip_hive_give_abilities() +{ + common_scripts\utility::flag_set( "give_player_abilities" ); + maps\mp\alien\_hive::skip_hive(); +} + +beacon_get_hintstring_for_pillaged_item_func( var_0 ) +{ + var_0 = "" + var_0; + + switch ( var_0 ) + { + case "crafting": + return &"ALIEN_CRAFTING_FOUND_CRAFTING_ITEM"; + case "locker_key": + return &"ALIEN_PILLAGE_LOCKER_FOUND_LOCKER_KEY"; + case "locker_weapon": + return &"ALIEN_PILLAGE_LOCKER_FOUND_LOCKER_WEAPON"; + } +} + +beacon_get_hintstring_for_item_pickup_func( var_0 ) +{ + var_0 = "" + var_0; + + switch ( var_0 ) + { + case "wire": + return &"ALIEN_CRAFTING_PICKUP_WIRE"; + case "amolecular": + return &"ALIEN_CRAFTING_PICKUP_AMOLECULAR"; + case "fuse": + return &"ALIEN_CRAFTING_PICKUP_FUSE"; + case "pipe": + return &"ALIEN_CRAFTING_PICKUP_PIPE"; + case "pressureplate": + return &"ALIEN_CRAFTING_PICKUP_PRESSUREPLATE"; + case "nucleicbattery": + return &"ALIEN_CRAFTING_PICKUP_NUCLEICBATTERY"; + case "cellbattery": + return &"ALIEN_CRAFTING_PICKUP_CELLBATTERY"; + case "liquidbattery": + return &"ALIEN_CRAFTING_PICKUP_LIQUIDBATTERY"; + case "tnt": + return &"ALIEN_CRAFTING_PICKUP_TNT"; + case "resin": + return &"ALIEN_CRAFTING_PICKUP_RESIN"; + case "biolum": + return &"ALIEN_CRAFTING_PICKUP_BIOLUM"; + case "locker_key": + return &"ALIEN_PILLAGE_LOCKER_PICKUP_LOCKER_KEY"; + case "locker_weapon": + return &"ALIEN_PILLAGE_LOCKER_PICKUP_LOCKER_WEAPON"; + case "venomx": + return &"ALIEN_CRAFTING_PICKUP_DISARMED_VENOM"; + case "bluebiolum": + return &"ALIEN_CRAFTING_PICKUP_BLUEBIOLUM"; + case "orangebiolum": + return &"ALIEN_CRAFTING_PICKUP_ORANGEBIOLUM"; + case "amethystbiolum": + return &"ALIEN_CRAFTING_PICKUP_PURPLEBIOLUM"; + case "iw6_aliendlc22_mp": + return &"ALIEN_CRAFTING_PICKUP_PIPEBOMB"; + case "flare": + case "stickyflare": + case "viewmodel_flare": + case "iw6_aliendlc21_mp": + return &"ALIEN_CRAFTING_PICKUP_STICKYFLARE"; + } + + if ( isdefined( level.level_locker_weapon_pickup_string_func ) ) + return [[ level.level_locker_weapon_pickup_string_func ]]( var_0 ); +} + +beacon_build_pillageitem_array_func( var_0 ) +{ + switch ( var_0 ) + { + case "easy": + maps\mp\alien\_pillage::build_pillageitem_array( var_0, "crafting", level.pillageinfo.crafting_easy ); + break; + case "medium": + maps\mp\alien\_pillage::build_pillageitem_array( var_0, "crafting", level.pillageinfo.crafting_medium ); + break; + case "hard": + maps\mp\alien\_pillage::build_pillageitem_array( var_0, "crafting", level.pillageinfo.crafting_hard ); + break; + } + + level thread maps\mp\alien\_pillage_intel::build_intel_pillageitem_arrays( var_0 ); +} + +beacon_locker_weapon_pickup_string_func( var_0 ) +{ + var_0 = "" + var_0; + + switch ( var_0 ) + { + case "weapon_maul": + return &"ALIEN_PICKUPS_BEACON_LOCKER_MAUL"; + case "weapon_kac_chainsaw": + return &"ALIEN_PICKUPS_BEACON_LOCKER_KAC"; + case "weapon_g28": + return &"ALIEN_PICKUPS_BEACON_LOCKER_G28"; + case "weapon_fabarm_fp6": + return &"ALIEN_PICKUPS_BEACON_LOCKER_FP6"; + case "weapon_pp19_bizon_iw6": + return &"ALIEN_PICKUPS_BEACON_LOCKER_PP19"; + case "weapon_cbj_ms_iw6": + return &"ALIEN_PICKUPS_BEACON_LOCKER_CBJMS"; + case "weapon_tar21": + return &"ALIEN_PICKUPS_BEACON_LOCKER_MICROTAR"; + case "weapon_honeybadger": + return &"ALIEN_PICKUPS_BEACON_LOCKER_HONEYBADGER"; + case "weapon_arx_160": + return &"ALIEN_PICKUPS_BEACON_LOCKER_ARX_160"; + case "weapon_lsat_iw6": + return &"ALIEN_PICKUPS_BEACON_LOCKER_LSAT"; + case "weapon_dragunov_svu": + return &"ALIEN_PICKUPS_BEACON_LOCKER_SVU"; + case "weapon_evopro": + return &"ALIEN_PICKUPS_BEACON_LOCKER_RIPPER"; + default: + return &"ALIEN_PILLAGE_LOCKER_PICKUP_LOCKER_WEAPON"; + } +} + +watch_cinematic_use( var_0, var_1, var_2, var_3 ) +{ + if ( !isdefined( var_0 ) ) + return; + + level waittill( var_1 ); + preloadcinematicforall( var_0 ); + level waittill( var_2 ); + playcinematicforall( var_0 ); + level waittill( var_3 ); + stopcinematicforall(); +} + +mp_alien_beacon_intro_ride() +{ + level thread intro_boat_ride(); + maps\mp\alien\_hive::regular_hive(); +} + +intro_boat_ride() +{ + common_scripts\utility::flag_init( "boat_ride_over" ); + thread maps\mp\mp_alien_beacon_vignettes::drill_swap(); + level.boat_vehicle = getent( "intro_hovercraft", "targetname" ); + var_0 = getent( "hovercraft_clip", "targetname" ); + var_0 linkto( level.boat_vehicle ); + var_1 = getent( "hovercraft_back_clip", "targetname" ); + var_1 notsolid(); + var_2 = getent( "hovercraft_clip_gate", "targetname" ); + var_2 linkto( level.boat_vehicle ); + level.boat_vehicle.spawn_locations = []; + + for ( var_3 = 0; var_3 < 4; var_3++ ) + { + level.boat_vehicle.spawn_locations[var_3] = getent( "beacon_hovercraft_spot" + ( var_3 + 1 ), "targetname" ); + level.boat_vehicle.spawn_locations[var_3] linkto( level.boat_vehicle ); + } + + foreach ( var_3, var_5 in level.players ) + { + var_6 = getent( "beacon_hovercraft_spot" + ( var_3 + 1 ), "targetname" ); + var_6.used_spot = 1; + var_5 setorigin( var_6.origin ); + var_5 setplayerangles( var_6.angles ); + } + + wait 0.5; + level.boat_vehicle scriptmodelplayanimdeltamotion( "alien_beacon_intro_hovercraft" ); + thread maps\mp\mp_alien_beacon_vignettes::boat_ride_vo(); + thread maps\mp\mp_alien_beacon_fx::fx_boatride_splashes(); + thread maps\mp\mp_alien_beacon_fx::fx_raindrops_screenfx_intro(); + wait 5; + level.boat_vehicle thread beacon_play_sound_on_moving_tag( "scn_beacon_intro_fan_left", "J_LE_Fan", 26 ); + level.boat_vehicle thread beacon_play_sound_on_moving_tag( "scn_beacon_intro_fan_right", "J_RI_Fan", 26 ); + wait 21; + var_2 delete(); + wait 2.33; + common_scripts\utility::flag_set( "boat_ride_over" ); + thread update_override_info( ( -281, -2645, 0.124998 ), ( 0, 90, 0 ) ); + common_scripts\utility::flag_set( "give_player_abilities" ); + var_1 solid(); + + foreach ( var_6 in level.boat_vehicle.spawn_locations ) + var_6 delete(); + + var_0 delete(); +} + +boat_intro_on_connect( var_0, var_1 ) +{ + var_2 = undefined; + + foreach ( var_4 in level.boat_vehicle.spawn_locations ) + { + if ( !isdefined( var_4.used_spot ) ) + { + var_2 = var_4; + var_4.used_spot = 1; + break; + } + } + + if ( !isdefined( var_2 ) ) + { + foreach ( var_4 in level.boat_vehicle.spawn_locations ) + var_4.used_node = undefined; + + var_2 = level.boat_vehicle.spawn_locations[1]; + var_2.usedspot = 1; + } + + wait 0.1; + var_0 setorigin( var_2.origin + ( 0, 0, 0 ) ); + var_0 setplayerangles( var_2.angles ); + wait 0.05; + var_0 playerlinkto( var_2 ); + wait 0.2; + var_0 unlink(); +} + +collision_test() +{ + self waittill( "unresolved_collision" ); +} + +hives_2_custom() +{ + maps\mp\alien\_hive::regular_hive(); +} + +hives_3_custom() +{ + thread maps\mp\mp_alien_beacon_vignettes::mini_boss(); + maps\mp\alien\_hive::regular_hive( ::get_mini_boss_score_component_list ); + thread update_override_info( ( -1300, 437, -127.875 ), ( 0, 0, 0 ) ); + level notify( "miniboss_retreat" ); + level.miniboss_beaten = 1; + thread maps\mp\mp_alien_beacon_vignettes::post_miniboss_vo(); + maps\mp\alien\_achievement_dlc2::update_blocker_achievements( "tentacle_fight" ); + + foreach ( var_1 in level.players ) + var_1 maps\mp\alien\_persistence::try_award_bonus_pool_token(); + + if ( maps\mp\alien\_utility::isplayingsolo() && !issplitscreen() ) + maps\mp\alien\_laststand::give_laststand( level.players[0], 1 ); +} + +get_mini_boss_score_component_list() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + return [ "drill", "personal", "challenge", "tentacle_bonus" ]; + else + return [ "drill", "team", "personal", "challenge", "tentacle_bonus" ]; +} + +first_cargo_hive() +{ + level thread maps\mp\mp_alien_beacon_vignettes::cargo_room_intro_vo(); + cargo_hive(); + thread update_override_info( ( -742, 1258, 136.125 ), ( 0, 90, 0 ) ); +} + +pre_hive() +{ + if ( level.current_hive_name == "cargo_area_mini_3" ) + return 23; + + return level.cycle_count; +} + +cargo_hive() +{ + maps\mp\alien\_hive::regular_hive(); + + if ( isdefined( level.icargohives ) ) + { + if ( level.icargohives == 1 ) + { + common_scripts\utility::flag_set( "delay_UGV_VO" ); + thread maps\mp\mp_alien_beacon_vignettes::cargo_room_hive_two_vo(); + level.icargohives++; + } + else if ( level.icargohives == 2 ) + { + level thread waypoint_after_drill_picked_up(); + level.icargohives++; + } + else + level.icargohives++; + } + + if ( level.current_hive_name == "cargo_area_mini_2_post" ) + { + wait 5; + spawn_beacon_cargo_drillbot(); + var_0 = undefined; + level thread use_drillbot_door( var_0, getent( "cargo_bot_entrance_door", "targetname" ) ); + wait 3; + level.drillbot_door_open = 1; + } + + level maps\mp\mp_alien_beacon_vignettes::set_up_blast_doors(); + + if ( level.current_hive_name == "cargo_area_mini_1_post" || level.current_hive_name == "cargo_area_mini_2_post" || level.current_hive_name == "cargo_area_mini_3_post" || level.current_hive_name == "cargo_area_mini_4_post" || level.current_hive_name == "cargo_area_mini_5_post" || level.current_hive_name == "cargo_area_mini_6_post" ) + level.blast_doors_lifted++; + + if ( level.current_hive_name == "cargo_area_mini_2_post" ) + level thread maps\mp\mp_alien_beacon_vignettes::cargo_room_use_ugv_vo(); + + if ( level.blast_doors_lifted > 3 && !common_scripts\utility::flag( "cargo_control_room_vo_played" ) ) + level thread maps\mp\mp_alien_beacon_vignettes::cargo_room_go_to_control_room_vo(); + + level thread spawn_elites_from_container(); +} + +cargo_blocker_door_setup() +{ + level.custom_hive_logic = ::beacon_cargo_hive_logic; + level.hive_is_really_a_door = 1; +} + +beacon_cargo_hive_logic() +{ + level notify( "drill_start_door_fx", 180 ); + level.drill scriptmodelplayanim( "alien_drill_open_door_long" ); + level thread beacon_cargo_hive_think(); +} + +beacon_cargo_hive_think() +{ + common_scripts\utility::flag_wait( "drill_detonated" ); + wait 10; + level.custom_hive_logic = undefined; + level.hive_is_really_a_door = undefined; +} + +top_deck_hive_01() +{ + thread maps\mp\mp_alien_beacon_vignettes::init_cinematics( "mp_beacon_archer_vig", 60 ); + thread raise_cargo_container(); + thread wait_for_players_reach_waypoint(); + maps\mp\alien\_hive::regular_hive(); +} + +wait_for_players_reach_waypoint() +{ + var_0 = "waypoint_alien_blocker"; + var_1 = 14; + var_2 = 14; + var_3 = 0.75; + var_4 = ( -252, 1139, 340 ); + var_5 = 60; + var_6 = 128; + var_7 = 100; + var_8 = maps\mp\alien\_hud::make_waypoint( var_0, var_1, var_2, var_3, var_4 ); + var_9 = spawn( "trigger_radius", var_4, 0, var_6, var_7 ); + var_9 watch_trigger_by_player(); + var_9 delete(); + var_8 destroy(); +} + +watch_trigger_by_player() +{ + self endon( "death" ); + level endon( "game_ended" ); + common_scripts\utility::waitframe(); + + for (;;) + { + self waittill( "trigger", var_0 ); + + if ( isplayer( var_0 ) ) + break; + } + + self notify( "trigger_by_player" ); +} + +final_deck_hive() +{ + maps\mp\alien\_hive::regular_hive(); + var_0 = []; + var_0 = getentarray( "deck_to_lab_door", "targetname" ); + var_1 = getent( "deck_to_lab_door_linker", "targetname" ); + + foreach ( var_3 in var_0 ) + { + if ( isdefined( var_3 ) && isdefined( var_1 ) ) + var_3 linkto( var_1 ); + } + + var_5 = getentarray( "top_deck_mini_1", "targetname" ); + + foreach ( var_7 in var_5 ) + { + if ( var_7.classname == "script_brushmodel" ) + var_7 delete(); + } + + var_1 movez( 92, 5, 0, 1 ); + thread maps\mp\mp_alien_beacon_vignettes::lab_entrance_vo(); + + if ( maps\mp\alien\_utility::isplayingsolo() && !issplitscreen() ) + maps\mp\alien\_laststand::give_laststand( level.players[0], 1 ); + + thread update_override_info( ( 264, 4232, 1152.13 ), ( 0, 130, 0 ) ); +} + +first_lab_hive() +{ + maps\mp\alien\_hive::regular_hive(); + thread maps\mp\mp_alien_beacon_vignettes::lab_first_hive_vo(); +} + +second_lab_hive() +{ + maps\mp\alien\_hive::regular_hive(); + thread maps\mp\mp_alien_beacon_vignettes::lab_second_hive_vo(); +} + +third_lab_hive() +{ + maps\mp\alien\_hive::regular_hive(); +} + +mp_alien_beacon_cargo_blocker_hive() +{ + generic_blocker_hive_logic( "cargo_blocker_dead" ); +} + +mp_alien_beacon_top_deck_hive() +{ + disable_lab_doors(); + maps\mp\alien\_gamescore::reset_encounter_performance(); + maps\mp\mp_alien_beacon_vignettes::setup_gas_encounter(); + give_gas_encounter_rewards(); + common_scripts\utility::flag_set( "top_deck_blocker_dead" ); + common_scripts\utility::flag_set( "boss_turrets_on" ); + var_0 = getent( "player128x128x128", "targetname" ); + + if ( isdefined( var_0 ) ) + { + var_0 moveto( ( -136.5, 6465.5, 1444 ), 0.05 ); + var_0.angles = ( 0, 0, 0 ); + } +} + +give_gas_encounter_rewards() +{ + var_0 = get_gas_encounter_score_components(); + maps\mp\alien\_gamescore::calculate_and_show_encounter_scores( level.players, var_0 ); + + foreach ( var_2 in level.players ) + { + var_2 maps\mp\alien\_persistence::eog_player_update_stat( "hivesdestroyed", 1 ); + var_2 thread maps\mp\alien\_hive::wait_to_give_rewards(); + } +} + +get_gas_encounter_score_components() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + return [ "gas", "personal" ]; + else + return [ "gas", "team", "personal" ]; +} + +mp_alien_beacon_story_moment() +{ + +} + +mp_alien_beacon_boss_encounter() +{ + var_0 = getent( "boss_trigger", "targetname" ); + var_0 waittill( "trigger" ); + setdvar( "sm_sunSampleSizeNear", 0.7 ); + level thread clean_aliens_for_kraken(); + wait 2; + level notify( "stop_teleport_script" ); + common_scripts\utility::flag_set( "tp_to_kraken_on_spawn" ); + update_override_info( ( -125.5, 7012.5, 1152.13 ), ( 0, 0, 0 ) ); + level thread gather_ye_players_for_kraken(); + wait 1.0; + level notify( "stop_drill_teleport_script" ); + level.blocker_hive_active = 1; + maps\mp\agents\alien\alien_kraken\_alien_kraken::initkraken(); + maps\mp\agents\alien\alien_kraken\_alien_kraken_tentacle::initkrakententacle(); + thread play_kraken_intro_music(); + wait 5.0; + var_1 = common_scripts\utility::getstruct( "kraken_position_1", "targetname" ); + level.kraken = maps\mp\agents\alien\alien_kraken\_alien_kraken::alienkrakenspawn( var_1.origin, var_1.angles ); + level.kraken maps\mp\agents\alien\alien_kraken\_alien_kraken::attachtentacles(); + level.kraken.feral_occludes = 1; + level.kraken attach( "fx_kraken_bones_jaw" ); + level.kraken attach( "fx_kraken_bones_helmet" ); + common_scripts\utility::flag_set( "boss_is_spawned" ); + level thread listen_for_emerge_phase(); + level thread kraken_start_cycle( 1 ); + maps\mp\alien\_gamescore::reset_encounter_performance(); + var_2 = gettime(); + level.kraken maps\mp\agents\alien\alien_kraken\_alien_kraken::alienkrakenthink(); + var_3 = gettime() - var_2; + update_lb_aliensession_final_kraken( var_3 ); + maps\mp\alien\_gamescore_beacon::calculate_kraken_score( var_3 ); + maps\mp\alien\_achievement_dlc2::update_blocker_achievements( "kraken", var_3 ); + maps\mp\mp_alien_beacon_vignettes::post_boss_vo(); + + if ( !maps\mp\alien\_utility::is_casual_mode() ) + set_players_escaped(); + + give_players_completion_tokens(); + maps\mp\alien\_unlock::update_escape_item_unlock( level.players ); + var_4 = get_win_condition(); + var_5 = maps\mp\alien\_hud::get_end_game_string_index( var_4 ); + level maps\mp\_utility::delaythread( 3, maps\mp\gametypes\aliens::alienendgame, "allies", var_5 ); +} + +gather_ye_players_for_kraken() +{ + level endon( "game_ended" ); + + foreach ( var_1 in level.kraken_turrets ) + { + if ( var_1.origin[1] < 6500 ) + { + var_1.overloaded = 1; + var_1 notify( "disable_turret" ); + var_1.use_trigger notify( "turret_is_broken" ); + var_1.use_trigger maps\mp\alien\mp_alien_beacon_turret::turret_is_broken( var_1 ); + } + } + + wait 1; + + for (;;) + { + foreach ( var_4 in level.players ) + { + var_5 = var_4; + + if ( isdefined( var_4.reviveent ) ) + var_5 = var_4.reviveent; + + if ( var_5.origin[1] < 6640 ) + { + var_4 teleport_player_to_boss_fight( var_5 ); + wait 0.1; + } + } + + wait 0.25; + } +} + +clean_aliens_for_kraken() +{ + var_0 = []; + var_1 = getentarray( "spawn_zone", "targetname" ); + + foreach ( var_3 in var_1 ) + { + if ( issubstr( var_3.script_linkname, "spawn_9" ) || issubstr( var_3.script_linkname, "spawn_10" ) || issubstr( var_3.script_linkname, "spawn_11" ) || issubstr( var_3.script_linkname, "spawn_12" ) || issubstr( var_3.script_linkname, "spawn_13" ) ) + var_0[var_0.size] = var_3; + } + + var_5 = maps\mp\alien\_spawnlogic::get_alive_agents(); + + foreach ( var_7 in var_5 ) + { + var_8 = 0; + + foreach ( var_3 in var_0 ) + { + if ( var_7 istouching( var_3 ) ) + var_8 = 1; + } + + if ( !var_8 ) + var_7 suicide(); + } +} + +teleport_player_to_boss_fight( var_0 ) +{ + var_1 = []; + var_1[0] = ( -125.5, 7012.5, 1165.5 ); + var_1[1] = ( -63, 7012.5, 1165.5 ); + var_1[2] = ( 1, 7012.5, 1165.5 ); + var_1[3] = ( 64.5, 7012.5, 1165.5 ); + var_2 = ( 0, 0, 0 ); + var_3 = 0; + + while ( !var_3 ) + { + foreach ( var_5 in var_1 ) + { + if ( canspawn( var_5 ) && !positionwouldtelefrag( var_5 ) ) + { + if ( !isdefined( self.teleport_overlay ) ) + { + thread teleport_black_screen(); + wait 1; + } + + if ( canspawn( var_5 ) && !positionwouldtelefrag( var_5 ) ) + { + if ( isdefined( var_0 ) && var_0 != self ) + teleport_player_to_spot( var_5, var_0 ); + else + teleport_player_to_spot( var_5 ); + + var_3 = 1; + break; + } + else + continue; + } + } + + wait 0.1; + } + + self notify( "player_teleported" ); +} + +beacon_player_initial_spawn_loc_override() +{ + if ( maps\mp\alien\_utility::is_chaos_mode() ) + chaos_player_initial_spawn_loc_override(); + else + regular_player_initial_spawn_loc_override(); +} + +regular_player_initial_spawn_loc_override() +{ + if ( !isdefined( level.currentspawnoriginoverride ) ) + return; + + if ( !isdefined( level.currentspawnanglesoverride ) ) + level.currentspawnanglesoverride = ( 0, 0, 0 ); + + self.forcespawnorigin = level.currentspawnoriginoverride; + self.forcespawnangles = level.currentspawnanglesoverride; +} + +chaos_player_initial_spawn_loc_override() +{ + var_0 = []; + var_1 = []; + + switch ( maps\mp\alien\_utility::get_chaos_area() ) + { + case "cargo": + var_0 = [ ( 1011, 1649, 145 ), ( 982, 1783, 145 ), ( -1547, 1765, 145 ), ( -1542, 1637, 145 ) ]; + var_1 = [ ( 0, 180, 0 ), ( 0, 180, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ) ]; + break; + } + + self.forcespawnorigin = var_0[level.players.size]; + self.forcespawnangles = var_1[level.players.size]; +} + +update_override_info( var_0, var_1 ) +{ + var_2 = common_scripts\utility::drop_to_ground( var_0, 5, -100 ); + level.currentspawnoriginoverride = var_0; + level.currentspawnanglesoverride = var_1; +} + +set_players_escaped() +{ + foreach ( var_1 in level.players ) + var_1 maps\mp\alien\_persistence::set_player_escaped(); +} + +give_players_completion_tokens() +{ + foreach ( var_1 in level.players ) + var_1 maps\mp\alien\_persistence::award_completion_tokens(); +} + +get_win_condition() +{ + foreach ( var_1 in level.players ) + { + if ( maps\mp\alien\_utility::is_true( var_1.inlaststand ) ) + return "some_escape"; + } + + return "all_escape"; +} + +play_kraken_intro_music() +{ + foreach ( var_1 in level.players ) + { + if ( common_scripts\utility::flag( "alien_music_playing" ) ) + { + var_1 stoplocalsound( "mp_suspense_01" ); + var_1 stoplocalsound( "mp_suspense_02" ); + var_1 stoplocalsound( "mp_suspense_03" ); + var_1 stoplocalsound( "mp_suspense_04" ); + var_1 stoplocalsound( "mp_suspense_05" ); + var_1 stoplocalsound( "mp_suspense_06" ); + var_1 stoplocalsound( "mus_alien_newwave" ); + var_1 stoplocalsound( "mus_alien_queen" ); + common_scripts\utility::flag_clear( "alien_music_playing" ); + } + + if ( !common_scripts\utility::flag( "exfil_music_playing" ) ) + level thread maps\mp\alien\_music_and_dialog::play_alien_music( "mus_alien_dlc2_kraken" ); + } +} + +kraken_start_cycle( var_0 ) +{ + +} + +update_lb_aliensession_final_kraken( var_0 ) +{ + var_1 = get_lb_final_kraken_rank( var_0 ); + + foreach ( var_3 in level.players ) + { + var_3 maps\mp\alien\_persistence::lb_player_update_stat( "escapedRank" + var_1, 1, 1 ); + var_3 maps\mp\alien\_persistence::lb_player_update_stat( "hits", 1, 1 ); + } +} + +get_lb_final_kraken_rank( var_0 ) +{ + var_1 = 555000; + var_2 = 630000; + var_3 = 750000; + + if ( var_0 <= var_1 ) + return 0; + else if ( var_0 <= var_2 ) + return 1; + else if ( var_0 <= var_3 ) + return 2; + else + return 3; +} + +generic_blocker_hive_logic( var_0 ) +{ + level endon( "game_ended" ); + var_1 = maps\mp\alien\_hive::select_hives( 1 ); + var_2 = var_1[0]; + var_3 = maps\mp\alien\_hive::create_attackable_ent( var_2 ); + var_2.attackable_ent = var_3; + level.current_blocker_hive = var_2; + level.encounter_name = var_2.target; + level thread maps\mp\alien\_spawnlogic::encounter_cycle_spawn( "blocker_hive_heli_inbound" ); + setomnvar( "ui_alien_boss_status", 2 ); + setomnvar( "ui_alien_boss_progression", 0 ); + var_3 show(); + var_3 setcandamage( 1 ); + var_3 thread maps\mp\alien\_hud::blocker_hive_hp_bar(); + var_3 thread maps\mp\alien\_hive::monitor_attackable_ent_damage( var_2 ); + var_3 waittill( "death" ); + common_scripts\utility::flag_set( var_0 ); + maps\mp\alien\_spawn_director::end_cycle(); + level.encounter_name = undefined; + maps\mp\alien\_hive::blocker_hive_explode_sequence( var_3, var_2 ); + maps\mp\alien\_hive::give_players_rewards( 1 ); +} + +mp_alien_beacon_attackable_ent_override( var_0 ) +{ + if ( maps\mp\alien\_hive::get_blocker_hive_index() == 1 ) + { + var_0.health = 10000; + var_0.maxhealth = 10000; + } + else + { + var_0.health = 15000; + var_0.maxhealth = 15000; + } + + if ( maps\mp\alien\_utility::isplayingsolo() ) + { + var_0.health = int( 0.66 * var_0.health ); + var_0.maxhealth = int( 0.66 * var_0.maxhealth ); + } + + return var_0; +} + +init_level_flags() +{ + common_scripts\utility::flag_init( "cargo_blocker_dead" ); + common_scripts\utility::flag_init( "top_deck_blocker_dead" ); +} + +beacon_enter_area_func( var_0 ) +{ + if ( !maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_container_spawn::activate_container_spawners_in_area( var_0 ); +} + +beacon_leave_area_func( var_0 ) +{ + if ( !maps\mp\alien\_utility::is_chaos_mode() ) + maps\mp\alien\_container_spawn::deactivate_container_spawners_in_area( var_0 ); +} + +init_container_spawn() +{ + maps\mp\alien\_container_spawn::init_container_spawn(); + level.should_skip_area_activation_func = ::should_skip_area_activation; + var_0 = []; + level thread maps\mp\alien\_container_spawn::container_spawn_hive_monitor( var_0 ); +} + +should_skip_area_activation( var_0 ) +{ + var_1 = []; + return common_scripts\utility::array_contains( var_1, var_0 ); +} + +spawn_elites_from_container() +{ + var_0 = 0; + + while ( !var_0 ) + { + level waittill( "drill_planted" ); + + if ( level.current_hive_name == "cargo_area_main" ) + { + var_0 = 1; + lower_cargo_container(); + wait 1.0; + level thread notify_and_remove_door( "container_3_spawn_1", "cargo_container_3_door_01" ); + wait 0.5; + + if ( maps\mp\alien\_utility::isplayingsolo() ) + { + level thread notify_and_remove_door( "fake_notify", "cargo_container_3_door_02" ); + continue; + } + + level thread notify_and_remove_door( "container_3_spawn_2", "cargo_container_3_door_02" ); + } + } +} + +notify_and_remove_door( var_0, var_1 ) +{ + var_2 = getent( var_1 + "_start", "targetname" ); + common_scripts\utility::waitframe(); + var_3 = getent( var_1, "targetname" ); + + if ( maps\mp\alien\_utility::isplayingsolo() ) + var_3 setscriptablepartstate( 0, 1 ); + else + var_3 setscriptablepartstate( 0, 4 ); + + common_scripts\utility::waitframe(); + + if ( isdefined( var_2 ) ) + var_2 delete(); + + level notify( var_0 ); +} + +jump_to_well_deck_1() +{ + +} + +jump_to_well_deck_2() +{ + +} + +jump_to_mini_boss() +{ + +} + +jump_to_cargo_area() +{ + +} + +jump_to_cargo_blocker() +{ + +} + +jump_to_top_deck() +{ + +} + +jump_to_lab_area() +{ + +} + +jump_to_lab_blocker() +{ + +} + +jump_to_boss_area() +{ + +} + +set_spawn_table() +{ + if ( maps\mp\alien\_utility::is_chaos_mode() ) + set_chaos_spawn_table(); + else + { + if ( maps\mp\alien\_utility::is_hardcore_mode() ) + { + set_hardcore_extinction_spawn_table(); + return; + } + + set_regular_extinction_spawn_table(); + } +} + +set_container_spawn_table() +{ + if ( maps\mp\alien\_utility::is_hardcore_mode() ) + set_hardcore_container_spawn_table(); + else + set_regular_container_spawn_table(); +} + +set_alien_definition_table() +{ + if ( maps\mp\alien\_utility::is_hardcore_mode() ) + set_hardcore_alien_definition_table(); + else + set_regular_alien_definition_table(); +} + +set_chaos_spawn_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + { + switch ( maps\mp\alien\_utility::get_chaos_area() ) + { + case "welldeck": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_welldeck_sp.csv"; + break; + case "cargo": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_cargo_sp.csv"; + break; + case "lab": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_lab_sp.csv"; + break; + } + } + else + { + switch ( maps\mp\alien\_utility::get_chaos_area() ) + { + case "welldeck": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_welldeck_mp.csv"; + break; + case "cargo": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_cargo_mp.csv"; + break; + case "lab": + level.alien_cycle_table = "mp/alien/chaos_spawn_beacon_lab_mp.csv"; + break; + } + } +} + +set_regular_extinction_spawn_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.alien_cycle_table = "mp/alien/cycle_spawn_beacon_sp.csv"; + else + level.alien_cycle_table = "mp/alien/cycle_spawn_beacon_mp.csv"; +} + +set_regular_container_spawn_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.container_spawn_table = "mp/alien/beacon_container_spawn_sp.csv"; + else + level.container_spawn_table = "mp/alien/beacon_container_spawn.csv"; +} + +set_regular_alien_definition_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.default_alien_definition = "mp/alien/beacon_alien_definition_sp.csv"; + else + level.default_alien_definition = "mp/alien/beacon_alien_definition.csv"; +} + +chaos_init() +{ + maps\mp\alien\_hive::init_hive_locs(); + maps\mp\alien\_chaos::init(); + register_egg_default_loc(); + set_end_cam_position(); + thread player_containment(); +} + +player_containment() +{ + level waittill( "spawn_nondeterministic_entities" ); + var_0 = spawn( "script_model", ( -674, 765, 136 ) ); + var_0 setmodel( "beacon_single_sliding_door_left" ); + var_0.angles = ( 0, 0, 0 ); + var_1 = spawn( "script_model", ( -742, 765, 136 ) ); + var_1 setmodel( "beacon_single_sliding_door_left" ); + var_1.angles = ( 0, 0, 0 ); + var_2 = getent( "player256x256x8", "targetname" ); + var_2.origin = ( -745, 760, 120 ); + var_2.angles = ( 270, 270, 0 ); + var_3 = spawn( "script_model", ( -410.3, 785, 280 ) ); + var_3 setmodel( "armory_weapon_chest" ); + var_3.angles = ( 0, 180, 0 ); + var_4 = getent( "player512x512x8", "targetname" ); + + if ( isdefined( var_4 ) ) + { + var_4.origin = ( 752, 3398, 64 ); + var_4.angles = ( 270, 180, 180 ); + var_5 = spawn( "script_model", ( 842, 3218, 440 ) ); + var_5 clonebrushmodeltoscriptmodel( var_4 ); + var_5.origin = ( 842, 3218, 440 ); + var_5.angles = ( 270, 180, 180 ); + } + + var_6 = getent( "monsterplayer512x512x8", "targetname" ); + + if ( isdefined( var_6 ) ) + { + var_6.origin = ( 1098, 3046, 440 ); + var_6.angles = ( 270, 270, -180 ); + var_7 = spawn( "script_model", ( 891, 3038, 184 ) ); + var_7 setmodel( "tool_cabinet_02_iw6" ); + var_7.angles = ( 0, 180, 0 ); + } +} + +set_end_cam_position() +{ + var_0 = getentarray( "mp_global_intermission", "classname" ); + var_1 = common_scripts\utility::getclosest( level.eggs_default_loc, var_0 ); + + switch ( maps\mp\alien\_utility::get_chaos_area() ) + { + case "welldeck": + var_1.origin = ( 264, 3012, 492 ); + var_1.angles = ( 15, 225, 0 ); + break; + case "cargo": + var_1.origin = ( 264, 3012, 492 ); + var_1.angles = ( 15, 225, 0 ); + break; + case "lab": + var_1.origin = ( 264, 3012, 492 ); + var_1.angles = ( 15, 225, 0 ); + break; + } +} + +register_egg_default_loc() +{ + switch ( maps\mp\alien\_utility::get_chaos_area() ) + { + case "welldeck": + maps\mp\alien\_chaos::set_egg_default_loc( ( -116, 2240, -1264 ) ); + break; + case "cargo": + maps\mp\alien\_chaos::set_egg_default_loc( ( -116, 2240, -1264 ) ); + break; + case "lab": + maps\mp\alien\_chaos::set_egg_default_loc( ( -116, 2240, -1264 ) ); + break; + } +} + +set_hardcore_extinction_spawn_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.alien_cycle_table_hardcore = "mp/alien/cycle_spawn_beacon_hardcore_sp.csv"; + else + level.alien_cycle_table_hardcore = "mp/alien/cycle_spawn_beacon_hardcore_mp.csv"; +} + +set_hardcore_container_spawn_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.container_spawn_table = "mp/alien/beacon_container_spawn_hardcore_sp.csv"; + else + level.container_spawn_table = "mp/alien/beacon_container_spawn_hardcore.csv"; +} + +set_hardcore_alien_definition_table() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + level.default_alien_definition = "mp/alien/beacon_alien_definition_hardcore_sp.csv"; + else + level.default_alien_definition = "mp/alien/beacon_alien_definition_hardcore_mp.csv"; +} + +beacon_door_encounter_logic() +{ + level endon( "game_ended" ); + + for (;;) + { + level waittill( "start_spawn_event", var_0 ); + var_1 = var_0 + "_" + randomintrange( 1, 4 ); + maps\mp\alien\_spawn_director::activate_spawn_event( var_1 ); + } +} + +lower_cargo_container() +{ + var_0 = 5; + wait 4; + var_1 = getent( "beacon_crane_top", "targetname" ); + var_2 = getent( "beacon_crane_bottom", "targetname" ); + var_1 scriptmodelplayanimdeltamotion( "alien_beacon_crane_enter_base" ); + var_2 scriptmodelplayanim( "alien_beacon_crane_enter_base" ); + var_3 = getent( "cargo_container_3_door_01_start", "targetname" ); + var_4 = getent( "cargo_container_3_door_02_start", "targetname" ); + var_5 = getent( "crane_sound_origin_1", "targetname" ); + var_6 = getent( "crane_sound_origin_2", "targetname" ); + var_7 = getentarray( "crane_container_top_bad_place", "targetname" ); + var_8 = getentarray( "move_container_clip", "targetname" ); + var_9 = getentarray( "move_container", "targetname" ); + var_9 = common_scripts\utility::add_to_array( var_9, var_3 ); + var_9 = common_scripts\utility::add_to_array( var_9, var_4 ); + var_9 = common_scripts\utility::add_to_array( var_9, var_5 ); + var_9 = common_scripts\utility::add_to_array( var_9, var_6 ); + var_9 = common_scripts\utility::array_combine( var_9, var_8 ); + var_9 = common_scripts\utility::array_combine( var_9, var_7 ); + + foreach ( var_11 in var_9 ) + var_11 linkto( var_1, "j_Base_Wire_07" ); + + var_13 = getent( "crane_container_bad_place", "targetname" ); + badplace_brush( "crane_lower_spot", 0, var_13, "axis" ); + var_4 thread lower_cargo_container_sfx(); + wait( var_0 + 1 ); + badplace_delete( "crane_lower_spot" ); + + if ( isdefined( var_13 ) ) + var_13 delete(); + + foreach ( var_11 in var_9 ) + var_11 unlink(); + + foreach ( var_17 in var_7 ) + var_17 disconnectpaths(); +} + +lower_cargo_container_sfx() +{ + wait 0.02; + self playsoundonmovingent( "scn_beacon_crane_down" ); +} + +raise_cargo_container_sfx( var_0 ) +{ + wait 0.04; + var_1 = lookupsoundlength( var_0 ); + self playsoundonmovingent( var_0 ); + wait( var_1 / 1000 + 1 ); + self unlink(); + self delete(); +} + +raise_cargo_container() +{ + var_0 = getent( "cargo_room_control_switch", "targetname" ); + var_0 sethintstring( &"MP_ALIEN_BEACON_CRANE_HINT" ); + var_1 = getent( var_0.target, "targetname" ); + maps\mp\alien\_outline_proto::add_to_outline_watch_list( var_1, 0 ); + var_0 waittill( "trigger", var_2 ); + var_2 playlocalsound( "scn_drillbot_activate" ); + level notify( "trigger_first_archer_bink" ); + thread maps\mp\mp_alien_beacon_vignettes::nag_bink_toggle(); + var_0 makeunusable(); + thread maps\mp\mp_alien_beacon_vignettes::pre_crane_vo(); + maps\mp\alien\_outline_proto::remove_from_outline_watch_list( var_1 ); + wait 5; + var_3 = getent( "beacon_crane_top", "targetname" ); + var_4 = getent( "beacon_crane_bottom", "targetname" ); + var_5 = getentarray( "move_container_clip", "targetname" ); + var_6 = getentarray( "crane_container_top_bad_place", "targetname" ); + var_7 = getentarray( "move_container", "targetname" ); + var_8 = getent( "crane_tag", "targetname" ); + var_8.origin = var_3 gettagorigin( "j_Base_Wire_07" ); + var_8.angles = var_3 gettagangles( "j_Base_Wire_07" ); + var_9 = getent( "cargo_players_trigger", "targetname" ); + var_9 wait_for_players_to_enter_container( var_8 ); + var_9 thread update_player_in_container_status(); + + foreach ( var_11 in var_5 ) + var_11.unresolved_collision_func = ::crane_unresolved_collision; + + level notify( "crane_started" ); + common_scripts\utility::flag_set( "everyone_in_cargo_container" ); + level thread disable_cargo_door_drill_spots(); + level thread teleport_drill_to_container_if_needed(); + var_9 enablelinkto(); + var_9 linkto( var_8 ); + var_13 = getent( "crane_sound_origin_1", "targetname" ); + var_14 = getent( "crane_sound_origin_2", "targetname" ); + var_7 = common_scripts\utility::add_to_array( var_7, var_13 ); + var_7 = common_scripts\utility::add_to_array( var_7, var_14 ); + var_7 = common_scripts\utility::array_combine( var_7, var_6 ); + var_7 = common_scripts\utility::array_combine( var_7, var_5 ); + + foreach ( var_16 in var_7 ) + var_16 linkto( var_8 ); + + thread update_override_info( ( 659, 1494, 1024.13 ), ( 0, 90, 0 ) ); + maps\mp\_utility::delaythread( 30, ::crane_walls_hide, 1 ); + var_3 scriptmodelplayanimdeltamotion( "alien_beacon_crane_exit_base" ); + var_4 scriptmodelplayanim( "alien_beacon_crane_exit_base" ); + var_8 scriptmodelplayanimdeltamotion( "alien_beacon_crane_exit_top_tag" ); + var_13 thread raise_cargo_container_sfx( "scn_beacon_crane_up_01" ); + var_14 thread raise_cargo_container_sfx( "scn_beacon_crane_up_02" ); + thread crane_vo_waiter(); + level notify( "cinematic_end" ); + level notify( "godfathers_explanation" ); + wait 30; + maps\mp\alien\_achievement_dlc2::update_blocker_achievements( "blocker_cargo" ); + badplace_delete( "crane_lower_spot" ); + + foreach ( var_11 in var_6 ) + var_11 disconnectpaths(); + + level notify( "beacon_starting_topdeck" ); + common_scripts\utility::flag_set( "players_on_top_deck" ); + var_9 unlink(); + var_9 delete(); + level thread teleport_player_if_not_on_top_deck(); + maps\mp\_utility::delaythread( 1.0, ::teleport_drill_if_below_top_deck ); + level.watch_bomb_stuck_override = undefined; +} + +crane_unresolved_collision( var_0 ) +{ + var_0 thread teleport_player_to_top_deck( undefined ); +} + +crane_vo_waiter() +{ + var_0 = lookupsoundlength( "beacon_gdf_drcrosshasbeendesignated" ) / 1000; + wait( 30 - var_0 ); + thread maps\mp\mp_alien_beacon_vignettes::crane_vo(); +} + +disable_cargo_door_drill_spots() +{ + var_0 = []; + + foreach ( var_2 in level.stronghold_hive_locs ) + { + if ( isdefined( var_2.target ) && ( var_2.target == "door_hive_7" || var_2.target == "door_hive_8" ) ) + { + if ( isdefined( var_2.icon ) ) + var_2.icon destroy(); + + var_2 makeunusable(); + var_2 sethintstring( "" ); + var_2 notify( "stop_listening" ); + var_2.target = undefined; + var_0[var_0.size] = var_2; + } + } + + level.stronghold_hive_locs = common_scripts\utility::array_remove_array( level.stronghold_hive_locs, var_0 ); +} + +teleport_player_to_spot( var_0, var_1 ) +{ + self endon( "disconnect" ); + self cancelmantle(); + self dontinterpolate(); + self setorigin( var_0 ); + self.forceteleportorigin = var_0; + + if ( isdefined( var_1 ) ) + { + var_1.origin = var_0; + self.reviveiconent.origin = var_0; + } + + self notify( "teleport_finished" ); + + if ( isdefined( self.teleport_overlay ) ) + { + self.teleport_overlay fadeovertime( 0.75 ); + self.teleport_overlay.alpha = 0; + wait 1; + + if ( isdefined( self.teleport_overlay ) ) + self.teleport_overlay destroy(); + } + + maps\mp\_utility::clearlowermessage( "cargo_teleport" ); + + if ( isdefined( self.reviveent ) ) + thread wait_for_spawn_and_remove_forceteleport(); + else + self.forceteleportorigin = undefined; +} + +wait_for_spawn_and_remove_forceteleport() +{ + for (;;) + { + level waittill( "player_spawned", var_0 ); + + if ( self == var_0 ) + break; + } + + self.forceteleportorigin = undefined; +} + +teleport_black_screen() +{ + self endon( "disconnect" ); + maps\mp\_utility::setlowermessage( "cargo_teleport", &"MP_ALIEN_BEACON_CARGO_TELEPORT", 3 ); + self.teleport_overlay = newclienthudelem( self ); + self.teleport_overlay.x = 0; + self.teleport_overlay.y = 0; + self.teleport_overlay setshader( "black", 640, 480 ); + self.teleport_overlay.alignx = "left"; + self.teleport_overlay.aligny = "top"; + self.teleport_overlay.sort = 1; + self.teleport_overlay.horzalign = "fullscreen"; + self.teleport_overlay.vertalign = "fullscreen"; + self.teleport_overlay.alpha = 0; + self.teleport_overlay.foreground = 1; + self.teleport_overlay fadeovertime( 0.75 ); + self.teleport_overlay.alpha = 1; +} + +update_player_in_container_status() +{ + level endon( "beacon_starting_topdeck" ); + + for (;;) + { + foreach ( var_1 in level.players ) + { + if ( var_1 istouching( self ) ) + { + var_1.on_container = 1; + continue; + } + + var_1.on_container = 0; + } + + common_scripts\utility::waitframe(); + } +} + +teleport_drill_to_container_if_needed() +{ + level endon( "beacon_starting_topdeck" ); + level endon( "drill_planted" ); + + for (;;) + { + var_0 = 0; + var_1 = ( 432, 1487, 1033 ); + var_2 = ( 0, 0, 0 ); + + if ( isdefined( level.drill_linked_to_container ) ) + var_0 = 1; + + if ( isdefined( level.drill_carrier ) ) + { + foreach ( var_4 in level.players ) + { + if ( level.drill_carrier == var_4 ) + var_0 = 1; + } + } + + if ( !var_0 ) + { + level.drill.origin = var_1; + level.drill.angles = var_2; + level.drill maps\mp\alien\_drill::set_drill_icon(); + } + + wait 0.1; + } +} + +teleport_player_to_top_deck( var_0 ) +{ + var_1 = []; + var_1[0] = ( 260, 1487, 1043 ); + var_1[1] = ( 360, 1487, 1043 ); + var_1[2] = ( 260, 1387, 1043 ); + var_1[3] = ( 360, 1387, 1043 ); + var_2 = ( 0, 0, 0 ); + var_3 = 0; + + while ( !var_3 ) + { + foreach ( var_5 in var_1 ) + { + if ( canspawn( var_5 ) && !positionwouldtelefrag( var_5 ) ) + { + if ( !isdefined( self.teleport_overlay ) ) + { + thread teleport_black_screen(); + wait 1; + } + + if ( canspawn( var_5 ) && !positionwouldtelefrag( var_5 ) ) + { + if ( isdefined( var_0 ) && var_0 != self ) + teleport_player_to_spot( var_5, var_0 ); + else + teleport_player_to_spot( var_5 ); + + var_3 = 1; + break; + } + else + continue; + } + } + + wait 0.1; + } + + self notify( "player_teleported" ); +} + +teleport_player_if_not_on_top_deck() +{ + level endon( "stop_teleport_script" ); + + for (;;) + { + foreach ( var_1 in level.players ) + { + var_2 = var_1; + + if ( isdefined( var_1.reviveent ) ) + var_2 = var_1.reviveent; + + if ( !isdefined( var_1.forceteleportorigin ) && var_2.origin[2] < 1000 ) + { + var_1 thread teleport_player_to_top_deck( var_2 ); + wait 0.1; + } + } + + wait 0.25; + } +} + +teleport_drill_if_below_top_deck() +{ + level endon( "stop_drill_teleport_script" ); + var_0 = ( 432, 1487, 1033 ); + var_1 = ( 0, 0, 0 ); + + for (;;) + { + if ( isdefined( level.drill ) && level.drill.origin[2] < 1000 ) + { + level.drill.origin = var_0; + level.drill.angles = var_1; + level.drill maps\mp\alien\_drill::set_drill_icon(); + } + + wait 1.0; + } +} + +cargo_activate_crane_hint() +{ + level endon( "crane_activated" ); + iprintlnbold( "Activate the crane to progress" ); + wait 8; + iprintlnbold( "Activate the crane to progress" ); + wait 12; + iprintlnbold( "Activate the crane to progress" ); + wait 18; + iprintlnbold( "Activate the crane to progress" ); +} + +crane_walls_hide( var_0 ) +{ + var_1 = getentarray( "cargo_container_walls", "targetname" ); + + foreach ( var_3 in var_1 ) + var_3 notsolid(); + + if ( maps\mp\alien\_utility::is_true( var_0 ) ) + { + foreach ( var_3 in var_1 ) + var_3 delete(); + } +} + +crane_walls_show_and_link( var_0 ) +{ + var_1 = getentarray( "cargo_container_walls", "targetname" ); + + foreach ( var_3 in var_1 ) + { + var_3 solid(); + var_3 linkto( var_0 ); + } +} + +wait_for_players_to_enter_container( var_0 ) +{ + level.all_players_on_container = 0; + var_1 = "waypoint_alien_blocker"; + var_2 = 14; + var_3 = 14; + var_4 = 0.75; + var_5 = self.origin + ( 0, 0, 4 ); + var_6 = maps\mp\alien\_hud::make_waypoint( var_1, var_2, var_3, var_4, var_5 ); + + for (;;) + { + self waittill( "trigger", var_7 ); + + if ( !maps\mp\alien\_utility::is_true( var_7.on_container ) ) + var_7.on_container = 1; + + var_8 = 1; + var_9 = 0; + + foreach ( var_7 in level.players ) + { + if ( !var_7 isonground() || !maps\mp\alien\_utility::is_true( var_7.on_container ) || !var_7 istouching( self ) || distance( var_7.origin, var_0.origin ) > 125 ) + var_8 = 0; + + if ( isdefined( level.drill_carrier ) && level.drill_carrier == var_7 ) + var_9 = 1; + } + + if ( !( var_9 || isdefined( level.drill_linked_to_container ) ) ) + var_8 = 0; + + if ( var_8 ) + { + level.all_players_on_container = 1; + var_6 destroy(); + return; + } + } +} + +cargo_get_in_crane_hint() +{ + level endon( "crane_started" ); + iprintlnbold( "Everyone get in the lift container!" ); + wait 8; + iprintlnbold( "Everyone get in the lift container!" ); + wait 12; + iprintlnbold( "Everyone get in the lift container!" ); + wait 18; + iprintlnbold( "Everyone get in the lift container!" ); +} + +beacon_cargo_drill_onconnect() +{ + level endon( "game_ended" ); + + for (;;) + { + level waittill( "connected", var_0 ); + var_0 thread check_for_player_near_bot_with_drill(); + } +} + +beacon_play_sound_on_moving_tag( var_0, var_1, var_2 ) +{ + if ( isdefined( var_1 ) ) + { + var_3 = spawn( "script_model", ( 0, 0, 0 ) ); + var_3 linkto( self, var_1, ( 0, 0, 0 ), ( 0, 0, 0 ) ); + wait 0.1; + var_3 playsoundonmovingent( var_0 ); + + if ( isdefined( var_2 ) ) + wait( var_2 ); + else + wait 10; + + var_3 delete(); + } +} + +player_death_trigger_monitor() +{ + var_0 = getentarray( "player_drill_death", "targetname" ); + + foreach ( var_2 in var_0 ) + var_2 thread _death_trigger_monitor(); +} + +_death_trigger_monitor() +{ + for (;;) + { + self waittill( "trigger", var_0 ); + + if ( isplayer( var_0 ) ) + { + var_1 = self; + var_2 = self; + var_3 = 100; + var_4 = "MOD_TRIGGER_HURT"; + var_5 = undefined; + var_6 = self.origin; + var_7 = "none"; + var_8 = undefined; + var_0 maps\mp\alien\_death::onplayerkilled( var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ); + logprint( "!!PLAYER WAS KILLED BY TRIGGER!! : " + var_0.name + " killed by death trigger at: " + var_0.origin + "\\n" ); + } + } +} + +beacon_intro_music() +{ + for (;;) + { + level waittill( "connected", var_0 ); + var_0 thread beacon_intro_music_play(); + } +} + +beacon_intro_music_play() +{ + self waittill( "spawned_player" ); + + foreach ( var_1 in level.players ) + { + wait 0.01; + + if ( common_scripts\utility::flag_exist( "boat_ride_over" ) && !common_scripts\utility::flag( "boat_ride_over" ) ) + { + var_1 stoplocalsound( "us_spawn_music" ); + + if ( !level.splitscreen || level.splitscreen && !isdefined( level.playedbeaconstartingmusic ) ) + { + if ( !self issplitscreenplayer() || self issplitscreenplayerprimary() ) + level thread maps\mp\alien\_music_and_dialog::play_alien_music( "mus_alien_dlc2_beacon_intro" ); + + if ( level.splitscreen ) + level.playedbeaconstartingmusic = 1; + } + + continue; + } + + wait 0.1; + var_1 stoplocalsound( "us_spawn_music" ); + wait 0.1; + var_1 stoplocalsound( "us_spawn_music" ); + wait 0.1; + var_1 stoplocalsound( "us_spawn_music" ); + wait 0.1; + var_1 stoplocalsound( "us_spawn_music" ); + wait 0.1; + var_1 stoplocalsound( "us_spawn_music" ); + } +} + +mp_alien_beacon_drill_attack_override() +{ + if ( level.current_hive_name == "cargo_area_main" ) + { + cargo_blocker_door_setup(); + self.synch_attack_setup = undefined; + return; + } + + if ( level.current_hive_name != "cargo_area_mini_3" ) + return; + + var_0 = []; + var_0["brute"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_drill_attack_drill_R_enter", "alien_drill_attack_drill_R_loop", "alien_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" ); + var_0["brute"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_drill_attack_drill_L_enter", "alien_drill_attack_drill_L_loop", "alien_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" ); + var_0["goon"][0] = maps\mp\alien\_utility::set_attack_sync_direction( ( -1, 0, 0 ), "alien_goon_drill_attack_drill_R_enter", "alien_goon_drill_attack_drill_R_loop", "alien_goon_drill_attack_drill_R_exit", "attack_drill_right", "attack_drill" ); + var_0["goon"][1] = maps\mp\alien\_utility::set_attack_sync_direction( ( 1, 0, 0 ), "alien_goon_drill_attack_drill_L_enter", "alien_goon_drill_attack_drill_L_loop", "alien_goon_drill_attack_drill_L_exit", "attack_drill_left", "attack_drill" ); + var_1[0] = "offline"; + var_1[1] = "death"; + var_1[2] = "drill_complete"; + var_1[3] = "destroyed"; + maps\mp\alien\_utility::set_synch_attack_setup( var_0, 1, var_1, undefined, maps\mp\alien\_drill::drill_synch_attack_play_anim, maps\mp\alien\_drill::drill_synch_attack_play_anim, maps\mp\alien\_drill::drill_synch_attack_exit, "drill" ); +} + +beacon_weapon_stats_update_name( var_0 ) +{ + switch ( var_0 ) + { + case "iw6_altalienlsat_mp": + var_0 = "iw6_alienDLC12_mp"; + break; + case "iw6_altaliensvu_mp": + var_0 = "iw6_alienDLC13_mp"; + break; + case "iw6_altalienarx_mp": + var_0 = "iw6_alienDLC14_mp"; + break; + case "iw6_altalienmaverick_mp": + var_0 = "iw6_alienDLC15_mp"; + break; + default: + break; + } + + return var_0; +} + +beacon_specific_vo_callouts( var_0 ) +{ + var_0["beacon_vo"] = ::playbeaconvo; + var_0["start_containment"] = ::beacon_start_containment_vo; + var_0["warn_gas"] = ::beacon_warn_gas_vo; + var_0["warn_pipes"] = ::beacon_warn_pipes; + var_0["kraken_intro"] = ::playkrakenintrovo; + var_0["kraken_vo"] = ::playkrakenvo; + var_0["tentacle_gone"] = ::playkrakenvo; + var_0["warn_kraken_attack"] = ::playkrakenattackvo; + return var_0; +} + +playbeaconvo( var_0 ) +{ + if ( !isdefined( var_0 ) ) + return; + + var_1 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_1.size < 1 ) + return; + + var_2 = var_1[0]; + + if ( !soundexists( var_2.vo_prefix + var_0 ) ) + return; + + var_1 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_1.size < 1 ) + return; + + var_2 = var_1[0]; + var_3 = var_2.vo_prefix + var_0; + var_2 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_3 ); +} + +listen_for_emerge_phase() +{ + var_0 = 1; + + for (;;) + { + level waittill( "kraken_emerge_phase" ); + + if ( var_0 == 0 ) + { + level notify( "dlc_vo_notify", "kraken_vo", "kraken_port" ); + var_0 = 1; + } + else + { + level notify( "dlc_vo_notify", "kraken_vo", "kraken_starboard" ); + var_0 = 0; + } + + wait 5; + level notify( "dlc_vo_notify", "kraken_vo", "use_turrets" ); + } +} + +beacon_start_containment_vo() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + return; + + var_0 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_0.size < 1 ) + return; + + var_1 = var_0[0]; + var_0 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_0.size < 1 ) + return; + + var_1 = var_0[0]; + var_2 = var_1.vo_prefix + "start_containment"; + var_1 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_2 ); +} + +beacon_warn_gas_vo() +{ + if ( maps\mp\alien\_utility::isplayingsolo() ) + return; + + var_0 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_0.size < 1 ) + return; + + var_1 = var_0[0]; + + if ( isdefined( level.warn_gas ) && randomint( 100 ) > 10 ) + return; + + level.warn_gas = 1; + var_2 = var_1.vo_prefix + "warn_gas"; + var_1 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_2 ); +} + +beacon_warn_pipes( var_0 ) +{ + if ( !isdefined( var_0 ) ) + return; + + var_1 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_1.size < 1 ) + return; + + var_2 = var_1[0]; + + if ( !soundexists( var_2.vo_prefix + var_0 ) ) + return; + + var_3 = 15000; + var_4 = gettime(); + + if ( !isdefined( level.next_pipe_vo_time ) ) + level.next_pipe_vo_time = var_4 + randomintrange( var_3, var_3 + 2000 ); + else if ( var_4 < level.next_pipe_vo_time ) + return; + + level.next_pipe_vo_time = var_4 + randomintrange( var_3, var_3 + 1500 ); + var_5 = var_2.vo_prefix + var_0; + var_2 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_5 ); +} + +playkrakenintrovo() +{ + wait 1.0; + var_0 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_0.size < 1 ) + return; + + var_1 = var_0[0]; + var_2 = var_1.vo_prefix + "kraken_intro"; + var_1 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_2 ); +} + +playkrakenvo( var_0 ) +{ + if ( !isdefined( var_0 ) ) + return; + + var_1 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_1.size < 1 ) + return; + + var_2 = var_1[0]; + + if ( !soundexists( var_2.vo_prefix + var_0 ) ) + return; + + if ( var_0 == "warn_metal" ) + wait 5.0; + + if ( var_0 == "kraken_weak" ) + wait 5.0; + + if ( var_0 == "warn_emp" ) + wait 5.0; + + var_3 = var_2.vo_prefix + var_0; + var_2 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_3, "high", 10 ); +} + +playkrakenattackvo() +{ + var_0 = "warn_kraken_attack"; + + if ( !isdefined( var_0 ) ) + return; + + var_1 = maps\mp\alien\_utility::get_array_of_valid_players(); + + if ( var_1.size < 1 ) + return; + + var_2 = var_1[0]; + + if ( !soundexists( var_2.vo_prefix + var_0 ) ) + return; + + var_3 = 20000; + var_4 = gettime(); + + if ( !isdefined( level.next_kraken_attack_vo_time ) ) + level.next_kraken_attack_vo_time = var_4 + randomintrange( var_3, var_3 + 2000 ); + else if ( var_4 < level.next_kraken_attack_vo_time ) + return; + + level.next_kraken_attack_vo_time = var_4 + randomintrange( var_3, var_3 + 1500 ); + var_5 = var_2.vo_prefix + var_0; + var_2 maps\mp\alien\_music_and_dialog_dlc::play_vo_on_player( var_5, "high", 5 ); +} + +beacon_customprematchperiod() +{ + if ( !maps\mp\alien\_utility::is_true( level.introscreen_done ) ) + level.prematchperiod = 10; + + while ( level.players.size == 0 ) + wait 0.05; + + foreach ( var_1 in level.players ) + { + var_1 maps\mp\_utility::freezecontrolswrapper( 1 ); + var_1 disableweapons(); + } + + if ( !maps\mp\alien\_intro_sequence::intro_sequence_enabled() ) + { + wait 7; + level notify( "introscreen_over" ); + level.introscreen_done = 1; + level notify( "spawn_intro_drill" ); + + for ( var_3 = 0; var_3 < level.players.size; var_3++ ) + { + level.players[var_3] maps\mp\_utility::freezecontrolswrapper( 0 ); + level.players[var_3] enableweapons(); + + if ( !isdefined( level.players[var_3].pers["team"] ) ) + continue; + } + + return; + } + + if ( level.prematchperiod > 0 ) + { + var_1 = level wait_for_first_player_connect(); + + if ( maps\mp\alien\_intro_sequence::intro_sequence_enabled() ) + level thread maps\mp\alien\_intro_sequence::play_intro_sequence( var_1 ); + + level thread show_introscreen_text(); + + if ( isdefined( level.intro_dialogue_func ) ) + level thread [[ level.intro_dialogue_func ]](); + + wait( level.prematchperiod - 3 ); + + if ( isdefined( level.postintroscreenfunc ) ) + [[ level.postintroscreenfunc ]](); + + level notify( "introscreen_over" ); + level.introscreen_done = 1; + } + else + { + wait 1; + level notify( "introscreen_over" ); + } + + for ( var_3 = 0; var_3 < level.players.size; var_3++ ) + { + level.players[var_3] maps\mp\_utility::freezecontrolswrapper( 0 ); + level.players[var_3] enableweapons(); + + if ( !isdefined( level.players[var_3].pers["team"] ) ) + continue; + } +} + +wait_for_first_player_connect() +{ + var_0 = undefined; + + if ( level.players.size == 0 ) + level waittill( "connected", var_0 ); + else + var_0 = level.players[0]; + + return var_0; +} + +show_introscreen_text() +{ + wait 2; + var_0 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_1, 1 ); + wait 1; + var_1 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_2, 2 ); + wait 1; + var_2 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_3, 3 ); + wait 1; + var_3 = maps\mp\alien\_hud::introscreen_corner_line( level.introscreen_line_4, 4 ); + level waittill( "introscreen_over" ); + var_0 fadeovertime( 3 ); + var_1 fadeovertime( 3 ); + var_2 fadeovertime( 3 ); + var_3 fadeovertime( 3 ); + wait 3.1; + var_0.alpha = 0; + var_1.alpha = 0; + var_2.alpha = 0; + var_3.alpha = 0; + var_0 destroy(); + var_1 destroy(); + var_2 destroy(); + var_3 destroy(); +} + +beacon_non_player_drill_plant_check() +{ + return level.non_player_drill_plant; +} + +beacon_get_alien_model( var_0 ) +{ + var_1 = level.alien_types[var_0].attributes["model"]; + + if ( isdefined( level.kraken ) ) + var_1 = var_1 + "_lowlod"; + + return var_1; +} + +beacon_cangive_weapon_handler_func( var_0, var_1, var_2, var_3 ) +{ + var_4 = 0; + + if ( self hasweapon( "aliensoflam_mp" ) ) + var_4++; + + if ( self.hasriotshield || self.hasriotshieldequipped ) + var_4++; + + var_5 = self getcurrentweapon(); + var_6 = 0; + + if ( issubstr( var_5, "aliendlc11" ) ) + var_6 = 1; + + if ( var_6 && var_0.size + 1 > var_3 + var_4 ) + return 0; + + return 1; +} + +beacon_give_weapon_handler_func( var_0 ) +{ + var_1 = self getcurrentweapon(); + + if ( issubstr( var_1, "aliendlc11" ) ) + return 0; + + return undefined; +} + +beacon_hive_icon_override_func() +{ + if ( isdefined( self.target ) && self.target == "cargo_area_main" ) + return 1; + + return 0; +} + +disable_lab_doors() +{ + foreach ( var_1 in level.stronghold_hive_locs ) + { + if ( isdefined( var_1.target ) && ( var_1.target == "door_hive_10" || var_1.target == "door_hive_9" ) ) + { + if ( isdefined( var_1.icon ) ) + var_1.icon destroy(); + + var_1 makeunusable(); + var_1 sethintstring( "" ); + var_1 notify( "stop_listening" ); + var_1.target = undefined; + level.stronghold_hive_locs = common_scripts\utility::array_remove( level.stronghold_hive_locs, var_1 ); + } + } +} + +beacon_randombox_item_check( var_0 ) +{ + if ( !isdefined( var_0 ) ) + return; + + switch ( var_0 ) + { + case "trophy": + case "flare": + self takeweapon( "iw6_aliendlc21_mp" ); + return; + } +} + +setintermissioncam() +{ + var_0 = getent( "mp_global_intermission", "classname" ); + var_0.origin = ( -316.775, 6480.45, 1528 ); + var_0.angles = ( 10, 90, 0 ); +} + +fix_beacon_jump_exploit() +{ + wait 3.0; + var_0 = getent( "player128x128x128", "targetname" ); + + if ( !isdefined( var_0 ) ) + return; + + var_1 = var_0.origin; + var_0.origin = ( -224, -608, 118 ); + + while ( level.current_hive_name != "door_hive_1_post" && level.current_hive_name != "well_deck_2_post" ) + wait 0.25; + + var_0.origin = var_1; +} + +fix_cargo_leftovers() +{ + level endon( "game_ended" ); + level waittill( "beacon_starting_topdeck" ); + var_0 = maps\mp\alien\_spawnlogic::get_alive_agents(); + + foreach ( var_2 in var_0 ) + { + if ( isdefined( var_2 ) && isalive( var_2 ) && var_2.origin[2] < 925 ) + { + var_2.scene = 1; + var_2 suicide(); + } + + wait 0.1; + } + + var_4 = []; + + foreach ( var_6 in level.players ) + { + if ( isdefined( var_6.crafted_items["alien_crafting_hypno_trap"] ) ) + { + var_7 = var_6.crafted_items["alien_crafting_hypno_trap"]; + + if ( !isarray( var_7 ) ) + var_4 = common_scripts\utility::add_to_array( var_4, var_7 ); + else + var_4 = common_scripts\utility::array_combine( var_4, var_7 ); + } + + if ( isdefined( var_6.crafted_items["alien_crafting_tesla_trap"] ) ) + { + var_7 = var_6.crafted_items["alien_crafting_tesla_trap"]; + + if ( !isarray( var_7 ) ) + var_4 = common_scripts\utility::add_to_array( var_4, var_7 ); + else + var_4 = common_scripts\utility::array_combine( var_4, var_7 ); + } + } + + var_4 = common_scripts\utility::array_combine( var_4, level.turrets ); + var_4 = common_scripts\utility::array_combine( var_4, level.placedims ); + var_4 = common_scripts\utility::array_combine( var_4, level.balldrones ); + + foreach ( var_10 in var_4 ) + { + if ( isdefined( var_10 ) && isdefined( var_10.origin ) && !isdefined( var_10.carriedby ) && var_10.origin[2] < 925 ) + var_10 notify( "death" ); + } +} + +should_enable_crafting() +{ + if ( maps\mp\alien\_utility::is_chaos_mode() ) + return 0; + + return 1; +} + +beacon_adjust_spawnlocation( var_0 ) +{ + if ( isdefined( var_0.script_noteworthy ) ) + { + switch ( var_0.script_noteworthy ) + { + case "cargo_air_vent_down_01": + if ( var_0.origin == ( 661, 2965, 501 ) ) + { + var_0.origin = ( 661, 2826, 501 ); + var_0.angles = ( 0, 90, 0 ); + var_0.script_noteworthy = "cargo_air_vent_down_02"; + } + + break; + case "cargo_crawl_out_grate_1": + var_0.origin = ( -943, 1719, 77.5 ); + var_0.angles = ( 0, 179.1, 0 ); + break; + case "cargo_crawl_out_grate_3": + var_0.origin = ( 704, 1720, 76 ); + var_0.angles = ( 0, 179.1, 0 ); + break; + } + } + + return var_0; +} + +spawn_weapon_in_boss_area() +{ + var_0 = common_scripts\utility::getstructarray( "item", "targetname" ); + + foreach ( var_2 in var_0 ) + { + if ( !isdefined( var_2.script_noteworthy ) ) + continue; + + if ( var_2.script_noteworthy == "weapon_iw6_alienhoneybadger_mp" ) + { + var_2.script_noteworthy = "weapon_iw6_altalienarx_mp"; + var_2.origin = ( -775.2, 882.1, 6 ); + var_2.angles = ( 311.4, 90, 0 ); + continue; + } + + if ( var_2.script_noteworthy == "weapon_iw6_alieng28_mp" ) + { + var_2.script_noteworthy = "weapon_iw6_alienvks_mp_alienvksscope"; + var_2.origin = ( -194.3, 822.9, 156.5 ); + continue; + } + + if ( var_2.script_noteworthy == "weapon_iw6_altaliensvu_mp" ) + { + var_2.script_noteworthy = "weapon_iw6_alienvks_mp_alienvksscope"; + var_2.origin = ( 512.6, 782, 157 ); + } + } + + var_4 = spawnstruct(); + var_4.script_noteworthy = "weapon_iw6_altalienarx_mp"; + var_4.targetname = "item"; + var_4.origin = ( -326, 8536, 1170 ); + var_4.angles = ( 311.4, 90, 0 ); + var_4.radius = 200; + return var_4; +} diff --git a/data/scripts/_team_balance.gsc b/data/scripts/_team_balance.gsc new file mode 100644 index 0000000..03de64a --- /dev/null +++ b/data/scripts/_team_balance.gsc @@ -0,0 +1,33 @@ +init() +{ + if (maps\mp\_utility::is_aliens()) + { + return; + } + + if (isdefined(level.ishorde) && level.ishorde) + { + return; + } + + // define onteamselection callback function used in balanceteams() + level.onteamselection = ::set_team; +} + +set_team(team) +{ + if (team != self.pers["team"]) + { + self.switching_teams = true; + self.joining_team = team; + self.leaving_team = self.pers["team"]; + } + + if (self.sessionstate == "playing") + { + self suicide(); + } + + maps\mp\gametypes\_menus::addtoteam(team); + maps\mp\gametypes\_menus::endrespawnnotify(); +} diff --git a/data/sound/patch-3-music.flac b/data/sound/patch-3-music.flac new file mode 100644 index 0000000..ad13711 Binary files /dev/null and b/data/sound/patch-3-music.flac differ diff --git a/data/ui_scripts/end_game/__init__.lua b/data/ui_scripts/end_game/__init__.lua new file mode 100644 index 0000000..445c870 --- /dev/null +++ b/data/ui_scripts/end_game/__init__.lua @@ -0,0 +1,228 @@ +if (game:issingleplayer() or Engine.InFrontend()) then + return +end + +f0_local0 = function ( f1_arg0, f1_arg1 ) + LUI.FlowManager.RequestLeaveMenu( f1_arg0 ) +end + +f0_local1 = function ( f2_arg0, f2_arg1 ) + f2_arg0:setText( f2_arg1.message_text ) + f2_arg0:dispatchEventToRoot( { + name = "resize_popup" + } ) +end + +f0_local2 = function ( f3_arg0 ) + Engine.ExecFirstClient( "xpartybackout" ) + Engine.ExecFirstClient( "disconnect" ) +end + +local f0_local3 = function ( f4_arg0 ) + Engine.ExecFirstClient( "xpartydisbandafterround" ) + Engine.ExecFirstClient( "disconnect" ) +end + +local f0_local4 = function ( f5_arg0 ) + return Engine.GetDvarBool( "onlinegame" ) +end + +local f0_local5 = function ( f6_arg0 ) + if f0_local4( f6_arg0 ) then + Engine.ExecFirstClient( "xstopprivateparty" ) + Engine.ExecFirstClient( "disconnect" ) + Engine.ExecFirstClient( "xblive_privatematch 0" ) + Engine.ExecFirstClient( "onlinegame 1" ) + Engine.ExecFirstClient( "xstartprivateparty" ) + else + Engine.ExecFirstClient( "disconnect" ) + end +end + +local f0_local6 = function ( f7_arg0 ) + Engine.ExecFirstClient( "xstopprivateparty" ) + Engine.ExecFirstClient( "xpartydisbandafterround" ) + + if Engine.GetDvarBool( "sv_running" ) then + Engine.NotifyServer( "end_game", 1 ) + Engine.ExecFirstClient( "xblive_privatematch 0" ) + Engine.ExecFirstClient( "onlinegame 1" ) + Engine.ExecFirstClient( "xstartprivateparty" ) + else + f0_local5( f7_arg0 ) + end +end + +local f0_local7 = function ( f8_arg0, f8_arg1 ) + if Engine.GetDvarBool( "sv_running" ) then + Engine.NotifyServer( "end_game", 1 ) + else + f0_local5( f8_arg0 ) + end + LUI.FlowManager.RequestCloseAllMenus( f8_arg0 ) +end + +local f0_local8 = function ( f9_arg0, f9_arg1 ) + LUI.FlowManager.RequestLeaveMenu( f9_arg0 ) + Engine.Exec( "onPlayerQuit" ) + if Engine.GetDvarBool( "sv_running" ) then + f0_local3( f9_arg0 ) + else + f0_local2( f9_arg0 ) + end + LUI.FlowManager.RequestCloseAllMenus( f9_arg0 ) +end + +local f0_local9 = function ( f10_arg0, f10_arg1 ) + LUI.FlowManager.RequestLeaveMenu( f10_arg0 ) + Engine.Exec( "onPlayerQuit" ) + if Engine.GetDvarBool( "sv_running" ) then + f0_local6( f10_arg0 ) + else + f0_local5( f10_arg0 ) + end + LUI.FlowManager.RequestCloseAllMenus( f10_arg0 ) +end + +local f0_local10 = function ( f11_arg0 ) + local f11_local0 = Lobby.IsInPrivateParty() + if f11_local0 then + f11_local0 = Lobby.IsPrivatePartyHost() + if f11_local0 then + f11_local0 = not Lobby.IsAloneInPrivateParty() + end + end + return f11_local0 +end + +local f0_local11 = function ( f12_arg0, f12_arg1 ) + local f12_local0 = Engine.GetDvarBool( "squad_match" ) + local f12_local1 = Engine.GetDvarBool( "squad_use_hosts_squad" ) + if f12_local0 and Lobby.IsInPrivateParty() and Lobby.IsPrivatePartyHost() then + Engine.NotifyServer( "end_game", 1 ) + elseif f12_local1 and Lobby.IsPrivatePartyHost() and Lobby.IsAloneInPrivateParty() and Lobby.IsAlone() then + Engine.NotifyServer( "end_game", 1 ) + elseif f0_local10( f12_arg0 ) then + LUI.FlowManager.RequestLeaveMenu( f12_arg0, true ) + LUI.FlowManager.RequestPopupMenu( f12_arg0, "popup_pull_party", false ) + else + Engine.Exec( "onPlayerQuit" ) + if Engine.GetDvarBool( "sv_running" ) then + f0_local6( f12_arg0 ) + else + f0_local5( f12_arg0 ) + end + LUI.FlowManager.RequestCloseAllMenus( f12_arg0 ) + end +end + +local f0_local12 = function () + local self = LUI.UIElement.new() + self.id = "end_game_id" + self:registerAnimationState( "default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = true, + rightAnchor = true, + top = -50, + left = 0, + bottom = 0, + right = 0, + alpha = 1 + } ) + self:animateToState( "default", 0 ) + local f13_local1 = Engine.Localize( "@LUA_MENU_END_GAME_DESC" ) + local f13_local2 = Engine.Localize( "@LUA_MENU_LEAVE_GAME_TITLE" ) + if Engine.IsAliensMode() and Game.GetOmnvar( "ui_alien_is_solo" ) then + f13_local1 = Engine.Localize( "@ALIENS_LEAVE_GAME_DESC" ) + f13_local2 = Engine.Localize( "@MENU_NOTICE" ) + end + LUI.MenuBuilder.BuildAddChild( self, { + type = "generic_yesno_popup", + id = "privateGame_options_list_id", + properties = { + message_text_alignment = LUI.Alignment.Center, + message_text = f13_local1, + popup_title = f13_local2, + padding_top = 12, + yes_action = f0_local7 + } + } ) + local f13_local3 = LUI.UIBindButton.new() + f13_local3.id = "endBackToGameStartButton" + f13_local3:registerEventHandler( "button_start", f0_local0 ) + self:addElement( f13_local3 ) + return self +end + +local f0_local13 = function () + local self = LUI.UIElement.new() + self.id = "leave_game_id" + self:registerAnimationState( "default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = true, + rightAnchor = true, + top = -50, + left = 0, + bottom = 0, + right = 0, + alpha = 1 + } ) + self:animateToState( "default", 0 ) + LUI.MenuBuilder.BuildAddChild( self, { + type = "generic_yesno_popup", + id = "publicGame_options_list_id", + properties = { + message_text_alignment = LUI.Alignment.Center, + message_text = Engine.IsAliensMode() and Engine.Localize( "@ALIENS_LEAVE_GAME_DESC" ) or Engine.Localize( "@LUA_MENU_LEAVE_GAME_DESC" ), + popup_title = Engine.IsAliensMode() and Engine.Localize( "@MENU_NOTICE" ) or Engine.Localize( "@LUA_MENU_LEAVE_GAME_TITLE" ), + padding_top = 12, + yes_action = f0_local11 + } + } ) + local f14_local1 = LUI.UIBindButton.new() + f14_local1.id = "leaveBackToGameStartButton" + f14_local1:registerEventHandler( "button_start", f0_local0 ) + self:addElement( f14_local1 ) + return self +end + +local f0_local14 = function () + local self = LUI.UIElement.new() + self.id = "pull_party_out_id" + self:registerAnimationState( "default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = true, + rightAnchor = true, + top = -50, + left = 0, + bottom = 0, + right = 0, + alpha = 1 + } ) + self:animateToState( "default", 0 ) + LUI.MenuBuilder.BuildAddChild( self, { + type = "generic_yesno_popup", + id = "party_pullout_list_id", + properties = { + message_text_alignment = LUI.Alignment.Center, + message_text = Engine.Localize( "@LUA_MENU_PULL_PARTY_DESC" ), + popup_title = Engine.Localize( "@LUA_MENU_LEAVE_GAME_TITLE" ), + padding_top = 12, + yes_action = f0_local8, + no_action = f0_local9, + cancel_means_no = false + } + } ) + local f15_local1 = LUI.UIBindButton.new() + f15_local1.id = "leavePullPartyButton" + f15_local1:registerEventHandler( "button_start", f0_local0 ) + self:addElement( f15_local1 ) + return self +end + +LUI.MenuBuilder.m_types["popup_end_game"] = f0_local12 +LUI.MenuBuilder.m_types["popup_leave_game"] = f0_local13 +LUI.MenuBuilder.m_types["popup_pull_party"] = f0_local14 diff --git a/data/ui_scripts/main_menu/__init__.lua b/data/ui_scripts/main_menu/__init__.lua new file mode 100644 index 0000000..5ac99e6 --- /dev/null +++ b/data/ui_scripts/main_menu/__init__.lua @@ -0,0 +1,250 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local SquadsModeButtonAction = function( f4_arg1 , f4_arg0) + controller = f4_arg0.controller + Engine.ExecNow( "forcenosplitscreencontrol main_XBOXLIVE_1", controller ) + local f4_local0, f4_local1 = Engine.UserCanPlayOnline( controller ) + if not f4_local0 then + Engine.Exec( "xrequirelivesignin", controller ) + Engine.Exec( "forcenosplitscreencontrol main_XBOXLIVE_2", controller ) + else + if SvS.IsSvS() then + Engine.Exec( "profile_SetHasEverPlayed_SP", controller ) + end + Engine.ExecNow( "resetSplitscreenSignIn", controller ) + Engine.ExecNow( "forcenosplitscreencontrol main_XBOXLIVE_3", controller ) + Engine.SetDvarBool( "systemlink", false ) + Engine.SetDvarBool( "splitscreen", false ) + Engine.SetDvarBool( "onlinegame", true ) + Engine.SetDvarBool( "xblive_privatematch", false ) + Engine.SetDvarBool( "ui_opensummary", false ) + Engine.SetDvarBool( "squad_match", false ) + Engine.SetDvarInt( "allow_online_squads", 1 ) + if Engine.GetDvarBool( "xblive_competitionmatch" ) then + Engine.SetDvarBool( "xblive_competitionmatch", false ) + Engine.Exec( "set remove_mlg_rules 1" ) + end + Engine.ExecNow( MPConfig.default_xboxlive, controller ) + if not SvS.IsSvS() then + Engine.ExecNow( "xstartprivateparty", controller ) + end + Engine.Exec( "startentitlements", controller ) + Engine.CacheUserDataForController( controller ) + if SvS.IsSvS() then + LUI.FlowManager.RequestAddMenu( nil, "squads_mode_select_menu", false, controller, false ) + else + LUI.FlowManager.RequestAddMenu( nil, "menu_xboxlive", false, controller, false ) + end + end +end + +local main_menu_options_feeder = function( f17_arg0 ) + local f17_local0 = Engine.IsAliensMode() + local f17_local1 = SvS.IsSvS() + local f17_local2 = false + if Engine.GetDvarInt( "allow_online_squads" ) == 1 or not Engine.IsConsoleGame() then + f17_local2 = true + end + local f17_local3 = Engine.DoWeNeedCompatibilityPacks() + if f17_local1 then + local f17_local4 = f17_local2 + end + local f17_local5 = f17_local4 or not f17_local1 + local f17_local6 = {} + if Engine.AllowOnline() and f17_local5 then + local f17_local7, f17_local8 = nil + if f17_local1 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_SQUADS_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_SQUADS_INTRO" ) + elseif f17_local0 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_PLAY_EXTINCTION_ONLINE_DESC" ) + else + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_0", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks, + properties = { + button_text = f17_local8, + button_action_func = LUI.mp_menus.MPMainMenu.xboxLiveButtonAction, + desc_text = f17_local7, + button_over_func = function ( f18_arg0, f18_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + end + if SvS.IsSvS() then + local f17_local7 = "@PLATFORM_PLAY_ONLINE_SQUADS_CAPS" + local f17_local8 = #f17_local6 + 1 + local f17_local9 = { + type = "UIGenericButton", + id = "btn_MPMain_1", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks + } + local f17_local10 = { + button_text = Engine.Localize( f17_local7 ), + button_action_func = SquadsModeButtonAction + } + local f17_local11 + if f17_local1 then + f17_local11 = Engine.Localize( "@LUA_MENU_SQUADS_INTRO" ) + if not f17_local11 then + + else + f17_local10.desc_text = f17_local11 + f17_local10.button_over_func = function ( f19_arg0, f19_arg1 ) + PersistentBackground.SetToDefault() + end + + f17_local9.properties = f17_local10 + f17_local6[f17_local8] = f17_local9 + end + end + f17_local11 = Engine.Localize( "@LUA_MENU_SPLITSCREEN_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_6", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_menus.MPMainMenu.optionsButtonAction, + desc_text = Engine.Localize( "@LUA_MENU_OPTIONS_DESC" ), + button_over_func = function ( f22_arg0, f22_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + f17_local6[#f17_local6 + 1] = { + type = "generic_separator", + id = "main_menu_spacer_id" + } + if not Engine.IsCoreMode() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_7", + properties = { + text = Engine.Localize( "@LUA_MENU_MULTIPLAYER_CAPS" ), + button_action_func = function ( f23_arg0, f23_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToCoreMode() + Engine.PlayMusic( CoD.Music.MainMPMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f24_arg0, f24_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.MPBackground ) + end, + desc_text = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + } + } + end + if not SvS.IsSvS() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_8", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_MODE_CAP" ), + button_action_func = function ( f25_arg0, f25_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToSquadVsSquadMode() + Engine.PlayMusic( CoD.Music.MainSquadMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f26_arg0, f26_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.SvSBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_SVS_MAIN_MENU_DESC" ) + } + } + end + if not Engine.IsAliensMode() and Engine.UnlockedAliens() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_9", + properties = { + button_text = Engine.Localize( "@LUA_MENU_ALIENS_CAPS" ), + button_action_func = function ( f27_arg0, f27_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToAliensMode() + Engine.PlayMusic( CoD.Music.MainExtinctMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f28_arg0, f28_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.AliensBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_ALIENS_MAIN_MENU_DESC" ), + additional_handlers = { + menu_create = LUI.mp_menus.MPMainMenu.AddExtinctionGlowBackground + } + } + } + end + f17_local6[#f17_local6 + 1] = { + type = "button_desc_text", + id = "mp_menu_button_description_id", + properties = { + lines = SvS.IsSvS() and 8 or nil + } + } + return f17_local6 +end + +-- Remove social button +LUI.MenuBuilder.m_definitions["online_friends_widget"] = function() + return { + type = "UIElement" + } +end + +f0_local0 = function () + return { + type = "UIVerticalList", + id = "mp_main_menu_id", + childrenFeeder = main_menu_options_feeder, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = false, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + alignment = LUI.Alignment.Top + } + }, + handlers = { + dlc_mount_complete = function ( f30_arg0, f30_arg1 ) + f30_arg0:processEvent( { + name = "menu_refresh" + } ) + end + , + dlc_mount_fail = function ( f31_arg0, f31_arg1 ) + f31_arg0:processEvent( { + name = "menu_refresh" + } ) + end + , + dlc_download_fail = function ( f32_arg0, f32_arg1 ) + f32_arg0:processEvent( { + name = "menu_refresh" + } ) + end + + } + } +end + +LUI.MenuBuilder.m_definitions[ "main_mp_menu_options"] = f0_local0 diff --git a/data/ui_scripts/menu_xboxlive/__init__.lua b/data/ui_scripts/menu_xboxlive/__init__.lua new file mode 100644 index 0000000..40f51b0 --- /dev/null +++ b/data/ui_scripts/menu_xboxlive/__init__.lua @@ -0,0 +1,275 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby + +local FindMatchAfterThrottleEvent = function( f4_arg0, f4_arg1 ) + local f4_local0 = false + local f4_local1 = -1 + for f4_local2 = 0, Engine.GetMaxControllerCount() - 1, 1 do + if Engine.HasActiveLocalClient( f4_local2 ) and IsFirstTimeFlowRequired( f4_local2 ) then + f4_local0 = true + if f4_local1 < 0 then + f4_local1 = f4_local2 + end + end + end + if f4_local0 then + LUI.FlowManager.RequestAddMenu( f4_arg0, "cac_member_select_main", true, f4_local1, false, { + next_screen = "cac_edit_main", + squad_location = "squadMembers", + class_location = "loadouts", + findMatch = true + } ) + elseif not LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons() then + Engine.Exec( "xblive_privatematch 0" ) + if Engine.IsAliensMode() then + LUI.mp_menus.Aliens.AliensRunConfig( f4_arg1.controller ) + end + if LUI.mp_menus.MPXboxLiveMenu.CheckHasRequiredDLC( f4_arg0 ) then + if LUI.mp_menus.MPXboxLiveMenu.DisplayLowRepWarning( f4_arg0, f4_arg1 ) then + return + elseif SvS.IsSvS() then + local f4_local3 = SvS.GetCurrentSquadModeInfo() + local f4_local4, f4_local5 = SvS.GetPlaylistFromSquadMode( f4_local3 ) + local f4_local6 = false + if f4_arg1.squadsPlayNow then + f4_local6 = true + end + if not f4_arg1.squadsPlayNow and f4_local3.DynamicMatchmaking then + Playlist.DoAction( f4_local4, f4_local5, true, f4_local6 ) + else + Playlist.DoAction( f4_local4, f4_local5, false, f4_local6 ) + end + if Engine.GetDvarBool( "squad_match" ) then + Squad.StartMatch( f4_arg1.controller, true ) + Engine.SetDvarBool( "squad_find_match", true ) + end + LUI.FlowManager.RequestAddMenu( f4_arg0, "menu_xboxlive_lobby", false, f4_arg1.controller, false ) + else + LUI.FlowManager.RequestPopupMenu( f4_arg0, "menu_systemlink_join" ) -- open server list instead of playlist_main + end + end + end +end + +local FindMatchAction = function( f5_arg0, f5_arg1 ) + if Lobby.EnteringLobby() == true then + LUI.FlowManager.RequestPopupMenu( f5_arg0, "popup_throttling", true, f5_arg1.controller, false, { + eventData = f5_arg1 + } ) + else + FindMatchAfterThrottleEvent( f5_arg0, f5_arg1 ) + end +end + +local BarracksAction = function( f9_arg0, f9_arg1 ) + LUI.FlowManager.RequestAddMenu( f9_arg0, "menu_stats", true, f9_arg1.controller ) -- custom stats menu +end + +package.loaded["LUI.mp_menus.MPXboxLiveMenu"].XboxLiveOptionsFeeder = function( f29_arg0 ) + local f29_local0 = Engine.IsAliensMode() + local f29_local1 = SvS.IsSvS() + local f29_local2 = SvS.IsSvS() + if f29_local2 then + f29_local2 = SvS.GetCurrentSquadModeInfo() + end + local f29_local3 = {} + local f29_local4 = nil + if f29_local0 then + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @LUA_MENU_PUBLIC_MATCH_CAPS but we need to use @LUA_MENU_STORE_CAPS + elseif f29_local1 then + f29_local4 = Engine.Localize( "@PLATFORM_FIND_GAME_CAPS" ) + else + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @PLATFORM_FIND_GAME_CAPS but we need to use @LUA_MENU_STORE_CAPS + end + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "find_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = f29_local4, + button_action_func = FindMatchAction, + desc_text = SvS.IsSvS() and Engine.Localize( "@LUA_MENU_SQUADS_FIND_MATCH_DESC" ) or Engine.Localize( "@LUA_MENU_STORE_DESC" ), -- Orginally @PLATFORM_DESC_FIND_GAME but we need to use @LUA_MENU_STORE_DESC + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + if f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "solo_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.SoloMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_CUSTOM_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if not f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "create_squad_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_CREATE_A_CLASS_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.CreateSquadAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CREATE_A_CLASS" ), + additional_handlers = { + refresh_new_icons = function ( f30_arg0, f30_arg1 ) + if Cac.AnyUnseenMDLCItems( Engine.GetFirstActiveController(), NewIconsTable.CACItemTypes ) then + f30_arg0:processEvent( { + name = "show_new_icon" + } ) + end + end + } + } + } + else + f29_local3[#f29_local3 + 1] = LUI.mp_menus.AliensLoadout.GetAliensLoadoutButton() + end + + -- Disable Leaderboard (Code Removed) + -- Disable Squad Reports (Code Removed) + + if not f29_local0 and not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "operations_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPERATIONS_TITLE" ), + button_action_func = LUI.mp_menus.MPBarracks.BarrackOperationsAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CHALLENGES" ) + } + } + end + if not f29_local0 then + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "barracks_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ), + button_action_func = BarracksAction, + desc_text = Clan.IsEnabled() and Engine.Localize( "@LUA_MENU_DESC_BARRACKS" ) or Engine.Localize( "@LUA_MENU_DESC_BARRACKS_PRIVATE" ) + } + } + end + if not f29_local1 or f29_local2 ~= SvS.SquadModes.SquadVsSquad then + f29_local3[#f29_local3 + 1] = { + type = "generic_separator" + } + end + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_PRIVATE_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + + -- Add Combat Training Button + if not f29_local0 and not f29_local1 then + game:addlocalizedstring("LUA_MENU_COMBAT", "COMBAT TRAINING"); + game:addlocalizedstring("LUA_MENU_COMBAT_DESC", "Rank up offline with bots."); + + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "find_match_button_id2", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize("@LUA_MENU_COMBAT"), -- Engine.Localize( "@PLATFORM_FIND_GAME_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.FindMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_COMBAT_DESC" ), -- Engine.Localize( "@LUA_MENU_SQUADS_FIND_MATCH_DESC" ) + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + + if f29_local1 then + -- Disable Challenge Friend Button (Code Removed) + if f29_local2 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "play_now_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "LUA_MENU_PLAY_NOW_CAPS" ), + button_action_func = function ( f36_arg0, f36_arg1 ) + f36_arg1.squadsPlayNow = true + FindMatchAction( f36_arg0, f36_arg1 ) + end, + desc_text = Engine.Localize( "LUA_MENU_PLAY_NOW_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + end + end + local f29_local6 = #f29_local3 + 1 + local f29_local7 = { + type = "button_desc_text", + id = "prelobby_description_id" + } + local f29_local8 = {} + local f29_local9 + if (SvS.IsSvS() or f29_local2 ~= SvS.SquadModes.SquadAssault) or Engine.IsAliensMode() or Engine.IsCoreMode() then + f29_local9 = 1 + if f29_local9 then + f29_local8.lines = f29_local9 + f29_local7.properties = f29_local8 + f29_local3[f29_local6] = f29_local7 + f29_local3[#f29_local3 + 1] = { + type = "UITimer", + id = "bnt_lock_tmr", + properties = { + event = "check_buttons", + interval = 500, + disposable = false, + broadcastToRoot = true + } + } + return f29_local3 + end + end + f29_local9 = nil +end diff --git a/data/ui_scripts/mp_live_public_lobby/__init__.lua b/data/ui_scripts/mp_live_public_lobby/__init__.lua new file mode 100644 index 0000000..ea2062b --- /dev/null +++ b/data/ui_scripts/mp_live_public_lobby/__init__.lua @@ -0,0 +1,305 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +package.loaded["LUI.mp_menus.MPLivePublicLobby"].LivePublicLobbyOptionsFeeder = function( f18_arg0 ) + local f18_local0 = Lobby.GetVoteMapName( MapVoting.MapA.refNum ) + local f18_local1 = Lobby.GetVoteMapName( MapVoting.MapB.refNum ) + local f18_local2 = Lobby.GetVoteMapImage( MapVoting.MapA.refNum ) + local f18_local3 = Lobby.GetVoteMapImage( MapVoting.MapB.refNum ) + local f18_local4 = LUI.mp_menus.Aliens.FixGameModeTextForChaos( Lobby.GetVoteMapGametype( MapVoting.MapA.refNum ) ) + local f18_local5 = LUI.mp_menus.Aliens.FixGameModeTextForChaos( Lobby.GetVoteMapGametype( MapVoting.MapB.refNum ) ) + local f18_local6 = LUI.mp_menus.MPLivePublicLobby.IsVotingFinished() + local f18_local7 = not LUI.mp_menus.MPLivePublicLobby.GetLobbyLeaderboardStatus() + local f18_local8 = Engine.IsAliensMode() + local f18_local9 = SvS.IsSvS() + if not f18_local9 then + f18_local9 = Engine.GetDvarBool( "squad_match" ) + end + local f18_local10 = 14 + local f18_local11 = {} + if not f18_arg0.slot then + DebugPrint( "[WARNING] CAC: using cac slot index 0, this is only ok if you are editing a menu" ) + local f18_local12 = 0 + end + local f18_local13 = Cac.GetCustomClassLoc( f18_arg0.classLocation ) + + + -- Add Start Button to Public Match Menu + function ReadyUpAction( f11_arg0, f11_arg1 ) + Engine.SetDvarInt( "party_minplayers", 1) + end + + if not f18_local9 then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "ready_up_button_id", + disabledFunc = false, + properties = { + disabledFunc = false, + button_text = Engine.Localize( "@LUA_MENU_START_GAME_CAPS" ), + button_action_func = ReadyUpAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_READY_UP" ), + } + } + end + + if f18_local8 then + local f18_local14 = Engine.GetDvarInt( "pt_AliensReadyUpPublicInUse" ) + if f18_local14 ~= nil and f18_local14 ~= 0 then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "ready_up_button_id", + disabledFunc = LUI.mp_menus.MPLivePublicLobby.GetReadyUpDisableValue, + properties = { + disabledFunc = LUI.mp_menus.MPLivePublicLobby.GetReadyUpDisableValue, + button_text = "", + button_action_func = LUI.mp_menus.MPLivePublicLobby.ReadyUpAction, + desc_text = LUI.mp_menus.MPLivePublicLobby.GetReadyUpDescText, + additional_handlers = { + recheck_start_button_lock = LUI.mp_menus.MPLivePublicLobby.RefreshButtonDisable, + element_refresh = LUI.mp_menus.MPLivePublicLobby.UpdateReadyUpText, + menu_create = LUI.mp_menus.MPLivePublicLobby.UpdateReadyUpText, + ready_up_button_refresh = LUI.mp_menus.MPLivePublicLobby.UpdateReadyUpText + } + }, + children = { + { + type = "UITimer", + id = "ready_up_button_refresh_timer_id", + properties = { + event = "ready_up_button_refresh", + interval = 100, + disposable = false, + broadcastToRoot = false + } + } + } + } + end + end + if not f18_local8 then + if not SvS.IsSvS() or SvS.GetCurrentSquadModeInfo() ~= SvS.SquadModes.SquadAssault then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "create_squad_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_CREATE_A_CLASS_CAPS" ), + button_action_func = LUI.mp_menus.MPLivePublicLobby.CreateSquadAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CREATE_A_CLASS" ) + } + } + end + else + f18_local11[#f18_local11 + 1] = LUI.mp_menus.AliensLoadout.GetAliensLoadoutButton() + end + if not f18_local8 and not f18_local9 then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "operations_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPERATIONS_TITLE" ), + button_action_func = LUI.mp_menus.MPBarracks.BarrackOperationsAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CHALLENGES" ) + } + } + end + if not f18_local9 and not f18_local8 then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "barracks_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ), + button_action_func = LUI.mp_menus.MPLivePublicLobby.BarracksAction, + desc_text = Clan.IsEnabled() and Engine.Localize( "@LUA_MENU_DESC_BARRACKS" ) or Engine.Localize( "@LUA_MENU_DESC_BARRACKS_PRIVATE" ) + } + } + end + -- Disable Leaderboard (Code Removed) + if f18_local9 then + local f18_local14 = SvS.GetCurrentSquadModeInfo() + if f18_local14 and f18_local14.HasReports then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "squad_reports_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS" ), + desc_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS_DESC" ), + button_action_func = function ( f19_arg0, f19_arg1 ) + LUI.FlowManager.RequestAddMenu( f19_arg0, "squad_reports_menu", false, f19_arg1.controller, false, { + controller = f19_arg1.controller, + fromLiveLobby = true + } ) + end + } + } + end + if f18_local14 and f18_local14.HasCompare then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "squad_compare_button_id", + disabled = LUI.mp_menus.MPLivePublicLobby.CheckSquadCompareDisabled(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_COMPARE" ), + desc_text = Engine.Localize( "@LUA_MENU_SQUAD_COMPARE_DESC" ), + button_action_func = function ( f20_arg0, f20_arg1 ) + if Squad.FoundMatch() then + local f20_local0 = SvS.BuildSquadCompareData( f20_arg1.controller ) + if f20_local0 then + LUI.FlowManager.RequestAddMenu( f20_arg0, "squad_report_detail_menu", false, f20_arg1.controller, false, { + reportData = f20_local0, + controller = f20_arg1.controller, + isCompare = true + } ) + end + end + end + }, + handlers = { + check_button_disable_status = function ( f21_arg0, f21_arg1 ) + local f21_local0 = f21_arg0 + local f21_local1 = f21_arg0.processEvent + local f21_local2 = {} + local f21_local3 + if not LUI.mp_menus.MPLivePublicLobby.CheckSquadCompareDisabled() then + f21_local3 = "enable" + if not f21_local3 then + + else + f21_local2.name = f21_local3 + f21_local1( f21_local0, f21_local2 ) + end + end + f21_local3 = "disable" + end + } + } + end + end + if f18_local9 then + local f18_local14 = SvS.GetCurrentSquadModeInfo() + if not f18_local14.HasLeaderboard then + + else + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "leaderboards_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_LEADERBOARDS_CAPS" ), + desc_text = Engine.Localize( "@LUA_MENU_DESC_LEADERBOARDS" ), + button_action_func = function ( f22_arg0, f22_arg1 ) + if Engine.IsUserAGuest( f22_arg1.controller ) then + LUI.FlowManager.RequestPopupMenu( f22_arg0, "popup_no_guest", true, f22_arg1.controller ) + else + LUI.FlowManager.RequestAddMenu( f22_arg0, "leaderboards", true, f22_arg1.controller ) + end + end + } + } + end + end + if f18_local8 then + f18_local11[#f18_local11 + 1] = { + type = "UIGenericButton", + id = "leaderboards_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_LEADERBOARDS_CAPS" ), + desc_text = Engine.Localize( "@LUA_MENU_DESC_LEADERBOARDS" ), + button_action_func = function ( f22_arg0, f22_arg1 ) + if Engine.IsUserAGuest( f22_arg1.controller ) then + LUI.FlowManager.RequestPopupMenu( f22_arg0, "popup_no_guest", true, f22_arg1.controller ) + else + LUI.FlowManager.RequestAddMenu( f22_arg0, "leaderboards", true, f22_arg1.controller ) + end + end + } + } + end + if f18_local8 and LUI.mp_menus.Aliens.CanAccessIntelMenu() then + f18_local11[#f18_local11 + 1] = LUI.mp_menus.AliensIntel.GetAliensIntelButton() + end + f18_local11[#f18_local11 + 1] = { + type = "button_desc_text", + id = "public_lobby_description_id", + properties = { + lines = 1 + } + } + f18_local11[#f18_local11 + 1] = { + type = "UIElement", + id = "just_a_spacer_id", + focusable = false, + states = { + default = { + leftAnchor = true, + rightAnchor = true, + topAnchor = true, + bottomAnchor = false, + left = 0, + right = 0, + top = 0, + bottom = f18_local10 + } + } + } + f18_local11[#f18_local11 + 1] = { + type = "UITimer", + id = "check_status_tmr", + properties = { + event = "check_button_disable_status", + interval = 500, + disposable = false, + broadcastToRoot = true + } + } + if not f18_local9 and not f18_local6 then + f18_local11[#f18_local11 + 1] = { + type = "map_button", + id = "map_button_1", + properties = { + mapVoteIndex = MapVoting.MapA.refNum, + mapImage = RegisterMaterial( f18_local2 ), + mapName = f18_local0, + gamemode = f18_local4, + votesText = Engine.GetDvarString( "party_nextMapVoteStatus" ), + votesDvarName = "party_nextMapVoteStatus", + action = function ( f23_arg0, f23_arg1 ) + LUI.mp_menus.MPLivePublicLobby.VoteForMap( f23_arg0, f23_arg1.controller, MapVoting.MapA.voteIndex ) + end + } + } + f18_local11[#f18_local11 + 1] = { + type = "UIElement", + id = "just_another_spacer_id", + focusable = false, + states = { + default = { + leftAnchor = true, + rightAnchor = true, + topAnchor = true, + bottomAnchor = false, + left = 0, + right = 0, + top = 0, + bottom = 40 + } + } + } + f18_local11[#f18_local11 + 1] = { + type = "map_button", + id = "map_button_2", + properties = { + mapVoteIndex = MapVoting.MapB.refNum, + mapImage = RegisterMaterial( f18_local3 ), + mapName = f18_local1, + gamemode = f18_local5, + votesText = Engine.GetDvarString( "party_alternateMapVoteStatus" ), + votesDvarName = "party_alternateMapVoteStatus", + action = function ( f24_arg0, f24_arg1 ) + LUI.mp_menus.MPLivePublicLobby.VoteForMap( f24_arg0, f24_arg1.controller, MapVoting.MapB.voteIndex ) + end + } + } + end + return f18_local11 +end diff --git a/data/ui_scripts/server_filter/__init__.lua b/data/ui_scripts/server_filter/__init__.lua new file mode 100644 index 0000000..c236356 --- /dev/null +++ b/data/ui_scripts/server_filter/__init__.lua @@ -0,0 +1,436 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby + +game:addlocalizedstring("LUA_MENU_SERVER_FILTER_POPUP_INSTR", "Change how the servers are filtered") + +function FiltersPopupClose(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + local f1_local1 = LUI.FlowManager.GetMenuScopedDataByMenuName("mp_leaderboard_main") + local f1_local2 = f1_local1.leaderboardType + if f1_local2 and f1_local2 ~= "" then + Leaderboards.OpenLeaderboard(f1_arg0, f1_local2, f1_local0.filterKey, f1_local1.filterDurationKey, f1_local1.isHardcore) + end +end + +function mp_server_filters_popup() + return { + type = "UIElement", + id = "mp_leaderboard_filters_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 170 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_FILTER_CAPS"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "mp_server_filters_popup_page" + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +function ForceRefreshServers(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataByMenuName("menu_systemlink_join") + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function OpenFiltersMenu(f36_arg0, f36_arg1) + LUI.FlowManager.RequestPopupMenu(f36_arg0, "mp_server_filters_popup", true, f36_arg1.controller, false, {}) +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup", mp_server_filters_popup) + +GameTypeRefCol = 0 +GameTypeNameCol = 1 +GameTypeDescCol = 2 +GameTypeImageCol = 3 + +function GetGametypes() + if Engine.IsCoreMode() then + return { "any", "dm", "war", "sd", "dom", "conf", "sr", "infect", "blitz", "grind", "cranked", "sotf", "sotf_ffa", + "horde", "gun", "grnd", "siege" } + end + return { "aliens" } +end + +function GetLocalizedStringFromGametype(gametype) + if gametype == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + local gametype_name = Engine.TableLookup("mp/gameTypesTable.csv", GameTypeRefCol, gametype, GameTypeNameCol) + if gametype_name ~= "" then + local token = "@" + local caps_token = "_CAPS" + localized = Engine.Localize(token .. gametype_name .. caps_token) + return localized + end + return "UNKNOWN" +end + +function GetMapnameFromID(id) + if id == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + + if id == "mp_descent_new" then + return Engine.Localize("@LUA_MENU_MAPNAME_DESCENT_CAPS") + elseif id == "mp_favela_iw6" then + return string.upper(Engine.Localize("@PRESENCE_MP_FAVELA_IW6")) + elseif id == "mp_conflict" then + return string.upper(Engine.Localize("@PRESENCE_MP_CONFLICT")) + elseif id == "mp_mine" then + return string.upper(Engine.Localize("@PRESENCE_MP_MINE")) + elseif id == "mp_shipment_ns" then + return string.upper(Engine.Localize("@PRESENCE_MP_SHIPMENT_NS")) + elseif id == "mp_zerosub" then + return string.upper(Engine.Localize("@PRESENCE_MP_ZEROSUB")) + elseif id == "mp_ca_red_river" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RED_RIVER")) + elseif id == "mp_ca_rumble" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RUMBLE")) + end + + if id == "mp_alien_town" then + return string.upper(Engine.Localize("@MPUI_ALIEN_TOWN")) + elseif id == "mp_alien_armory" then + return string.upper(Engine.Localize("@MPUI_ALIEN_ARMORY")) + elseif id == "mp_alien_beacon" then + return string.upper(Engine.Localize("@MPUI_ALIEN_BEACON")) + elseif id == "mp_alien_dlc3" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_DLC3")) + elseif id == "mp_alien_last" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_LAST")) + end + + return Engine.Localize("@LUA_MENU_MAPNAME_" .. id:sub(4) .. "_CAPS") +end + +function GetMaps() + if Engine.IsCoreMode() then + return { + "any", + "mp_prisonbreak", + "mp_dart", + "mp_lonestar", + "mp_frag", + "mp_snow", + "mp_fahrenheit", + "mp_hashima", + "mp_warhawk", + "mp_sovereign", + "mp_zebra", + "mp_skeleton", + "mp_chasm", + "mp_flooded", + "mp_strikezone", + "mp_descent_new", + "mp_ca_red_river", + "mp_ca_rumble", + "mp_swamp", + "mp_boneyard_ns", + "mp_dome_ns", + "mp_battery3", + "mp_ca_impact", + "mp_ca_behemoth", + "mp_dig", + "mp_zulu", + "mp_pirate", + "mp_favela_iw6", + "mp_zerosub", + "mp_conflict", + "mp_mine", + "mp_shipment_ns", + } + elseif Engine.IsAliensMode() then + return { + "any", + "mp_alien_town", + "mp_alien_armory", + "mp_alien_beacon", + "mp_alien_dlc3", + "mp_alien_last" + } + end + + return { "any" } +end + +function ServerFiltersPopupItems(f7_arg0) + + local rules = {} + if Engine.IsCoreMode() then + local gametype = { + type = "UIGenericButton", + id = "server_filters_gametype", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MODE_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterGametypeKey == nil then + focusedElement.filterGametypeKey = Engine.GetDvarString("ui_mapvote_entrya_gametype") + end + Engine.SetDvarString("ui_mapvote_entrya_gametype", focusedElement.filterGametypeKey) + return Engine.Localize(GetLocalizedStringFromGametype(focusedElement.filterGametypeKey)) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterGametypeKey = keys[#keys] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterGametypeKey = keys[1] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, gametype) + end + + local maps = { + type = "UIGenericButton", + id = "server_filters_map", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MAPS_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterMapnameKey == nil then + focusedElement.filterMapnameKey = Engine.GetDvarString("ui_mapvote_entrya_mapname") + end + Engine.SetDvarString("ui_mapvote_entrya_mapname", focusedElement.filterMapnameKey) + return GetMapnameFromID(focusedElement.filterMapnameKey) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterMapnameKey = keys[#keys] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterMapnameKey = keys[1] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, maps) + + return rules +end + +function mp_server_filters_popup_page() + return { + type = "UIElement", + id = "mp_server_filters_popup_page_id", + properties = {}, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "UIText", + id = "leaderboard_filters_instruction", + properties = { + text = Engine.Localize("@LUA_MENU_SERVER_FILTER_POPUP_INSTR") + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 10, + bottom = 10 + CoD.TextSettings.NormalFont.Height, + left = 75, + right = -75, + alignment = LUI.Alignment.Center, + font = CoD.TextSettings.NormalFont.Font, + red = Colors.white.r, + green = Colors.white.g, + blue = Colors.white.b + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -75, + bottom = 0, + left = 2, + right = -2, + spacing = 5 + } + }, + childrenFeeder = ServerFiltersPopupItems + } + } + } +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup_page", mp_server_filters_popup_page) diff --git a/data/ui_scripts/server_list/__init__.lua b/data/ui_scripts/server_list/__init__.lua new file mode 100644 index 0000000..6dbcb64 --- /dev/null +++ b/data/ui_scripts/server_list/__init__.lua @@ -0,0 +1,636 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby +local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu + +local controller = nil +local server = nil + +COLUMN_0 = 0 +COLUMN_1 = 460 +COLUMN_2 = 660 +COLUMN_3 = 800 +COLUMN_4 = 985 +COLUMN_5 = 500 + +SystemLinkJoinMenu.UpdateGameList = function(f3_arg0, f3_arg1) + local f3_local0 = f3_arg1.controller + if not f3_local0 then + f3_local0 = Engine.GetFirstActiveController() + end + local f3_local1 = LUI.FlowManager.GetMenuScopedDataFromElement(f3_arg0) + Lobby.UpdateServerDisplayList(f3_local0) + local f3_local2 = Lobby.GetServerCount(f3_local0) + if f3_local2 ~= f3_local1.serverCount then + f3_local1.serverCount = f3_local2 + f3_arg0:processEvent({ + name = "menu_refresh", + immediate = true + }) + f3_arg0:processEvent({ + name = "gain_focus", + immediate = true + }) + end +end + +SystemLinkJoinMenu.RefreshServers = function(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f4_arg0) + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function CreateColumnImage(id, shader, leftAnchor, rightAnchor, left, alpha) + return { + type = "UIImage", + id = id, + states = { + default = { + font = CoD.TextSettings.NormalFont.Font, + alignment = LUI.Alignment.right, + height = 20, + width = 20, + left = left, + red = Colors.cac_label_text.r, + green = Colors.cac_label_text.g, + blue = Colors.cac_label_text.b, + alpha = alpha, + material = RegisterMaterial(shader) + }, + }, + handlers = { + button_over = MBh.AnimateToState("over"), + button_up = MBh.AnimateToState("default"), + button_disable = MBh.AnimateToState("disabled") + } + } +end + +SystemLinkJoinMenu.CreateHeaderDef = function() + local header = { + type = "UIElement", + id = "header_row_id", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 2, + left = 2, + right = -2, + height = GenericTitleBarDims.TitleBarHeight, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + }, + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(SystemLinkJoinMenu.Colors.generic_menu_bg_color)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("host_header", Engine.Localize("@MENU_HOST_NAME"), true, false, COLUMN_0, COLUMN_1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("map_header", Engine.Localize("@MENU_MAP"), true, false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("players_header", Engine.Localize("@MENU_NUMPLAYERS"), true, false, COLUMN_2, COLUMN_3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("type_header", Engine.Localize("@MENU_TYPE1"), true, true, COLUMN_3, COLUMN_4)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("ping_header", Engine.Localize("@MENU_PING"), true, true, COLUMN_4, COLUMN_5)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, 1)) + header.children = columns + return header +end + +SystemLinkJoinMenu.CreateRowDef = function(f6_arg0, f6_arg1, f6_arg2, f6_arg3) + local option = { + type = "UIButton", + id = "row_" .. f6_arg1, + disabled = f6_arg2, + focusable = not f6_arg2, + properties = { + button_height = GenericButtonDims.button_height + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = MBh.Property("button_height"), + left = 0, + right = 0 + } + }, + handlers = { + button_action = MBh.EmitEventToRoot({ + name = "select_game", + idx = f6_arg1 + }) + } + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(f6_arg3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + local shade = SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1) + table.insert(columns, shade) + local hostname = SystemLinkJoinMenu.CreateColumnText("host_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Host), true, false, COLUMN_0, COLUMN_1) + table.insert(columns, hostname) + local mapname = SystemLinkJoinMenu.CreateColumnText("map_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Map), true, false, COLUMN_1, COLUMN_2) + table.insert(columns, mapname) + local players = SystemLinkJoinMenu.CreateColumnText("players_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Clients), true, false, COLUMN_2, COLUMN_3) + table.insert(columns, players) + local gametype = SystemLinkJoinMenu.CreateColumnText("type_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Game), true, true, COLUMN_3, COLUMN_4) + table.insert(columns, gametype) + local ping = SystemLinkJoinMenu.CreateColumnText("ping_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Ping), true, true, COLUMN_4, COLUMN_5) + table.insert(columns, ping) + local is_private = SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, Lobby.GetServerData(f6_arg0, f6_arg1, 5) == "1" and 1 or 0) + table.insert(columns, is_private) + option.children = columns + return option +end + +SystemLinkJoinMenu.OnCreate = function(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + f1_local0.serverCount = 0 + f1_arg0:processEvent(LUI.ButtonHelperText.CommonEvents.addBackButton) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt2", + helper_text = Engine.Localize("@LUA_MENU_FILTER"), + side = "right", + clickable = true + }) + local f1_local1 = Lobby.BuildServerList + local f1_local2 = f1_arg1.controller + if not f1_local2 then + f1_local2 = Engine.GetFirstActiveController() + end + f1_local1(f1_local2) +end + +function ServerListBackground() + if Engine.IsAliensMode() then + return { + image = "frontend_aliens_art", + fill_color = { + r = 1, + g = 1, + b = 1 + }, + fill_alpha = 1 + } + end + + if Engine.IsCoreMode() then + return { + image = "white", + fill_color = { + r = 0.07, + g = 0.1, + b = 0.11 + }, + fill_alpha = 1 + } + end +end + +function JoinGame(f2_arg0, f2_arg1) + server = f2_arg1 + controller = server.controller + if not f2_local1 then + controller = Engine.GetFirstActiveController() + end + + local is_private = Lobby.GetServerData(controller, server.idx, 5) + if is_private == "1" then + LUI.FlowManager.RequestPopupMenu(server, "server_password_field", false, controller, false) + else + Lobby.JoinServer(controller, server.idx) + end +end + +SystemLinkJoinMenu.menu_systemlink_join = function() + if Engine.IsCoreMode() then + Engine.SetDvarString("ui_customModeName", "mp") + elseif Engine.IsAliensMode() then + Engine.SetDvarString("ui_customModeName", "aliens") + end + + if Engine.GetDvarString("ui_mapvote_entrya_gametype") == nil + or Engine.GetDvarString("ui_mapvote_entrya_gametype") then + Engine.SetDvarString("ui_mapvote_entrya_gametype", "any") + end + + if Engine.GetDvarString("ui_mapvote_entrya_mapname") == nil + or Engine.GetDvarString("ui_mapvote_entrya_mapname") == "" + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == nil and Engine.IsAliensMode()) + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == "alien" and Engine.IsCoreMode()) then + Engine.SetDvarString("ui_mapvote_entrya_mapname", "any") + end + + return { + type = "UIElement", + id = "menu_systemlink_join_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = SystemLinkJoinMenu.OnCreate, + select_game = JoinGame + }, + children = { + { + type = "UIImage", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore, + }) + } + }, + { + type = "UIElement", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + left = 200, + right = -200, + height = 550 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "menu_systemlink_join_title_id", + properties = { + fill_alpha = 1, + font = CoD.TextSettings.BoldFont, + title_bar_text = Engine.Localize("@PLATFORM_SYSTEM_LINK_TITLE"), + title_bar_text_indent = GenericTitleBarDims.TitleBarLCapWidth, + title_bar_alignment = LUI.Alignment.Left + } + }, + { + type = "generic_menu_background", + id = "menu_systemlink_join_bg_id", + properties = { + fill_alpha = Swatches.Overlay.AlphaMore, + }, + children = { + SystemLinkJoinMenu.CreateHeaderDef(), + { + type = "UIVerticalList", + id = "menu_systemlink_join_game_list_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = GenericTitleBarDims.TitleBarHeight + 4, + bottom = 600, + left = 2, + right = -2 + } + }, + childrenFeeder = SystemLinkJoinMenu.LinkGamesFeeder, + handlers = { + update_game_list = SystemLinkJoinMenu.UpdateGameList, + menu_create = function(f12_arg0, f12_arg1) + local f12_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f12_arg0) + f12_local0.serverList = f12_arg0 + SystemLinkJoinMenu.RefreshServers(f12_arg0, f12_arg1) + end + + } + }, + { + type = "button_helper_text_main", + id = "online_vault_helper_text_id", + properties = { + left_inset = 10, + right_inset = -10, + top_margin = GenericFooterDims.TopMargin_WithoutBackground, + height = 42, + spacing = 12, + background_alpha = 0 + } + } + } + } + } + }, + { + type = "UITimer", + id = "menu_systemlink_join_update_timer", + properties = { + event = "update_game_list", + interval = 250, + disposable = false, + broadcastToRoot = true + } + }, + { + type = "UIBindButton", + id = "menu_systemlink_join_bind_button_id", + handlers = { + button_secondary = MBh.LeaveMenu(), + button_alt1 = SystemLinkJoinMenu.RefreshServers, + button_alt2 = OpenFiltersMenu + } + }, + } + } +end + + +LUI.MenuBuilder.m_definitions["menu_systemlink_join"] = function() + local menu = SystemLinkJoinMenu.menu_systemlink_join() + + local rows = menu.children[2].children[3].children + local header = rows[1] + + + -- Increase server list width + menu.children[2].states.default.left = 100 + menu.children[2].states.default.right = -100 + + menu.children[3].properties.interval = 10 -- 250 + + return menu +end + +ServerPasswordListFeeder = function() + return { + { + type = "UIVerticalList", + id = "password_field_items", + states = { + default = { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = true, + } + }, + children = { + { + type = "UIGenericButton", + id = "password_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("PATCH_MENU_CHANGE_PASSWORD_CAPS"), + button_display_func = function() + local f31_local0 = Engine.GetDvarString("password") + if f31_local0 then + f31_local0 = Engine.GetDvarString("password") ~= "" + end + local f31_local1 + if f31_local0 then + f31_local1 = Engine.Localize("PATCH_MENU_PASSWORD_SET") + if not f31_local1 then + + else + return f31_local1 + end + end + f31_local1 = Engine.Localize("MENU_NONE") + end, + button_action_func = function(f32_arg0, f32_arg1) + Engine.ExecNow("setfromdvar ui_password password") + Engine.OpenScreenKeyboard(f32_arg1.controller, Engine.Localize("MENU_PASSWORD"), Engine.GetDvarString("ui_password") or "", Lobby.PasswordLength, false, false, CoD.KeyboardInputTypes.Password) + end + }, + handlers = { + text_input_complete = function(f33_arg0, f33_arg1) + if f33_arg1.text then + Engine.SetDvarString("password", f33_arg1.text) + f33_arg0:processEvent({ + name = "content_refresh" + }) + end + end + } + }, + { + type = "UIGenericButton", + id = "connect_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("MENU_JOIN_GAME"), button_action_func = function() + Lobby.JoinServer(controller, server.idx) + end + } + + } + } + } + } +end + +password_field = function(f50_arg0, f50_arg1) + return { + type = "UIElement", + id = "server_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 145 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_LOBBY_JOINING"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "UIElement", + id = "mp_server_password_popup_page_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "generic_border", + properties = { + thickness = 2, + border_red = Colors.generic_menu_frame_color.r, + border_green = Colors.generic_menu_frame_color.g, + border_blue = Colors.generic_menu_frame_color.b + }, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + alpha = 0.6 + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -90, + bottom = 0, + left = 0, + right = 0, + spacing = 5 + } + }, + childrenFeeder = ServerPasswordListFeeder + } + } + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +LUI.MenuBuilder.registerDef("server_password_field", password_field) diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua new file mode 100644 index 0000000..af09c63 --- /dev/null +++ b/data/ui_scripts/stats/__init__.lua @@ -0,0 +1,167 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +game:addlocalizedstring("LUA_MENU_UNLOCKALL", "UNLOCK ALL") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_DESC", + "Whether all items should be unlocked.") + +function UnlockAllAction( f1_arg0, f1_arg1 ) + Engine.Exec("unlockstats") +end + +function StatsButtonHelper( f2_arg0, f2_arg1 ) + f2_arg0:processEvent( LUI.ButtonHelperText.CommonEvents.addBackButton ) +end + +function BarrackPrestigeResetStatsAction( f3_arg0, f3_arg1 ) + LUI.FlowManager.RequestAddMenu( f3_arg0, "prestige_reset", true, f3_arg1.controller ) +end + +function menu_stats() + return { + type = "UIElement", + id = "menu_stats_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = StatsButtonHelper, + }, + children = { + { + type = "generic_menu_title", + id = "stats_title_text_id", + properties = { + menu_title = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ) + } + }, + { + type = "UIVerticalList", + id = "stats_options_vlist_id", + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + }, + childrenFeeder = StatsOptionsFeeder + }, + { + type = "button_helper_text_main", + id = "stats_button_helper_text_id" + }, + { + type = "UIBindButton", + id = "stats_bind_buttons_id", + handlers = { + button_secondary = MBh.LeaveMenu() + } + }, + } + } +end + +function StatsOptionsFeeder( f8_arg0 ) + local f8_local4 = {} + local f8_local0 = Engine.IsAliensMode() + local f8_local2 = Engine.InLobby() + local f8_local3 = f8_arg0.exclusiveController + f8_local4[#f8_local4 + 1] = { + type = "UIGenericButton", + id = "unlockall_items_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_UNLOCKALL" ), + button_action_func = UnlockAllAction, + desc_text = Engine.Localize( "@LUA_MENU_UNLOCKALL_DESC" ) + } + } + if not f8_local2 then + local f8_local5 = #f8_local4 + 1 + local f8_local6 = { + type = "UIGenericButton", + id = "reset_stats_button_id" + } + local f8_local7 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f8_local7 = Engine.IsUserAGuest( f8_local3 ) + else + f8_local7 = true + end + f8_local6.disabled = f8_local7 + f8_local6.properties = { + button_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_CAPS" ), + button_action_func = BarrackPrestigeResetStatsAction, + desc_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_DESC" ) + } + f8_local6.handlers = { + element_refresh = function ( f12_arg0, f12_arg1 ) + local f12_local0 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f12_local0 = Engine.IsUserAGuest( f8_local3 ) + else + f12_local0 = true + end + local f12_local1 = f12_arg0 + local f12_local2 = f12_arg0.processEvent + local f12_local3 = {} + local f12_local4 + if f12_local0 then + f12_local4 = "disable" + if not f12_local4 then + + else + f12_local3.name = f12_local4 + f12_local2( f12_local1, f12_local3 ) + end + end + f12_local4 = "enable" + end + } + f8_local4[f8_local5] = f8_local6 + end + f8_local4[#f8_local4 + 1] = { + type = "button_desc_text", + id = "stats_button_description_id" + } + return f8_local4 +end + +function stats_options_vlist() + return { + type = "UIVerticalList", + focusable = true, + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + } + } +end + +LUI.MenuBuilder.registerDef( "menu_stats", menu_stats ) +LUI.MenuBuilder.registerDef( "stats_options_vlist", stats_options_vlist ) diff --git a/data/ui_scripts/string_override/__init__.lua b/data/ui_scripts/string_override/__init__.lua new file mode 100644 index 0000000..555dc9b --- /dev/null +++ b/data/ui_scripts/string_override/__init__.lua @@ -0,0 +1,6 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +game:addlocalizedstring("LUA_MENU_MP_SQUADS_DLC_CATEGORY_4_CAPS", "^3SAFEGUARD - BOTS^7"); +game:addlocalizedstring("LUA_MENU_MP_SQUADS_DLC_DESC_4", "Play Safeguard alongside AI teammates."); diff --git a/data/ui_scripts/team_select/__init__.lua b/data/ui_scripts/team_select/__init__.lua new file mode 100644 index 0000000..f482e6b --- /dev/null +++ b/data/ui_scripts/team_select/__init__.lua @@ -0,0 +1,101 @@ +if (game:issingleplayer()) then + return +end + +if (package.loaded["LUI.mp_hud.OptionsMenu"] == nil) then + return +end + +package.loaded["LUI.mp_hud.OptionsMenu"].options_def = function() + local f14_local0 = GameX.GetGameMode() + local f14_local1 = Engine.TableLookup( GameTypesTable.File, GameTypesTable.Cols.Ref, f14_local0, GameTypesTable.Cols.ClassChoice ) == "1" + + if not f14_local1 then + f14_local1 = GameX.UsesFakeLoadout() + end + + local f14_local2 = LUI.mp_hud.OptionsMenu.checkTeamChoice( f14_local0 ) + local f14_local3 = GameX.IsRankedMatch() + local f14_local4 = Engine.GetDvarBool( "splitscreen_ingame" ) + local f14_local5 = Game.GetOmnvar( "ui_team_selected" ) + local f14_local6 = Game.GetOmnvar( "ui_loadout_selected" ) + local f14_local7 = LUI.mp_hud.OptionsMenu.chooseClassCheck( f14_local3, f14_local5, f14_local2 ) + local self = LUI.UIVerticalList.new() + self.id = "pause_selections_Id" + + self:registerAnimationState("default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = false, + top = GenericMenuDims.menu_top, + left = GenericMenuDims.menu_left, + bottom = GenericMenuDims.menu_bottom, + right = GenericMenuDims.menu_right, + alignment = LUI.Alignment.Top + }) + + self:animateToState( "default", 0 ) + self:makeFocusable() + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and GameX.IsSpectatingNotOnTeam() == false and f14_local1 == true and f14_local7 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_0", + properties = { + childNum = 1, + button_text = Engine.Localize( "@LUA_MENU_CHOOSE_CLASS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.chooseClassButtonAction + } + }) + end + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and f14_local2 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_1", + properties = { + childNum = 2, + button_text = Engine.Localize( "@LUA_MENU_CHANGE_TEAM_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.changeTeamButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_2", + disabledFunc = LUI.mp_hud.OptionsMenu.optionsLockedUpdate, + properties = { + childNum = 3, + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.optionsButtonAction + }, + handlers = { + refresh_options_button = LUI.mp_hud.OptionsMenu.refreshOptionDisable + } + }) + + if GameX.IsOnlineMatch() and (not Engine.IsAliensMode() or not Game.GetOmnvar( "ui_alien_is_solo" )) and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_3", + properties = { + childNum = 4, + button_text = Engine.Localize( "@LUA_MENU_MUTE_PLAYERS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.mutePlayersButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_5", + properties = { + childNum = 6, + button_text = Engine.Localize( "@LUA_MENU_END_GAME_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.endGameButtonAction + } + }) + return self +end diff --git a/iw6/server.cfg b/iw6/server.cfg new file mode 100644 index 0000000..4d5ca6d --- /dev/null +++ b/iw6/server.cfg @@ -0,0 +1,366 @@ +/////////////////////////////////////////////////// +/// IW6 Server Configuration // +/////////////////////////////////////////////////// + +/////////////////////////////////////////////////// +// SERVER NAME & COLORS TIPS // +/////////////////////////////////////////////////// +// // +// ^1 Red // +// ^2 Green // +// ^3 yellow // +// ^4 Blue // +// ^5 Cyan // +// ^6 Pink // +// ^7 White // +// ^8 Depends on the team colors playing. // +// ^9 grey // +// ^0 Black // +// ^: Rainbow colors // +// // +/////////////////////////////////////////////////// + +set sv_hostname "IW6 Default Server" // Sets the server hostname. +name "[IW6] server" // Currently sets the say name + +////////////////////////////////////////////////// +// ADMIN INFO (Optional) // +////////////////////////////////////////////////// + +set _Admin "" // Your username. +set _Email "" // E-mail address. you can leave blank +set _Website "" // Website. (IW4MAdmin uses this.) +set _Location "Earth" // Location + +////////////////////////////////////////////////// +// NON-GAMEPLAY CONFIGURATION // +////////////////////////////////////////////////// + +set sv_maxclients "18" // Max players in your server. +set rcon_password "" // Access to your server to change stuff remotely or ingame. (Empty = disabled) +set g_password "" // Password Protected Server. Leave blank if you want players to join or set password if you want to keep public out. +set g_deadChat "0" // Toggle allowing dead players to chat with living players. (0 (default) or 1) +set g_inactivity "420" // Time in seconds before the server will kick a user for inactivity. (range 0 - 10000) +set sv_kickBanTime "3600" // Time in seconds for a player temporary ban. (on kick/tempban) (range 0 - 3600) +set sv_allowClientConsole "1" // Enable or Disable players ability to access server commands. +set sv_timeout "20" // Timeout time period. You will timeout after (20) seconds when attempting to connect or if you are getting connection interruptions. +set sv_reconnectlimit "3" // How many times you can try to reconnect. + +////////////////////////////////////////////////// +// BASE GAME CONFIGURATION // +////////////////////////////////////////////////// +// // +// blitz - Blitz // +// conf - Kill Confirmed // +// cranked - Cranked // +// dm - Free-for-all // +// dom - Domination // +// grind - Grind // +// grnd - Drop Zone // +// gun - Gun Game // +// horde - Safeguard // +// infect - Infected // +// sd - Search and Destroy // +// siege - Reinforce // +// sotf - Hunted // +// sotf_ffa - Hunted FFA // +// sr - Search and Rescue // +// war - Team Deathmatch // +// // +////////////////////////////////////////////////// + +//GAMETYPE CURRENTLY HAS TO BE SET VIA THE MAP ROTATION + +set scr_game_allowkillcam "1" // Allow Killcam. +set team_rebalance "1" // Auto Balance teams? +set scr_teambalance "1" // Enable or Disable auto balance. +set scr_game_spectatetype "2" // Allow Spectators. 0 Disabled, 1 Team/Player only, 2 Free +set sv_checkMinPlayers "0" +set scr_game_graceperiod "0" +set scr_game_onlyheadshots "0" +set scr_game_deathpointloss "0" +set scr_game_suicidepointloss "0" +set scr_team_teamkillpointloss "1" +set scr_game_perks "1" +set scr_game_forceuav "0" +set scr_game_hardpoints "1" +set scr_nukeTimer "10" +set scr_nukeCancelMode "0" +set scr_default_maxagents "5" +set scr_disableClientSpawnTraces "0" +set scr_hardpoint_allowartillery "1" +set scr_hardpoint_allowuav "1" +set scr_hardpoint_allowhelicopter "1" +set scr_team_respawntime "0" +set scr_player_numlives "0" +set scr_player_respawndelay "0" +set scr_player_suicidespawndelay "0" +set scr_player_forcerespawn "1" +set scr_player_sprinttime "4" +set scr_explBulletMod "1" +set scr_maxPerPlayerExplosives "2" + +////////////////////////////////////////////////// +// HARDCORE CONFIGURATION // +////////////////////////////////////////////////// +// uncomment below commands for some hardcore // +// by removing the // before each set dvar. // +////////////////////////////////////////////////// + +// set g_hardcore "1" // Enable hardcore mode. +// set scr_hardcore "1" // Enable hardcore mode again... +// set ui_hud_hardcore "1" // Removes Heads up display which can be used both regular and HC. +// set scr_player_maxhealth "30" // Percent of Health players will have on Respawn. (100 is normal. 30 is hardcore) +// set scr_team_fftype "1" // Enable or Disable Friendly Fire. (1 on, 2 reflect, 3 shared) +// set scr_player_healthregentime "0" // Time it takes you to recover damage. (5 is normal, 0 is hardcore) +// set scr_team_teamkillspawndelay "20" +// set scr_team_kickteamkillers "0" + +////////////////////////////////////////////////// +// TEAM DEATHMATCH GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_war_scorelimit "75" // Score limit to win the game. +set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_war_playerrespawndelay "0" // How long player will wait until respawn. +set scr_war_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_war_numlives "0" // Number of lives per player 0 for unlimited. +set scr_war_roundlimit "1" // Rounds per game. +set scr_war_winlimit "1" // Amount of wins needed to win a round-based game +set scr_war_promode "0" + +////////////////////////////////////////////////// +// FREE FOR ALL GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_dm_scorelimit "30" // Score limit to win the game. +set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_dm_playerrespawndelay "0" // How long player will wait until respawn. +set scr_dm_numlives "0" // Number of lives per player. 0 for unlimited. +set scr_dm_roundlimit "1" // Rounds per game. +set scr_dm_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_dm_promode "0" + +////////////////////////////////////////////////// +// DOMINATION GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_dom_scorelimit "200" // Score limit to win the game. +set scr_dom_timelimit "0" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_dom_playerrespawndelay "0" // How long player will wait until respawn. +set scr_dom_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_dom_numlives "0" // Number of lives per player per game. 0 is unlimited. +set scr_dom_roundlimit "1" // Rounds per game. +set scr_dom_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_dom_promode "0" + +////////////////////////////////////////////////// +// SEARCH AND DESTROY GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_sd_scorelimit "1" // Score limit required to win the game. +set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_sd_playerrespawndelay "0" // How long player will wait until respawn. +set scr_sd_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_sd_numlives "1" // Number of lives per player per game. +set scr_sd_roundlimit "0" // Rounds the game is limited to 0 for unlimited. +set scr_sd_winlimit "4" // Amount of wins needed to win a round-based game. +set scr_sd_roundswitch "3" // After X rounds, switch sides. +set scr_sd_bombtimer "45" // Time taken for the bomb to detonate. +set scr_sd_defusetime "5" // Time taken to defuse the bomb. +set scr_sd_multibomb "0" // Allow multiple people to 'have the bomb'. +set scr_sd_planttime "5" // How long will it take player to 'plant the bomb'. +set scr_sd_promode "0" + +////////////////////////////////////////////////// +// SEARCH AND RESCUE GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_sr_scorelimit "1" // Score limit required to win the game. +set scr_sr_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_sr_playerrespawndelay "0" // How long player will wait until respawn. +set scr_sr_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_sr_numlives "1" // Number of lives per player per game. +set scr_sr_roundlimit "0" // Rounds the game is limited to 0 for unlimited. +set scr_sr_winlimit "4" // amount of wins needed to win a round-based game. +set scr_sr_roundswitch "3" // After X rounds, switch sides. +set scr_sr_bombtimer "45" // Time taken for the bomb to detonate. +set scr_sr_defusetime "5" // Time taken to defuse the bomb. +set scr_sr_multibomb "0" // allow multiple people to 'have the bomb'. +set scr_sr_planttime "5" // How long will it take player to 'plant the bomb'. +set scr_sr_promode "0" + +////////////////////////////////////////////////// +// KILL CONFIRMED GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_conf_scorelimit "65" // Score limit to win the game. +set scr_conf_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_conf_playerrespawndelay "0" // How long player will wait until respawn. +set scr_conf_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_conf_numlives "0" // Number of lives per player 0 for unlimited. +set scr_conf_roundlimit "1" // Rounds per game. +set scr_conf_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_conf_promode "0" + +////////////////////////////////////////////////// +// INFECTED DRAFT GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_infect_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_infect_playerrespawndelay "0" // How long player will wait until respawn. +set scr_infect_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_infect_numlives "0" // Number of lives per player 0 for unlimited. +set scr_infect_roundlimit "1" // Rounds per game. +set scr_infect_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_infect_promode "0" + +////////////////////////////////////////////////// +// GRIND GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_grind_scorelimit "65" // Score limit to win the game. +set scr_grind_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_grind_playerrespawndelay "0" // How long player will wait until respawn. +set scr_grind_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_grind_numlives "0" // Number of lives per player 0 for unlimited. +set scr_grind_roundlimit "1" // Rounds per game. +set scr_grind_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_grind_promode "0" + +////////////////////////////////////////////////// +// DROP ZONE GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_grnd_scorelimit "7500" // Score limit to win the game. +set scr_grnd_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_grnd_dropTime "15" // Time it takes for the care packages to drop. +set scr_grnd_numlives "0" // Number of lives per player 0 for unlimited. +set scr_grnd_playerrespawndelay "0" // How long player will wait until respawn. +set scr_grnd_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_grnd_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_grnd_zoneSwitchTime "60" // Amount of time before the zone switches. +set scr_grnd_promode "0" + +////////////////////////////////////////////////// +// BLITZ GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_blitz_scorelimit "16" // Score limit to win the game. +set scr_blitz_timelimit "5" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_blitz_playerrespawndelay "0" // How long player will wait until respawn. +set scr_blitz_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_blitz_numlives "0" // Number of lives per player 0 for unlimited. +set scr_blitz_roundlimit "2" // Rounds per game. +set scr_blitz_roundswitch "1" // Switching sides. +set scr_blitz_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_blitz_scoredelay "10" +set scr_blitz_promode "0" + +////////////////////////////////////////////////// +// CRANKED GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_cranked_scorelimit "100" // Score limit to win the game. +set scr_cranked_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_cranked_playerrespawndelay "0" // How long player will wait until respawn. +set scr_cranked_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_cranked_numlives "0" // Number of lives per player 0 for unlimited. +set scr_cranked_roundlimit "1" // Rounds per game. +set scr_cranked_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_cranked_teambased "1" // Cranked in Team mode instead of Free-for-all. +set scr_cranked_scorelimit_ffa "60" // Score limit to win the game on FFA mode if teambased is set to 0. +set scr_cranked_promode "0" + +////////////////////////////////////////////////// +// SAFEGUARD GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_horde_scorelimit "0" // Score limit to win the game. +set scr_horde_timelimit "0" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_horde_roundlimit "1" // Rounds per game. +set scr_horde_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_horde_numlives "1" // Number of lives per player 0 for unlimited. +set scr_horde_playerrespawndelay "0" // How long player will wait until respawn. +set scr_horde_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_horde_promode "0" +set scr_horde_maxagents "24" +set scr_horde_difficulty "3" + +////////////////////////////////////////////////// +// HUNTED GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_sotf_scorelimit "65" // Score limit to win the game. +set scr_sotf_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_sotf_roundlimit "1" // Rounds per game. +set scr_sotf_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_sotf_numlives "0" // Number of lives per player 0 for unlimited. +set scr_sotf_playerrespawndelay "0" // How long player will wait until respawn. +set scr_sotf_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_sotf_promode "0" + +////////////////////////////////////////////////// +// HUNTED (FFA) GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_sotf_ffa_scorelimit "25" // Score limit to win the game. +set scr_sotf_ffa_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached. +set scr_sotf_ffa_roundlimit "1" // Rounds per game. +set scr_sotf_ffa_winlimit "1" // Amount of wins needed to win a round-based game. +set scr_sotf_ffa_numlives "0" // Number of lives per player 0 for unlimited. +set scr_sotf_ffa_playerrespawndelay "0" // How long player will wait until respawn. +set scr_sotf_ffa_waverespawndelay "0" // Duration is seconds before the first respawn in each round. +set scr_sotf_ffa_promode "0" + +//////////////////////////////////////////////////////// +// MAP SHORT NAMES ROTATION LIST // +//////////////////////////////////////////////////////// +// // +// Prision Break - mp_prisonbreak // +// Octane - mp_dart // +// Tremor - mp_lonestar // +// Freight - mp_frag // +// Whiteout - mp_snow // +// Stormfront - mp_fahrenheit // +// Siege - mp_hashima // +// Warhawk - mp_warhawk // +// Sovereign - mp_sovereign // +// Overload - mp_zebra // +// Stonehaven - mp_skeleton // +// Chasm - mp_chasm // +// Flooded - mp_flooded // +// Strikezone - mp_strikezone // +// Free Fall - mp_descent_new // +// // +/// DEVASTATION DLC //////////////////////////////////// +// // +// Unearthed - mp_dome_ns // +// Collision - mp_ca_impact // +// Behemoth - mp_ca_behemoth // +// Ruins - mp_battery3 // +// // +/// INVASION DLC /////////////////////////////////////// +// // +// Pharaoh - mp_dig // +// Favela - mp_favela_iw6 // +// Mutiny - mp_pirate // +// Departed - mp_zulu // +// // +/// NEMESIS DLC //////////////////////////////////////// +// // +// Dynasty - mp_conflict // +// Goldrush - mp_mine // +// Showtime - mp_shipment_ns // +// Subzero - mp_zerosub // +// // +/// ONSLAUGHT DLC ////////////////////////////////////// +// // +// Ignition - mp_boneyard_ns // +// Containment - mp_ca_red_river // +// Bayview - mp_ca_rumble // +// Fog - mp_swamp // +// // +//////////////////////////////////////////////////////// + +set sv_maprotation "gametype war map mp_prisonbreak map mp_dart map mp_lonestar map mp_frag map mp_snow map mp_fahrenheit map mp_hashima map mp_warhawk map mp_sovereign map mp_zebra map mp_skeleton map mp_chasm map mp_flooded map mp_strikezone map mp_descent_new map mp_dome_ns map mp_ca_impact map mp_ca_behemoth map mp_battery3 map mp_dig map mp_favela_iw6 map mp_pirate map mp_conflict map mp_mine map mp_shipment_ns map mp_zerosub map mp_boneyard_ns map mp_ca_red_river map mp_ca_rumble map mp_swamp" diff --git a/iw6/server_zm.cfg b/iw6/server_zm.cfg new file mode 100644 index 0000000..116844f --- /dev/null +++ b/iw6/server_zm.cfg @@ -0,0 +1,130 @@ +/////////////////////////////////////////////////// +/// IW6 Server Configuration // +/////////////////////////////////////////////////// + +/////////////////////////////////////////////////// +// SERVER NAME & COLORS TIPS // +/////////////////////////////////////////////////// +// // +// ^1 Red // +// ^2 Green // +// ^3 yellow // +// ^4 Blue // +// ^5 Cyan // +// ^6 Pink // +// ^7 White // +// ^8 Depends on the team colors playing. // +// ^9 grey // +// ^0 Black // +// ^: Rainbow colors // +// // +/////////////////////////////////////////////////// + +set sv_hostname "IW6 Default Server" // Sets the server hostname. +name "[IW6] server" // Currently sets the say name + +////////////////////////////////////////////////// +// ADMIN INFO (Optional) // +////////////////////////////////////////////////// + +set _Admin "" // Your username. +set _Email "" // E-mail address. you can leave blank +set _Website "" // Website. (IW4MAdmin uses this.) +set _Location "Earth" // Location + +////////////////////////////////////////////////// +// NON-GAMEPLAY CONFIGURATION // +////////////////////////////////////////////////// + +set sv_maxclients "4" // Max players in your server. +set rcon_password "" // Access to your server to change stuff remotely or ingame. (Empty = disabled) +set g_password "" // Password Protected Server. Leave blank if you want players to join or set password if you want to keep public out. +set g_deadChat "0" // Toggle allowing dead players to chat with living players. (0 (default) or 1) +set g_inactivity "420" // Time in seconds before the server will kick a user for inactivity. (range 0 - 10000) +set sv_kickBanTime "3600" // Time in seconds for a player temporary ban. (on kick/tempban) (range 0 - 3600) +set sv_allowClientConsole "1" // Enable or Disable players ability to access server commands. +set sv_timeout "20" // Timeout time period. You will timeout after (20) seconds when attempting to connect or if you are getting connection interruptions. +set sv_reconnectlimit "3" // How many times you can try to reconnect. + +////////////////////////////////////////////////// +// BASE GAME CONFIGURATION // +////////////////////////////////////////////////// +// // +// aliens - Extinction (CO-OP MODE) // +// // +////////////////////////////////////////////////// + +//GAMETYPE CURRENTLY HAS TO BE SET VIA THE MAP ROTATION + +set scr_game_allowkillcam "1" // Allow Killcam. +set team_rebalance "1" // Auto Balance teams? +set scr_teambalance "1" // Enable or Disable auto balance. +set scr_game_spectatetype "2" // Allow Spectators. 0 Disabled, 1 Team/Player only, 2 Free +set sv_checkMinPlayers "0" +set scr_game_graceperiod "0" +set scr_game_onlyheadshots "0" +set scr_game_deathpointloss "0" +set scr_game_suicidepointloss "0" +set scr_team_teamkillpointloss "1" +set scr_game_perks "1" +set scr_game_forceuav "0" +set scr_game_hardpoints "1" +set scr_nukeTimer "10" +set scr_nukeCancelMode "0" +set scr_default_maxagents "5" +set scr_disableClientSpawnTraces "0" +set scr_hardpoint_allowartillery "1" +set scr_hardpoint_allowuav "1" +set scr_hardpoint_allowhelicopter "1" +set scr_team_respawntime "0" +set scr_player_numlives "0" +set scr_player_respawndelay "0" +set scr_player_suicidespawndelay "0" +set scr_player_forcerespawn "1" +set scr_player_sprinttime "4" +set scr_explBulletMod "1" +set scr_maxPerPlayerExplosives "2" + +////////////////////////////////////////////////// +// EXTINCTION GAMETYPE SETTINGS // +////////////////////////////////////////////////// + +set scr_aliens_scorelimit "2500" +set scr_aliens_timelimit "0" +set scr_aliens_roundlimit "1" +set scr_aliens_winlimit "1" +set scr_aliens_numlives "0" +set scr_aliens_playerrespawndelay "0" +set scr_aliens_waverespawndelay "0" +set scr_aliens_promode "0" +set scr_aliens_maxagents "24" +set scr_alien_intro "0" +set scr_chaos_mode "0" // Extinction chaos game mode. + +//////////////////////////////////////////////////////// +// MAP SHORT NAMES ROTATION LIST // +//////////////////////////////////////////////////////// +/// Maps only work with Aliens Game Mode Set // +//////////////////////////////////////////////////////// +// // +// Point of Contact - mp_alien_town // +// // +// ONSLAUGHT DLC /////////////////////////////////////// +// // +// Nightfall - mp_alien_armory // +// // +// DEVASTATION DLC ///////////////////////////////////// +// // +// Mayday - mp_alien_beacon // +// // +// INVASION DLC //////////////////////////////////////// +// // +// Awakening - mp_alien_dlc3 // +// // +// NEMESIS DLC ///////////////////////////////////////// +// // +// Exodus - mp_alien_last // +// // +//////////////////////////////////////////////////////// + +set sv_maprotation "gametype aliens map mp_alien_town map mp_alien_armory map mp_alien_beacon map mp_alien_dlc3 map mp_alien_last"