From 80ffa1a3d70453184e7448c94abfc3c6ad84e40d Mon Sep 17 00:00:00 2001 From: JezuzLizard Date: Wed, 25 Mar 2020 01:52:40 -0700 Subject: [PATCH] initial commit --- .../maps/mp/gametypes_zm/_clientids.gsc | 16 + .../maps/mp/gametypes_zm/_globalentities.gsc | 0 .../maps/mp/gametypes_zm/_scoreboard.gsc | 25 + .../maps/mp/gametypes_zm/_shellshock.gsc | 65 + .../maps/mp/gametypes_zm/zclassic.gsc | 31 + .../patch_zm/maps/mp/zombies/_zm.gsc | 6086 +++++++++++++++++ .../patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc | 742 ++ .../patch_zm/maps/mp/zombies/_zm_bot.gsc | 10 + .../patch_zm/maps/mp/zombies/_zm_magicbox.gsc | 1656 +++++ .../mp/zombies/_zm_perk_electric_cherry.gsc | 400 ++ .../maps/mp/zombies/_zm_tombstone.gsc | 540 ++ Fixed Zombies GSCs for compiling/readme.md | 25 + .../maps/mp/gametypes_zm/zgrief.gsc | 730 ++ .../maps/mp/zm_transit_utility.gsc | 279 + .../maps/mp/zombies/_zm_weap_jetgun.gsc | 935 +++ 15 files changed, 11540 insertions(+) create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_clientids.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_globalentities.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_shellshock.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/zclassic.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_bot.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_magicbox.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perk_electric_cherry.gsc create mode 100644 Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_tombstone.gsc create mode 100644 Fixed Zombies GSCs for compiling/readme.md create mode 100644 Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc create mode 100644 Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zm_transit_utility.gsc create mode 100644 Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_clientids.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_clientids.gsc new file mode 100644 index 0000000..b17e410 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_clientids.gsc @@ -0,0 +1,16 @@ + +init() +{ + level.clientid = 0; + level thread onplayerconnect(); +} + +onplayerconnect() +{ + for ( ;; ) + { + level waittill( "connecting", player ); + player.clientid = level.clientid; + level.clientid++; + } +} diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_globalentities.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_globalentities.gsc new file mode 100644 index 0000000..e69de29 diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc new file mode 100644 index 0000000..9c57984 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc @@ -0,0 +1,25 @@ + +init() +{ + setdvar( "g_ScoresColor_Spectator", ".25 .25 .25" ); + setdvar( "g_ScoresColor_Free", ".76 .78 .10" ); + setdvar( "g_teamColor_MyTeam", ".4 .7 .4" ); + setdvar( "g_teamColor_EnemyTeam", "1 .315 0.35" ); + setdvar( "g_teamColor_MyTeamAlt", ".35 1 1" ); + setdvar( "g_teamColor_EnemyTeamAlt", "1 .5 0" ); + setdvar( "g_teamColor_Squad", ".315 0.35 1" ); + if ( level.createfx_enabled ) + { + return; + } + if ( sessionmodeiszombiesgame() ) + { + setdvar( "g_TeamIcon_Axis", "faction_cia" ); + setdvar( "g_TeamIcon_Allies", "faction_cdc" ); + } + else + { + setdvar( "g_TeamIcon_Axis", game[ "icons" ][ "axis" ] ); + setdvar( "g_TeamIcon_Allies", game[ "icons" ][ "allies" ] ); + } +} diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_shellshock.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_shellshock.gsc new file mode 100644 index 0000000..c718e80 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_shellshock.gsc @@ -0,0 +1,65 @@ +#include common_scripts/utility; +#include maps/mp/_utility; + +init() +{ + precacheshellshock( "frag_grenade_mp" ); + precacheshellshock( "damage_mp" ); + precacherumble( "artillery_rumble" ); + precacherumble( "grenade_rumble" ); +} + +shellshockondamage( cause, damage ) +{ + if ( cause != "MOD_EXPLOSIVE" && cause != "MOD_GRENADE" && cause != "MOD_GRENADE_SPLASH" || cause == "MOD_PROJECTILE" && cause == "MOD_PROJECTILE_SPLASH" ) + { + time = 0; + if ( damage >= 90 ) + { + time = 4; + } + else if ( damage >= 50 ) + { + time = 3; + } + else if ( damage >= 25 ) + { + time = 2; + } + else + { + if ( damage > 10 ) + { + time = 2; + } + } + if ( time ) + { + if ( self mayapplyscreeneffect() ) + { + self shellshock( "frag_grenade_mp", 0.5 ); + } + } + } +} + +endondeath() +{ + self waittill( "death" ); + waittillframeend; + self notify( "end_explode" ); +} + +endontimer( timer ) +{ + self endon( "disconnect" ); + wait timer; + self notify( "end_on_timer" ); +} + +rcbomb_earthquake( position ) +{ + playrumbleonposition( "grenade_rumble", position ); + earthquake( 0.5, 0.5, self.origin, 512 ); +} + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/zclassic.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/zclassic.gsc new file mode 100644 index 0000000..50bbe3d --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/zclassic.gsc @@ -0,0 +1,31 @@ +#include maps/mp/zombies/_zm_stats; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/_utility; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/zombies/_zm_stats; + +main() +{ + maps/mp/gametypes_zm/_zm_gametype::main(); + level.onprecachegametype = ::onprecachegametype; + level.onstartgametype = ::onstartgametype; + level._game_module_custom_spawn_init_func = ::custom_spawn_init_func; + level._game_module_stat_update_func = ::survival_classic_custom_stat_update; + maps/mp/gametypes_zm/_zm_gametype::post_gametype_main( "zclassic" ); +} + +onprecachegametype() +{ + level.playersuicideallowed = 1; + level.canplayersuicide = ::canplayersuicide; + level.suicide_weapon = "death_self_zm"; + precacheitem( "death_self_zm" ); + maps/mp/gametypes_zm/_zm_gametype::rungametypeprecache( "zclassic" ); +} + +onstartgametype() +{ + maps/mp/gametypes_zm/_zm_gametype::rungametypemain( "zclassic", ::zclassic_main ); +} + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc new file mode 100644 index 0000000..027c6e5 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc @@ -0,0 +1,6086 @@ +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/zombies/_zm_pers_upgrades_system; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ffotd; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_blockers; + +init() +{ + //level.player_out_of_playable_area_monitor = 1; + //level.player_too_many_weapons_monitor = 1; + //level.player_too_many_weapons_monitor_func = ::player_too_many_weapons_monitor; + //level.player_too_many_players_check = 1; + //level.player_too_many_players_check_func = ::player_too_many_players_check; + level._use_choke_weapon_hints = 1; + level._use_choke_blockers = 1; + level.passed_introscreen = 0; + if ( !isDefined( level.custom_ai_type ) ) + { + level.custom_ai_type = []; + } + level.custom_ai_spawn_check_funcs = []; + level.spawn_funcs = []; + level.spawn_funcs[ "allies" ] = []; + level.spawn_funcs[ "axis" ] = []; + level.spawn_funcs[ "team3" ] = []; + level thread maps/mp/zombies/_zm_ffotd::main_start(); + level.zombiemode = 1; + level.revivefeature = 0; + level.swimmingfeature = 0; + level.calc_closest_player_using_paths = 0; + level.zombie_melee_in_water = 1; + level.put_timed_out_zombies_back_in_queue = 1; + level.use_alternate_poi_positioning = 1; + level.zmb_laugh_alias = "zmb_laugh_richtofen"; + level.sndannouncerisrich = 1; + level.scr_zm_ui_gametype = getDvar( "ui_gametype" ); + level.scr_zm_ui_gametype_group = getDvar( "ui_zm_gamemodegroup" ); + level.scr_zm_map_start_location = getDvar( "ui_zm_mapstartlocation" ); + level.curr_gametype_affects_rank = 0; + gametype = tolower( getDvar( "g_gametype" ) ); + if ( gametype == "zclassic" || gametype == "zstandard" ) + { + level.curr_gametype_affects_rank = 1; + } + level.grenade_multiattack_bookmark_count = 1; + level.rampage_bookmark_kill_times_count = 3; + level.rampage_bookmark_kill_times_msec = 6000; + level.rampage_bookmark_kill_times_delay = 6000; + level thread watch_rampage_bookmark(); + if ( !isDefined( level._zombies_round_spawn_failsafe ) ) + { + level._zombies_round_spawn_failsafe = ::round_spawn_failsafe; + } + level.zombie_visionset = "zombie_neutral"; + if ( getDvar( "anim_intro" ) == "1" ) + { + level.zombie_anim_intro = 1; + } + else + { + level.zombie_anim_intro = 0; + } + precache_shaders(); + precache_models(); + precacherumble( "explosion_generic" ); + precacherumble( "dtp_rumble" ); + precacherumble( "slide_rumble" ); + precache_zombie_leaderboards(); + level._zombie_gib_piece_index_all = 0; + level._zombie_gib_piece_index_right_arm = 1; + level._zombie_gib_piece_index_left_arm = 2; + level._zombie_gib_piece_index_right_leg = 3; + level._zombie_gib_piece_index_left_leg = 4; + level._zombie_gib_piece_index_head = 5; + level._zombie_gib_piece_index_guts = 6; + level._zombie_gib_piece_index_hat = 7; + if ( !isDefined( level.zombie_ai_limit ) ) + { + level.zombie_ai_limit = 24; + } + if ( !isDefined( level.zombie_actor_limit ) ) + { + level.zombie_actor_limit = 31; + } + maps/mp/_visionset_mgr::init(); + init_dvars(); + init_strings(); + init_levelvars(); + init_sounds(); + init_shellshocks(); + init_flags(); + init_client_flags(); + registerclientfield( "world", "zombie_power_on", 1, 1, "int" ); + if ( isDefined( level._no_navcards ) && !level._no_navcards ) + { + if ( level.scr_zm_ui_gametype_group == "zclassic" && !level.createfx_enabled ) + { + registerclientfield( "allplayers", "navcard_held", 1, 4, "int" ); + level.navcards = []; + level.navcards[ 0 ] = "navcard_held_zm_transit"; + level.navcards[ 1 ] = "navcard_held_zm_highrise"; + level.navcards[ 2 ] = "navcard_held_zm_buried"; + level thread setup_player_navcard_hud(); + } + } + register_offhand_weapons_for_level_defaults(); + level thread drive_client_connected_notifies(); + /* +/# + maps/mp/zombies/_zm_devgui::init(); +#/ + */ + maps/mp/zombies/_zm_zonemgr::init(); + maps/mp/zombies/_zm_unitrigger::init(); + maps/mp/zombies/_zm_audio::init(); + maps/mp/zombies/_zm_blockers::init(); + maps/mp/zombies/_zm_bot::init(); + maps/mp/zombies/_zm_clone::init(); + maps/mp/zombies/_zm_buildables::init(); + maps/mp/zombies/_zm_equipment::init(); + maps/mp/zombies/_zm_laststand::init(); + maps/mp/zombies/_zm_magicbox::init(); + maps/mp/zombies/_zm_perks::init(); + maps/mp/zombies/_zm_playerhealth::init(); + maps/mp/zombies/_zm_power::init(); + maps/mp/zombies/_zm_powerups::init(); + maps/mp/zombies/_zm_score::init(); + maps/mp/zombies/_zm_spawner::init(); + maps/mp/zombies/_zm_gump::init(); + maps/mp/zombies/_zm_timer::init(); + maps/mp/zombies/_zm_traps::init(); + maps/mp/zombies/_zm_weapons::init(); + init_function_overrides(); + level thread last_stand_pistol_rank_init(); + level thread maps/mp/zombies/_zm_tombstone::init(); + level thread post_all_players_connected(); + init_utility(); + maps/mp/_utility::registerclientsys( "lsm" ); + maps/mp/zombies/_zm_stats::init(); + initializestattracking(); + if ( get_players().size <= 1 ) + { + incrementcounter( "global_solo_games", 1 ); + } + else if ( level.systemlink ) + { + incrementcounter( "global_systemlink_games", 1 ); + } + else if ( getDvarInt( "splitscreen_playerCount" ) == get_players().size ) + { + incrementcounter( "global_splitscreen_games", 1 ); + } + else + { + incrementcounter( "global_coop_games", 1 ); + } + onplayerconnect_callback( ::zm_on_player_connect ); + maps/mp/zombies/_zm_pers_upgrades::pers_upgrade_init(); + set_demo_intermission_point(); + level thread maps/mp/zombies/_zm_ffotd::main_end(); + level thread track_players_intersection_tracker(); + level thread onallplayersready(); + level thread startunitriggers(); + level thread maps/mp/gametypes_zm/_zm_gametype::post_init_gametype(); +} + +post_main() +{ + level thread init_custom_ai_type(); +} + +startunitriggers() +{ + flag_wait_any( "start_zombie_round_logic", "start_encounters_match_logic" ); + level thread maps/mp/zombies/_zm_unitrigger::main(); +} + +drive_client_connected_notifies() +{ + while ( 1 ) + { + level waittill( "connected", player ); + player reset_rampage_bookmark_kill_times(); + player callback( "on_player_connect" ); + } +} + +fade_out_intro_screen_zm( hold_black_time, fade_out_time, destroyed_afterwards ) +{ + if ( !isDefined( level.introscreen ) ) + { + level.introscreen = newhudelem(); + level.introscreen.x = 0; + level.introscreen.y = 0; + level.introscreen.horzalign = "fullscreen"; + level.introscreen.vertalign = "fullscreen"; + level.introscreen.foreground = 0; + level.introscreen setshader( "black", 640, 480 ); + level.introscreen.immunetodemogamehudsettings = 1; + level.introscreen.immunetodemofreecamera = 1; + wait 0.05; + } + level.introscreen.alpha = 1; + if ( isDefined( hold_black_time ) ) + { + wait hold_black_time; + } + else + { + wait 0.2; + } + if ( !isDefined( fade_out_time ) ) + { + fade_out_time = 1.5; + } + level.introscreen fadeovertime( fade_out_time ); + level.introscreen.alpha = 0; + wait 1.6; + level.passed_introscreen = 1; + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] setclientuivisibilityflag( "hud_visible", 1 ); + if ( isDefined( level.host_ended_game ) && !level.host_ended_game ) + { + if ( isDefined( level.player_movement_suppressed ) ) + { + players[ i ] freezecontrols( level.player_movement_suppressed ); + /* +/# + println( " Unfreeze controls 4" ); +#/ + */ + i++; + continue; + } + else + { + if ( isDefined( players[ i ].hostmigrationcontrolsfrozen ) && !players[ i ].hostmigrationcontrolsfrozen ) + { + players[ i ] freezecontrols( 0 ); + /* +/# + println( " Unfreeze controls 5" ); +#/ + */ + } + } + } + i++; + } + if ( destroyed_afterwards == 1 ) + { + level.introscreen destroy(); + } + flag_set( "initial_blackscreen_passed" ); +} + +onallplayersready() +{ + timeout = getTime() + 5000; + while ( getnumexpectedplayers() == 0 && getTime() < timeout ) + { + wait 0.1; + } + /* +/# + println( "ZM >> player_count_expected=" + getnumexpectedplayers() ); +#/ + */ + player_count_actual = 0; + while ( getnumconnectedplayers() < getnumexpectedplayers() || player_count_actual != getnumexpectedplayers() ) + { + players = get_players(); + player_count_actual = 0; + i = 0; + while ( i < players.size ) + { + players[ i ] freezecontrols( 1 ); + if ( players[ i ].sessionstate == "playing" ) + { + player_count_actual++; + } + i++; + } + /* +/# + println( "ZM >> Num Connected =" + getnumconnectedplayers() + " Expected : " + getnumexpectedplayers() ); +#/ + */ + wait 0.1; + } + setinitialplayersconnected(); + /* +/# + println( "ZM >> We have all players - START ZOMBIE LOGIC" ); +#/ + */ + if ( getnumconnectedplayers() == 1 && getDvarInt( "scr_zm_enable_bots" ) == 1 ) + { + level thread add_bots(); + flag_set( "initial_players_connected" ); + } + else + { + players = get_players(); + if ( players.size == 1 ) + { + flag_set( "solo_game" ); + level.solo_lives_given = 0; + _a379 = players; + _k379 = getFirstArrayKey( _a379 ); + while ( isDefined( _k379 ) ) + { + player = _a379[ _k379 ]; + player.lives = 0; + _k379 = getNextArrayKey( _a379, _k379 ); + } + //level maps/mp/zombies/_zm::set_default_laststand_pistol( 1 ); + } + flag_set( "initial_players_connected" ); + while ( !aretexturesloaded() ) + { + wait 0.05; + } + thread start_zombie_logic_in_x_sec( 3 ); + } + fade_out_intro_screen_zm( 5, 1.5, 1 ); +} + +start_zombie_logic_in_x_sec( time_to_wait ) +{ + wait time_to_wait; + flag_set( "start_zombie_round_logic" ); +} + +getallotherplayers() +{ + aliveplayers = []; + i = 0; + while ( i < level.players.size ) + { + if ( !isDefined( level.players[ i ] ) ) + { + i++; + continue; + } + else player = level.players[ i ]; + if ( player.sessionstate != "playing" || player == self ) + { + i++; + continue; + } + else + { + aliveplayers[ aliveplayers.size ] = player; + } + i++; + } + return aliveplayers; +} + +getfreespawnpoint( spawnpoints, player ) +{ + if ( !isDefined( spawnpoints ) ) + { + /* +/# + iprintlnbold( "ZM >> No free spawn points in map" ); +#/ + */ + return undefined; + } + if ( !isDefined( game[ "spawns_randomized" ] ) ) + { + game[ "spawns_randomized" ] = 1; + spawnpoints = array_randomize( spawnpoints ); + random_chance = randomint( 100 ); + if ( random_chance > 50 ) + { + set_game_var( "side_selection", 1 ); + } + else + { + set_game_var( "side_selection", 2 ); + } + } + side_selection = get_game_var( "side_selection" ); + if ( get_game_var( "switchedsides" ) ) + { + if ( side_selection == 2 ) + { + side_selection = 1; + } + else + { + if ( side_selection == 1 ) + { + side_selection = 2; + } + } + } + while ( isDefined( player ) && isDefined( player.team ) ) + { + i = 0; + while ( isDefined( spawnpoints ) && i < spawnpoints.size ) + { + if ( side_selection == 1 ) + { + if ( player.team != "allies" && isDefined( spawnpoints[ i ].script_int ) && spawnpoints[ i ].script_int == 1 ) + { + arrayremovevalue( spawnpoints, spawnpoints[ i ] ); + i = 0; + } + else + { + if ( player.team == "allies" && isDefined( spawnpoints[ i ].script_int ) && spawnpoints[ i ].script_int == 2 ) + { + arrayremovevalue( spawnpoints, spawnpoints[ i ] ); + i = 0; + } + else + { + i++; + } + } + continue; + } + else if ( player.team == "allies" && isDefined( spawnpoints[ i ].script_int ) && spawnpoints[ i ].script_int == 1 ) + { + arrayremovevalue( spawnpoints, spawnpoints[ i ] ); + i = 0; + continue; + } + else + { + if ( player.team != "allies" && isDefined( spawnpoints[ i ].script_int ) && spawnpoints[ i ].script_int == 2 ) + { + arrayremovevalue( spawnpoints, spawnpoints[ i ] ); + i = 0; + } + else + { + i++; + } + } + } + } + if ( !isDefined( self.playernum ) ) + { + if ( self.team == "allies" ) + { + self.playernum = get_game_var( "_team1_num" ); + set_game_var( "_team1_num", self.playernum + 1 ); + } + else + { + self.playernum = get_game_var( "_team2_num" ); + set_game_var( "_team2_num", self.playernum + 1 ); + } + } + j = 0; + while ( j < spawnpoints.size ) + { + while ( !isDefined( spawnpoints[ j ].en_num ) ) + { + m = 0; + while ( m < spawnpoints.size ) + { + spawnpoints[ m ].en_num = m; + m++; + } + } + if ( spawnpoints[ j ].en_num == self.playernum ) + { + return spawnpoints[ j ]; + } + j++; + } + return spawnpoints[ 0 ]; +} + +delete_in_createfx() +{ + exterior_goals = getstructarray( "exterior_goal", "targetname" ); + i = 0; + while ( i < exterior_goals.size ) + { + if ( !isDefined( exterior_goals[ i ].target ) ) + { + i++; + continue; + } + else + { + targets = getentarray( exterior_goals[ i ].target, "targetname" ); + j = 0; + while ( j < targets.size ) + { + targets[ j ] self_delete(); + j++; + } + } + i++; + } + if ( isDefined( level.level_createfx_callback_thread ) ) + { + level thread [[ level.level_createfx_callback_thread ]](); + } +} + +add_bots() +{ + host = gethostplayer(); + while ( !isDefined( host ) ) + { + wait 0.05; + host = gethostplayer(); + } + wait 4; + zbot_spawn(); + setdvar( "bot_AllowMovement", "1" ); + setdvar( "bot_PressAttackBtn", "1" ); + setdvar( "bot_PressMeleeBtn", "1" ); + while ( get_players().size < 2 ) + { + wait 0.05; + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] freezecontrols( 0 ); + /* +/# + println( " Unfreeze controls 6" ); +#/ + */ + i++; + } + level.numberbotsadded = 1; + flag_set( "start_zombie_round_logic" ); +} + +zbot_spawn() +{ + player = gethostplayer(); + spawnpoints = getstructarray( "initial_spawn_points", "targetname" ); + spawnpoint = getfreespawnpoint( spawnpoints ); + bot = addtestclient(); + if ( !isDefined( bot ) ) + { + /* +/# + println( "Could not add test client" ); +#/ + */ + return; + } + bot.pers[ "isBot" ] = 1; + bot.equipment_enabled = 0; + yaw = spawnpoint.angles[ 1 ]; + bot thread zbot_spawn_think( spawnpoint.origin, yaw ); + return bot; +} + +zbot_spawn_think( origin, yaw ) +{ + self endon( "disconnect" ); + for ( ;; ) + { + self waittill( "spawned_player" ); + self setorigin( origin ); + angles = ( 0, yaw, 0 ); + self setplayerangles( angles ); + } +} + +post_all_players_connected() +{ + level thread end_game(); + flag_wait( "start_zombie_round_logic" ); + /* +/# + println( "sessions: mapname=", level.script, " gametype zom isserver 1 player_count=", get_players().size ); +#/ + */ + level thread clear_mature_blood(); + level thread round_end_monitor(); + if ( !level.zombie_anim_intro ) + { + if ( isDefined( level._round_start_func ) ) + { + level thread [[ level._round_start_func ]](); + } + } + level thread players_playing(); + disablegrenadesuicide(); + level.startinvulnerabletime = getDvarInt( "player_deathInvulnerableTime" ); + if ( !isDefined( level.music_override ) ) + { + level.music_override = 0; + } +} + +init_custom_ai_type() +{ + while ( isDefined( level.custom_ai_type ) ) + { + i = 0; + while ( i < level.custom_ai_type.size ) + { + [[ level.custom_ai_type[ i ] ]](); + i++; + } + } +} + +zombiemode_melee_miss() +{ + if ( isDefined( self.enemy.curr_pay_turret ) ) + { + self.enemy dodamage( getDvarInt( "ai_meleeDamage" ), self.origin, self, self, "none", "melee" ); + } +} + +player_track_ammo_count() +{ + self notify( "stop_ammo_tracking" ); + self endon( "disconnect" ); + self endon( "stop_ammo_tracking" ); + ammolowcount = 0; + ammooutcount = 0; + while ( 1 ) + { + wait 0.5; + weap = self getcurrentweapon(); + while ( isDefined( weap ) || weap == "none" && !can_track_ammo( weap ) ) + { + continue; + } + while ( self getammocount( weap ) > 5 || self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + ammooutcount = 0; + ammolowcount = 0; + } + if ( self getammocount( weap ) > 0 ) + { + if ( ammolowcount < 1 ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "ammo_low" ); + ammolowcount++; + } + } + else + { + if ( ammooutcount < 1 ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "ammo_out" ); + ammooutcount++; + } + } + wait 20; + } +} + +can_track_ammo( weap ) +{ + if ( !isDefined( weap ) ) + { + return 0; + } + switch( weap ) + { + case "alcatraz_shield_zm": + case "chalk_draw_zm": + case "death_throe_zm": + case "equip_dieseldrone_zm": + case "equip_gasmask_zm": + case "humangun_upgraded_zm": + case "humangun_zm": + case "lower_equip_gasmask_zm": + case "no_hands_zm": + case "none": + case "riotshield_zm": + case "screecher_arms_zm": + case "slowgun_upgraded_zm": + case "slowgun_zm": + case "tazer_knuckles_upgraded_zm": + case "tazer_knuckles_zm": + case "time_bomb_detonator_zm": + case "time_bomb_zm": + case "zombie_bowie_flourish": + case "zombie_builder_zm": + case "zombie_fists_zm": + case "zombie_knuckle_crack": + case "zombie_sickle_flourish": + case "zombie_tazer_flourish": + return 0; + default: + if ( !is_zombie_perk_bottle( weap ) && !is_placeable_mine( weap ) && !is_equipment( weap ) && !issubstr( weap, "knife_ballistic_" ) && getsubstr( weap, 0, 3 ) != "gl_" || weaponfuellife( weap ) > 0 && weap == level.revive_tool ) + { + return 0; + } + } + return 1; +} + +spawn_vo() +{ + wait 1; + players = get_players(); + if ( players.size > 1 ) + { + player = random( players ); + index = maps/mp/zombies/_zm_weapons::get_player_index( player ); + player thread spawn_vo_player( index, players.size ); + } +} + +spawn_vo_player( index, num ) +{ + sound = "plr_" + index + "_vox_" + num + "play"; + self playsoundwithnotify( sound, "sound_done" ); + self waittill( "sound_done" ); +} + +precache_shaders() +{ + precacheshader( "hud_chalk_1" ); + precacheshader( "hud_chalk_2" ); + precacheshader( "hud_chalk_3" ); + precacheshader( "hud_chalk_4" ); + precacheshader( "hud_chalk_5" ); + precacheshader( "zom_icon_community_pot" ); + precacheshader( "zom_icon_community_pot_strip" ); + precacheshader( "zom_icon_player_life" ); + precacheshader( "waypoint_revive" ); +} + +precache_models() +{ + precachemodel( "p_zom_win_bars_01_vert04_bend_180" ); + precachemodel( "p_zom_win_bars_01_vert01_bend_180" ); + precachemodel( "p_zom_win_bars_01_vert04_bend" ); + precachemodel( "p_zom_win_bars_01_vert01_bend" ); + precachemodel( "p_zom_win_cell_bars_01_vert04_bent" ); + precachemodel( "p_zom_win_cell_bars_01_vert01_bent" ); + precachemodel( "tag_origin" ); + precachemodel( "zombie_z_money_icon" ); + if ( isDefined( level.precachecustomcharacters ) ) + { + self [[ level.precachecustomcharacters ]](); + } +} + +init_shellshocks() +{ + level.player_killed_shellshock = "zombie_death"; + precacheshellshock( level.player_killed_shellshock ); + precacheshellshock( "pain" ); + precacheshellshock( "explosion" ); +} + +init_strings() +{ + precachestring( &"ZOMBIE_WEAPONCOSTAMMO" ); + precachestring( &"ZOMBIE_ROUND" ); + precachestring( &"SCRIPT_PLUS" ); + precachestring( &"ZOMBIE_GAME_OVER" ); + precachestring( &"ZOMBIE_SURVIVED_ROUND" ); + precachestring( &"ZOMBIE_SURVIVED_ROUNDS" ); + precachestring( &"ZOMBIE_SURVIVED_NOMANS" ); + precachestring( &"ZOMBIE_EXTRA_LIFE" ); + add_zombie_hint( "undefined", &"ZOMBIE_UNDEFINED" ); + add_zombie_hint( "default_treasure_chest", &"ZOMBIE_RANDOM_WEAPON_COST" ); + add_zombie_hint( "default_treasure_chest_950", &"ZOMBIE_RANDOM_WEAPON_950" ); + add_zombie_hint( "powerup_fire_sale_cost", &"ZOMBIE_FIRE_SALE_COST" ); + add_zombie_hint( "default_buy_barrier_piece_10", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_10" ); + add_zombie_hint( "default_buy_barrier_piece_20", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_20" ); + add_zombie_hint( "default_buy_barrier_piece_50", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_50" ); + add_zombie_hint( "default_buy_barrier_piece_100", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_100" ); + add_zombie_hint( "default_reward_barrier_piece", &"ZOMBIE_BUTTON_REWARD_BARRIER" ); + add_zombie_hint( "default_reward_barrier_piece_10", &"ZOMBIE_BUTTON_REWARD_BARRIER_10" ); + add_zombie_hint( "default_reward_barrier_piece_20", &"ZOMBIE_BUTTON_REWARD_BARRIER_20" ); + add_zombie_hint( "default_reward_barrier_piece_30", &"ZOMBIE_BUTTON_REWARD_BARRIER_30" ); + add_zombie_hint( "default_reward_barrier_piece_40", &"ZOMBIE_BUTTON_REWARD_BARRIER_40" ); + add_zombie_hint( "default_reward_barrier_piece_50", &"ZOMBIE_BUTTON_REWARD_BARRIER_50" ); + add_zombie_hint( "default_buy_debris", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_COST" ); + add_zombie_hint( "default_buy_debris_100", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_100" ); + add_zombie_hint( "default_buy_debris_200", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_200" ); + add_zombie_hint( "default_buy_debris_250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_250" ); + add_zombie_hint( "default_buy_debris_500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_500" ); + add_zombie_hint( "default_buy_debris_750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_750" ); + add_zombie_hint( "default_buy_debris_1000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1000" ); + add_zombie_hint( "default_buy_debris_1250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1250" ); + add_zombie_hint( "default_buy_debris_1500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1500" ); + add_zombie_hint( "default_buy_debris_1750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1750" ); + add_zombie_hint( "default_buy_debris_2000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_2000" ); + add_zombie_hint( "default_buy_debris_3000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_3000" ); + add_zombie_hint( "default_buy_door", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_COST" ); + add_zombie_hint( "default_buy_door_close", &"ZOMBIE_BUTTON_BUY_CLOSE_DOOR" ); + add_zombie_hint( "default_buy_door_100", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_100" ); + add_zombie_hint( "default_buy_door_200", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_200" ); + add_zombie_hint( "default_buy_door_250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_250" ); + add_zombie_hint( "default_buy_door_500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_500" ); + add_zombie_hint( "default_buy_door_750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_750" ); + add_zombie_hint( "default_buy_door_1000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1000" ); + add_zombie_hint( "default_buy_door_1250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1250" ); + add_zombie_hint( "default_buy_door_1500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1500" ); + add_zombie_hint( "default_buy_door_1750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1750" ); + add_zombie_hint( "default_buy_door_2000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_2000" ); + add_zombie_hint( "default_buy_door_2500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_2500" ); + add_zombie_hint( "default_buy_door_3000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_3000" ); + add_zombie_hint( "default_buy_door_4000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_4000" ); + add_zombie_hint( "default_buy_door_8000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_8000" ); + add_zombie_hint( "default_buy_door_16000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_16000" ); + add_zombie_hint( "default_buy_area", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_COST" ); + add_zombie_hint( "default_buy_area_100", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_100" ); + add_zombie_hint( "default_buy_area_200", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_200" ); + add_zombie_hint( "default_buy_area_250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_250" ); + add_zombie_hint( "default_buy_area_500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_500" ); + add_zombie_hint( "default_buy_area_750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_750" ); + add_zombie_hint( "default_buy_area_1000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1000" ); + add_zombie_hint( "default_buy_area_1250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1250" ); + add_zombie_hint( "default_buy_area_1500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1500" ); + add_zombie_hint( "default_buy_area_1750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1750" ); + add_zombie_hint( "default_buy_area_2000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_2000" ); +} + +init_sounds() +{ + add_sound( "end_of_round", "mus_zmb_round_over" ); + add_sound( "end_of_game", "mus_zmb_game_over" ); + add_sound( "chalk_one_up", "mus_zmb_chalk" ); + add_sound( "purchase", "zmb_cha_ching" ); + add_sound( "no_purchase", "zmb_no_cha_ching" ); + add_sound( "playerzombie_usebutton_sound", "zmb_zombie_vocals_attack" ); + add_sound( "playerzombie_attackbutton_sound", "zmb_zombie_vocals_attack" ); + add_sound( "playerzombie_adsbutton_sound", "zmb_zombie_vocals_attack" ); + add_sound( "zombie_head_gib", "zmb_zombie_head_gib" ); + add_sound( "rebuild_barrier_piece", "zmb_repair_boards" ); + add_sound( "rebuild_barrier_metal_piece", "zmb_metal_repair" ); + add_sound( "rebuild_barrier_hover", "zmb_boards_float" ); + add_sound( "debris_hover_loop", "zmb_couch_loop" ); + add_sound( "break_barrier_piece", "zmb_break_boards" ); + add_sound( "grab_metal_bar", "zmb_bar_pull" ); + add_sound( "break_metal_bar", "zmb_bar_break" ); + add_sound( "drop_metal_bar", "zmb_bar_drop" ); + add_sound( "blocker_end_move", "zmb_board_slam" ); + add_sound( "barrier_rebuild_slam", "zmb_board_slam" ); + add_sound( "bar_rebuild_slam", "zmb_bar_repair" ); + add_sound( "zmb_rock_fix", "zmb_break_rock_barrier_fix" ); + add_sound( "zmb_vent_fix", "evt_vent_slat_repair" ); + add_sound( "door_slide_open", "zmb_door_slide_open" ); + add_sound( "door_rotate_open", "zmb_door_slide_open" ); + add_sound( "debris_move", "zmb_weap_wall" ); + add_sound( "open_chest", "zmb_lid_open" ); + add_sound( "music_chest", "zmb_music_box" ); + add_sound( "close_chest", "zmb_lid_close" ); + add_sound( "weapon_show", "zmb_weap_wall" ); + add_sound( "break_stone", "break_stone" ); +} + +init_levelvars() +{ + level.is_zombie_level = 1; + level.laststandpistol = "m1911_zm"; + level.default_laststandpistol = "m1911_zm"; + level.default_solo_laststandpistol = "m1911_upgraded_zm"; + level.start_weapon = "m1911_zm"; + level.first_round = 1; + level.start_round = getgametypesetting( "startRound" ); + level.round_number = level.start_round; + level.enable_magic = getgametypesetting( "magic" ); + level.headshots_only = getgametypesetting( "headshotsonly" ); + level.player_starting_points = level.round_number * 500; + level.round_start_time = 0; + level.pro_tips_start_time = 0; + level.intermission = 0; + level.dog_intermission = 0; + level.zombie_total = 0; + level.total_zombies_killed = 0; + level.hudelem_count = 0; + level.zombie_spawn_locations = []; + level.zombie_rise_spawners = []; + level.current_zombie_array = []; + level.current_zombie_count = 0; + level.zombie_total_subtract = 0; + level.destructible_callbacks = []; + level.zombie_vars = []; + _a1039 = level.teams; + _k1039 = getFirstArrayKey( _a1039 ); + while ( isDefined( _k1039 ) ) + { + team = _a1039[ _k1039 ]; + level.zombie_vars[ team ] = []; + _k1039 = getNextArrayKey( _a1039, _k1039 ); + } + difficulty = 1; + column = int( difficulty ) + 1; + set_zombie_var( "zombie_health_increase", 100, 0, column ); + set_zombie_var( "zombie_health_increase_multiplier", 0,1, 1, column ); + set_zombie_var( "zombie_health_start", 150, 0, column ); + set_zombie_var( "zombie_spawn_delay", 2, 1, column ); + set_zombie_var( "zombie_new_runner_interval", 10, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier", 8, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier_easy", 2, 0, column ); + set_zombie_var( "zombie_max_ai", 24, 0, column ); + set_zombie_var( "zombie_ai_per_player", 6, 0, column ); + set_zombie_var( "below_world_check", -1000 ); + set_zombie_var( "spectators_respawn", 1 ); + set_zombie_var( "zombie_use_failsafe", 1 ); + set_zombie_var( "zombie_between_round_time", 10 ); + set_zombie_var( "zombie_intermission_time", 15 ); + set_zombie_var( "game_start_delay", 0, 0, column ); + set_zombie_var( "penalty_no_revive", 0,1, 1, column ); + set_zombie_var( "penalty_died", 0, 1, column ); + set_zombie_var( "penalty_downed", 0,05, 1, column ); + set_zombie_var( "starting_lives", 1, 0, column ); + set_zombie_var( "zombie_score_kill_4player", 50 ); + set_zombie_var( "zombie_score_kill_3player", 50 ); + set_zombie_var( "zombie_score_kill_2player", 50 ); + set_zombie_var( "zombie_score_kill_1player", 50 ); + set_zombie_var( "zombie_score_kill_4p_team", 30 ); + set_zombie_var( "zombie_score_kill_3p_team", 35 ); + set_zombie_var( "zombie_score_kill_2p_team", 45 ); + set_zombie_var( "zombie_score_kill_1p_team", 0 ); + set_zombie_var( "zombie_score_damage_normal", 10 ); + set_zombie_var( "zombie_score_damage_light", 10 ); + set_zombie_var( "zombie_score_bonus_melee", 80 ); + set_zombie_var( "zombie_score_bonus_head", 50 ); + set_zombie_var( "zombie_score_bonus_neck", 20 ); + set_zombie_var( "zombie_score_bonus_torso", 10 ); + set_zombie_var( "zombie_score_bonus_burn", 10 ); + set_zombie_var( "zombie_flame_dmg_point_delay", 500 ); + set_zombie_var( "zombify_player", 0 ); + if ( issplitscreen() ) + { + set_zombie_var( "zombie_timer_offset", 280 ); + } + level thread init_player_levelvars(); + level.gamedifficulty = getgametypesetting( "zmDifficulty" ); + if ( level.gamedifficulty == 0 ) + { + level.zombie_move_speed = level.round_number * level.zombie_vars[ "zombie_move_speed_multiplier_easy" ]; + } + else + { + level.zombie_move_speed = level.round_number * level.zombie_vars[ "zombie_move_speed_multiplier" ]; + } + if ( level.round_number == 1 ) + { + level.zombie_move_speed = 100; + } + else + { + i = 1; + while ( i <= level.round_number ) + { + timer = level.zombie_vars[ "zombie_spawn_delay" ]; + if ( timer > 0.08 ) + { + level.zombie_vars[ "zombie_spawn_delay" ] = timer * 0.95; + i++; + continue; + } + else + { + if ( timer < 0.08 ) + { + level.zombie_vars[ "zombie_spawn_delay" ] = 0.08; + } + } + i++; + } + } + level.speed_change_max = 0; + level.speed_change_num = 0; +} + +init_player_levelvars() +{ + flag_wait( "start_zombie_round_logic" ); + difficulty = 1; + column = int( difficulty ) + 1; + i = 0; + while ( i < 8 ) + { + points = 500; + if ( i > 3 ) + { + points = 3000; + } + points = set_zombie_var( "zombie_score_start_" + ( i + 1 ) + "p", points, 0, column ); + i++; + } +} + +init_dvars() +{ + if ( getDvar( "zombie_debug" ) == "" ) + { + setdvar( "zombie_debug", "0" ); + } + if ( getDvar( "scr_zm_enable_bots" ) == "" ) + { + setdvar( "scr_zm_enable_bots", "0" ); + } + if ( getDvar( "zombie_cheat" ) == "" ) + { + setdvar( "zombie_cheat", "0" ); + } + if ( level.script != "zombie_cod5_prototype" ) + { + setdvar( "magic_chest_movable", "1" ); + } + setdvar( "revive_trigger_radius", "75" ); + setdvar( "player_lastStandBleedoutTime", "45" ); + setdvar( "scr_deleteexplosivesonspawn", "0" ); +} + +init_function_overrides() +{ + level.callbackplayerdamage = ::callback_playerdamage; + level.overrideplayerdamage = ::player_damage_override; + level.callbackplayerkilled = ::player_killed_override; + level.playerlaststand_func = ::player_laststand; + level.callbackplayerlaststand = ::callback_playerlaststand; + level.prevent_player_damage = ::player_prevent_damage; + level.callbackactorkilled = ::actor_killed_override; + level.callbackactordamage = ::actor_damage_override_wrapper; + level.custom_introscreen = ::zombie_intro_screen; + level.custom_intermission = ::player_intermission; + level.global_damage_func = ::zombie_damage; //maps/mp/zombies/_zm_spawner + level.global_damage_func_ads = ::zombie_damage_ads; //maps/mp/zombies/_zm_spawner + level.reset_clientdvars = ::onplayerconnect_clientdvars; + level.zombie_last_stand = ::last_stand_pistol_swap; + level.zombie_last_stand_pistol_memory = ::last_stand_save_pistol_ammo; + level.zombie_last_stand_ammo_return = ::last_stand_restore_pistol_ammo; + level.player_becomes_zombie = ::zombify_player; + level.validate_enemy_path_length = ::default_validate_enemy_path_length; + level.zm_laststand_playerlaststand = ::playerlaststand; //maps/mp/zombies/_zm_laststand +} + +callback_playerlaststand( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime, deathanimduration ) +{ + self endon( "disconnect" ); + [[ level.zm_laststand_playerlaststand ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime, deathanimduration ); +} + +codecallback_destructibleevent( event, param1, param2, param3 ) +{ + if ( event == "broken" ) + { + notify_type = param1; + attacker = param2; + weapon = param3; + if ( isDefined( level.destructible_callbacks[ notify_type ] ) ) + { + self thread [[ level.destructible_callbacks[ notify_type ] ]]( notify_type, attacker ); + } + self notify( event ); + } + else + { + if ( event == "breakafter" ) + { + piece = param1; + time = param2; + damage = param3; + self thread breakafter( time, damage, piece ); + } + } +} + +breakafter( time, damage, piece ) +{ + self notify( "breakafter" ); + self endon( "breakafter" ); + wait time; + self dodamage( damage, self.origin, undefined, undefined ); +} + +callback_playerdamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ +/* +/# + println( "ZM Callback_PlayerDamage" + idamage + "\n" ); +#/ +*/ + if ( isDefined( eattacker ) && isplayer( eattacker ) && eattacker.sessionteam == self.sessionteam && !eattacker hasperk( "specialty_noname" ) && isDefined( self.is_zombie ) && !self.is_zombie ) + { + self process_friendly_fire_callbacks( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + if ( self != eattacker ) + { + /* +/# + println( "Exiting - players can't hurt each other." ); +#/ + */ + return; + } + else + { + if ( smeansofdeath != "MOD_GRENADE_SPLASH" && smeansofdeath != "MOD_GRENADE" && smeansofdeath != "MOD_EXPLOSIVE" && smeansofdeath != "MOD_PROJECTILE" && smeansofdeath != "MOD_PROJECTILE_SPLASH" && smeansofdeath != "MOD_BURNED" && smeansofdeath != "MOD_SUICIDE" ) + { + /* +/# + println( "Exiting - damage type verbotten." ); +#/ + */ + return; + } + } + } + if ( isDefined( level.pers_upgrade_insta_kill ) && level.pers_upgrade_insta_kill ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_insta_kill_melee_swipe( smeansofdeath, eattacker ); + } + if ( isDefined( self.overrideplayerdamage ) ) + { + idamage = self [[ self.overrideplayerdamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + else + { + if ( isDefined( level.overrideplayerdamage ) ) + { + idamage = self [[ level.overrideplayerdamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + } + /* +/# + assert( isDefined( idamage ), "You must return a value from a damage override function." ); +#/ + */ + if ( isDefined( self.magic_bullet_shield ) && self.magic_bullet_shield ) + { + maxhealth = self.maxhealth; + self.health += idamage; + self.maxhealth = maxhealth; + } + if ( isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + if ( smeansofdeath == "MOD_GRENADE_SPLASH" ) + { + dist = distance2d( vpoint, self.origin ); + if ( dist > 32 ) + { + dot_product = vectordot( anglesToForward( self.angles ), vdir ); + if ( dot_product > 0 ) + { + idamage = int( idamage * 0.5 ); + } + } + } + } + /* +/# + println( "CB PD" ); +#/ + */ + if ( isDefined( level.prevent_player_damage ) ) + { + if ( self [[ level.prevent_player_damage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) ) + { + return; + } + } + idflags |= level.idflags_no_knockback; + if ( idamage > 0 && shitloc == "riotshield" ) + { + shitloc = "torso_upper"; + } + /* +/# + println( "Finishplayerdamage wrapper." ); +#/ + */ + self finishplayerdamagewrapper( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +finishplayerdamagewrapper( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + self finishplayerdamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +register_player_friendly_fire_callback( callback ) +{ + if ( !isDefined( level.player_friendly_fire_callbacks ) ) + { + level.player_friendly_fire_callbacks = []; + } + level.player_friendly_fire_callbacks[ level.player_friendly_fire_callbacks.size ] = callback; +} + +process_friendly_fire_callbacks( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + while ( isDefined( level.player_friendly_fire_callbacks ) ) + { + _a1421 = level.player_friendly_fire_callbacks; + _k1421 = getFirstArrayKey( _a1421 ); + while ( isDefined( _k1421 ) ) + { + callback = _a1421[ _k1421 ]; + self [[ callback ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + _k1421 = getNextArrayKey( _a1421, _k1421 ); + } + } +} + +init_flags() +{ + flag_init( "solo_game" ); + flag_init( "start_zombie_round_logic" ); + flag_init( "start_encounters_match_logic" ); + flag_init( "spawn_point_override" ); + flag_init( "power_on" ); + flag_init( "crawler_round" ); + flag_init( "spawn_zombies", 1 ); + flag_init( "dog_round" ); + flag_init( "begin_spawning" ); + flag_init( "end_round_wait" ); + flag_init( "wait_and_revive" ); + flag_init( "instant_revive" ); + flag_init( "initial_blackscreen_passed" ); + flag_init( "initial_players_connected" ); +} + +init_client_flags() +{ + if ( isDefined( level.use_clientside_board_fx ) && level.use_clientside_board_fx ) + { + level._zombie_scriptmover_flag_board_horizontal_fx = 14; + level._zombie_scriptmover_flag_board_vertical_fx = 13; + } + if ( isDefined( level.use_clientside_rock_tearin_fx ) && level.use_clientside_rock_tearin_fx ) + { + level._zombie_scriptmover_flag_rock_fx = 12; + } + level._zombie_player_flag_cloak_weapon = 14; + if ( isDefined( level.disable_deadshot_clientfield ) && !level.disable_deadshot_clientfield ) + { + registerclientfield( "toplayer", "deadshot_perk", 1, 1, "int" ); + } + registerclientfield( "actor", "zombie_riser_fx", 1, 1, "int" ); + if ( isDefined( level._no_water_risers ) && !level._no_water_risers ) + { + registerclientfield( "actor", "zombie_riser_fx_water", 1, 1, "int" ); + } + if ( isDefined( level._foliage_risers ) && level._foliage_risers ) + { + registerclientfield( "actor", "zombie_riser_fx_foliage", 12000, 1, "int" ); + } + if ( isDefined( level.risers_use_low_gravity_fx ) && level.risers_use_low_gravity_fx ) + { + registerclientfield( "actor", "zombie_riser_fx_lowg", 1, 1, "int" ); + } +} + +init_fx() +{ + level.createfx_callback_thread = ::delete_in_createfx; + level._effect[ "wood_chunk_destory" ] = loadfx( "impacts/fx_large_woodhit" ); + level._effect[ "fx_zombie_bar_break" ] = loadfx( "maps/zombie/fx_zombie_bar_break" ); + level._effect[ "fx_zombie_bar_break_lite" ] = loadfx( "maps/zombie/fx_zombie_bar_break_lite" ); + if ( isDefined( level.fx_exclude_edge_fog ) && !level.fx_exclude_edge_fog ) + { + level._effect[ "edge_fog" ] = loadfx( "maps/zombie/fx_fog_zombie_amb" ); + } + level._effect[ "chest_light" ] = loadfx( "maps/zombie/fx_zmb_tranzit_marker_glow" ); + if ( isDefined( level.fx_exclude_default_eye_glow ) && !level.fx_exclude_default_eye_glow ) + { + level._effect[ "eye_glow" ] = loadfx( "misc/fx_zombie_eye_single" ); + } + level._effect[ "headshot" ] = loadfx( "impacts/fx_flesh_hit" ); + level._effect[ "headshot_nochunks" ] = loadfx( "misc/fx_zombie_bloodsplat" ); + level._effect[ "bloodspurt" ] = loadfx( "misc/fx_zombie_bloodspurt" ); + if ( isDefined( level.fx_exclude_tesla_head_light ) && !level.fx_exclude_tesla_head_light ) + { + level._effect[ "tesla_head_light" ] = loadfx( "maps/zombie/fx_zombie_tesla_neck_spurt" ); + } + level._effect[ "zombie_guts_explosion" ] = loadfx( "maps/zombie/fx_zmb_tranzit_torso_explo" ); + level._effect[ "rise_burst_water" ] = loadfx( "maps/zombie/fx_mp_zombie_hand_dirt_burst" ); + level._effect[ "rise_billow_water" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dirt_billowing" ); + level._effect[ "rise_dust_water" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dust_falling" ); + level._effect[ "rise_burst" ] = loadfx( "maps/zombie/fx_mp_zombie_hand_dirt_burst" ); + level._effect[ "rise_billow" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dirt_billowing" ); + level._effect[ "rise_dust" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dust_falling" ); + level._effect[ "fall_burst" ] = loadfx( "maps/zombie/fx_mp_zombie_hand_dirt_burst" ); + level._effect[ "fall_billow" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dirt_billowing" ); + level._effect[ "fall_dust" ] = loadfx( "maps/zombie/fx_mp_zombie_body_dust_falling" ); + level._effect[ "character_fire_death_sm" ] = loadfx( "env/fire/fx_fire_zombie_md" ); + level._effect[ "character_fire_death_torso" ] = loadfx( "env/fire/fx_fire_zombie_torso" ); + if ( isDefined( level.fx_exclude_default_explosion ) && !level.fx_exclude_default_explosion ) + { + level._effect[ "def_explosion" ] = loadfx( "explosions/fx_default_explosion" ); + } + if ( isDefined( level._uses_default_wallbuy_fx ) && level._uses_default_wallbuy_fx ) + { + level._effect[ "870mcs_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_870mcs" ); + level._effect[ "ak74u_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_ak74u" ); + level._effect[ "beretta93r_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_berreta93r" ); + level._effect[ "bowie_knife_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + level._effect[ "claymore_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_claymore" ); + level._effect[ "m14_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_m14" ); + level._effect[ "m16_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_m16" ); + level._effect[ "mp5k_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_mp5k" ); + level._effect[ "rottweil72_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_olympia" ); + } + if ( isDefined( level._uses_sticky_grenades ) && level._uses_sticky_grenades ) + { + if ( isDefined( level.disable_fx_zmb_wall_buy_semtex ) && !level.disable_fx_zmb_wall_buy_semtex ) + { + level._effect[ "sticky_grenade_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_semtex" ); + } + } + if ( isDefined( level._uses_taser_knuckles ) && level._uses_taser_knuckles ) + { + level._effect[ "tazer_knuckles_zm_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + } + if ( isDefined( level.buildable_wallbuy_weapons ) ) + { + level._effect[ "dynamic_wallbuy_fx" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_question" ); + } + if ( isDefined( level.disable_fx_upgrade_aquired ) && !level.disable_fx_upgrade_aquired ) + { + level._effect[ "upgrade_aquired" ] = loadfx( "maps/zombie/fx_zmb_tanzit_upgrade" ); + } +} + +zombie_intro_screen( string1, string2, string3, string4, string5 ) +{ + flag_wait( "start_zombie_round_logic" ); +} + +players_playing() +{ + players = get_players(); + level.players_playing = players.size; + wait 20; + players = get_players(); + level.players_playing = players.size; +} + +onplayerconnect_clientdvars() +{ + self setclientcompass( 0 ); + self setclientthirdperson( 0 ); + self resetfov(); + self setclientthirdpersonangle( 0 ); + self setclientammocounterhide( 1 ); + self setclientminiscoreboardhide( 1 ); + self setclienthudhardcore( 0 ); + self setclientplayerpushamount( 1 ); + self setdepthoffield( 0, 0, 512, 4000, 4, 0 ); + self setclientaimlockonpitchstrength( 0 ); + self maps/mp/zombies/_zm_laststand::player_getup_setup(); +} + +checkforalldead( excluded_player ) +{ + players = get_players(); + count = 0; + i = 0; + while ( i < players.size ) + { + if ( isDefined( excluded_player ) && excluded_player == players[ i ] ) + { + i++; + continue; + } + else + { + if ( !players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].sessionstate != "spectator" ) + { + count++; + } + } + i++; + } + if ( count == 0 && isDefined( level.no_end_game_check ) && !level.no_end_game_check ) + { + level notify( "end_game" ); + } +} + +onplayerspawned() +{ + self endon( "disconnect" ); + self notify( "stop_onPlayerSpawned" ); + self endon( "stop_onPlayerSpawned" ); + for ( ;; ) + { + self waittill( "spawned_player" ); + if ( isDefined( level.host_ended_game ) && !level.host_ended_game ) + { + self freezecontrols( 0 ); + /* +/# + println( " Unfreeze controls 7" ); +#/ + */ + } + self.hits = 0; + self init_player_offhand_weapons(); + lethal_grenade = self get_player_lethal_grenade(); + if ( !self hasweapon( lethal_grenade ) ) + { + self giveweapon( lethal_grenade ); + self setweaponammoclip( lethal_grenade, 0 ); + } + self recordplayerrevivezombies( self ); + /* +/# + if ( getDvarInt( "zombie_cheat" ) >= 1 && getDvarInt( "zombie_cheat" ) <= 3 ) + { + self enableinvulnerability(); + + } +#/ + */ + self setactionslot( 3, "altMode" ); + self playerknockback( 0 ); + self setclientthirdperson( 0 ); + self resetfov(); + self setclientthirdpersonangle( 0 ); + self setdepthoffield( 0, 0, 512, 4000, 4, 0 ); + self cameraactivate( 0 ); + self.num_perks = 0; + self.on_lander_last_stand = undefined; + self setblur( 0, 0.1 ); + self.zmbdialogqueue = []; + self.zmbdialogactive = 0; + self.zmbdialoggroups = []; + self.zmbdialoggroup = ""; + /* + if ( isDefined( level.player_out_of_playable_area_monitor ) && level.player_out_of_playable_area_monitor ) + { + self thread player_out_of_playable_area_monitor(); + } + if ( isDefined( level.player_too_many_weapons_monitor ) && level.player_too_many_weapons_monitor ) + { + self thread [[ level.player_too_many_weapons_monitor_func ]](); + } + if ( isDefined( level.player_too_many_players_check ) && level.player_too_many_players_check ) + { + level thread [[ level.player_too_many_players_check_func ]](); + } + */ + self.disabled_perks = []; + if ( isDefined( self.player_initialized ) ) + { + if ( self.player_initialized == 0 ) + { + self.player_initialized = 1; + self giveweapon( self get_player_lethal_grenade() ); + self setweaponammoclip( self get_player_lethal_grenade(), 0 ); + self setclientammocounterhide( 0 ); + self setclientminiscoreboardhide( 0 ); + self.is_drinking = 0; + self thread player_zombie_breadcrumb(); + self thread player_monitor_travel_dist(); + self thread player_monitor_time_played(); + if ( isDefined( level.custom_player_track_ammo_count ) ) + { + self thread [[ level.custom_player_track_ammo_count ]](); + } + else + { + self thread player_track_ammo_count(); + } + self thread shock_onpain(); + self thread player_grenade_watcher(); + self maps/mp/zombies/_zm_laststand::revive_hud_create(); + if ( isDefined( level.zm_gamemodule_spawn_func ) ) + { + self thread [[ level.zm_gamemodule_spawn_func ]](); + } + self thread player_spawn_protection(); + if ( !isDefined( self.lives ) ) + { + self.lives = 0; + } + } + } + } +} + +player_spawn_protection() +{ + self endon( "disconnect" ); + x = 0; + while ( x < 60 ) + { + self.ignoreme = 1; + x++; + wait 0.05; + } + self.ignoreme = 0; +} + +spawn_life_brush( origin, radius, height ) +{ + life_brush = spawn( "trigger_radius", origin, 0, radius, height ); + life_brush.script_noteworthy = "life_brush"; + return life_brush; +} + +in_life_brush() +{ + life_brushes = getentarray( "life_brush", "script_noteworthy" ); + if ( !isDefined( life_brushes ) ) + { + return 0; + } + i = 0; + while ( i < life_brushes.size ) + { + if ( self istouching( life_brushes[ i ] ) ) + { + return 1; + } + i++; + } + return 0; +} + +spawn_kill_brush( origin, radius, height ) +{ + kill_brush = spawn( "trigger_radius", origin, 0, radius, height ); + kill_brush.script_noteworthy = "kill_brush"; + return kill_brush; +} + +in_kill_brush() +{ + kill_brushes = getentarray( "kill_brush", "script_noteworthy" ); + if ( !isDefined( kill_brushes ) ) + { + return 0; + } + i = 0; + while ( i < kill_brushes.size ) + { + if ( self istouching( kill_brushes[ i ] ) ) + { + return 1; + } + i++; + } + return 0; +} + +in_enabled_playable_area() +{ + playable_area = getentarray( "player_volume", "script_noteworthy" ); + if ( !isDefined( playable_area ) ) + { + return 0; + } + i = 0; + while ( i < playable_area.size ) + { + if ( maps/mp/zombies/_zm_zonemgr::zone_is_enabled( playable_area[ i ].targetname ) && self istouching( playable_area[ i ] ) ) + { + return 1; + } + i++; + } + return 0; +} +/* +get_player_out_of_playable_area_monitor_wait_time() +{ + +/# + if ( isDefined( level.check_kill_thread_every_frame ) && level.check_kill_thread_every_frame ) + { + return 0.05; +#/ + } + + return 3; +} +*/ +/* +player_out_of_playable_area_monitor() +{ + self notify( "stop_player_out_of_playable_area_monitor" ); + self endon( "stop_player_out_of_playable_area_monitor" ); + self endon( "disconnect" ); + level endon( "end_game" ); + while ( !isDefined( self.characterindex ) ) + { + wait 0.05; + } + wait ( 0.15 * self.characterindex ); + while ( 1 ) + { + while ( self.sessionstate == "spectator" ) + { + wait get_player_out_of_playable_area_monitor_wait_time(); + } + while ( is_true( level.hostmigration_occured ) ) + { + wait get_player_out_of_playable_area_monitor_wait_time(); + } + if ( !self in_life_brush() || self in_kill_brush() && !self in_enabled_playable_area() ) + { + if ( !isDefined( level.player_out_of_playable_area_monitor_callback ) || self [[ level.player_out_of_playable_area_monitor_callback ]]() ) + { + /* +/# + while ( isDefined( level.kill_thread_test_mode ) && level.kill_thread_test_mode ) + { + iprintlnbold( "out of playable" ); + wait get_player_out_of_playable_area_monitor_wait_time(); + } + while ( !self isinmovemode( "ufo", "noclip" ) && isDefined( level.disable_kill_thread ) || level.disable_kill_thread && getDvarInt( "zombie_cheat" ) > 0 ) + { + wait get_player_out_of_playable_area_monitor_wait_time(); +#/ + } + + self maps/mp/zombies/_zm_stats::increment_map_cheat_stat( "cheat_out_of_playable" ); + self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_out_of_playable", 0 ); + self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_total", 0 ); + self playlocalsound( level.zmb_laugh_alias ); + wait 0.5; + if ( get_players().size == 1 && flag( "solo_game" ) && isDefined( self.waiting_to_revive ) && self.waiting_to_revive ) + { + level notify( "end_game" ); + break; + } + else + { + self disableinvulnerability(); + self.lives = 0; + self dodamage( self.health + 1000, self.origin ); + self.bleedout_time = 0; + } + } + } + wait get_player_out_of_playable_area_monitor_wait_time(); + } +} + +get_player_too_many_weapons_monitor_wait_time() +{ + return 3; +} + +player_too_many_weapons_monitor_takeaway_simultaneous( primary_weapons_to_take ) +{ + self endon( "player_too_many_weapons_monitor_takeaway_sequence_done" ); + self waittill_any( "player_downed", "replace_weapon_powerup" ); + i = 0; + while ( i < primary_weapons_to_take.size ) + { + self takeweapon( primary_weapons_to_take[ i ] ); + i++; + } + self maps/mp/zombies/_zm_score::minus_to_player_score( self.score ); + self give_start_weapon( 0 ); + if ( !self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + self decrement_is_drinking(); + } + else + { + if ( flag( "solo_game" ) ) + { + self.score_lost_when_downed = 0; + } + } + self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" ); +} + +player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take ) +{ + self thread player_too_many_weapons_monitor_takeaway_simultaneous( primary_weapons_to_take ); + self endon( "player_downed" ); + self endon( "replace_weapon_powerup" ); + self increment_is_drinking(); + score_decrement = round_up_to_ten( int( self.score / ( primary_weapons_to_take.size + 1 ) ) ); + i = 0; + while ( i < primary_weapons_to_take.size ) + { + self playlocalsound( level.zmb_laugh_alias ); + self switchtoweapon( primary_weapons_to_take[ i ] ); + self maps/mp/zombies/_zm_score::minus_to_player_score( score_decrement ); + wait 3; + self takeweapon( primary_weapons_to_take[ i ] ); + i++; + } + self playlocalsound( level.zmb_laugh_alias ); + self maps/mp/zombies/_zm_score::minus_to_player_score( self.score ); + wait 1; + self give_start_weapon( 1 ); + self decrement_is_drinking(); + self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" ); +} + +player_too_many_weapons_monitor() +{ + self notify( "stop_player_too_many_weapons_monitor" ); + self endon( "stop_player_too_many_weapons_monitor" ); + self endon( "disconnect" ); + level endon( "end_game" ); + scalar = self.characterindex; + if ( !isDefined( scalar ) ) + { + scalar = self getentitynumber(); + } + wait ( 0.15 * scalar ); + while ( 1 ) + { + while ( !self has_powerup_weapon() || self maps/mp/zombies/_zm_laststand::player_is_in_laststand() && self.sessionstate == "spectator" ) + { + wait get_player_too_many_weapons_monitor_wait_time(); + } + /* +/# + while ( getDvarInt( "zombie_cheat" ) > 0 ) + { + wait get_player_too_many_weapons_monitor_wait_time(); +#/ + } + + weapon_limit = get_player_weapon_limit( self ); + primaryweapons = self getweaponslistprimaries(); + if ( primaryweapons.size > weapon_limit ) + { + self maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + primaryweapons = self getweaponslistprimaries(); + } + primary_weapons_to_take = []; + i = 0; + while ( i < primaryweapons.size ) + { + if ( maps/mp/zombies/_zm_weapons::is_weapon_included( primaryweapons[ i ] ) || maps/mp/zombies/_zm_weapons::is_weapon_upgraded( primaryweapons[ i ] ) ) + { + primary_weapons_to_take[ primary_weapons_to_take.size ] = primaryweapons[ i ]; + } + i++; + } + if ( primary_weapons_to_take.size > weapon_limit ) + { + if ( !isDefined( level.player_too_many_weapons_monitor_callback ) || self [[ level.player_too_many_weapons_monitor_callback ]]( primary_weapons_to_take ) ) + { + self maps/mp/zombies/_zm_stats::increment_map_cheat_stat( "cheat_too_many_weapons" ); + self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_too_many_weapons", 0 ); + self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_total", 0 ); + self thread player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take ); + self waittill( "player_too_many_weapons_monitor_takeaway_sequence_done" ); + } + } + wait get_player_too_many_weapons_monitor_wait_time(); + } +} +*/ +player_monitor_travel_dist() +{ + self endon( "disconnect" ); + self notify( "stop_player_monitor_travel_dist" ); + self endon( "stop_player_monitor_travel_dist" ); + prevpos = self.origin; + while ( 1 ) + { + wait 0.1; + self.pers[ "distance_traveled" ] += distance( self.origin, prevpos ); + prevpos = self.origin; + } +} + +player_monitor_time_played() +{ + self endon( "disconnect" ); + self notify( "stop_player_monitor_time_played" ); + self endon( "stop_player_monitor_time_played" ); + flag_wait( "start_zombie_round_logic" ); + for ( ;; ) + { + wait 1; + maps/mp/zombies/_zm_stats::increment_client_stat( "time_played_total" ); + } +} + +reset_rampage_bookmark_kill_times() +{ + if ( !isDefined( self.rampage_bookmark_kill_times ) ) + { + self.rampage_bookmark_kill_times = []; + self.ignore_rampage_kill_times = 0; + } + i = 0; + while ( i < level.rampage_bookmark_kill_times_count ) + { + self.rampage_bookmark_kill_times[ i ] = 0; + i++; + } +} + +add_rampage_bookmark_kill_time() +{ + now = getTime(); + if ( now <= self.ignore_rampage_kill_times ) + { + return; + } + oldest_index = 0; + oldest_time = now + 1; + i = 0; + while ( i < level.rampage_bookmark_kill_times_count ) + { + if ( !self.rampage_bookmark_kill_times[ i ] ) + { + oldest_index = i; + break; + } + else if ( oldest_time > self.rampage_bookmark_kill_times[ i ] ) + { + oldest_index = i; + oldest_time = self.rampage_bookmark_kill_times[ i ]; + } + i++; + } + self.rampage_bookmark_kill_times[ oldest_index ] = now; +} + +watch_rampage_bookmark() +{ + while ( 1 ) + { + wait 0.05; + waittillframeend; + now = getTime(); + oldest_allowed = now - level.rampage_bookmark_kill_times_msec; + players = get_players(); + player_index = 0; + while ( player_index < players.size ) + { + player = players[ player_index ]; + + + if ( isDefined( player.pers[ "isBot" ] ) && player.pers[ "isBot" ] ) + { + /* + player_index++; + continue; + */ + } + + else + { + time_index = 0; + while ( time_index < level.rampage_bookmark_kill_times_count ) + { + if ( !player.rampage_bookmark_kill_times[ time_index ] ) + { + break; + } + else if ( oldest_allowed > player.rampage_bookmark_kill_times[ time_index ] ) + { + player.rampage_bookmark_kill_times[ time_index ] = 0; + break; + } + else + { + time_index++; + } + } + if ( time_index >= level.rampage_bookmark_kill_times_count ) + { + maps/mp/_demo::bookmark( "zm_player_rampage", getTime(), player ); + player reset_rampage_bookmark_kill_times(); + player.ignore_rampage_kill_times = now + level.rampage_bookmark_kill_times_delay; + } + } + player_index++; + } + } +} + +player_grenade_multiattack_bookmark_watcher( grenade ) +{ + self endon( "disconnect" ); + waittillframeend; + if ( !isDefined( grenade ) ) + { + return; + } + inflictorentnum = grenade getentitynumber(); + inflictorenttype = grenade getentitytype(); + inflictorbirthtime = 0; + if ( isDefined( grenade.birthtime ) ) + { + inflictorbirthtime = grenade.birthtime; + } + ret_val = grenade waittill_any_timeout( 15, "explode" ); + if ( !isDefined( self ) || isDefined( ret_val ) && ret_val == "timeout" ) + { + return; + } + self.grenade_multiattack_count = 0; + self.grenade_multiattack_ent = undefined; + waittillframeend; + if ( !isDefined( self ) ) + { + return; + } + count = level.grenade_multiattack_bookmark_count; + if ( isDefined( grenade.grenade_multiattack_bookmark_count ) && grenade.grenade_multiattack_bookmark_count ) + { + count = grenade.grenade_multiattack_bookmark_count; + } + bookmark_string = "zm_player_grenade_multiattack"; + if ( isDefined( grenade.use_grenade_special_long_bookmark ) && grenade.use_grenade_special_long_bookmark ) + { + bookmark_string = "zm_player_grenade_special_long"; + } + else + { + if ( isDefined( grenade.use_grenade_special_bookmark ) && grenade.use_grenade_special_bookmark ) + { + bookmark_string = "zm_player_grenade_special"; + } + } + if ( count <= self.grenade_multiattack_count && isDefined( self.grenade_multiattack_ent ) ) + { + adddemobookmark( level.bookmark[ bookmark_string ], getTime(), self getentitynumber(), 255, 0, inflictorentnum, inflictorenttype, inflictorbirthtime, 0, self.grenade_multiattack_ent getentitynumber() ); + } + self.grenade_multiattack_count = 0; +} + +player_grenade_watcher() +{ + self endon( "disconnect" ); + self notify( "stop_player_grenade_watcher" ); + self endon( "stop_player_grenade_watcher" ); + self.grenade_multiattack_count = 0; + while ( 1 ) + { + self waittill( "grenade_fire", grenade, weapname ); + if ( isDefined( grenade ) && isalive( grenade ) ) + { + grenade.team = self.team; + } + self thread player_grenade_multiattack_bookmark_watcher( grenade ); + if ( isDefined( level.grenade_watcher ) ) + { + self [[ level.grenade_watcher ]]( grenade, weapname ); + } + } +} + +player_prevent_damage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if ( !isDefined( einflictor ) || !isDefined( eattacker ) ) + { + return 0; + } + if ( einflictor == self || eattacker == self ) + { + return 0; + } + if ( isDefined( einflictor ) && isDefined( einflictor.team ) ) + { + if ( isDefined( einflictor.damage_own_team ) && !einflictor.damage_own_team ) + { + if ( einflictor.team == self.team ) + { + return 1; + } + } + } + return 0; +} + +player_revive_monitor() +{ + self endon( "disconnect" ); + self notify( "stop_player_revive_monitor" ); + self endon( "stop_player_revive_monitor" ); + while ( 1 ) + { + self waittill( "player_revived", reviver ); + self playsoundtoplayer( "zmb_character_revived", self ); + if ( isDefined( level.isresetting_grief ) && level.isresetting_grief ) + { + continue; + } + bbprint( "zombie_playerdeaths", "round %d playername %s deathtype %s x %f y %f z %f", level.round_number, self.name, "revived", self.origin ); + if ( isDefined( reviver ) ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "revive_up" ); + points = self.score_lost_when_downed; + /* +/# + println( "ZM >> LAST STAND - points = " + points ); +#/ + */ + reviver maps/mp/zombies/_zm_score::player_add_points( "reviver", points ); + self.score_lost_when_downed = 0; + } + } +} + +laststand_giveback_player_perks() +{ + while ( isDefined( self.laststand_perks ) ) + { + lost_perk_index = int( -1 ); + if ( self.laststand_perks.size > 1 ) + { + lost_perk_index = randomint( self.laststand_perks.size - 1 ); + } + i = 0; + while ( i < self.laststand_perks.size ) + { + if ( self hasperk( self.laststand_perks[ i ] ) ) + { + i++; + continue; + } + else if ( i == lost_perk_index ) + { + i++; + continue; + } + else + { + maps/mp/zombies/_zm_perks::give_perk( self.laststand_perks[ i ] ); + } + i++; + } + } +} + +remote_revive_watch() +{ + self endon( "death" ); + self endon( "player_revived" ); + keep_checking = 1; + while ( keep_checking ) + { + self waittill( "remote_revive", reviver ); + if ( reviver.team == self.team ) + { + keep_checking = 0; + } + } + self maps/mp/zombies/_zm_laststand::remote_revive( reviver ); +} + +remove_deadshot_bottle() +{ + wait 0.05; + if ( isDefined( self.lastactiveweapon ) && self.lastactiveweapon == "zombie_perk_bottle_deadshot" ) + { + self.lastactiveweapon = "none"; + } +} + +take_additionalprimaryweapon() +{ + weapon_to_take = undefined; + if ( isDefined( self._retain_perks ) || self._retain_perks && isDefined( self._retain_perks_array ) && isDefined( self._retain_perks_array[ "specialty_additionalprimaryweapon" ] ) && self._retain_perks_array[ "specialty_additionalprimaryweapon" ] ) + { + return weapon_to_take; + } + primary_weapons_that_can_be_taken = []; + primaryweapons = self getweaponslistprimaries(); + i = 0; + while ( i < primaryweapons.size ) + { + if ( maps/mp/zombies/_zm_weapons::is_weapon_included( primaryweapons[ i ] ) || maps/mp/zombies/_zm_weapons::is_weapon_upgraded( primaryweapons[ i ] ) ) + { + primary_weapons_that_can_be_taken[ primary_weapons_that_can_be_taken.size ] = primaryweapons[ i ]; + } + i++; + } + pwtcbt = primary_weapons_that_can_be_taken.size; + while ( pwtcbt >= 3 ) + { + weapon_to_take = primary_weapons_that_can_be_taken[ pwtcbt - 1 ]; + pwtcbt--; + + if ( weapon_to_take == self getcurrentweapon() ) + { + self switchtoweapon( primary_weapons_that_can_be_taken[ 0 ] ); + } + self takeweapon( weapon_to_take ); + } + return weapon_to_take; +} + +player_laststand( einflictor, attacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime, deathanimduration ) +{ +/* +/# + println( "ZM >> LAST STAND - player_laststand called" ); +#/ +*/ + b_alt_visionset = 0; + self allowjump( 0 ); + currweapon = self getcurrentweapon(); + statweapon = currweapon; + if ( is_alt_weapon( statweapon ) ) + { + statweapon = weaponaltweaponname( statweapon ); + } + self addweaponstat( statweapon, "deathsDuringUse", 1 ); + if ( isDefined( self.hasperkspecialtytombstone ) && self.hasperkspecialtytombstone ) + { + self.laststand_perks = maps/mp/zombies/_zm_tombstone::tombstone_save_perks( self ); + } + if ( isDefined( self.pers_upgrades_awarded[ "perk_lose" ] ) && self.pers_upgrades_awarded[ "perk_lose" ] ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_perk_lose_save(); + } + players = get_players(); + if ( players.size == 1 && flag( "solo_game" ) ) + { + if ( self.lives > 0 && self hasperk( "specialty_quickrevive" ) ) + { + self thread wait_and_revive(); + } + } + if ( self hasperk( "specialty_additionalprimaryweapon" ) ) + { + self.weapon_taken_by_losing_specialty_additionalprimaryweapon = take_additionalprimaryweapon(); + } + if ( isDefined( self.hasperkspecialtytombstone ) && self.hasperkspecialtytombstone ) + { + self [[ level.tombstone_laststand_func ]](); + self thread [[ level.tombstone_spawn_func ]](); + self.hasperkspecialtytombstone = undefined; + self notify( "specialty_scavenger_stop" ); + } + self clear_is_drinking(); + self thread remove_deadshot_bottle(); + self thread remote_revive_watch(); + self maps/mp/zombies/_zm_score::player_downed_penalty(); + self disableoffhandweapons(); + self thread last_stand_grenade_save_and_return(); + if ( smeansofdeath != "MOD_SUICIDE" && smeansofdeath != "MOD_FALLING" ) + { + if ( isDefined( self.intermission ) && !self.intermission ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "revive_down" ); + } + else + { + if ( isDefined( level.custom_player_death_vo_func ) && !( self [[ level.custom_player_death_vo_func ]]() ) ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "exert_death" ); + } + } + } + bbprint( "zombie_playerdeaths", "round %d playername %s deathtype %s x %f y %f z %f", level.round_number, self.name, "downed", self.origin ); + if ( isDefined( level._zombie_minigun_powerup_last_stand_func ) ) + { + self thread [[ level._zombie_minigun_powerup_last_stand_func ]](); + } + if ( isDefined( level._zombie_tesla_powerup_last_stand_func ) ) + { + self thread [[ level._zombie_tesla_powerup_last_stand_func ]](); + } + if ( self hasperk( "specialty_grenadepulldeath" ) ) + { + b_alt_visionset = 1; + if ( isDefined( level.custom_laststand_func ) ) + { + self thread [[ level.custom_laststand_func ]](); + } + } + if ( isDefined( self.intermission ) && self.intermission ) + { + bbprint( "zombie_playerdeaths", "round %d playername %s deathtype %s x %f y %f z %f", level.round_number, self.name, "died", self.origin ); + wait 0.5; + self stopsounds(); + level waittill( "forever" ); + } + if ( !b_alt_visionset ) + { + visionsetlaststand( "zombie_last_stand", 1 ); + } +} + +failsafe_revive_give_back_weapons( excluded_player ) +{ + i = 0; + while ( i < 10 ) + { + wait 0.05; + players = get_players(); + _a2621 = players; + _k2621 = getFirstArrayKey( _a2621 ); + while ( isDefined( _k2621 ) ) + { + player = _a2621[ _k2621 ]; + if ( excluded_player != player || !isDefined( player.reviveprogressbar ) && player maps/mp/zombies/_zm_laststand::is_reviving_any() ) + { + } + else + { + /* +/# + iprintlnbold( "FAILSAFE CLEANING UP REVIVE HUD AND GUN" ); +#/ + */ + player maps/mp/zombies/_zm_laststand::revive_give_back_weapons( "none" ); + if ( isDefined( player.reviveprogressbar ) ) + { + player.reviveprogressbar maps/mp/gametypes_zm/_hud_util::destroyelem(); + } + if ( isDefined( player.revivetexthud ) ) + { + player.revivetexthud destroy(); + } + } + _k2621 = getNextArrayKey( _a2621, _k2621 ); + } + i++; + } +} + +spawnspectator() +{ + self endon( "disconnect" ); + self endon( "spawned_spectator" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + if ( level.intermission ) + { + return; + } + if ( isDefined( level.no_spectator ) && level.no_spectator ) + { + wait 3; + exitlevel(); + } + self.is_zombie = 1; + level thread failsafe_revive_give_back_weapons( self ); + self notify( "zombified" ); + if ( isDefined( self.revivetrigger ) ) + { + self.revivetrigger delete(); + self.revivetrigger = undefined; + } + self.zombification_time = getTime(); + resettimeout(); + self stopshellshock(); + self stoprumble( "damage_heavy" ); + self.sessionstate = "spectator"; + self.spectatorclient = -1; + self.maxhealth = self.health; + self.shellshocked = 0; + self.inwater = 0; + self.friendlydamage = undefined; + self.hasspawned = 1; + self.spawntime = getTime(); + self.afk = 0; + /* +/# + println( "*************************Zombie Spectator***" ); +#/ + */ + self detachall(); + if ( isDefined( level.custom_spectate_permissions ) ) + { + self [[ level.custom_spectate_permissions ]](); + } + else + { + self setspectatepermissions( 1 ); + } + self thread spectator_thread(); + self spawn( self.origin, self.angles ); + self notify( "spawned_spectator" ); +} + +setspectatepermissions( ison ) +{ + if ( ison ) + { + self allowspectateteam( "allies", self.team == "allies" ); + } + if ( ison ) + { + self allowspectateteam( "axis", self.team == "axis" ); + } + self allowspectateteam( "freelook", 0 ); + self allowspectateteam( "none", 0 ); +} + +spectator_thread() +{ + self endon( "disconnect" ); + self endon( "spawned_player" ); +} + +spectator_toggle_3rd_person() +{ + self endon( "disconnect" ); + self endon( "spawned_player" ); + third_person = 1; + self set_third_person( 1 ); +} + +set_third_person( value ) +{ + if ( value ) + { + self setclientthirdperson( 1 ); + self setclientthirdpersonangle( 354 ); + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); + } + else + { + self setclientthirdperson( 0 ); + self setclientthirdpersonangle( 0 ); + self setdepthoffield( 0, 0, 512, 4000, 4, 0 ); + } + self resetfov(); +} + +last_stand_revive() +{ + level endon( "between_round_over" ); + players = get_players(); + laststand_count = 0; + _a2811 = players; + _k2811 = getFirstArrayKey( _a2811 ); + while ( isDefined( _k2811 ) ) + { + player = _a2811[ _k2811 ]; + if ( !is_player_valid( player ) ) + { + laststand_count++; + } + _k2811 = getNextArrayKey( _a2811, _k2811 ); + } + while ( laststand_count == players.size ) + { + i = 0; + while ( i < players.size ) + { + if ( players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].revivetrigger.beingrevived == 0 ) + { + players[ i ] maps/mp/zombies/_zm_laststand::auto_revive( players[ i ] ); + } + i++; + } + } +} + +last_stand_pistol_rank_init() +{ + level.pistol_values = []; + level.pistol_values[ level.pistol_values.size ] = "m1911_zm"; + level.pistol_values[ level.pistol_values.size ] = "c96_zm"; + level.pistol_values[ level.pistol_values.size ] = "cz75_zm"; + level.pistol_values[ level.pistol_values.size ] = "cz75dw_zm"; + level.pistol_values[ level.pistol_values.size ] = "kard_zm"; + level.pistol_values[ level.pistol_values.size ] = "fiveseven_zm"; + level.pistol_values[ level.pistol_values.size ] = "beretta93r_zm"; + level.pistol_values[ level.pistol_values.size ] = "beretta93r_extclip_zm"; + level.pistol_values[ level.pistol_values.size ] = "fivesevendw_zm"; + level.pistol_values[ level.pistol_values.size ] = "rnma_zm"; + level.pistol_values[ level.pistol_values.size ] = "python_zm"; + level.pistol_values[ level.pistol_values.size ] = "judge_zm"; + level.pistol_values[ level.pistol_values.size ] = "cz75_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "cz75dw_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "kard_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "fiveseven_upgraded_zm"; + level.pistol_value_solo_replace_below = level.pistol_values.size - 1; + level.pistol_values[ level.pistol_values.size ] = "m1911_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "c96_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "beretta93r_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "beretta93r_extclip_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "fivesevendw_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "rnma_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "python_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "judge_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "ray_gun_zm"; + level.pistol_values[ level.pistol_values.size ] = "raygun_mark2_zm"; + level.pistol_values[ level.pistol_values.size ] = "freezegun_zm"; + level.pistol_values[ level.pistol_values.size ] = "ray_gun_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "raygun_mark2_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "freezegun_upgraded_zm"; + level.pistol_values[ level.pistol_values.size ] = "microwavegundw_zm"; + level.pistol_values[ level.pistol_values.size ] = "microwavegundw_upgraded_zm"; +} + +last_stand_pistol_swap() +{ + if ( self has_powerup_weapon() ) + { + self.lastactiveweapon = "none"; + } + if ( !self hasweapon( self.laststandpistol ) ) + { + self giveweapon( self.laststandpistol ); + } + ammoclip = weaponclipsize( self.laststandpistol ); + doubleclip = ammoclip * 2; + if ( isDefined( self._special_solo_pistol_swap ) || self._special_solo_pistol_swap && self.laststandpistol == level.default_solo_laststandpistol && !self.hadpistol ) + { + self._special_solo_pistol_swap = 0; + self.hadpistol = 0; + self setweaponammostock( self.laststandpistol, doubleclip ); + } + else + { + if ( flag( "solo_game" ) && self.laststandpistol == level.default_solo_laststandpistol ) + { + self setweaponammostock( self.laststandpistol, doubleclip ); + } + else + { + if ( self.laststandpistol == level.default_laststandpistol ) + { + self setweaponammostock( self.laststandpistol, doubleclip ); + } + else if ( self.laststandpistol == "ray_gun_zm" || self.laststandpistol == "ray_gun_upgraded_zm" ) + { + if ( self.stored_weapon_info[ self.laststandpistol ].total_amt >= ammoclip ) + { + self setweaponammoclip( self.laststandpistol, ammoclip ); + self.stored_weapon_info[ self.laststandpistol ].given_amt = ammoclip; + } + else + { + self setweaponammoclip( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].total_amt ); + self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt; + } + self setweaponammostock( self.laststandpistol, 0 ); + } + else + { + if ( self.stored_weapon_info[ self.laststandpistol ].stock_amt >= doubleclip ) + { + self setweaponammostock( self.laststandpistol, doubleclip ); + self.stored_weapon_info[ self.laststandpistol ].given_amt = doubleclip + self.stored_weapon_info[ self.laststandpistol ].clip_amt + self.stored_weapon_info[ self.laststandpistol ].left_clip_amt; + } + else + { + self setweaponammostock( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].stock_amt ); + self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt; + } + } + } + } + self switchtoweapon( self.laststandpistol ); +} + +last_stand_best_pistol() +{ + pistol_array = []; + current_weapons = self getweaponslistprimaries(); + i = 0; + while ( i < current_weapons.size ) + { + class = weaponclass( current_weapons[ i ] ); + if ( issubstr( current_weapons[ i ], "knife_ballistic_" ) ) + { + class = "knife"; + } + while ( class != "pistol" || class == "pistolspread" && class == "pistol spread" ) + { + if ( current_weapons[ i ] != level.default_laststandpistol || !flag( "solo_game" ) && !flag( "solo_game" ) && current_weapons[ i ] != level.default_solo_laststandpistol ) + { + if ( self getammocount( current_weapons[ i ] ) <= 0 ) + { + i++; + continue; + } + } + else pistol_array_index = pistol_array.size; + pistol_array[ pistol_array_index ] = spawnstruct(); + pistol_array[ pistol_array_index ].gun = current_weapons[ i ]; + pistol_array[ pistol_array_index ].value = 0; + j = 0; + while ( j < level.pistol_values.size ) + { + if ( level.pistol_values[ j ] == current_weapons[ i ] ) + { + pistol_array[ pistol_array_index ].value = j; + i++; + continue; + } + else + { + j++; + } + } + } + i++; + } + self.laststandpistol = last_stand_compare_pistols( pistol_array ); +} + +last_stand_compare_pistols( struct_array ) +{ + if ( !isarray( struct_array ) || struct_array.size <= 0 ) + { + self.hadpistol = 0; + while ( isDefined( self.stored_weapon_info ) ) + { + stored_weapon_info = getarraykeys( self.stored_weapon_info ); + j = 0; + while ( j < stored_weapon_info.size ) + { + if ( stored_weapon_info[ j ] == level.laststandpistol ) + { + self.hadpistol = 1; + } + j++; + } + } + return level.laststandpistol; + } + highest_score_pistol = struct_array[ 0 ]; + i = 1; + while ( i < struct_array.size ) + { + if ( struct_array[ i ].value > highest_score_pistol.value ) + { + highest_score_pistol = struct_array[ i ]; + } + i++; + } + if ( flag( "solo_game" ) ) + { + self._special_solo_pistol_swap = 0; + if ( highest_score_pistol.value <= level.pistol_value_solo_replace_below ) + { + self.hadpistol = 0; + self._special_solo_pistol_swap = 1; + if ( isDefined( level.force_solo_quick_revive ) && level.force_solo_quick_revive && !self hasperk( "specialty_quickrevive" ) && !self hasperk( "specialty_quickrevive" ) ) + { + return highest_score_pistol.gun; + } + else + { + return level.laststandpistol; + } + } + else + { + return highest_score_pistol.gun; + } + } + else + { + return highest_score_pistol.gun; + } +} + +last_stand_save_pistol_ammo() +{ + weapon_inventory = self getweaponslist( 1 ); + self.stored_weapon_info = []; + i = 0; + while ( i < weapon_inventory.size ) + { + weapon = weapon_inventory[ i ]; + class = weaponclass( weapon ); + if ( issubstr( weapon, "knife_ballistic_" ) ) + { + class = "knife"; + } + if ( class != "pistol" || class == "pistolspread" && class == "pistol spread" ) + { + self.stored_weapon_info[ weapon ] = spawnstruct(); + self.stored_weapon_info[ weapon ].clip_amt = self getweaponammoclip( weapon ); + self.stored_weapon_info[ weapon ].left_clip_amt = 0; + dual_wield_name = weapondualwieldweaponname( weapon ); + if ( dual_wield_name != "none" ) + { + self.stored_weapon_info[ weapon ].left_clip_amt = self getweaponammoclip( dual_wield_name ); + } + self.stored_weapon_info[ weapon ].stock_amt = self getweaponammostock( weapon ); + self.stored_weapon_info[ weapon ].total_amt = self.stored_weapon_info[ weapon ].clip_amt + self.stored_weapon_info[ weapon ].left_clip_amt + self.stored_weapon_info[ weapon ].stock_amt; + self.stored_weapon_info[ weapon ].given_amt = 0; + } + i++; + } + self last_stand_best_pistol(); +} + +last_stand_restore_pistol_ammo() +{ + self.weapon_taken_by_losing_specialty_additionalprimaryweapon = undefined; + if ( !isDefined( self.stored_weapon_info ) ) + { + return; + } + weapon_inventory = self getweaponslist( 1 ); + weapon_to_restore = getarraykeys( self.stored_weapon_info ); + i = 0; + while ( i < weapon_inventory.size ) + { + weapon = weapon_inventory[ i ]; + if ( weapon != self.laststandpistol ) + { + i++; + continue; + } + else j = 0; + while ( j < weapon_to_restore.size ) + { + check_weapon = weapon_to_restore[ j ]; + if ( weapon == check_weapon ) + { + dual_wield_name = weapondualwieldweaponname( weapon_to_restore[ j ] ); + if ( weapon != level.default_laststandpistol ) + { + last_clip = self getweaponammoclip( weapon ); + last_left_clip = 0; + if ( dual_wield_name != "none" ) + { + last_left_clip = self getweaponammoclip( dual_wield_name ); + } + last_stock = self getweaponammostock( weapon ); + last_total = last_clip + last_left_clip + last_stock; + used_amt = self.stored_weapon_info[ weapon ].given_amt - last_total; + if ( used_amt >= self.stored_weapon_info[ weapon ].stock_amt ) + { + used_amt -= self.stored_weapon_info[ weapon ].stock_amt; + self.stored_weapon_info[ weapon ].stock_amt = 0; + self.stored_weapon_info[ weapon ].clip_amt -= used_amt; + if ( self.stored_weapon_info[ weapon ].clip_amt < 0 ) + { + self.stored_weapon_info[ weapon ].clip_amt = 0; + } + break; + } + else + { + new_stock_amt = self.stored_weapon_info[ weapon ].stock_amt - used_amt; + if ( new_stock_amt < self.stored_weapon_info[ weapon ].stock_amt ) + { + self.stored_weapon_info[ weapon ].stock_amt = new_stock_amt; + } + } + } + self setweaponammoclip( weapon_to_restore[ j ], self.stored_weapon_info[ weapon_to_restore[ j ] ].clip_amt ); + if ( dual_wield_name != "none" ) + { + self setweaponammoclip( dual_wield_name, self.stored_weapon_info[ weapon_to_restore[ j ] ].left_clip_amt ); + } + self setweaponammostock( weapon_to_restore[ j ], self.stored_weapon_info[ weapon_to_restore[ j ] ].stock_amt ); + i++; + continue; + } + else + { + j++; + } + } + i++; + } +} + +last_stand_take_thrown_grenade() +{ + self endon( "disconnect" ); + self endon( "bled_out" ); + self endon( "player_revived" ); + self waittill( "grenade_fire", grenade, weaponname ); + if ( isDefined( self.lsgsar_lethal ) && weaponname == self.lsgsar_lethal ) + { + self.lsgsar_lethal_nade_amt--; + + } + if ( isDefined( self.lsgsar_tactical ) && weaponname == self.lsgsar_tactical ) + { + self.lsgsar_tactical_nade_amt--; + + } +} + +last_stand_grenade_save_and_return() +{ + if ( isDefined( level.isresetting_grief ) && level.isresetting_grief ) + { + return; + } + self endon( "disconnect" ); + self endon( "bled_out" ); + level endon( "between_round_over" ); + self.lsgsar_lethal_nade_amt = 0; + self.lsgsar_has_lethal_nade = 0; + self.lsgsar_tactical_nade_amt = 0; + self.lsgsar_has_tactical_nade = 0; + self.lsgsar_lethal = undefined; + self.lsgsar_tactical = undefined; + if ( self isthrowinggrenade() ) + { + self thread last_stand_take_thrown_grenade(); + } + weapons_on_player = self getweaponslist( 1 ); + i = 0; + while ( i < weapons_on_player.size ) + { + if ( self is_player_lethal_grenade( weapons_on_player[ i ] ) ) + { + self.lsgsar_has_lethal_nade = 1; + self.lsgsar_lethal = self get_player_lethal_grenade(); + self.lsgsar_lethal_nade_amt = self getweaponammoclip( self get_player_lethal_grenade() ); + self setweaponammoclip( self get_player_lethal_grenade(), 0 ); + self takeweapon( self get_player_lethal_grenade() ); + i++; + continue; + } + else + { + if ( self is_player_tactical_grenade( weapons_on_player[ i ] ) ) + { + self.lsgsar_has_tactical_nade = 1; + self.lsgsar_tactical = self get_player_tactical_grenade(); + self.lsgsar_tactical_nade_amt = self getweaponammoclip( self get_player_tactical_grenade() ); + self setweaponammoclip( self get_player_tactical_grenade(), 0 ); + self takeweapon( self get_player_tactical_grenade() ); + } + } + i++; + } + self waittill( "player_revived" ); + if ( self.lsgsar_has_lethal_nade ) + { + self set_player_lethal_grenade( self.lsgsar_lethal ); + self giveweapon( self.lsgsar_lethal ); + self setweaponammoclip( self.lsgsar_lethal, self.lsgsar_lethal_nade_amt ); + } + if ( self.lsgsar_has_tactical_nade ) + { + self set_player_tactical_grenade( self.lsgsar_tactical ); + self giveweapon( self.lsgsar_tactical ); + self setweaponammoclip( self.lsgsar_tactical, self.lsgsar_tactical_nade_amt ); + } + self.lsgsar_lethal_nade_amt = undefined; + self.lsgsar_has_lethal_nade = undefined; + self.lsgsar_tactical_nade_amt = undefined; + self.lsgsar_has_tactical_nade = undefined; + self.lsgsar_lethal = undefined; + self.lsgsar_tactical = undefined; +} + +spectators_respawn() +{ + level endon( "between_round_over" ); + if ( !isDefined( level.zombie_vars[ "spectators_respawn" ] ) || !level.zombie_vars[ "spectators_respawn" ] ) + { + return; + } + if ( !isDefined( level.custom_spawnplayer ) ) + { + level.custom_spawnplayer = ::spectator_respawn; + } + while ( 1 ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].sessionstate == "spectator" && isDefined( players[ i ].spectator_respawn ) ) + { + players[ i ] [[ level.spawnplayer ]](); + thread refresh_player_navcard_hud(); + if ( isDefined( level.script ) && level.round_number > 6 && players[ i ].score < 1500 ) + { + players[ i ].old_score = players[ i ].score; + if ( isDefined( level.spectator_respawn_custom_score ) ) + { + players[ i ] [[ level.spectator_respawn_custom_score ]](); + } + players[ i ].score = 1500; + } + } + i++; + } + wait 1; + } +} + +spectator_respawn() +{ +/* +/# + println( "*************************Respawn Spectator***" ); +#/ +/# + assert( isDefined( self.spectator_respawn ) ); +#/ +*/ + origin = self.spectator_respawn.origin; + angles = self.spectator_respawn.angles; + self setspectatepermissions( 0 ); + new_origin = undefined; + if ( isDefined( level.check_valid_spawn_override ) ) + { + new_origin = [[ level.check_valid_spawn_override ]]( self ); + } + if ( !isDefined( new_origin ) ) + { + new_origin = check_for_valid_spawn_near_team( self, 1 ); + } + if ( isDefined( new_origin ) ) + { + if ( !isDefined( new_origin.angles ) ) + { + angles = ( 0, 0, -1 ); + } + else + { + angles = new_origin.angles; + } + self spawn( new_origin.origin, angles ); + } + else + { + self spawn( origin, angles ); + } + if ( isDefined( self get_player_placeable_mine() ) ) + { + self takeweapon( self get_player_placeable_mine() ); + self set_player_placeable_mine( undefined ); + } + self maps/mp/zombies/_zm_equipment::equipment_take(); + self.is_burning = undefined; + self.abilities = []; + self.is_zombie = 0; + self.ignoreme = 0; + setclientsysstate( "lsm", "0", self ); + self reviveplayer(); + self notify( "spawned_player" ); + if ( isDefined( level._zombiemode_post_respawn_callback ) ) + { + self thread [[ level._zombiemode_post_respawn_callback ]](); + } + self maps/mp/zombies/_zm_score::player_reduce_points( "died" ); + self maps/mp/zombies/_zm_melee_weapon::spectator_respawn_all(); + claymore_triggers = getentarray( "claymore_purchase", "targetname" ); + i = 0; + while ( i < claymore_triggers.size ) + { + claymore_triggers[ i ] setvisibletoplayer( self ); + claymore_triggers[ i ].claymores_triggered = 0; + i++; + } + self thread player_zombie_breadcrumb(); + self thread return_retained_perks(); + return 1; +} + +check_for_valid_spawn_near_team( revivee, return_struct ) +{ + if ( isDefined( level.check_for_valid_spawn_near_team_callback ) ) + { + spawn_location = [[ level.check_for_valid_spawn_near_team_callback ]]( revivee, return_struct ); + return spawn_location; + } + else + { + players = get_players(); + spawn_points = maps/mp/gametypes_zm/_zm_gametype::get_player_spawns_for_gametype(); + closest_group = undefined; + closest_distance = 100000000; + backup_group = undefined; + backup_distance = 100000000; + if ( spawn_points.size == 0 ) + { + return undefined; + } + i = 0; + while ( i < players.size ) + { + while ( is_player_valid( players[ i ], undefined, 1 ) && players[ i ] != self ) + { + j = 0; + while ( j < spawn_points.size ) + { + if ( isDefined( spawn_points[ j ].script_int ) ) + { + ideal_distance = spawn_points[ j ].script_int; + } + else + { + ideal_distance = 1000; + } + if ( spawn_points[ j ].locked == 0 ) + { + plyr_dist = distancesquared( players[ i ].origin, spawn_points[ j ].origin ); + if ( plyr_dist < ( ideal_distance * ideal_distance ) ) + { + if ( plyr_dist < closest_distance ) + { + closest_distance = plyr_dist; + closest_group = j; + } + j++; + continue; + } + else + { + if ( plyr_dist < backup_distance ) + { + backup_group = j; + backup_distance = plyr_dist; + } + } + } + j++; + } + } + if ( !isDefined( closest_group ) ) + { + closest_group = backup_group; + } + if ( isDefined( closest_group ) ) + { + spawn_location = get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct ); + if ( isDefined( spawn_location ) ) + { + return spawn_location; + } + } + i++; + } + return undefined; + } +} + +get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct ) +{ + spawn_array = getstructarray( spawn_points[ closest_group ].target, "targetname" ); + spawn_array = array_randomize( spawn_array ); + k = 0; + while ( k < spawn_array.size ) + { + if ( isDefined( spawn_array[ k ].plyr ) && spawn_array[ k ].plyr == revivee getentitynumber() ) + { + if ( positionwouldtelefrag( spawn_array[ k ].origin ) ) + { + spawn_array[ k ].plyr = undefined; + break; + } + else if ( isDefined( return_struct ) && return_struct ) + { + return spawn_array[ k ]; + } + else + { + return spawn_array[ k ].origin; + } + } + k++; + } + k = 0; + while ( k < spawn_array.size ) + { + if ( positionwouldtelefrag( spawn_array[ k ].origin ) ) + { + k++; + continue; + } + else if ( !isDefined( spawn_array[ k ].plyr ) || spawn_array[ k ].plyr == revivee getentitynumber() ) + { + spawn_array[ k ].plyr = revivee getentitynumber(); + if ( isDefined( return_struct ) && return_struct ) + { + return spawn_array[ k ]; + } + else + { + return spawn_array[ k ].origin; + } + } + k++; + } + if ( isDefined( return_struct ) && return_struct ) + { + return spawn_array[ 0 ]; + } + return spawn_array[ 0 ].origin; +} + +check_for_valid_spawn_near_position( revivee, v_position, return_struct ) +{ + spawn_points = maps/mp/gametypes_zm/_zm_gametype::get_player_spawns_for_gametype(); + if ( spawn_points.size == 0 ) + { + return undefined; + } + closest_group = undefined; + closest_distance = 100000000; + backup_group = undefined; + backup_distance = 100000000; + i = 0; + while ( i < spawn_points.size ) + { + if ( isDefined( spawn_points[ i ].script_int ) ) + { + ideal_distance = spawn_points[ i ].script_int; + } + else + { + ideal_distance = 1000; + } + if ( spawn_points[ i ].locked == 0 ) + { + dist = distancesquared( v_position, spawn_points[ i ].origin ); + if ( dist < ( ideal_distance * ideal_distance ) ) + { + if ( dist < closest_distance ) + { + closest_distance = dist; + closest_group = i; + } + break; + } + else + { + if ( dist < backup_distance ) + { + backup_group = i; + backup_distance = dist; + } + } + } + if ( !isDefined( closest_group ) ) + { + closest_group = backup_group; + } + i++; + } + if ( isDefined( closest_group ) ) + { + spawn_location = get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct ); + if ( isDefined( spawn_location ) ) + { + return spawn_location; + } + } + return undefined; +} + +check_for_valid_spawn_within_range( revivee, v_position, return_struct, min_distance, max_distance ) +{ + spawn_points = maps/mp/gametypes_zm/_zm_gametype::get_player_spawns_for_gametype(); + if ( spawn_points.size == 0 ) + { + return undefined; + } + closest_group = undefined; + closest_distance = 100000000; + i = 0; + while ( i < spawn_points.size ) + { + if ( spawn_points[ i ].locked == 0 ) + { + dist = distance( v_position, spawn_points[ i ].origin ); + if ( dist >= min_distance && dist <= max_distance ) + { + if ( dist < closest_distance ) + { + closest_distance = dist; + closest_group = i; + } + } + } + i++; + } + if ( isDefined( closest_group ) ) + { + spawn_location = get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct ); + if ( isDefined( spawn_location ) ) + { + return spawn_location; + } + } + return undefined; +} + +get_players_on_team( exclude ) +{ + teammates = []; + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].spawn_side == self.spawn_side && !isDefined( players[ i ].revivetrigger ) && players[ i ] != exclude ) + { + teammates[ teammates.size ] = players[ i ]; + } + i++; + } + return teammates; +} + +get_safe_breadcrumb_pos( player ) +{ + players = get_players(); + valid_players = []; + min_dist = 22500; + i = 0; + while ( i < players.size ) + { + if ( !is_player_valid( players[ i ] ) ) + { + i++; + continue; + } + else + { + valid_players[ valid_players.size ] = players[ i ]; + } + i++; + } + i = 0; + while ( i < valid_players.size ) + { + count = 0; + q = 1; + while ( q < player.zombie_breadcrumbs.size ) + { + if ( distancesquared( player.zombie_breadcrumbs[ q ], valid_players[ i ].origin ) < min_dist ) + { + q++; + continue; + } + else + { + count++; + if ( count == valid_players.size ) + { + return player.zombie_breadcrumbs[ q ]; + } + } + q++; + } + i++; + } + return undefined; +} + +default_max_zombie_func( max_num ) +{ + /* +/# + count = getDvarInt( #"CF687B54" ); + if ( count > -1 ) + { + return count; +#/ + } + */ + max = max_num; + if ( level.round_number < 2 ) + { + max = int( max_num * 0.25 ); + } + else if ( level.round_number < 3 ) + { + max = int( max_num * 0.3 ); + } + else if ( level.round_number < 4 ) + { + max = int( max_num * 0.5 ); + } + else if ( level.round_number < 5 ) + { + max = int( max_num * 0.7 ); + } + else + { + if ( level.round_number < 6 ) + { + max = int( max_num * 0.9 ); + } + } + return max; +} + +round_spawning() +{ + level endon( "intermission" ); + level endon( "end_of_round" ); + level endon( "restart_round" ); + /* +/# + level endon( "kill_round" ); +#/ + */ + if ( level.intermission ) + { + return; + } + /* +/# + if ( getDvarInt( "zombie_cheat" ) == 2 || getDvarInt( "zombie_cheat" ) >= 4 ) + { + return; +#/ + } + */ + if ( level.zombie_spawn_locations.size < 1 ) + { + /* +/# + assertmsg( "No active spawners in the map. Check to see if the zone is active and if it's pointing to spawners." ); +#/ + */ + return; + } + ai_calculate_health( level.round_number ); + count = 0; + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ].zombification_time = 0; + i++; + } + max = level.zombie_vars[ "zombie_max_ai" ]; + multiplier = level.round_number / 5; + if ( multiplier < 1 ) + { + multiplier = 1; + } + if ( level.round_number >= 10 ) + { + multiplier *= level.round_number * 0.15; + } + player_num = get_players().size; + if ( player_num == 1 ) + { + max += int( 0.5 * level.zombie_vars[ "zombie_ai_per_player" ] * multiplier ); + } + else + { + max += int( ( player_num - 1 ) * level.zombie_vars[ "zombie_ai_per_player" ] * multiplier ); + } + if ( !isDefined( level.max_zombie_func ) ) + { + level.max_zombie_func = ::default_max_zombie_func; + } + if ( isDefined( level.kill_counter_hud ) && level.zombie_total > 0 ) + { + level.zombie_total = [[ level.max_zombie_func ]]( max ); + level notify( "zombie_total_set" ); + } + if ( isDefined( level.zombie_total_set_func ) ) + { + level thread [[ level.zombie_total_set_func ]](); + } + if ( level.round_number < 10 || level.speed_change_max > 0 ) + { + level thread zombie_speed_up(); + } + mixed_spawns = 0; + old_spawn = undefined; + while ( 1 ) + { + while ( get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 ) + { + wait 0.1; + } + while ( get_current_actor_count() >= level.zombie_actor_limit ) + { + clear_all_corpses(); + wait 0.1; + } + flag_wait( "spawn_zombies" ); + while ( level.zombie_spawn_locations.size <= 0 ) + { + wait 0.1; + } + run_custom_ai_spawn_checks(); + spawn_point = level.zombie_spawn_locations[ randomint( level.zombie_spawn_locations.size ) ]; + if ( !isDefined( old_spawn ) ) + { + old_spawn = spawn_point; + } + else + { + if ( spawn_point == old_spawn ) + { + spawn_point = level.zombie_spawn_locations[ randomint( level.zombie_spawn_locations.size ) ]; + } + } + old_spawn = spawn_point; + while ( isDefined( level.mixed_rounds_enabled ) && level.mixed_rounds_enabled == 1 ) + { + spawn_dog = 0; + if ( level.round_number > 30 ) + { + if ( randomint( 100 ) < 3 ) + { + spawn_dog = 1; + } + } + else if ( level.round_number > 25 && mixed_spawns < 3 ) + { + if ( randomint( 100 ) < 2 ) + { + spawn_dog = 1; + } + } + else + { + if ( level.round_number > 20 && mixed_spawns < 2 ) + { + if ( randomint( 100 ) < 2 ) + { + spawn_dog = 1; + } + break; + } + else + { + if ( level.round_number > 15 && mixed_spawns < 1 ) + { + if ( randomint( 100 ) < 1 ) + { + spawn_dog = 1; + } + } + } + } + while ( spawn_dog ) + { + keys = getarraykeys( level.zones ); + i = 0; + while ( i < keys.size ) + { + while ( level.zones[ keys[ i ] ].is_occupied ) + { + akeys = getarraykeys( level.zones[ keys[ i ] ].adjacent_zones ); + k = 0; + while ( k < akeys.size ) + { + if ( level.zones[ akeys[ k ] ].is_active && !level.zones[ akeys[ k ] ].is_occupied && level.zones[ akeys[ k ] ].dog_locations.size > 0 ) + { + maps/mp/zombies/_zm_ai_dogs::special_dog_spawn( undefined, 1 ); + level.zombie_total--; + + wait_network_frame(); + } + k++; + } + } + i++; + } + } + } + if ( isDefined( level.zombie_spawners ) ) + { + if ( isDefined( level.use_multiple_spawns ) && level.use_multiple_spawns ) + { + if ( isDefined( spawn_point.script_int ) ) + { + if ( isDefined( level.zombie_spawn[ spawn_point.script_int ] ) && level.zombie_spawn[ spawn_point.script_int ].size ) + { + spawner = random( level.zombie_spawn[ spawn_point.script_int ] ); + } + else + { + /* +/# + assertmsg( "Wanting to spawn from zombie group " + spawn_point.script_int + "but it doens't exist" ); +#/ + */ + } + } + else if ( isDefined( level.zones[ spawn_point.zone_name ].script_int ) && level.zones[ spawn_point.zone_name ].script_int ) + { + spawner = random( level.zombie_spawn[ level.zones[ spawn_point.zone_name ].script_int ] ); + } + else + { + if ( isDefined( level.spawner_int ) && isDefined( level.zombie_spawn[ level.spawner_int ].size ) && level.zombie_spawn[ level.spawner_int ].size ) + { + spawner = random( level.zombie_spawn[ level.spawner_int ] ); + break; + } + else + { + spawner = random( level.zombie_spawners ); + } + } + } + else + { + spawner = random( level.zombie_spawners ); + } + ai = spawn_zombie( spawner, spawner.targetname, spawn_point ); + } + if ( isDefined( ai ) ) + { + level.zombie_total--; + + ai thread round_spawn_failsafe(); + count++; + } + wait level.zombie_vars[ "zombie_spawn_delay" ]; + wait_network_frame(); + } +} + +run_custom_ai_spawn_checks() +{ + _a3949 = level.custom_ai_spawn_check_funcs; + str_id = getFirstArrayKey( _a3949 ); + while ( isDefined( str_id ) ) + { + s = _a3949[ str_id ]; + if ( [[ s.func_check ]]() ) + { + a_spawners = [[ s.func_get_spawners ]](); + level.zombie_spawners = arraycombine( level.zombie_spawners, a_spawners, 0, 0 ); + while ( isDefined( level.use_multiple_spawns ) && level.use_multiple_spawns ) + { + _a3958 = a_spawners; + _k3958 = getFirstArrayKey( _a3958 ); + while ( isDefined( _k3958 ) ) + { + sp = _a3958[ _k3958 ]; + if ( isDefined( sp.script_int ) ) + { + if ( !isDefined( level.zombie_spawn[ sp.script_int ] ) ) + { + level.zombie_spawn[ sp.script_int ] = []; + } + if ( !isinarray( level.zombie_spawn[ sp.script_int ], sp ) ) + { + level.zombie_spawn[ sp.script_int ][ level.zombie_spawn[ sp.script_int ].size ] = sp; + } + } + _k3958 = getNextArrayKey( _a3958, _k3958 ); + } + } + if ( isDefined( s.func_get_locations ) ) + { + a_locations = [[ s.func_get_locations ]](); + level.zombie_spawn_locations = arraycombine( level.zombie_spawn_locations, a_locations, 0, 0 ); + } + } + else + { + a_spawners = [[ s.func_get_spawners ]](); + _a3985 = a_spawners; + _k3985 = getFirstArrayKey( _a3985 ); + while ( isDefined( _k3985 ) ) + { + sp = _a3985[ _k3985 ]; + arrayremovevalue( level.zombie_spawners, sp ); + _k3985 = getNextArrayKey( _a3985, _k3985 ); + } + while ( isDefined( level.use_multiple_spawns ) && level.use_multiple_spawns ) + { + _a3992 = a_spawners; + _k3992 = getFirstArrayKey( _a3992 ); + while ( isDefined( _k3992 ) ) + { + sp = _a3992[ _k3992 ]; + if ( isDefined( sp.script_int ) && isDefined( level.zombie_spawn[ sp.script_int ] ) ) + { + arrayremovevalue( level.zombie_spawn[ sp.script_int ], sp ); + } + _k3992 = getNextArrayKey( _a3992, _k3992 ); + } + } + while ( isDefined( s.func_get_locations ) ) + { + a_locations = [[ s.func_get_locations ]](); + _a4005 = a_locations; + _k4005 = getFirstArrayKey( _a4005 ); + while ( isDefined( _k4005 ) ) + { + s_loc = _a4005[ _k4005 ]; + arrayremovevalue( level.zombie_spawn_locations, s_loc ); + _k4005 = getNextArrayKey( _a4005, _k4005 ); + } + } + } + str_id = getNextArrayKey( _a3949, str_id ); + } +} + +register_custom_ai_spawn_check( str_id, func_check, func_get_spawners, func_get_locations ) +{ + if ( !isDefined( level.custom_ai_spawn_check_funcs[ str_id ] ) ) + { + level.custom_ai_spawn_check_funcs[ str_id ] = spawnstruct(); + } + level.custom_ai_spawn_check_funcs[ str_id ].func_check = func_check; + level.custom_ai_spawn_check_funcs[ str_id ].func_get_spawners = func_get_spawners; + level.custom_ai_spawn_check_funcs[ str_id ].func_get_locations = func_get_locations; +} + +zombie_speed_up() +{ + if ( level.round_number <= 3 ) + { + return; + } + level endon( "intermission" ); + level endon( "end_of_round" ); + level endon( "restart_round" ); + /* +/# + level endon( "kill_round" ); +#/ + */ + while ( level.zombie_total > 4 ) + { + wait 2; + } + num_zombies = get_current_zombie_count(); + while ( num_zombies > 3 ) + { + wait 2; + num_zombies = get_current_zombie_count(); + } + zombies = get_round_enemy_array(); + while ( zombies.size > 0 ) + { + if ( zombies.size == 1 && isDefined( zombies[ 0 ].has_legs ) && zombies[ 0 ].has_legs ) + { + if ( isDefined( level.zombie_speed_up ) ) + { + zombies[ 0 ] thread [[ level.zombie_speed_up ]](); + break; + } + else + { + if ( zombies[ 0 ].zombie_move_speed != "sprint" ) + { + zombies[ 0 ] set_zombie_run_cycle( "sprint" ); + zombies[ 0 ].zombie_move_speed_original = zombies[ 0 ].zombie_move_speed; + } + } + } + wait 0.5; + zombies = get_round_enemy_array(); + } +} + +round_spawning_test() +{ + while ( 1 ) + { + spawn_point = level.zombie_spawn_locations[ randomint( level.zombie_spawn_locations.size ) ]; + spawner = random( level.zombie_spawners ); + ai = spawn_zombie( spawner, spawner.targetname, spawn_point ); + ai waittill( "death" ); + wait 5; + } +} + +round_pause( delay ) +{ + if ( !isDefined( delay ) ) + { + delay = 30; + } + level.countdown_hud = create_counter_hud(); + level.countdown_hud setvalue( delay ); + level.countdown_hud.color = ( 0, 0, -1 ); + level.countdown_hud.alpha = 1; + level.countdown_hud fadeovertime( 2 ); + wait 2; + level.countdown_hud.color = vectorScale( ( 0, 0, -1 ), 0,21 ); + level.countdown_hud fadeovertime( 3 ); + wait 3; + while ( delay >= 1 ) + { + wait 1; + delay--; + + level.countdown_hud setvalue( delay ); + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] playlocalsound( "zmb_perks_packa_ready" ); + i++; + } + level.countdown_hud fadeovertime( 1 ); + level.countdown_hud.color = ( 0, 0, -1 ); + level.countdown_hud.alpha = 0; + wait 1; + level.countdown_hud destroy_hud(); +} + +round_start() +{ +/* +/# + println( "ZM >> round_start start" ); +#/ +*/ + if ( isDefined( level.round_prestart_func ) ) + { + [[ level.round_prestart_func ]](); + } + else + { + n_delay = 2; + if ( isDefined( level.zombie_round_start_delay ) ) + { + n_delay = level.zombie_round_start_delay; + } + wait n_delay; + } + level.zombie_health = level.zombie_vars[ "zombie_health_start" ]; + if ( getDvarInt( "scr_writeConfigStrings" ) == 1 ) + { + wait 5; + exitlevel(); + return; + } + if ( level.zombie_vars[ "game_start_delay" ] > 0 ) + { + round_pause( level.zombie_vars[ "game_start_delay" ] ); + } + flag_set( "begin_spawning" ); + if ( !isDefined( level.round_spawn_func ) ) + { + level.round_spawn_func = ::round_spawning; + } + /* +/# + if ( getDvarInt( #"7688603C" ) ) + { + level.round_spawn_func = ::round_spawning_test; +#/ + } + */ + if ( !isDefined( level.round_wait_func ) ) + { + level.round_wait_func = ::round_wait; + } + if ( !isDefined( level.round_think_func ) ) + { + level.round_think_func = ::round_think; + } + level thread [[ level.round_think_func ]](); +} + +play_door_dialog() +{ + level endon( "power_on" ); + self endon( "warning_dialog" ); + timer = 0; + while ( 1 ) + { + wait 0.05; + players = get_players(); + i = 0; + while ( i < players.size ) + { + dist = distancesquared( players[ i ].origin, self.origin ); + if ( dist > 4900 ) + { + timer = 0; + i++; + continue; + } + else + { + while ( dist < 4900 && timer < 3 ) + { + wait 0.5; + timer++; + } + if ( dist > 4900 && timer >= 3 ) + { + self playsound( "door_deny" ); + players[ i ] maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "door_deny" ); + wait 3; + self notify( "warning_dialog" ); + } + } + i++; + } + } +} + +wait_until_first_player() +{ + players = get_players(); + if ( !isDefined( players[ 0 ] ) ) + { + level waittill( "first_player_ready" ); + } +} + +round_one_up() +{ + level endon( "end_game" ); + if ( isDefined( level.noroundnumber ) && level.noroundnumber == 1 ) + { + return; + } + if ( !isDefined( level.doground_nomusic ) ) + { + level.doground_nomusic = 0; + } + if ( level.first_round ) + { + intro = 1; + if ( isDefined( level._custom_intro_vox ) ) + { + level thread [[ level._custom_intro_vox ]](); + } + else + { + level thread play_level_start_vox_delayed(); + } + } + else + { + intro = 0; + } + if ( level.round_number != 5 && level.round_number != 10 && level.round_number != 20 || level.round_number == 35 && level.round_number == 50 ) + { + players = get_players(); + rand = randomintrange( 0, players.size ); + players[ rand ] thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "round_" + level.round_number ); + } + if ( intro ) + { + if ( isDefined( level.host_ended_game ) && level.host_ended_game ) + { + return; + } + wait 6.25; + level notify( "intro_hud_done" ); + wait 2; + } + else + { + wait 2.5; + } + reportmtu( level.round_number ); +} + +round_over() +{ + if ( isDefined( level.noroundnumber ) && level.noroundnumber == 1 ) + { + return; + } + time = level.zombie_vars[ "zombie_between_round_time" ]; + players = getplayers(); + player_index = 0; + while ( player_index < players.size ) + { + if ( !isDefined( players[ player_index ].pers[ "previous_distance_traveled" ] ) ) + { + players[ player_index ].pers[ "previous_distance_traveled" ] = 0; + } + distancethisround = int( players[ player_index ].pers[ "distance_traveled" ] - players[ player_index ].pers[ "previous_distance_traveled" ] ); + players[ player_index ].pers[ "previous_distance_traveled" ] = players[ player_index ].pers[ "distance_traveled" ]; + players[ player_index ] incrementplayerstat( "distance_traveled", distancethisround ); + if ( players[ player_index ].pers[ "team" ] != "spectator" ) + { + zonename = players[ player_index ] get_current_zone(); + if ( isDefined( zonename ) ) + { + players[ player_index ] recordzombiezone( "endingZone", zonename ); + } + } + player_index++; + } + recordzombieroundend(); + wait time; +} + +round_think( restart ) +{ + if ( !isDefined( restart ) ) + { + restart = 0; + } + /* +/# + println( "ZM >> round_think start" ); +#/ + */ + level endon( "end_round_think" ); + while ( isDefined( restart ) && !restart ) + { + if ( isDefined( level.initial_round_wait_func ) ) + { + [[ level.initial_round_wait_func ]](); + } + while ( isDefined( level.host_ended_game ) && !level.host_ended_game ) + { + players = get_players(); + _a4430 = players; + _k4430 = getFirstArrayKey( _a4430 ); + while ( isDefined( _k4430 ) ) + { + player = _a4430[ _k4430 ]; + if ( isDefined( player.hostmigrationcontrolsfrozen ) && !player.hostmigrationcontrolsfrozen ) + { + player freezecontrols( 0 ); + /* +/# + println( " Unfreeze controls 8" ); +#/ + */ + } + player maps/mp/zombies/_zm_stats::set_global_stat( "rounds", level.round_number ); + _k4430 = getNextArrayKey( _a4430, _k4430 ); + } + } + } + setroundsplayed( level.round_number ); + for ( ;; ) + { + maxreward = 50 * level.round_number; + if ( maxreward > 500 ) + { + maxreward = 500; + } + level.zombie_vars[ "rebuild_barrier_cap_per_round" ] = maxreward; + level.pro_tips_start_time = getTime(); + level.zombie_last_run_time = getTime(); + if ( isDefined( level.zombie_round_change_custom ) ) + { + [[ level.zombie_round_change_custom ]](); + } + else + { + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "round_start" ); + round_one_up(); + } + maps/mp/zombies/_zm_powerups::powerup_round_start(); + players = get_players(); + array_thread( players, ::rebuild_barrier_reward_reset ); + if ( isDefined( level.headshots_only ) && !level.headshots_only && !restart ) + { + level thread award_grenades_for_survivors(); + } + /* + bbprint( "zombie_rounds", "round %d player_count %d", level.round_number, players.size ); +/# + println( "ZM >> round_think, round=" + level.round_number + ", player_count=" + players.size ); +#/ + */ + level.round_start_time = getTime(); + while ( level.zombie_spawn_locations.size <= 0 ) + { + wait 0.1; + } + level thread [[ level.round_spawn_func ]](); + level notify( "start_of_round" ); + recordzombieroundstart(); + players = getplayers(); + index = 0; + while ( index < players.size ) + { + zonename = players[ index ] get_current_zone(); + if ( isDefined( zonename ) ) + { + players[ index ] recordzombiezone( "startingZone", zonename ); + } + index++; + } + if ( isDefined( level.round_start_custom_func ) ) + { + [[ level.round_start_custom_func ]](); + } + [[ level.round_wait_func ]](); + level.first_round = 0; + level notify( "end_of_round" ); + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "round_end" ); + uploadstats(); + if ( isDefined( level.round_end_custom_logic ) ) + { + [[ level.round_end_custom_logic ]](); + } + players = get_players(); + if ( isDefined( level.no_end_game_check ) && level.no_end_game_check ) + { + level thread last_stand_revive(); + level thread spectators_respawn(); + } + else + { + if ( players.size != 1 ) + { + level thread spectators_respawn(); + } + } + players = get_players(); + array_thread( players, ::round_end ); + timer = level.zombie_vars[ "zombie_spawn_delay" ]; + if ( timer > 0.08 ) + { + level.zombie_vars[ "zombie_spawn_delay" ] = timer * 0.95; + } + else + { + if ( timer < 0.08 ) + { + level.zombie_vars[ "zombie_spawn_delay" ] = 0.08; + } + } + if ( level.gamedifficulty == 0 ) + { + level.zombie_move_speed = level.round_number * level.zombie_vars[ "zombie_move_speed_multiplier_easy" ]; + } + else + { + level.zombie_move_speed = level.round_number * level.zombie_vars[ "zombie_move_speed_multiplier" ]; + } + level.round_number++; + if ( level.round_number >= 255 ) + { + level.round_number = 255; + } + setroundsplayed( level.round_number ); + matchutctime = getutc(); + players = get_players(); + _a4579 = players; + _k4579 = getFirstArrayKey( _a4579 ); + while ( isDefined( _k4579 ) ) + { + player = _a4579[ _k4579 ]; + if ( level.curr_gametype_affects_rank && level.round_number > ( 3 + level.start_round ) ) + { + player maps/mp/zombies/_zm_stats::add_client_stat( "weighted_rounds_played", level.round_number ); + } + player maps/mp/zombies/_zm_stats::set_global_stat( "rounds", level.round_number ); + player maps/mp/zombies/_zm_stats::update_playing_utc_time( matchutctime ); + _k4579 = getNextArrayKey( _a4579, _k4579 ); + } + //check_quickrevive_for_hotjoin(); + level round_over(); + level notify( "between_round_over" ); + restart = 0; + } +} + +award_grenades_for_survivors() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( !players[ i ].is_zombie ) + { + lethal_grenade = players[ i ] get_player_lethal_grenade(); + if ( !players[ i ] hasweapon( lethal_grenade ) ) + { + players[ i ] giveweapon( lethal_grenade ); + players[ i ] setweaponammoclip( lethal_grenade, 0 ); + } + if ( players[ i ] getfractionmaxammo( lethal_grenade ) < 0.25 ) + { + players[ i ] setweaponammoclip( lethal_grenade, 2 ); + i++; + continue; + } + else if ( players[ i ] getfractionmaxammo( lethal_grenade ) < 0.5 ) + { + players[ i ] setweaponammoclip( lethal_grenade, 3 ); + i++; + continue; + } + else + { + players[ i ] setweaponammoclip( lethal_grenade, 4 ); + } + } + i++; + } +} + +ai_calculate_health( round_number ) +{ + level.zombie_health = level.zombie_vars[ "zombie_health_start" ]; + i = 2; + while ( i <= round_number ) + { + if ( i >= 10 ) + { + old_health = level.zombie_health; + level.zombie_health += int( level.zombie_health * level.zombie_vars[ "zombie_health_increase_multiplier" ] ); + if ( level.zombie_health < old_health ) + { + level.zombie_health = old_health; + return; + } + i++; + continue; + } + else + { + level.zombie_health = int( level.zombie_health + level.zombie_vars[ "zombie_health_increase" ] ); + } + i++; + } +} + +ai_zombie_health( round_number ) +{ + zombie_health = level.zombie_vars[ "zombie_health_start" ]; + i = 2; + while ( i <= round_number ) + { + if ( i >= 10 ) + { + old_health = zombie_health; + zombie_health += int( zombie_health * level.zombie_vars[ "zombie_health_increase_multiplier" ] ); + if ( zombie_health < old_health ) + { + return old_health; + } + } + else + { + zombie_health = int( zombie_health + level.zombie_vars[ "zombie_health_increase" ] ); + } + i++; + } + return zombie_health; +} + +round_spawn_failsafe_debug() +{ +/* +/# + level notify( "failsafe_debug_stop" ); + level endon( "failsafe_debug_stop" ); + start = getTime(); + level.chunk_time = 0; + while ( 1 ) + { + level.failsafe_time = getTime() - start; + if ( isDefined( self.lastchunk_destroy_time ) ) + { + level.chunk_time = getTime() - self.lastchunk_destroy_time; + } + wait_network_frame(); +#/ + } +*/ +} + +round_spawn_failsafe() +{ + self endon( "death" ); + prevorigin = self.origin; + while ( 1 ) + { + if ( !level.zombie_vars[ "zombie_use_failsafe" ] ) + { + return; + } + if ( isDefined( self.ignore_round_spawn_failsafe ) && self.ignore_round_spawn_failsafe ) + { + return; + } + wait 30; + if ( !self.has_legs ) + { + wait 10; + } + if ( isDefined( self.is_inert ) && self.is_inert ) + { + continue; + } + while ( isDefined( self.lastchunk_destroy_time ) ) + { + while ( ( getTime() - self.lastchunk_destroy_time ) < 8000 ) + { + continue; + } + } + if ( self.origin[ 2 ] < level.zombie_vars[ "below_world_check" ] ) + { + if ( isDefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) && isDefined( self.isscreecher ) && !self.isscreecher ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + /* +/# +#/ + */ + self dodamage( self.health + 100, ( 0, 0, -1 ) ); + return; + } + else if ( distancesquared( self.origin, prevorigin ) < 576 ) + { + if ( isDefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) ) + { + if ( !self.ignoreall && isDefined( self.nuked ) && !self.nuked && isDefined( self.marked_for_death ) && !self.marked_for_death && isDefined( self.isscreecher ) && !self.isscreecher && isDefined( self.has_legs ) && self.has_legs ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + } + level.zombies_timeout_playspace++; + /* +/# +#/ + */ + self dodamage( self.health + 100, ( 0, 0, -1 ) ); + return; + } + else + { + prevorigin = self.origin; + } + } +} + +round_wait() +{ + level endon( "restart_round" ); + /* +/# + if ( getDvarInt( #"7688603C" ) ) + { + level waittill( "forever" ); +#/ + } +/# + if ( getDvarInt( "zombie_cheat" ) == 2 || getDvarInt( "zombie_cheat" ) >= 4 ) + { + level waittill( "forever" ); +#/ + } + */ + wait 1; + if ( flag( "dog_round" ) ) + { + wait 7; + while ( level.dog_intermission ) + { + wait 0.5; + } + increment_dog_round_stat( "finished" ); + } + else + { + while ( 1 ) + { + should_wait = 0; + if ( isDefined( level.is_ghost_round_started ) && [[ level.is_ghost_round_started ]]() ) + { + should_wait = 1; + } + else + { + if ( get_current_zombie_count() > 0 && level.zombie_total > 0 ) + { + should_wait = level.intermission; + } + } + if ( !should_wait ) + { + return; + } + if ( flag( "end_round_wait" ) ) + { + return; + } + wait 1; + } + } +} + +zombify_player() +{ + self maps/mp/zombies/_zm_score::player_died_penalty(); + bbprint( "zombie_playerdeaths", "round %d playername %s deathtype %s x %f y %f z %f", level.round_number, self.name, "died", self.origin ); + self recordplayerdeathzombies(); + if ( isDefined( level.deathcard_spawn_func ) ) + { + self [[ level.deathcard_spawn_func ]](); + } + if ( !isDefined( level.zombie_vars[ "zombify_player" ] ) || !level.zombie_vars[ "zombify_player" ] ) + { + self thread spawnspectator(); + return; + } + self.ignoreme = 1; + self.is_zombie = 1; + self.zombification_time = getTime(); + self.team = level.zombie_team; + self notify( "zombified" ); + if ( isDefined( self.revivetrigger ) ) + { + self.revivetrigger delete(); + } + self.revivetrigger = undefined; + self setmovespeedscale( 0.3 ); + self reviveplayer(); + self takeallweapons(); + self giveweapon( "zombie_melee", 0 ); + self switchtoweapon( "zombie_melee" ); + self disableweaponcycling(); + self disableoffhandweapons(); + setclientsysstate( "zombify", 1, self ); + self thread maps/mp/zombies/_zm_spawner::zombie_eye_glow(); + self thread playerzombie_player_damage(); + self thread playerzombie_soundboard(); +} + +playerzombie_player_damage() +{ + self endon( "death" ); + self endon( "disconnect" ); + self thread playerzombie_infinite_health(); + self.zombiehealth = level.zombie_health; + while ( 1 ) + { + self waittill( "damage", amount, attacker, directionvec, point, type ); + while ( !isDefined( attacker ) || !isplayer( attacker ) ) + { + wait 0.05; + } + self.zombiehealth -= amount; + if ( self.zombiehealth <= 0 ) + { + self thread playerzombie_downed_state(); + self waittill( "playerzombie_downed_state_done" ); + self.zombiehealth = level.zombie_health; + } + } +} + +playerzombie_downed_state() +{ + self endon( "death" ); + self endon( "disconnect" ); + downtime = 15; + starttime = getTime(); + endtime = starttime + ( downtime * 1000 ); + self thread playerzombie_downed_hud(); + self.playerzombie_soundboard_disable = 1; + self thread maps/mp/zombies/_zm_spawner::zombie_eye_glow_stop(); + self disableweapons(); + self allowstand( 0 ); + self allowcrouch( 0 ); + self allowprone( 1 ); + while ( getTime() < endtime ) + { + wait 0.05; + } + self.playerzombie_soundboard_disable = 0; + self thread maps/mp/zombies/_zm_spawner::zombie_eye_glow(); + self enableweapons(); + self allowstand( 1 ); + self allowcrouch( 0 ); + self allowprone( 0 ); + self notify( "playerzombie_downed_state_done" ); +} + +playerzombie_downed_hud() +{ + self endon( "death" ); + self endon( "disconnect" ); + text = newclienthudelem( self ); + text.alignx = "center"; + text.aligny = "middle"; + text.horzalign = "user_center"; + text.vertalign = "user_bottom"; + text.foreground = 1; + text.font = "default"; + text.fontscale = 1.8; + text.alpha = 0; + text.color = ( 0, 0, -1 ); + text settext( &"ZOMBIE_PLAYERZOMBIE_DOWNED" ); + text.y = -113; + if ( self issplitscreen() ) + { + text.y = -137; + } + text fadeovertime( 0.1 ); + text.alpha = 1; + self waittill( "playerzombie_downed_state_done" ); + text fadeovertime( 0.1 ); + text.alpha = 0; +} + +playerzombie_infinite_health() +{ + self endon( "death" ); + self endon( "disconnect" ); + bighealth = 100000; + while ( 1 ) + { + if ( self.health < bighealth ) + { + self.health = bighealth; + } + wait 0.1; + } +} + +playerzombie_soundboard() +{ + self endon( "death" ); + self endon( "disconnect" ); + self.playerzombie_soundboard_disable = 0; + self.buttonpressed_use = 0; + self.buttonpressed_attack = 0; + self.buttonpressed_ads = 0; + self.usesound_waittime = 3000; + self.usesound_nexttime = getTime(); + usesound = "playerzombie_usebutton_sound"; + self.attacksound_waittime = 3000; + self.attacksound_nexttime = getTime(); + attacksound = "playerzombie_attackbutton_sound"; + self.adssound_waittime = 3000; + self.adssound_nexttime = getTime(); + adssound = "playerzombie_adsbutton_sound"; + self.inputsound_nexttime = getTime(); + while ( 1 ) + { + while ( self.playerzombie_soundboard_disable ) + { + wait 0.05; + } + if ( self usebuttonpressed() ) + { + if ( self can_do_input( "use" ) ) + { + self thread playerzombie_play_sound( usesound ); + self thread playerzombie_waitfor_buttonrelease( "use" ); + self.usesound_nexttime = getTime() + self.usesound_waittime; + } + } + else if ( self attackbuttonpressed() ) + { + if ( self can_do_input( "attack" ) ) + { + self thread playerzombie_play_sound( attacksound ); + self thread playerzombie_waitfor_buttonrelease( "attack" ); + self.attacksound_nexttime = getTime() + self.attacksound_waittime; + } + } + else + { + if ( self adsbuttonpressed() ) + { + if ( self can_do_input( "ads" ) ) + { + self thread playerzombie_play_sound( adssound ); + self thread playerzombie_waitfor_buttonrelease( "ads" ); + self.adssound_nexttime = getTime() + self.adssound_waittime; + } + } + } + wait 0.05; + } +} + +can_do_input( inputtype ) +{ + if ( getTime() < self.inputsound_nexttime ) + { + return 0; + } + cando = 0; + switch( inputtype ) + { + case "use": + if ( getTime() >= self.usesound_nexttime && !self.buttonpressed_use ) + { + cando = 1; + } + break; + case "attack": + if ( getTime() >= self.attacksound_nexttime && !self.buttonpressed_attack ) + { + cando = 1; + } + break; + case "ads": + if ( getTime() >= self.usesound_nexttime && !self.buttonpressed_ads ) + { + cando = 1; + } + break; + default: + /* +/# + assertmsg( "can_do_input(): didn't recognize inputType of " + inputtype ); +#/ + */ + break; + } + return cando; +} + +playerzombie_play_sound( alias ) +{ + self play_sound_on_ent( alias ); +} + +playerzombie_waitfor_buttonrelease( inputtype ) +{ + if ( inputtype != "use" && inputtype != "attack" && inputtype != "ads" ) + { + /* +/# + assertmsg( "playerzombie_waitfor_buttonrelease(): inputType of " + inputtype + " is not recognized." ); +#/ + */ + return; + } + notifystring = "waitfor_buttonrelease_" + inputtype; + self notify( notifystring ); + self endon( notifystring ); + if ( inputtype == "use" ) + { + self.buttonpressed_use = 1; + while ( self usebuttonpressed() ) + { + wait 0.05; + } + self.buttonpressed_use = 0; + } + else if ( inputtype == "attack" ) + { + self.buttonpressed_attack = 1; + while ( self attackbuttonpressed() ) + { + wait 0.05; + } + self.buttonpressed_attack = 0; + } + else + { + if ( inputtype == "ads" ) + { + self.buttonpressed_ads = 1; + while ( self adsbuttonpressed() ) + { + wait 0.05; + } + self.buttonpressed_ads = 0; + } + } +} + +remove_ignore_attacker() +{ + self notify( "new_ignore_attacker" ); + self endon( "new_ignore_attacker" ); + self endon( "disconnect" ); + if ( !isDefined( level.ignore_enemy_timer ) ) + { + level.ignore_enemy_timer = 0.4; + } + wait level.ignore_enemy_timer; + self.ignoreattacker = undefined; +} + +player_shield_facing_attacker( vdir, limit ) +{ + orientation = self getplayerangles(); + forwardvec = anglesToForward( orientation ); + forwardvec2d = ( forwardvec[ 0 ], forwardvec[ 1 ], 0 ); + unitforwardvec2d = vectornormalize( forwardvec2d ); + tofaceevec = vdir * -1; + tofaceevec2d = ( tofaceevec[ 0 ], tofaceevec[ 1 ], 0 ); + unittofaceevec2d = vectornormalize( tofaceevec2d ); + dotproduct = vectordot( unitforwardvec2d, unittofaceevec2d ); + return dotproduct > limit; +} + +player_damage_override_cheat( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + player_damage_override( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + return 0; +} + +player_damage_override( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if ( isDefined( level._game_module_player_damage_callback ) ) + { + self [[ level._game_module_player_damage_callback ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + idamage = self check_player_damage_callbacks( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + if ( isDefined( self.use_adjusted_grenade_damage ) && self.use_adjusted_grenade_damage ) + { + self.use_adjusted_grenade_damage = undefined; + if ( self.health > idamage ) + { + return idamage; + } + } + if ( !idamage ) + { + return 0; + } + if ( self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + return 0; + } + if ( isDefined( einflictor ) ) + { + if ( isDefined( einflictor.water_damage ) && einflictor.water_damage ) + { + return 0; + } + } + if ( isDefined( eattacker ) && isDefined( eattacker.is_zombie ) || eattacker.is_zombie && isplayer( eattacker ) ) + { + if ( isDefined( self.hasriotshield ) && self.hasriotshield && isDefined( vdir ) ) + { + if ( isDefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( self player_shield_facing_attacker( vdir, 0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + self [[ self.player_shield_apply_damage ]]( 100, 0 ); + return 0; + } + } + else + { + if ( !isDefined( self.riotshieldentity ) ) + { + if ( !self player_shield_facing_attacker( vdir, -0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + self [[ self.player_shield_apply_damage ]]( 100, 0 ); + return 0; + } + } + } + } + } + if ( isDefined( eattacker ) ) + { + if ( isDefined( self.ignoreattacker ) && self.ignoreattacker == eattacker ) + { + return 0; + } + if ( isDefined( self.is_zombie ) && self.is_zombie && isDefined( eattacker.is_zombie ) && eattacker.is_zombie ) + { + return 0; + } + if ( isDefined( eattacker.is_zombie ) && eattacker.is_zombie ) + { + self.ignoreattacker = eattacker; + self thread remove_ignore_attacker(); + if ( isDefined( eattacker.custom_damage_func ) ) + { + idamage = eattacker [[ eattacker.custom_damage_func ]]( self ); + } + else if ( isDefined( eattacker.meleedamage ) ) + { + idamage = eattacker.meleedamage; + } + else + { + idamage = 50; + } + } + eattacker notify( "hit_player" ); + if ( smeansofdeath != "MOD_FALLING" ) + { + self thread playswipesound( smeansofdeath, eattacker ); + if ( isDefined( eattacker.is_zombie ) || eattacker.is_zombie && isplayer( eattacker ) ) + { + self playrumbleonentity( "damage_heavy" ); + } + canexert = 1; + if ( isDefined( level.pers_upgrade_flopper ) && level.pers_upgrade_flopper ) + { + if ( isDefined( self.pers_upgrades_awarded[ "flopper" ] ) && self.pers_upgrades_awarded[ "flopper" ] ) + { + if ( smeansofdeath != "MOD_PROJECTILE_SPLASH" && smeansofdeath != "MOD_GRENADE" ) + { + canexert = smeansofdeath != "MOD_GRENADE_SPLASH"; + } + } + } + if ( isDefined( canexert ) && canexert ) + { + if ( randomintrange( 0, 1 ) == 0 ) + { + self thread maps/mp/zombies/_zm_audio::playerexert( "hitmed" ); + } + else + { + self thread maps/mp/zombies/_zm_audio::playerexert( "hitlrg" ); + } + } + } + } + finaldamage = idamage; + if ( !is_placeable_mine( sweapon ) || sweapon == "freezegun_zm" && sweapon == "freezegun_upgraded_zm" ) + { + return 0; + } + if ( isDefined( self.player_damage_override ) ) + { + self thread [[ self.player_damage_override ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + if ( smeansofdeath == "MOD_FALLING" ) + { + if ( self hasperk( "specialty_flakjacket" ) && isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + if ( isDefined( level.zombiemode_divetonuke_perk_func ) ) + { + [[ level.zombiemode_divetonuke_perk_func ]]( self, self.origin ); + } + return 0; + } + if ( isDefined( level.pers_upgrade_flopper ) && level.pers_upgrade_flopper ) + { + if ( self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_flopper_damage_check( smeansofdeath, idamage ) ) + { + return 0; + } + } + } + if ( smeansofdeath != "MOD_PROJECTILE" && smeansofdeath != "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" && smeansofdeath == "MOD_GRENADE_SPLASH" ) + { + if ( self hasperk( "specialty_flakjacket" ) ) + { + return 0; + } + if ( isDefined( level.pers_upgrade_flopper ) && level.pers_upgrade_flopper ) + { + if ( isDefined( self.pers_upgrades_awarded[ "flopper" ] ) && self.pers_upgrades_awarded[ "flopper" ] ) + { + return 0; + } + } + if ( self.health > 75 && isDefined( self.is_zombie ) && !self.is_zombie ) + { + return 75; + } + } + if ( idamage < self.health ) + { + if ( isDefined( eattacker ) ) + { + if ( isDefined( level.custom_kill_damaged_vo ) ) + { + eattacker thread [[ level.custom_kill_damaged_vo ]]( self ); + } + else + { + eattacker.sound_damage_player = self; + } + if ( isDefined( eattacker.has_legs ) && !eattacker.has_legs ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "crawl_hit" ); + } + else + { + if ( isDefined( eattacker.animname ) && eattacker.animname == "monkey_zombie" ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "monkey_hit" ); + } + } + } + return finaldamage; + } + if ( isDefined( eattacker ) ) + { + if ( isDefined( eattacker.animname ) && eattacker.animname == "zombie_dog" ) + { + self maps/mp/zombies/_zm_stats::increment_client_stat( "killed_by_zdog" ); + self maps/mp/zombies/_zm_stats::increment_player_stat( "killed_by_zdog" ); + } + else + { + if ( isDefined( eattacker.is_avogadro ) && eattacker.is_avogadro ) + { + self maps/mp/zombies/_zm_stats::increment_client_stat( "killed_by_avogadro", 0 ); + self maps/mp/zombies/_zm_stats::increment_player_stat( "killed_by_avogadro" ); + } + } + } + self thread clear_path_timers(); + if ( level.intermission ) + { + level waittill( "forever" ); + } + if ( level.scr_zm_ui_gametype == "zcleansed" && idamage > 0 ) + { + if ( isDefined( eattacker ) && isplayer( eattacker ) && eattacker.team != self.team && isDefined( self.laststand ) && !self.laststand || !self maps/mp/zombies/_zm_laststand::player_is_in_laststand() && !isDefined( self.last_player_attacker ) ) + { + if ( isDefined( eattacker.maxhealth ) && isDefined( eattacker.is_zombie ) && eattacker.is_zombie ) + { + eattacker.health = eattacker.maxhealth; + } + if ( isDefined( level.player_kills_player ) ) + { + self thread [[ level.player_kills_player ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + } + } + if ( self.lives > 0 && self hasperk( "specialty_finalstand" ) ) + { + self.lives--; + + if ( isDefined( level.chugabud_laststand_func ) ) + { + self thread [[ level.chugabud_laststand_func ]](); + return 0; + } + } + players = get_players(); + count = 0; + i = 0; + while ( i < players.size ) + { + if ( self != players[ i ] && !players[ i ].is_zombie || players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].sessionstate == "spectator" ) + { + count++; + } + i++; + } + if ( count < players.size || isDefined( level._game_module_game_end_check ) && !( [[ level._game_module_game_end_check ]]() ) ) + { + if ( isDefined( self.lives ) && self.lives > 0 && isDefined( level.force_solo_quick_revive ) && level.force_solo_quick_revive && self hasperk( "specialty_quickrevive" ) ) + { + self thread wait_and_revive(); + } + return finaldamage; + } + if ( players.size == 1 && flag( "solo_game" ) ) + { + if ( self.lives == 0 || !self hasperk( "specialty_quickrevive" ) ) + { + self.intermission = 1; + } + } + if ( players.size == 1 && flag( "solo_game" ) ) + { + if ( self.lives != 0 ) + { + solo_death = !self hasperk( "specialty_quickrevive" ); + } + } + if ( count > 1 ) + { + if ( players.size == 1 ) + { + non_solo_death = !flag( "solo_game" ); + } + } + if ( !solo_death && non_solo_death && isDefined( level.no_end_game_check ) && !level.no_end_game_check ) + { + level notify( "stop_suicide_trigger" ); + self thread maps/mp/zombies/_zm_laststand::playerlaststand( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime ); + if ( !isDefined( vdir ) ) + { + vdir = ( 0, 0, -1 ); + } + self fakedamagefrom( vdir ); + if ( isDefined( level.custom_player_fake_death ) ) + { + self thread [[ level.custom_player_fake_death ]]( vdir, smeansofdeath ); + } + else + { + self thread player_fake_death(); + } + } + if ( count == players.size && isDefined( level.no_end_game_check ) && !level.no_end_game_check ) + { + if ( players.size == 1 && flag( "solo_game" ) ) + { + if ( self.lives == 0 || !self hasperk( "specialty_quickrevive" ) ) + { + self.lives = 0; + level notify( "pre_end_game" ); + wait_network_frame(); + if ( flag( "dog_round" ) ) + { + increment_dog_round_stat( "lost" ); + } + level notify( "end_game" ); + } + else + { + return finaldamage; + } + } + else + { + level notify( "pre_end_game" ); + wait_network_frame(); + if ( flag( "dog_round" ) ) + { + increment_dog_round_stat( "lost" ); + } + level notify( "end_game" ); + } + return 0; + } + else + { + surface = "flesh"; + return finaldamage; + } +} + +clear_path_timers() +{ + zombies = getaiarray( level.zombie_team ); + _a5596 = zombies; + _k5596 = getFirstArrayKey( _a5596 ); + while ( isDefined( _k5596 ) ) + { + zombie = _a5596[ _k5596 ]; + if ( isDefined( zombie.favoriteenemy ) && zombie.favoriteenemy == self ) + { + zombie.zombie_path_timer = 0; + } + _k5596 = getNextArrayKey( _a5596, _k5596 ); + } +} + +check_player_damage_callbacks( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if ( !isDefined( level.player_damage_callbacks ) ) + { + return idamage; + } + i = 0; + while ( i < level.player_damage_callbacks.size ) + { + newdamage = self [[ level.player_damage_callbacks[ i ] ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + if ( newdamage != -1 ) + { + return newdamage; + } + i++; + } + return idamage; +} + +register_player_damage_callback( func ) +{ + if ( !isDefined( level.player_damage_callbacks ) ) + { + level.player_damage_callbacks = []; + } + level.player_damage_callbacks[ level.player_damage_callbacks.size ] = func; +} + +wait_and_revive() +{ + flag_set( "wait_and_revive" ); + if ( isDefined( self.waiting_to_revive ) && self.waiting_to_revive == 1 ) + { + return; + } + if ( isDefined( self.pers_upgrades_awarded[ "perk_lose" ] ) && self.pers_upgrades_awarded[ "perk_lose" ] ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_perk_lose_save(); + } + self.waiting_to_revive = 1; + if ( isDefined( level.exit_level_func ) ) + { + self thread [[ level.exit_level_func ]](); + } + else + { + if ( get_players().size == 1 ) + { + self thread default_exit_level(); + } + } + solo_revive_time = 10; + self.revive_hud settext( &"ZOMBIE_REVIVING_SOLO", self ); + self maps/mp/zombies/_zm_laststand::revive_hud_show_n_fade( solo_revive_time ); + flag_wait_or_timeout( "instant_revive", solo_revive_time ); + if ( flag( "instant_revive" ) ) + { + self maps/mp/zombies/_zm_laststand::revive_hud_show_n_fade( 1 ); + } + flag_clear( "wait_and_revive" ); + self maps/mp/zombies/_zm_laststand::auto_revive( self ); + self.lives--; + + self.waiting_to_revive = 0; + if ( isDefined( self.pers_upgrades_awarded[ "perk_lose" ] ) && self.pers_upgrades_awarded[ "perk_lose" ] ) + { + self thread maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_perk_lose_restore(); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if ( !isDefined( self ) || !isDefined( attacker ) ) + { + return damage; + } + if ( weapon == "tazer_knuckles_zm" || weapon == "jetgun_zm" ) + { + self.knuckles_extinguish_flames = 1; + } + else + { + if ( weapon != "none" ) + { + self.knuckles_extinguish_flames = undefined; + } + } + if ( isDefined( attacker.animname ) && attacker.animname == "quad_zombie" ) + { + if ( isDefined( self.animname ) && self.animname == "quad_zombie" ) + { + return 0; + } + } + if ( !isplayer( attacker ) && isDefined( self.non_attacker_func ) ) + { + if ( isDefined( self.non_attack_func_takes_attacker ) && self.non_attack_func_takes_attacker ) + { + return self [[ self.non_attacker_func ]]( damage, weapon, attacker ); + } + else + { + return self [[ self.non_attacker_func ]]( damage, weapon ); + } + } + if ( !isplayer( attacker ) && !isplayer( self ) ) + { + return damage; + } + if ( !isDefined( damage ) || !isDefined( meansofdeath ) ) + { + return damage; + } + if ( meansofdeath == "" ) + { + return damage; + } + old_damage = damage; + final_damage = damage; + if ( isDefined( self.actor_damage_func ) ) + { + final_damage = [[ self.actor_damage_func ]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + /* +/# + if ( getDvarInt( #"5ABA6445" ) ) + { + println( "Perk/> Damage Factor: " + ( final_damage / old_damage ) + " - Pre Damage: " + old_damage + " - Post Damage: " + final_damage ); +#/ + } + */ + if ( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) ) + { + attacker = attacker.owner; + } + if ( isDefined( self.in_water ) && self.in_water ) + { + if ( int( final_damage ) >= self.health ) + { + self.water_damage = 1; + } + } + attacker thread maps/mp/gametypes_zm/_weapons::checkhit( weapon ); + if ( attacker maps/mp/zombies/_zm_pers_upgrades_functions::pers_mulit_kill_headshot_active() && is_headshot( weapon, shitloc, meansofdeath ) ) + { + final_damage *= 2; + } + if ( isDefined( level.headshots_only ) && level.headshots_only && isDefined( attacker ) && isplayer( attacker ) ) + { + if ( meansofdeath == "MOD_MELEE" || shitloc == "head" && shitloc == "helmet" ) + { + return int( final_damage ); + } + if ( is_explosive_damage( meansofdeath ) ) + { + return int( final_damage ); + } + else + { + if ( !is_headshot( weapon, shitloc, meansofdeath ) ) + { + return 0; + } + } + } + return int( final_damage ); +} + +actor_damage_override_wrapper( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + damage_override = self actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + if ( damage_override < self.health || isDefined( self.dont_die_on_me ) && !self.dont_die_on_me ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_killed_override( einflictor, attacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime ) +{ + if ( game[ "state" ] == "postgame" ) + { + return; + } + if ( isai( attacker ) && isDefined( attacker.script_owner ) ) + { + if ( attacker.script_owner.team != self.aiteam ) + { + attacker = attacker.script_owner; + } + } + if ( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) ) + { + attacker = attacker.owner; + } + if ( isDefined( attacker ) && isplayer( attacker ) ) + { + multiplier = 1; + if ( is_headshot( sweapon, shitloc, smeansofdeath ) ) + { + multiplier = 1.5; + } + type = undefined; + if ( isDefined( self.animname ) ) + { + switch( self.animname ) + { + case "quad_zombie": + type = "quadkill"; + break; + case "ape_zombie": + type = "apekill"; + break; + case "zombie": + type = "zombiekill"; + break; + case "zombie_dog": + type = "dogkill"; + break; + } + } + } + if ( isDefined( self.is_ziplining ) && self.is_ziplining ) + { + self.deathanim = undefined; + } + if ( isDefined( self.actor_killed_override ) ) + { + self [[ self.actor_killed_override ]]( einflictor, attacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime ); + } +} + +round_end_monitor() +{ + while ( 1 ) + { + level waittill( "end_of_round" ); + maps/mp/_demo::bookmark( "zm_round_end", getTime(), undefined, undefined, 1 ); + bbpostdemostreamstatsforround( level.round_number ); + wait 0.05; + } +} + +end_game() +{ + level waittill( "end_game" ); + check_end_game_intermission_delay(); + /* +/# + println( "end_game TRIGGERED " ); +#/ + */ + clientnotify( "zesn" ); + if ( isDefined( level.sndgameovermusicoverride ) ) + { + level thread maps/mp/zombies/_zm_audio::change_zombie_music( level.sndgameovermusicoverride ); + } + else + { + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "game_over" ); + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + setclientsysstate( "lsm", "0", players[ i ] ); + i++; + } + i = 0; + while ( i < players.size ) + { + if ( players[ i ] player_is_in_laststand() ) + { + players[ i ] recordplayerdeathzombies(); + players[ i ] maps/mp/zombies/_zm_stats::increment_player_stat( "deaths" ); + players[ i ] maps/mp/zombies/_zm_stats::increment_client_stat( "deaths" ); + players[ i ] maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_jugg_player_death_stat(); + } + if ( isDefined( players[ i ].revivetexthud ) ) + { + players[ i ].revivetexthud destroy(); + } + i++; + } + stopallrumbles(); + level.intermission = 1; + level.zombie_vars[ "zombie_powerup_insta_kill_time" ] = 0; + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = 0; + level.zombie_vars[ "zombie_powerup_point_doubler_time" ] = 0; + wait 0.1; + game_over = []; + survived = []; + players = get_players(); + setmatchflag( "disableIngameMenu", 1 ); + _a5934 = players; + _k5934 = getFirstArrayKey( _a5934 ); + while ( isDefined( _k5934 ) ) + { + player = _a5934[ _k5934 ]; + player closemenu(); + player closeingamemenu(); + _k5934 = getNextArrayKey( _a5934, _k5934 ); + } + while ( !isDefined( level._supress_survived_screen ) ) + { + i = 0; + while ( i < players.size ) + { + if ( isDefined( level.custom_game_over_hud_elem ) ) + { + game_over[ i ] = [[ level.custom_game_over_hud_elem ]]( players[ i ] ); + } + else + { + game_over[ i ] = newclienthudelem( players[ i ] ); + game_over[ i ].alignx = "center"; + game_over[ i ].aligny = "middle"; + game_over[ i ].horzalign = "center"; + game_over[ i ].vertalign = "middle"; + game_over[ i ].y -= 130; + game_over[ i ].foreground = 1; + game_over[ i ].fontscale = 3; + game_over[ i ].alpha = 0; + game_over[ i ].color = ( 0, 0, -1 ); + game_over[ i ].hidewheninmenu = 1; + game_over[ i ] settext( &"ZOMBIE_GAME_OVER" ); + game_over[ i ] fadeovertime( 1 ); + game_over[ i ].alpha = 1; + if ( players[ i ] issplitscreen() ) + { + game_over[ i ].fontscale = 2; + game_over[ i ].y += 40; + } + } + survived[ i ] = newclienthudelem( players[ i ] ); + survived[ i ].alignx = "center"; + survived[ i ].aligny = "middle"; + survived[ i ].horzalign = "center"; + survived[ i ].vertalign = "middle"; + survived[ i ].y -= 100; + survived[ i ].foreground = 1; + survived[ i ].fontscale = 2; + survived[ i ].alpha = 0; + survived[ i ].color = ( 0, 0, -1 ); + survived[ i ].hidewheninmenu = 1; + if ( players[ i ] issplitscreen() ) + { + survived[ i ].fontscale = 1.5; + survived[ i ].y += 40; + } + if ( level.round_number < 2 ) + { + if ( level.script == "zombie_moon" ) + { + if ( !isDefined( level.left_nomans_land ) ) + { + nomanslandtime = level.nml_best_time; + player_survival_time = int( nomanslandtime / 1000 ); + player_survival_time_in_mins = maps/mp/zombies/_zm::to_mins( player_survival_time ); + survived[ i ] settext( &"ZOMBIE_SURVIVED_NOMANS", player_survival_time_in_mins ); + } + else + { + if ( level.left_nomans_land == 2 ) + { + survived[ i ] settext( &"ZOMBIE_SURVIVED_ROUND" ); + } + } + } + else + { + survived[ i ] settext( &"ZOMBIE_SURVIVED_ROUND" ); + } + } + else + { + survived[ i ] settext( &"ZOMBIE_SURVIVED_ROUNDS", level.round_number ); + } + survived[ i ] fadeovertime( 1 ); + survived[ i ].alpha = 1; + i++; + } + } + if ( isDefined( level.custom_end_screen ) ) + { + level [[ level.custom_end_screen ]](); + } + i = 0; + while ( i < players.size ) + { + players[ i ] setclientammocounterhide( 1 ); + players[ i ] setclientminiscoreboardhide( 1 ); + i++; + } + uploadstats(); + maps/mp/zombies/_zm_stats::update_players_stats_at_match_end( players ); + maps/mp/zombies/_zm_stats::update_global_counters_on_match_end(); + wait 1; + wait 3.95; + players = get_players(); + _a6045 = players; + _k6045 = getFirstArrayKey( _a6045 ); + while ( isDefined( _k6045 ) ) + { + player = _a6045[ _k6045 ]; + if ( isDefined( player.sessionstate ) && player.sessionstate == "spectator" ) + { + player.sessionstate = "playing"; + } + _k6045 = getNextArrayKey( _a6045, _k6045 ); + } + wait 0.05; + players = get_players(); + if ( !isDefined( level._supress_survived_screen ) ) + { + i = 0; + while ( i < players.size ) + { + survived[ i ] destroy(); + game_over[ i ] destroy(); + i++; + } + } + else i = 0; + while ( i < players.size ) + { + if ( isDefined( players[ i ].survived_hud ) ) + { + players[ i ].survived_hud destroy(); + } + if ( isDefined( players[ i ].game_over_hud ) ) + { + players[ i ].game_over_hud destroy(); + } + i++; + } + intermission(); + wait level.zombie_vars[ "zombie_intermission_time" ]; + level notify( "stop_intermission" ); + array_thread( get_players(), ::player_exit_level ); + bbprint( "zombie_epilogs", "rounds %d", level.round_number ); + wait 1.5; + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] cameraactivate( 0 ); + i++; + } + exitlevel( 0 ); + wait 666; +} + +disable_end_game_intermission( delay ) +{ + level.disable_intermission = 1; + wait delay; + level.disable_intermission = undefined; +} + +check_end_game_intermission_delay() +{ + while ( isDefined( level.disable_intermission ) ) + { + while ( 1 ) + { + if ( !isDefined( level.disable_intermission ) ) + { + return; + } + else + { + wait 0.01; + } + } + } +} + +upload_leaderboards() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] uploadleaderboards(); + i++; + } +} + +initializestattracking() +{ + level.global_zombies_killed = 0; + level.zombies_timeout_spawn = 0; + level.zombies_timeout_playspace = 0; + level.zombies_timeout_undamaged = 0; + level.zombie_player_killed_count = 0; + level.zombie_trap_killed_count = 0; + level.zombie_pathing_failed = 0; + level.zombie_breadcrumb_failed = 0; +} + +uploadglobalstatcounters() +{ + incrementcounter( "global_zombies_killed", level.global_zombies_killed ); + incrementcounter( "global_zombies_killed_by_players", level.zombie_player_killed_count ); + incrementcounter( "global_zombies_killed_by_traps", level.zombie_trap_killed_count ); +} + +player_fake_death() +{ + level notify( "fake_death" ); + self notify( "fake_death" ); + self takeallweapons(); + self allowstand( 0 ); + self allowcrouch( 0 ); + self allowprone( 1 ); + self.ignoreme = 1; + self enableinvulnerability(); + wait 1; + self freezecontrols( 1 ); +} + +player_exit_level() +{ + self allowstand( 1 ); + self allowcrouch( 0 ); + self allowprone( 0 ); + if ( isDefined( self.game_over_bg ) ) + { + self.game_over_bg.foreground = 1; + self.game_over_bg.sort = 100; + self.game_over_bg fadeovertime( 1 ); + self.game_over_bg.alpha = 1; + } +} + +player_killed_override( einflictor, attacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime, deathanimduration ) +{ + level waittill( "forever" ); +} + +player_zombie_breadcrumb() +{ + self notify( "stop_player_zombie_breadcrumb" ); + self endon( "stop_player_zombie_breadcrumb" ); + self endon( "disconnect" ); + self endon( "spawned_spectator" ); + level endon( "intermission" ); + self.zombie_breadcrumbs = []; + self.zombie_breadcrumb_distance = 576; + self.zombie_breadcrumb_area_num = 3; + self.zombie_breadcrumb_area_distance = 16; + self store_crumb( self.origin ); + last_crumb = self.origin; + self thread debug_breadcrumbs(); + while ( 1 ) + { + wait_time = 0.1; + while ( self.ignoreme ) + { + wait wait_time; + } + store_crumb = 1; + airborne = 0; + crumb = self.origin; + if ( !self isonground() && self isinvehicle() ) + { + trace = bullettrace( self.origin + vectorScale( ( 0, 0, -1 ), 10 ), self.origin, 0, undefined ); + crumb = trace[ "position" ]; + } + if ( !airborne && distancesquared( crumb, last_crumb ) < self.zombie_breadcrumb_distance ) + { + store_crumb = 0; + } + if ( airborne && self isonground() ) + { + store_crumb = 1; + airborne = 0; + } + if ( isDefined( level.custom_breadcrumb_store_func ) ) + { + store_crumb = self [[ level.custom_breadcrumb_store_func ]]( store_crumb ); + } + if ( isDefined( level.custom_airborne_func ) ) + { + airborne = self [[ level.custom_airborne_func ]]( airborne ); + } + if ( store_crumb ) + { + debug_print( "Player is storing breadcrumb " + crumb ); + if ( isDefined( self.node ) ) + { + debug_print( "has closest node " ); + } + last_crumb = crumb; + self store_crumb( crumb ); + } + wait wait_time; + } +} + +store_crumb( origin ) +{ + offsets = []; + height_offset = 32; + index = 0; + j = 1; + while ( j <= self.zombie_breadcrumb_area_num ) + { + offset = j * self.zombie_breadcrumb_area_distance; + offsets[ 0 ] = ( origin[ 0 ] - offset, origin[ 1 ], origin[ 2 ] ); + offsets[ 1 ] = ( origin[ 0 ] + offset, origin[ 1 ], origin[ 2 ] ); + offsets[ 2 ] = ( origin[ 0 ], origin[ 1 ] - offset, origin[ 2 ] ); + offsets[ 3 ] = ( origin[ 0 ], origin[ 1 ] + offset, origin[ 2 ] ); + offsets[ 4 ] = ( origin[ 0 ] - offset, origin[ 1 ], origin[ 2 ] + height_offset ); + offsets[ 5 ] = ( origin[ 0 ] + offset, origin[ 1 ], origin[ 2 ] + height_offset ); + offsets[ 6 ] = ( origin[ 0 ], origin[ 1 ] - offset, origin[ 2 ] + height_offset ); + offsets[ 7 ] = ( origin[ 0 ], origin[ 1 ] + offset, origin[ 2 ] + height_offset ); + i = 0; + while ( i < offsets.size ) + { + self.zombie_breadcrumbs[ index ] = offsets[ i ]; + index++; + i++; + } + j++; + } +} + +to_mins( seconds ) +{ + hours = 0; + minutes = 0; + if ( seconds > 59 ) + { + minutes = int( seconds / 60 ); + seconds = int( seconds * 1000 ) % 60000; + seconds *= 0.001; + if ( minutes > 59 ) + { + hours = int( minutes / 60 ); + minutes = int( minutes * 1000 ) % 60000; + minutes *= 0.001; + } + } + if ( hours < 10 ) + { + hours = "0" + hours; + } + if ( minutes < 10 ) + { + minutes = "0" + minutes; + } + seconds = int( seconds ); + if ( seconds < 10 ) + { + seconds = "0" + seconds; + } + combined = "" + hours + ":" + minutes + ":" + seconds; + return combined; +} + +intermission() +{ + level.intermission = 1; + level notify( "intermission" ); + players = get_players(); + i = 0; + while ( i < players.size ) + { + setclientsysstate( "levelNotify", "zi", players[ i ] ); + players[ i ] setclientthirdperson( 0 ); + players[ i ] resetfov(); + players[ i ].health = 100; + players[ i ] thread [[ level.custom_intermission ]](); + players[ i ] stopsounds(); + i++; + } + wait 0.25; + players = get_players(); + i = 0; + while ( i < players.size ) + { + setclientsysstate( "lsm", "0", players[ i ] ); + i++; + } + level thread zombie_game_over_death(); +} + +zombie_game_over_death() +{ + zombies = getaiarray( level.zombie_team ); + i = 0; + while ( i < zombies.size ) + { + if ( !isalive( zombies[ i ] ) ) + { + i++; + continue; + } + else + { + zombies[ i ] setgoalpos( zombies[ i ].origin ); + } + i++; + } + i = 0; + while ( i < zombies.size ) + { + if ( !isalive( zombies[ i ] ) ) + { + i++; + continue; + } + else if ( isDefined( zombies[ i ].ignore_game_over_death ) && zombies[ i ].ignore_game_over_death ) + { + i++; + continue; + } + else + { + wait ( 0.5 + randomfloat( 2 ) ); + if ( isDefined( zombies[ i ] ) ) + { + zombies[ i ] maps/mp/zombies/_zm_spawner::zombie_head_gib(); + zombies[ i ] dodamage( zombies[ i ].health + 666, zombies[ i ].origin ); + } + } + i++; + } +} + +player_intermission() +{ + self closemenu(); + self closeingamemenu(); + level endon( "stop_intermission" ); + self endon( "disconnect" ); + self endon( "death" ); + self notify( "_zombie_game_over" ); + self.score = self.score_total; + self.sessionstate = "intermission"; + self.spectatorclient = -1; + self.killcamentity = -1; + self.archivetime = 0; + self.psoffsettime = 0; + self.friendlydamage = undefined; + points = getstructarray( "intermission", "targetname" ); + if ( !isDefined( points ) || points.size == 0 ) + { + points = getentarray( "info_intermission", "classname" ); + if ( points.size < 1 ) + { + /* +/# + println( "NO info_intermission POINTS IN MAP" ); +#/ + */ + return; + } + } + self.game_over_bg = newclienthudelem( self ); + self.game_over_bg.horzalign = "fullscreen"; + self.game_over_bg.vertalign = "fullscreen"; + self.game_over_bg setshader( "black", 640, 480 ); + self.game_over_bg.alpha = 1; + org = undefined; + while ( 1 ) + { + points = array_randomize( points ); + i = 0; + while ( i < points.size ) + { + point = points[ i ]; + if ( !isDefined( org ) ) + { + self spawn( point.origin, point.angles ); + } + if ( isDefined( points[ i ].target ) ) + { + if ( !isDefined( org ) ) + { + org = spawn( "script_model", self.origin + vectorScale( ( 0, 0, -1 ), 60 ) ); + org setmodel( "tag_origin" ); + } + org.origin = points[ i ].origin; + org.angles = points[ i ].angles; + j = 0; + while ( j < get_players().size ) + { + player = get_players()[ j ]; + player camerasetposition( org ); + player camerasetlookat(); + player cameraactivate( 1 ); + j++; + } + speed = 20; + if ( isDefined( points[ i ].speed ) ) + { + speed = points[ i ].speed; + } + target_point = getstruct( points[ i ].target, "targetname" ); + dist = distance( points[ i ].origin, target_point.origin ); + time = dist / speed; + q_time = time * 0.25; + if ( q_time > 1 ) + { + q_time = 1; + } + self.game_over_bg fadeovertime( q_time ); + self.game_over_bg.alpha = 0; + org moveto( target_point.origin, time, q_time, q_time ); + org rotateto( target_point.angles, time, q_time, q_time ); + wait ( time - q_time ); + self.game_over_bg fadeovertime( q_time ); + self.game_over_bg.alpha = 1; + wait q_time; + i++; + continue; + } + else + { + self.game_over_bg fadeovertime( 1 ); + self.game_over_bg.alpha = 0; + wait 5; + self.game_over_bg thread fade_up_over_time( 1 ); + } + i++; + } + } +} + +fade_up_over_time( t ) +{ + self fadeovertime( t ); + self.alpha = 1; +} + +default_exit_level() +{ + zombies = getaiarray( level.zombie_team ); + i = 0; + while ( i < zombies.size ) + { + if ( isDefined( zombies[ i ].ignore_solo_last_stand ) && zombies[ i ].ignore_solo_last_stand ) + { + i++; + continue; + } + else + { + if ( isDefined( zombies[ i ].find_exit_point ) ) + { + zombies[ i ] thread [[ zombies[ i ].find_exit_point ]](); + i++; + continue; + } + else if ( zombies[ i ].ignoreme ) + { + zombies[ i ] thread default_delayed_exit(); + i++; + continue; + } + else + { + zombies[ i ] thread default_find_exit_point(); + } + } + i++; + } +} + +default_delayed_exit() +{ + self endon( "death" ); + while ( 1 ) + { + if ( !flag( "wait_and_revive" ) ) + { + return; + } + if ( !self.ignoreme ) + { + break; + } + else + { + wait 0.1; + } + } + self thread default_find_exit_point(); +} + +default_find_exit_point() +{ + self endon( "death" ); + player = get_players()[ 0 ]; + dist_zombie = 0; + dist_player = 0; + dest = 0; + away = vectornormalize( self.origin - player.origin ); + endpos = self.origin + vectorScale( away, 600 ); + locs = array_randomize( level.enemy_dog_locations ); + i = 0; + while ( i < locs.size ) + { + dist_zombie = distancesquared( locs[ i ].origin, endpos ); + dist_player = distancesquared( locs[ i ].origin, player.origin ); + if ( dist_zombie < dist_player ) + { + dest = i; + break; + } + else + { + i++; + } + } + self notify( "stop_find_flesh" ); + self notify( "zombie_acquire_enemy" ); + if ( isDefined( locs[ dest ] ) ) + { + self setgoalpos( locs[ dest ].origin ); + } + while ( 1 ) + { + b_passed_override = 1; + if ( isDefined( level.default_find_exit_position_override ) ) + { + b_passed_override = [[ level.default_find_exit_position_override ]](); + } + if ( !flag( "wait_and_revive" ) && b_passed_override ) + { + break; + } + else + { + wait 0.1; + } + } + self thread maps/mp/zombies/_zm_ai_basic::find_flesh(); +} + +play_level_start_vox_delayed() +{ + wait 3; + players = get_players(); + num = randomintrange( 0, players.size ); + players[ num ] maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "intro" ); +} + +register_sidequest( id, sidequest_stat ) +{ + if ( !isDefined( level.zombie_sidequest_stat ) ) + { + level.zombie_sidequest_previously_completed = []; + level.zombie_sidequest_stat = []; + } + level.zombie_sidequest_stat[ id ] = sidequest_stat; + flag_wait( "start_zombie_round_logic" ); + level.zombie_sidequest_previously_completed[ id ] = 0; + if ( level.systemlink || getDvarInt( "splitscreen_playerCount" ) == get_players().size ) + { + return; + } + if ( isDefined( level.zm_disable_recording_stats ) && level.zm_disable_recording_stats ) + { + return; + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ] maps/mp/zombies/_zm_stats::get_global_stat( level.zombie_sidequest_stat[ id ] ) ) + { + level.zombie_sidequest_previously_completed[ id ] = 1; + return; + } + i++; + } +} + +is_sidequest_previously_completed( id ) +{ + if ( isDefined( level.zombie_sidequest_previously_completed[ id ] ) ) + { + return level.zombie_sidequest_previously_completed[ id ]; + } +} + +set_sidequest_completed( id ) +{ + level notify( "zombie_sidequest_completed" ); + level.zombie_sidequest_previously_completed[ id ] = 1; + if ( level.systemlink ) + { + return; + } + if ( getDvarInt( "splitscreen_playerCount" ) == get_players().size ) + { + return; + } + if ( isDefined( level.zm_disable_recording_stats ) && level.zm_disable_recording_stats ) + { + return; + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( isDefined( level.zombie_sidequest_stat[ id ] ) ) + { + players[ i ] maps/mp/zombies/_zm_stats::add_global_stat( level.zombie_sidequest_stat[ id ], 1 ); + } + i++; + } +} + +playswipesound( mod, attacker ) +{ + if ( isDefined( attacker.is_zombie ) && attacker.is_zombie ) + { + self playsoundtoplayer( "evt_player_swiped", self ); + return; + } +} + +precache_zombie_leaderboards() +{ + if ( sessionmodeissystemlink() ) + { + return; + } + globalleaderboards = "LB_ZM_GB_BULLETS_FIRED_AT "; + globalleaderboards += "LB_ZM_GB_BULLETS_HIT_AT "; + globalleaderboards += "LB_ZM_GB_DEATHS_AT "; + globalleaderboards += "LB_ZM_GB_DISTANCE_TRAVELED_AT "; + globalleaderboards += "LB_ZM_GB_DOORS_PURCHASED_AT "; + globalleaderboards += "LB_ZM_GB_DOWNS_AT "; + globalleaderboards += "LB_ZM_GB_GIBS_AT "; + globalleaderboards += "LB_ZM_GB_GRENADE_KILLS_AT "; + globalleaderboards += "LB_ZM_GB_HEADSHOTS_AT "; + globalleaderboards += "LB_ZM_GB_KILLS_AT "; + globalleaderboards += "LB_ZM_GB_PERKS_DRANK_AT "; + globalleaderboards += "LB_ZM_GB_REVIVES_AT "; + if ( sessionmodeisprivateonlinegame() ) + { + precacheleaderboards( globalleaderboards ); + return; + } + maplocationname = level.scr_zm_map_start_location; + if ( maplocationname != "default" && maplocationname == "" && isDefined( level.default_start_location ) ) + { + maplocationname = level.default_start_location; + } + if ( level.scr_zm_ui_gametype_group != "zclassic" && level.scr_zm_ui_gametype_group == "zsurvival" && level.scr_zm_ui_gametype != "zcleansed" ) + { + expectedplayernum = getnumexpectedplayers(); + if ( expectedplayernum == 1 ) + { + gamemodeleaderboard = "LB_ZM_GM_" + level.scr_zm_ui_gametype + "_" + maplocationname + "_" + expectedplayernum + "PLAYER"; + } + else + { + gamemodeleaderboard = "LB_ZM_GM_" + level.scr_zm_ui_gametype + "_" + maplocationname + "_" + expectedplayernum + "PLAYERS"; + } + } + else + { + gamemodeleaderboard = "LB_ZM_GM_" + level.scr_zm_ui_gametype + "_" + maplocationname; + } + precacheleaderboards( globalleaderboards + gamemodeleaderboard ); +} + +zm_on_player_connect() +{ + if ( level.passed_introscreen ) + { + self setclientuivisibilityflag( "hud_visible", 1 ); + } + thread refresh_player_navcard_hud(); + self thread watchdisconnect(); +} + +zm_on_player_disconnect() +{ + thread refresh_player_navcard_hud(); +} + +watchdisconnect() +{ + self notify( "watchDisconnect" ); + self endon( "watchDisconnect" ); + self waittill( "disconnect" ); + zm_on_player_disconnect(); +} + +increment_dog_round_stat( stat ) +{ + players = get_players(); + _a6853 = players; + _k6853 = getFirstArrayKey( _a6853 ); + while ( isDefined( _k6853 ) ) + { + player = _a6853[ _k6853 ]; + player maps/mp/zombies/_zm_stats::increment_client_stat( "zdog_rounds_" + stat ); + _k6853 = getNextArrayKey( _a6853, _k6853 ); + } +} + +setup_player_navcard_hud() +{ + flag_wait( "start_zombie_round_logic" ); + thread refresh_player_navcard_hud(); +} + +refresh_player_navcard_hud() +{ + if ( !isDefined( level.navcards ) ) + { + return; + } + players = get_players(); + _a6871 = players; + _k6871 = getFirstArrayKey( _a6871 ); + while ( isDefined( _k6871 ) ) + { + player = _a6871[ _k6871 ]; + navcard_bits = 0; + i = 0; + while ( i < level.navcards.size ) + { + hasit = player maps/mp/zombies/_zm_stats::get_global_stat( level.navcards[ i ] ); + if ( isDefined( player.navcard_grabbed ) && player.navcard_grabbed == level.navcards[ i ] ) + { + hasit = 1; + } + if ( hasit ) + { + //navcard_bits +=( 1 << i ); + } + i++; + } + wait_network_frame(); + player setclientfield( "navcard_held", 0 ); + if ( navcard_bits > 0 ) + { + wait_network_frame(); + player setclientfield( "navcard_held", navcard_bits ); + } + _k6871 = getNextArrayKey( _a6871, _k6871 ); + } +} + + +check_quickrevive_for_hotjoin( disconnecting_player ) +{ + solo_mode = 0; + subtract_num = 0; + should_update = 0; + if ( isDefined( disconnecting_player ) ) + { + subtract_num = 1; + } + players = get_players(); + if ( ( players.size - subtract_num ) == 1 || isDefined( level.force_solo_quick_revive ) && level.force_solo_quick_revive ) + { + solo_mode = 1; + if ( !flag( "solo_game" ) ) + { + should_update = 1; + } + flag_set( "solo_game" ); + } + else + { + if ( flag( "solo_game" ) ) + { + should_update = 1; + } + flag_clear( "solo_game" ); + } + level.using_solo_revive = solo_mode; + level.revive_machine_is_solo = solo_mode; + set_default_laststand_pistol( solo_mode ); + if ( should_update && isDefined( level.quick_revive_machine ) ) + { + update_quick_revive( solo_mode ); + } +} + +set_default_laststand_pistol( solo_mode ) +{ + if ( !solo_mode ) + { + level.laststandpistol = level.default_laststandpistol; + } + else + { + level.laststandpistol = level.default_solo_laststandpistol; + } +} + +update_quick_revive( solo_mode ) +{ + if ( !isDefined( solo_mode ) ) + { + solo_mode = 0; + } + clip = undefined; + if ( isDefined( level.quick_revive_machine_clip ) ) + { + clip = level.quick_revive_machine_clip; + } + level.quick_revive_machine thread maps/mp/zombies/_zm_perks::reenable_quickrevive( clip, solo_mode ); +} + +/* +player_too_many_players_check() +{ + max_players = 4; + if ( level.scr_zm_ui_gametype == "zgrief" || level.scr_zm_ui_gametype == "zmeat" ) + { + max_players = 8; + } + if ( get_players().size > max_players ) + { + maps/mp/zombies/_zm_game_module::freeze_players( 1 ); + level notify( "end_game" ); + } +} +*/ + + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc new file mode 100644 index 0000000..d59efd8 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc @@ -0,0 +1,742 @@ +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +init() +{ + level.dogs_enabled = 1; + level.dog_rounds_enabled = 0; + level.dog_round_count = 1; + level.dog_spawners = []; + level.enemy_dog_spawns = []; + level.enemy_dog_locations = []; + flag_init( "dog_clips" ); + precacherumble( "explosion_generic" ); + precacheshellshock( "dog_bite" ); + if ( getDvar( "zombie_dog_animset" ) == "" ) + { + setdvar( "zombie_dog_animset", "zombie" ); + } + if ( getDvar( "scr_dog_health_walk_multiplier" ) == "" ) + { + setdvar( "scr_dog_health_walk_multiplier", "4.0" ); + } + if ( getDvar( "scr_dog_run_distance" ) == "" ) + { + setdvar( "scr_dog_run_distance", "500" ); + } + level.melee_range_sav = getDvar( "ai_meleeRange" ); + level.melee_width_sav = getDvar( "ai_meleeWidth" ); + level.melee_height_sav = getDvar( "ai_meleeHeight" ); + setdvar( "dog_MeleeDamage", "100" ); + set_zombie_var( "dog_fire_trail_percent", 50 ); + level._effect[ "lightning_dog_spawn" ] = loadfx( "maps/zombie/fx_zombie_dog_lightning_buildup" ); + level._effect[ "dog_eye_glow" ] = loadfx( "maps/zombie/fx_zombie_dog_eyes" ); + level._effect[ "dog_gib" ] = loadfx( "maps/zombie/fx_zombie_dog_explosion" ); + level._effect[ "dog_trail_fire" ] = loadfx( "maps/zombie/fx_zombie_dog_fire_trail" ); + level._effect[ "dog_trail_ash" ] = loadfx( "maps/zombie/fx_zombie_dog_ash_trail" ); + dog_spawner_init(); + level thread dog_clip_monitor(); +} + +enable_dog_rounds() +{ + level.dog_rounds_enabled = 1; + if ( !isDefined( level.dog_round_track_override ) ) + { + level.dog_round_track_override = ::dog_round_tracker; + } + level thread [[ level.dog_round_track_override ]](); +} + +dog_spawner_init() +{ + level.dog_spawners = getentarray( "zombie_dog_spawner", "script_noteworthy" ); + later_dogs = getentarray( "later_round_dog_spawners", "script_noteworthy" ); + level.dog_spawners = arraycombine( level.dog_spawners, later_dogs, 1, 0 ); + if ( level.dog_spawners.size == 0 ) + { + return; + } + i = 0; + while ( i < level.dog_spawners.size ) + { + if ( maps/mp/zombies/_zm_spawner::is_spawner_targeted_by_blocker( level.dog_spawners[ i ] ) ) + { + level.dog_spawners[ i ].is_enabled = 0; + i++; + continue; + } + else + { + level.dog_spawners[ i ].is_enabled = 1; + level.dog_spawners[ i ].script_forcespawn = 1; + } + i++; + } + level.dog_health = 100; + array_thread( level.dog_spawners, ::add_spawn_function, ::dog_init ); + level.enemy_dog_spawns = getentarray( "zombie_spawner_dog_init", "targetname" ); +} + +dog_round_spawning() +{ + level endon( "intermission" ); + level.dog_targets = getplayers(); + i = 0; + while ( i < level.dog_targets.size ) + { + level.dog_targets[ i ].hunted_by = 0; + i++; + } + if ( level.intermission ) + { + return; + } + level.dog_intermission = 1; + level thread dog_round_aftermath(); + players = get_players(); + array_thread( players, ::play_dog_round ); + wait 1; + playsoundatposition( "vox_zmba_event_dogstart_0", ( 0, 0, 0 ) ); + wait 6; + if ( level.dog_round_count < 3 ) + { + max = players.size * 6; + } + else + { + max = players.size * 8; + } + level.zombie_total = max; + dog_health_increase(); + count = 0; + while ( count < max ) + { + num_player_valid = get_number_of_valid_players(); + while ( get_current_zombie_count() >= ( num_player_valid * 2 ) ) + { + wait 2; + num_player_valid = get_number_of_valid_players(); + } + players = get_players(); + favorite_enemy = get_favorite_enemy(); + if ( isDefined( level.dog_spawn_func ) ) + { + spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[ 0 ] ); + if ( isDefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_loc thread dog_spawn_fx( ai, spawn_loc ); + level.zombie_total--; + + count++; + } + } + else + { + spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[ 0 ] ); + if ( isDefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread dog_spawn_fx( ai, spawn_point ); + level.zombie_total--; + + count++; + flag_set( "dog_clips" ); + } + } + waiting_for_next_dog_spawn( count, max ); + } +} + +waiting_for_next_dog_spawn( count, max ) +{ + default_wait = 1.5; + if ( level.dog_round_count == 1 ) + { + default_wait = 3; + } + else if ( level.dog_round_count == 2 ) + { + default_wait = 2.5; + } + else if ( level.dog_round_count == 3 ) + { + default_wait = 2; + } + else + { + default_wait = 1.5; + } + default_wait -= count / max; + wait default_wait; +} + +dog_round_aftermath() +{ + level waittill( "last_dog_down" ); + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "dog_end" ); + power_up_origin = level.last_dog_origin; + if ( isDefined( power_up_origin ) ) + { + level thread maps/mp/zombies/_zm_powerups::specific_powerup_drop( "full_ammo", power_up_origin ); + } + wait 2; + clientnotify( "dog_stop" ); + wait 6; + level.dog_intermission = 0; +} + +dog_spawn_fx( ai, ent ) +{ + ai endon( "death" ); + ai setfreecameralockonallowed( 0 ); + playfx( level._effect[ "lightning_dog_spawn" ], ent.origin ); + playsoundatposition( "zmb_hellhound_prespawn", ent.origin ); + wait 1.5; + playsoundatposition( "zmb_hellhound_bolt", ent.origin ); + earthquake( 0.5, 0.75, ent.origin, 1000 ); + playrumbleonposition( "explosion_generic", ent.origin ); + playsoundatposition( "zmb_hellhound_spawn", ent.origin ); + angle = vectorToAngles( ai.favoriteenemy.origin - ent.origin ); + angles = ( ai.angles[ 0 ], angle[ 1 ], ai.angles[ 2 ] ); + ai forceteleport( ent.origin, angles ); + ai zombie_setup_attack_properties_dog(); + ai stop_magic_bullet_shield(); + wait 0.1; + ai show(); + ai setfreecameralockonallowed( 1 ); + ai.ignoreme = 0; + ai notify( "visible" ); +} + +dog_spawn_sumpf_logic( dog_array, favorite_enemy ) +{ + dog_array = array_randomize( dog_array ); + i = 0; + while ( i < dog_array.size ) + { + if ( isDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_array[ i ] ) + { + i++; + continue; + } + else + { + if ( distancesquared( dog_array[ i ].origin, favorite_enemy.origin ) > 160000 && distancesquared( dog_array[ i ].origin, favorite_enemy.origin ) < 640000 ) + { + if ( distancesquared( ( 0, 0, dog_array[ i ].origin[ 2 ] ), ( 0, 0, favorite_enemy.origin[ 2 ] ) ) > 10000 ) + { + i++; + continue; + } + else level.old_dog_spawn = dog_array[ i ]; + return dog_array[ i ]; + } + } + i++; + } + return dog_array[ 0 ]; +} + +dog_spawn_factory_logic( dog_array, favorite_enemy ) +{ + dog_locs = array_randomize( level.enemy_dog_locations ); + i = 0; + while ( i < dog_locs.size ) + { + if ( isDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[ i ] ) + { + i++; + continue; + } + else + { + dist_squared = distancesquared( dog_locs[ i ].origin, favorite_enemy.origin ); + if ( dist_squared > 160000 && dist_squared < 1000000 ) + { + level.old_dog_spawn = dog_locs[ i ]; + return dog_locs[ i ]; + } + } + i++; + } + return dog_locs[ 0 ]; +} + +get_favorite_enemy() +{ + dog_targets = getplayers(); + least_hunted = dog_targets[ 0 ]; + i = 0; + while ( i < dog_targets.size ) + { + if ( !isDefined( dog_targets[ i ].hunted_by ) ) + { + dog_targets[ i ].hunted_by = 0; + } + if ( !is_player_valid( dog_targets[ i ] ) ) + { + i++; + continue; + } + else + { + if ( !is_player_valid( least_hunted ) ) + { + least_hunted = dog_targets[ i ]; + } + if ( dog_targets[ i ].hunted_by < least_hunted.hunted_by ) + { + least_hunted = dog_targets[ i ]; + } + } + i++; + } + least_hunted.hunted_by += 1; + return least_hunted; +} + +dog_health_increase() +{ + players = getplayers(); + if ( level.dog_round_count == 1 ) + { + level.dog_health = 400; + } + else if ( level.dog_round_count == 2 ) + { + level.dog_health = 900; + } + else if ( level.dog_round_count == 3 ) + { + level.dog_health = 1300; + } + else + { + if ( level.dog_round_count == 4 ) + { + level.dog_health = 1600; + } + } + if ( level.dog_health > 1600 ) + { + level.dog_health = 1600; + } +} + +dog_round_tracker() +{ + level.dog_round_count = 1; + level.next_dog_round = level.round_number + randomintrange( 4, 7 ); + old_spawn_func = level.round_spawn_func; + old_wait_func = level.round_wait_func; + while ( 1 ) + { + level waittill( "between_round_over" ); + if ( level.round_number == level.next_dog_round ) + { + level.music_round_override = 1; + old_spawn_func = level.round_spawn_func; + old_wait_func = level.round_wait_func; + dog_round_start(); + level.round_spawn_func = ::dog_round_spawning; + level.next_dog_round = level.round_number + randomintrange( 4, 6 ); + continue; + } + else + { + if ( flag( "dog_round" ) ) + { + dog_round_stop(); + level.round_spawn_func = old_spawn_func; + level.round_wait_func = old_wait_func; + level.music_round_override = 0; + level.dog_round_count += 1; + } + } + } +} + +dog_round_start() +{ + flag_set( "dog_round" ); + flag_set( "dog_clips" ); + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "dog_start" ); + if ( !isDefined( level.doground_nomusic ) ) + { + level.doground_nomusic = 0; + } + level.doground_nomusic = 1; + level notify( "dog_round_starting" ); + clientnotify( "dog_start" ); + if ( isDefined( level.dog_melee_range ) ) + { + setdvar( "ai_meleeRange", level.dog_melee_range ); + } + else + { + setdvar( "ai_meleeRange", 100 ); + } +} + +dog_round_stop() +{ + flag_clear( "dog_round" ); + flag_clear( "dog_clips" ); + if ( !isDefined( level.doground_nomusic ) ) + { + level.doground_nomusic = 0; + } + level.doground_nomusic = 0; + level notify( "dog_round_ending" ); + clientnotify( "dog_stop" ); + setdvar( "ai_meleeRange", level.melee_range_sav ); + setdvar( "ai_meleeWidth", level.melee_width_sav ); + setdvar( "ai_meleeHeight", level.melee_height_sav ); +} + +play_dog_round() +{ + self playlocalsound( "zmb_dog_round_start" ); + variation_count = 5; + wait 4.5; + players = getplayers(); + num = randomintrange( 0, players.size ); + players[ num ] maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "dog_spawn" ); +} + +dog_init() +{ + self.targetname = "zombie_dog"; + self.script_noteworthy = undefined; + self.animname = "zombie_dog"; + self.ignoreall = 1; + self.ignoreme = 1; + self.allowdeath = 1; + self.allowpain = 0; + self.force_gib = 1; + self.is_zombie = 1; + self.has_legs = 1; + self.gibbed = 0; + self.head_gibbed = 0; + self.default_goalheight = 40; + self.ignore_inert = 1; + self.grenadeawareness = 0; + self.badplaceawareness = 0; + self.ignoresuppression = 1; + self.suppressionthreshold = 1; + self.nododgemove = 1; + self.dontshootwhilemoving = 1; + self.pathenemylookahead = 0; + self.badplaceawareness = 0; + self.chatinitialized = 0; + self.team = level.zombie_team; + health_multiplier = 1; + if ( getDvar( "scr_dog_health_walk_multiplier" ) != "" ) + { + health_multiplier = getDvarFloat( "scr_dog_health_walk_multiplier" ); + } + self.maxhealth = int( level.dog_health * health_multiplier ); + self.health = int( level.dog_health * health_multiplier ); + self.freezegun_damage = 0; + self.zombie_move_speed = "sprint"; + self thread dog_run_think(); + self thread dog_stalk_audio(); + self thread maps/mp/zombies/_zm::round_spawn_failsafe(); + self ghost(); + self thread magic_bullet_shield(); + self dog_fx_eye_glow(); + self dog_fx_trail(); + self thread dog_death(); + level thread maps/mp/zombies/_zm_spawner::zombie_death_event( self ); + self thread maps/mp/zombies/_zm_spawner::enemy_death_detection(); + self.a.disablepain = 1; + self disable_react(); + self clearenemy(); + self cleargoalvolume(); + self.flame_damage_time = 0; + self.meleedamage = 40; + self.thundergun_knockdown_func = ::dog_thundergun_knockdown; + self maps/mp/zombies/_zm_spawner::zombie_history( "zombie_dog_spawn_init -> Spawned = " + self.origin ); + if ( isDefined( level.achievement_monitor_func ) ) + { + self [[ level.achievement_monitor_func ]](); + } +} + +dog_fx_eye_glow() +{ + self.fx_dog_eye = spawn( "script_model", self gettagorigin( "J_EyeBall_LE" ) ); + self.fx_dog_eye.angles = self gettagangles( "J_EyeBall_LE" ); + self.fx_dog_eye setmodel( "tag_origin" ); + self.fx_dog_eye linkto( self, "J_EyeBall_LE" ); +} + +dog_fx_trail() +{ + if ( !is_mature() || randomint( 100 ) > level.zombie_vars[ "dog_fire_trail_percent" ] ) + { + self.fx_dog_trail_type = level._effect[ "dog_trail_ash" ]; + self.fx_dog_trail_sound = "zmb_hellhound_loop_breath"; + } + else + { + self.a.nodeath = 1; + self.fx_dog_trail_type = level._effect[ "dog_trail_fire" ]; + self.fx_dog_trail_sound = "zmb_hellhound_loop_fire"; + } + self.fx_dog_trail = spawn( "script_model", self gettagorigin( "tag_origin" ) ); + self.fx_dog_trail.angles = self gettagangles( "tag_origin" ); + self.fx_dog_trail setmodel( "tag_origin" ); + self.fx_dog_trail linkto( self, "tag_origin" ); +} + +dog_death() +{ + self waittill( "death" ); + if ( get_current_zombie_count() == 0 && level.zombie_total == 0 ) + { + level.last_dog_origin = self.origin; + level notify( "last_dog_down" ); + } + if ( isplayer( self.attacker ) ) + { + event = "death"; + if ( issubstr( self.damageweapon, "knife_ballistic_" ) ) + { + event = "ballistic_knife_death"; + } + self.attacker maps/mp/zombies/_zm_score::player_add_points( event, self.damagemod, self.damagelocation, 1 ); + if ( randomintrange( 0, 100 ) >= 80 ) + { + self.attacker maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "hellhound" ); + } + self.attacker maps/mp/zombies/_zm_stats::increment_client_stat( "zdogs_killed" ); + self.attacker maps/mp/zombies/_zm_stats::increment_player_stat( "zdogs_killed" ); + } + if ( isDefined( self.attacker ) && isai( self.attacker ) ) + { + self.attacker notify( "killed" ); + } + self stoploopsound(); + self.fx_dog_trail delete(); + if ( isDefined( self.a.nodeath ) ) + { + level thread dog_explode_fx( self.origin ); + self delete(); + } + else + { + self playsound( "zmb_hellhound_vocals_death" ); + } +} + +dog_explode_fx( origin ) +{ + playfx( level._effect[ "dog_gib" ], origin ); + playsoundatposition( "zmb_hellhound_explode", origin ); +} + +zombie_setup_attack_properties_dog() +{ + self maps/mp/zombies/_zm_spawner::zombie_history( "zombie_setup_attack_properties()" ); + self thread dog_behind_audio(); + self.ignoreall = 0; + self.pathenemyfightdist = 64; + self.meleeattackdist = 64; + self.disablearrivals = 1; + self.disableexits = 1; +} + +stop_dog_sound_on_death() +{ + self waittill( "death" ); + self stopsounds(); +} + +dog_behind_audio() +{ + self thread stop_dog_sound_on_death(); + self endon( "death" ); + self waittill_any( "dog_running", "dog_combat" ); + self playsound( "zmb_hellhound_vocals_close" ); + wait 3; + while ( 1 ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + vectorAngle = vectorToAngles( self.origin - players[ i ].origin ); + dogangle = AbsAngleClamp180( vectorAngle[ 1 ] - players[ i ].angles[ 1 ] ); + if ( isalive( players[ i ] ) && !isDefined( players[ i ].revivetrigger ) ) + { + if ( Abs( dogangle ) > 90 && distance2d( self.origin, players[ i ].origin ) > 100 ) + { + self playsound( "zmb_hellhound_vocals_close" ); + wait 3; + } + } + i++; + } + wait 0.75; + } +} + +dog_clip_monitor() +{ + clips_on = 0; + level.dog_clips = getentarray( "dog_clips", "targetname" ); + while ( 1 ) + { + i = 0; + while ( i < level.dog_clips.size ) + { + level.dog_clips[ i ] trigger_off(); + level.dog_clips[ i ] connectpaths(); + i++; + } + flag_wait( "dog_clips" ); + if ( isDefined( level.no_dog_clip ) && level.no_dog_clip == 1 ) + { + return; + } + i = 0; + while ( i < level.dog_clips.size ) + { + level.dog_clips[ i ] trigger_on(); + level.dog_clips[ i ] disconnectpaths(); + wait_network_frame(); + i++; + } + dog_is_alive = 1; + while ( dog_is_alive || flag( "dog_round" ) ) + { + dog_is_alive = 0; + dogs = getentarray( "zombie_dog", "targetname" ); + i = 0; + while ( i < dogs.size ) + { + if ( isalive( dogs[ i ] ) ) + { + dog_is_alive = 1; + } + i++; + } + wait 1; + } + flag_clear( "dog_clips" ); + wait 1; + } +} + +special_dog_spawn( spawners, num_to_spawn ) +{ + dogs = getaispeciesarray( "all", "zombie_dog" ); + if ( isDefined( dogs ) && dogs.size >= 9 ) + { + return 0; + } + if ( !isDefined( num_to_spawn ) ) + { + num_to_spawn = 1; + } + spawn_point = undefined; + count = 0; + while ( count < num_to_spawn ) + { + players = get_players(); + favorite_enemy = get_favorite_enemy(); + if ( isDefined( spawners ) ) + { + spawn_point = spawners[ randomint( spawners.size ) ]; + ai = spawn_zombie( spawn_point ); + if ( isDefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread dog_spawn_fx( ai ); + count++; + flag_set( "dog_clips" ); + } + } + else if ( isDefined( level.dog_spawn_func ) ) + { + spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[ 0 ] ); + if ( isDefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_loc thread dog_spawn_fx( ai, spawn_loc ); + count++; + flag_set( "dog_clips" ); + } + } + else + { + spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[ 0 ] ); + if ( isDefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread dog_spawn_fx( ai, spawn_point ); + count++; + flag_set( "dog_clips" ); + } + } + waiting_for_next_dog_spawn( count, num_to_spawn ); + } + return 1; +} + +dog_run_think() +{ + self endon( "death" ); + self waittill( "visible" ); + if ( self.health > level.dog_health ) + { + self.maxhealth = level.dog_health; + self.health = level.dog_health; + } + maps/mp/zombies/_zm_net::network_safe_play_fx_on_tag( "dog_fx", 2, self.fx_dog_trail_type, self.fx_dog_trail, "tag_origin" ); + self playloopsound( self.fx_dog_trail_sound ); + while ( 1 ) + { + if ( !is_player_valid( self.favoriteenemy ) ) + { + self.favoriteenemy = get_favorite_enemy(); + } + wait 0.2; + } +} + +dog_stalk_audio() +{ + self endon( "death" ); + self endon( "dog_running" ); + self endon( "dog_combat" ); + while ( 1 ) + { + self playsound( "zmb_hellhound_vocals_amb" ); + wait randomfloatrange( 3, 6 ); + } +} + +dog_thundergun_knockdown( player, gib ) +{ + self endon( "death" ); + damage = int( self.maxhealth * 0.5 ); + self dodamage( damage, player.origin, player ); +} + + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_bot.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_bot.gsc new file mode 100644 index 0000000..bcef80d --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_bot.gsc @@ -0,0 +1,10 @@ +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +init() +{ +/# + println( "ZM >> Zombiemode Server Scripts Init (_zm_bot.gsc)" ); +#/ +} diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_magicbox.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_magicbox.gsc new file mode 100644 index 0000000..2ab30df --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_magicbox.gsc @@ -0,0 +1,1656 @@ +#include maps/mp/zombies/_zm_stats; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +init() +{ + if ( !isDefined( level.chest_joker_model ) ) + { + level.chest_joker_model = "zombie_teddybear"; + precachemodel( level.chest_joker_model ); + } + if ( !isDefined( level.magic_box_zbarrier_state_func ) ) + { + level.magic_box_zbarrier_state_func = ::process_magic_box_zbarrier_state; + } + if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox ) + { + maps/mp/zombies/_zm_magicbox_lock::init(); + } + if ( is_classic() ) + { + level.chests = getstructarray( "treasure_chest_use", "targetname" ); + treasure_chest_init( "start_chest" ); + } + if ( level.createfx_enabled ) + { + return; + } + registerclientfield( "zbarrier", "magicbox_glow", 1000, 1, "int" ); + registerclientfield( "zbarrier", "zbarrier_show_sounds", 9000, 1, "int" ); + registerclientfield( "zbarrier", "zbarrier_leave_sounds", 9000, 1, "int" ); + if ( !isDefined( level.magic_box_check_equipment ) ) + { + level.magic_box_check_equipment = ::default_magic_box_check_equipment; + } + level thread magicbox_host_migration(); +} + +treasure_chest_init( start_chest_name ) +{ + flag_init( "moving_chest_enabled" ); + flag_init( "moving_chest_now" ); + flag_init( "chest_has_been_used" ); + level.chest_moves = 0; + level.chest_level = 0; + if ( level.chests.size == 0 ) + { + return; + } + i = 0; + while ( i < level.chests.size ) + { + level.chests[ i ].box_hacks = []; + level.chests[ i ].orig_origin = level.chests[ i ].origin; + level.chests[ i ] get_chest_pieces(); + if ( isDefined( level.chests[ i ].zombie_cost ) ) + { + level.chests[ i ].old_cost = level.chests[ i ].zombie_cost; + i++; + continue; + } + else + { + level.chests[ i ].old_cost = 950; + } + i++; + } + if ( !level.enable_magic ) + { + _a102 = level.chests; + _k102 = getFirstArrayKey( _a102 ); + while ( isDefined( _k102 ) ) + { + chest = _a102[ _k102 ]; + chest hide_chest(); + _k102 = getNextArrayKey( _a102, _k102 ); + } + return; + } + level.chest_accessed = 0; + if ( level.chests.size > 1 ) + { + flag_set( "moving_chest_enabled" ); + level.chests = array_randomize( level.chests ); + } + else + { + level.chest_index = 0; + level.chests[ 0 ].no_fly_away = 1; + } + init_starting_chest_location( start_chest_name ); + array_thread( level.chests, ::treasure_chest_think ); +} + +init_starting_chest_location( start_chest_name ) +{ + level.chest_index = 0; + start_chest_found = 0; + if ( level.chests.size == 1 ) + { + start_chest_found = 1; + if ( isDefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + } + else + { + i = 0; + while ( i < level.chests.size ) + { + if ( isDefined( level.random_pandora_box_start ) && level.random_pandora_box_start == 1 ) + { + if ( start_chest_found || isDefined( level.chests[ i ].start_exclude ) && level.chests[ i ].start_exclude == 1 ) + { + level.chests[ i ] hide_chest(); + } + else + { + level.chest_index = i; + level.chests[ level.chest_index ].hidden = 0; + if ( isDefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + i++; + continue; + } + else + { + if ( !start_chest_found || !isDefined( level.chests[ i ].script_noteworthy ) && !issubstr( level.chests[ i ].script_noteworthy, start_chest_name ) ) + { + level.chests[ i ] hide_chest(); + i++; + continue; + } + else + { + level.chest_index = i; + level.chests[ level.chest_index ].hidden = 0; + if ( isDefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + } + i++; + } + } + if ( !isDefined( level.pandora_show_func ) ) + { + level.pandora_show_func = ::default_pandora_show_func; + } + level.chests[ level.chest_index ] thread [[ level.pandora_show_func ]](); +} + +set_treasure_chest_cost( cost ) +{ + level.zombie_treasure_chest_cost = cost; +} + +get_chest_pieces() +{ + self.chest_box = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + self.chest_rubble = []; + rubble = getentarray( self.script_noteworthy + "_rubble", "script_noteworthy" ); + i = 0; + while ( i < rubble.size ) + { + if ( distancesquared( self.origin, rubble[ i ].origin ) < 10000 ) + { + self.chest_rubble[ self.chest_rubble.size ] = rubble[ i ]; + } + i++; + } + self.zbarrier = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier zbarrierpieceuseboxriselogic( 3 ); + self.zbarrier zbarrierpieceuseboxriselogic( 4 ); + } + self.unitrigger_stub = spawnstruct(); + self.unitrigger_stub.origin = self.origin + ( anglesToRight( self.angles ) * -22.5 ); + self.unitrigger_stub.angles = self.angles; + self.unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + self.unitrigger_stub.script_width = 104; + self.unitrigger_stub.script_height = 50; + self.unitrigger_stub.script_length = 45; + self.unitrigger_stub.trigger_target = self; + unitrigger_force_per_player_triggers( self.unitrigger_stub, 1 ); + self.unitrigger_stub.prompt_and_visibility_func = ::boxtrigger_update_prompt; + self.zbarrier.owner = self; +} + +boxtrigger_update_prompt( player ) +{ + can_use = self boxstub_update_prompt( player ); + if ( isDefined( self.hint_string ) ) + { + if ( isDefined( self.hint_parm1 ) ) + { + self sethintstring( self.hint_string, self.hint_parm1 ); + } + else + { + self sethintstring( self.hint_string ); + } + } + return can_use; +} + +boxstub_update_prompt( player ) +{ + self setcursorhint( "HINT_NOICON" ); + if ( !self trigger_visible_to_player( player ) ) + { + return 0; + } + self.hint_parm1 = undefined; + if ( isDefined( self.stub.trigger_target.grab_weapon_hint ) && self.stub.trigger_target.grab_weapon_hint ) + { + if ( isDefined( level.magic_box_check_equipment ) && [[ level.magic_box_check_equipment ]]( self.stub.trigger_target.grab_weapon_name ) ) + { + self.hint_string = &"ZOMBIE_TRADE_EQUIP"; + } + else + { + self.hint_string = &"ZOMBIE_TRADE_WEAPON"; + } + } + else + { + if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox && isDefined( self.stub.trigger_target.is_locked ) && self.stub.trigger_target.is_locked ) + { + self.hint_string = get_hint_string( self, "locked_magic_box_cost" ); + } + else + { + self.hint_parm1 = self.stub.trigger_target.zombie_cost; + self.hint_string = get_hint_string( self, "default_treasure_chest" ); + } + } + return 1; +} + +default_magic_box_check_equipment( weapon ) +{ + return is_offhand_weapon( weapon ); +} + +trigger_visible_to_player( player ) +{ + self setinvisibletoplayer( player ); + visible = 1; + if ( isDefined( self.stub.trigger_target.chest_user ) && !isDefined( self.stub.trigger_target.box_rerespun ) ) + { + if ( player != self.stub.trigger_target.chest_user || is_placeable_mine( self.stub.trigger_target.chest_user getcurrentweapon() ) && self.stub.trigger_target.chest_user hacker_active() ) + { + visible = 0; + } + } + else + { + if ( !player can_buy_weapon() ) + { + visible = 0; + } + } + if ( !visible ) + { + return 0; + } + self setvisibletoplayer( player ); + return 1; +} + +magicbox_unitrigger_think() +{ + self endon( "kill_trigger" ); + while ( 1 ) + { + self waittill( "trigger", player ); + self.stub.trigger_target notify( "trigger" ); + } +} + +play_crazi_sound() +{ + self playlocalsound( level.zmb_laugh_alias ); +} + +show_chest_sound_thread() +{ + self.zbarrier setclientfield( "zbarrier_show_sounds", 1 ); + wait 1; + self.zbarrier setclientfield( "zbarrier_show_sounds", 0 ); +} + +show_chest() +{ + self.zbarrier set_magic_box_zbarrier_state( "arriving" ); + self.zbarrier waittill( "arrived" ); + self thread [[ level.pandora_show_func ]](); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + self thread show_chest_sound_thread(); + self.hidden = 0; + if ( isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 0 ); + } +} + +hide_chest_sound_thread() +{ + self.zbarrier setclientfield( "zbarrier_leave_sounds", 1 ); + wait 1; + self.zbarrier setclientfield( "zbarrier_leave_sounds", 0 ); +} + +hide_chest( doboxleave ) +{ + if ( isDefined( self.unitrigger_stub ) ) + { + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + } + if ( isDefined( self.pandora_light ) ) + { + self.pandora_light delete(); + } + self.hidden = 1; + if ( isDefined( self.box_hacks ) && isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 1 ); + } + if ( isDefined( self.zbarrier ) ) + { + if ( isDefined( doboxleave ) && doboxleave ) + { + self thread hide_chest_sound_thread(); + level thread leaderdialog( "boxmove" ); + self.zbarrier thread magic_box_zbarrier_leave(); + self.zbarrier waittill( "left" ); + playfx( level._effect[ "poltergeist" ], self.zbarrier.origin, anglesToUp( self.angles ), anglesToForward( self.angles ) ); + playsoundatposition( "zmb_box_poof", self.zbarrier.origin ); + return; + } + else + { + self.zbarrier thread set_magic_box_zbarrier_state( "away" ); + } + } +} + +magic_box_zbarrier_leave() +{ + self set_magic_box_zbarrier_state( "leaving" ); + self waittill( "left" ); + self set_magic_box_zbarrier_state( "away" ); +} + +default_pandora_fx_func() +{ + self endon( "death" ); + self.pandora_light = spawn( "script_model", self.zbarrier.origin ); + self.pandora_light.angles = self.zbarrier.angles + vectorScale( ( 0, 1, 0 ), 90 ); + self.pandora_light setmodel( "tag_origin" ); + if ( isDefined( level._box_initialized ) && !level._box_initialized ) + { + flag_wait( "start_zombie_round_logic" ); + level._box_initialized = 1; + } + wait 1; + if ( isDefined( self ) && isDefined( self.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], self.pandora_light, "tag_origin" ); + } +} + +default_pandora_show_func( anchor, anchortarget, pieces ) +{ + if ( !isDefined( self.pandora_light ) ) + { + if ( !isDefined( level.pandora_fx_func ) ) + { + level.pandora_fx_func = ::default_pandora_fx_func; + } + self thread [[ level.pandora_fx_func ]](); + } + playfx( level._effect[ "lght_marker_flare" ], self.pandora_light.origin ); +} + +unregister_unitrigger_on_kill_think() +{ + self notify( "unregister_unitrigger_on_kill_think" ); + self endon( "unregister_unitrigger_on_kill_think" ); + self waittill( "kill_chest_think" ); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); +} + +treasure_chest_think() +{ + self endon( "kill_chest_think" ); + user = undefined; + user_cost = undefined; + self.box_rerespun = undefined; + self.weapon_out = undefined; + self thread unregister_unitrigger_on_kill_think(); + for ( ;; ) + { + while ( 1 ) + { + if ( !isDefined( self.forced_user ) ) + { + self waittill( "trigger", user ); + while ( user == level ) + { + continue; + } + } + else user = self.forced_user; + while ( user in_revive_trigger() ) + { + wait 0.1; + } + while ( user.is_drinking > 0 ) + { + wait 0.1; + } + while ( isDefined( self.disabled ) && self.disabled ) + { + wait 0.1; + } + while ( user getcurrentweapon() == "none" ) + { + wait 0.1; + } + reduced_cost = undefined; + if ( is_player_valid( user ) && user maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() ) + { + reduced_cost = int( self.zombie_cost / 2 ); + } + if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox && isDefined( self.is_locked ) && self.is_locked ) + { + if ( user.score >= level.locked_magic_box_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( level.locked_magic_box_cost ); + self.zbarrier set_magic_box_zbarrier_state( "unlocking" ); + self.unitrigger_stub run_visibility_function_for_all_triggers(); + } + else + { + user create_and_play_dialog( "general", "no_money_box" ); + } + wait 0.1; + } + } + if ( isDefined( self.auto_open ) && is_player_valid( user ) ) + { + if ( !isDefined( self.no_charge ) ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + } + else + { + user_cost = 0; + } + self.chest_user = user; + break; + } + else if ( is_player_valid( user ) && user.score >= self.zombie_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + self.chest_user = user; + break; + } + else if ( isDefined( reduced_cost ) && user.score >= reduced_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( reduced_cost ); + user_cost = reduced_cost; + self.chest_user = user; + break; + } + else while ( user.score < self.zombie_cost ) + { + play_sound_at_pos( "no_purchase", self.origin ); + user create_and_play_dialog( "general", "no_money_box" ); + } + wait 0.05; + } + flag_set( "chest_has_been_used" ); + maps/mp/_demo::bookmark( "zm_player_use_magicbox", getTime(), user ); + user maps/mp/zombies/_zm_stats::increment_client_stat( "use_magicbox" ); + user maps/mp/zombies/_zm_stats::increment_player_stat( "use_magicbox" ); + if ( isDefined( level._magic_box_used_vo ) ) + { + user thread [[ level._magic_box_used_vo ]](); + } + self thread watch_for_emp_close(); + if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox ) + { + self thread maps/mp/zombies/_zm_magicbox_lock::watch_for_lock(); + } + self._box_open = 1; + self._box_opened_by_fire_sale = 0; + if ( isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !isDefined( self.auto_open ) && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + self._box_opened_by_fire_sale = 1; + } + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_open(); + } + if ( isDefined( self.zbarrier ) ) + { + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); + self.zbarrier set_magic_box_zbarrier_state( "open" ); + } + self.timedout = 0; + self.weapon_out = 1; + self.zbarrier thread treasure_chest_weapon_spawn( self, user ); + self.zbarrier thread treasure_chest_glowfx(); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + self.zbarrier waittill_any( "randomization_done", "box_hacked_respin" ); + if ( flag( "moving_chest_now" ) && !self._box_opened_by_fire_sale && isDefined( user_cost ) ) + { + user maps/mp/zombies/_zm_score::add_to_player_score( user_cost, 0 ); + } + if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !self._box_opened_by_fire_sale ) + { + self thread treasure_chest_move( self.chest_user ); + } + else + { + self.grab_weapon_hint = 1; + self.grab_weapon_name = self.zbarrier.weapon_string; + self.chest_user = user; + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + if ( isDefined( self.zbarrier ) && !is_true( self.zbarrier.closed_by_emp ) ) + { + self thread treasure_chest_timeout(); + } + while ( isDefined( self.closed_by_emp ) && !self.closed_by_emp ) + { + self waittill( "trigger", grabber ); + self.weapon_out = undefined; + if ( isDefined( level.magic_box_grab_by_anyone ) && level.magic_box_grab_by_anyone ) + { + if ( isplayer( grabber ) ) + { + user = grabber; + } + } + if ( isDefined( level.pers_upgrade_box_weapon ) && level.pers_upgrade_box_weapon ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_box_weapon_used( user, grabber ); + } + while ( isDefined( grabber.is_drinking ) && grabber.is_drinking > 0 ) + { + wait 0.1; + } + while ( grabber == user && user getcurrentweapon() == "none" ) + { + wait 0.1; + } + if ( grabber != level && isDefined( self.box_rerespun ) && self.box_rerespun ) + { + user = grabber; + } + if ( grabber == user || grabber == level ) + { + self.box_rerespun = undefined; + current_weapon = "none"; + if ( is_player_valid( user ) ) + { + current_weapon = user getcurrentweapon(); + } + if ( grabber == user && is_player_valid( user ) && user.is_drinking > 0 && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_accept" ); + self notify( "user_grabbed_weapon" ); + user notify( "user_grabbed_weapon" ); + user thread treasure_chest_give_weapon( self.zbarrier.weapon_string ); + maps/mp/_demo::bookmark( "zm_player_grabbed_magicbox", getTime(), user ); + user maps/mp/zombies/_zm_stats::increment_client_stat( "grabbed_from_magicbox" ); + user maps/mp/zombies/_zm_stats::increment_player_stat( "grabbed_from_magicbox" ); + } + else if ( grabber == level ) + { + unacquire_weapon_toggle( self.zbarrier.weapon_string ); + self.timedout = 1; + if ( is_player_valid( user ) ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %S", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_reject" ); + } + } + } + else + { + wait 0.05; + } + } + self.grab_weapon_hint = 0; + self.zbarrier notify( "weapon_grabbed" ); + if ( isDefined( self._box_opened_by_fire_sale ) && !self._box_opened_by_fire_sale ) + { + level.chest_accessed += 1; + } + if ( level.chest_moves > 0 && isDefined( level.pulls_since_last_ray_gun ) ) + { + level.pulls_since_last_ray_gun += 1; + } + if ( isDefined( level.pulls_since_last_tesla_gun ) ) + { + level.pulls_since_last_tesla_gun += 1; + } + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_close( self.timedout ); + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier set_magic_box_zbarrier_state( "close" ); + play_sound_at_pos( "close_chest", self.origin ); + self.zbarrier waittill( "closed" ); + wait 1; + } + else + { + wait 3; + } + if ( isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && level.zombie_vars[ "zombie_powerup_fire_sale_on" ] || self [[ level._zombiemode_check_firesale_loc_valid_func ]]() && self == level.chests[ level.chest_index ] ) + { + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + } + } + self._box_open = 0; + self._box_opened_by_fire_sale = 0; + self.chest_user = undefined; + self notify( "chest_accessed" ); + self thread treasure_chest_think(); +} + +watch_for_emp_close() +{ + self endon( "chest_accessed" ); + self.closed_by_emp = 0; + if ( !should_watch_for_emp() ) + { + return; + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 0; + } + while ( 1 ) + { + level waittill( "emp_detonate", origin, radius ); + if ( distancesquared( origin, self.origin ) < ( radius * radius ) ) + { + break; + } + else + { + } + } + if ( flag( "moving_chest_now" ) ) + { + return; + } + self.closed_by_emp = 1; + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 1; + self.zbarrier notify( "box_hacked_respin" ); + if ( isDefined( self.zbarrier.weapon_model ) ) + { + self.zbarrier.weapon_model notify( "kill_weapon_movement" ); + } + if ( isDefined( self.zbarrier.weapon_model_dw ) ) + { + self.zbarrier.weapon_model_dw notify( "kill_weapon_movement" ); + } + } + wait 0.1; + self notify( "trigger" ); +} + +can_buy_weapon() +{ + if ( isDefined( self.is_drinking ) && self.is_drinking > 0 ) + { + return 0; + } + if ( self hacker_active() ) + { + return 0; + } + current_weapon = self getcurrentweapon(); + if ( is_placeable_mine( current_weapon ) || is_equipment_that_blocks_purchase( current_weapon ) ) + { + return 0; + } + if ( self in_revive_trigger() ) + { + return 0; + } + if ( current_weapon == "none" ) + { + return 0; + } + return 1; +} + +default_box_move_logic() +{ + index = -1; + i = 0; + while ( i < level.chests.size ) + { + if ( issubstr( level.chests[ i ].script_noteworthy, "move" + ( level.chest_moves + 1 ) ) && i != level.chest_index ) + { + index = i; + break; + } + else + { + i++; + } + } + if ( index != -1 ) + { + level.chest_index = index; + } + else + { + level.chest_index++; + } + if ( level.chest_index >= level.chests.size ) + { + temp_chest_name = level.chests[ level.chest_index - 1 ].script_noteworthy; + level.chest_index = 0; + level.chests = array_randomize( level.chests ); + if ( temp_chest_name == level.chests[ level.chest_index ].script_noteworthy ) + { + level.chest_index++; + } + } +} + +treasure_chest_move( player_vox ) +{ + level waittill( "weapon_fly_away_start" ); + players = get_players(); + array_thread( players, ::play_crazi_sound ); + if ( isDefined( player_vox ) ) + { + player_vox delay_thread( randomintrange( 2, 7 ), ::create_and_play_dialog, "general", "box_move" ); + } + level waittill( "weapon_fly_away_end" ); + if ( isDefined( self.zbarrier ) ) + { + self hide_chest( 1 ); + } + wait 0.1; + post_selection_wait_duration = 7; + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + current_sale_time = level.zombie_vars[ "zombie_powerup_fire_sale_time" ]; + wait_network_frame(); + self thread fire_sale_fix(); + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = current_sale_time; + while ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 ) + { + wait 0.1; + } + } + else post_selection_wait_duration += 5; + level.verify_chest = 0; + if ( isDefined( level._zombiemode_custom_box_move_logic ) ) + { + [[ level._zombiemode_custom_box_move_logic ]](); + } + else + { + default_box_move_logic(); + } + if ( isDefined( level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ) ) + { + level.chests[ level.chest_index ] [[ level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ]]( 0 ); + } + wait post_selection_wait_duration; + playfx( level._effect[ "poltergeist" ], level.chests[ level.chest_index ].zbarrier.origin ); + level.chests[ level.chest_index ] show_chest(); + flag_clear( "moving_chest_now" ); + self.zbarrier.chest_moving = 0; +} + +fire_sale_fix() +{ + if ( !isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) ) + { + return; + } + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) + { + self.old_cost = 950; + self thread show_chest(); + self.zombie_cost = 10; + self.unitrigger_stub unitrigger_set_hint_string( self, "default_treasure_chest", self.zombie_cost ); + wait_network_frame(); + level waittill( "fire_sale_off" ); + while ( isDefined( self._box_open ) && self._box_open ) + { + wait 0.1; + } + self hide_chest( 1 ); + self.zombie_cost = self.old_cost; + } +} + +check_for_desirable_chest_location() +{ + if ( !isDefined( level.desirable_chest_location ) ) + { + return level.chest_index; + } + if ( level.chests[ level.chest_index ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return level.chest_index; + } + i = 0; + while ( i < level.chests.size ) + { + if ( level.chests[ i ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return i; + } + i++; + } + /* +/# + iprintln( level.desirable_chest_location + " is an invalid box location!" ); +#/ + */ + level.desirable_chest_location = undefined; + return level.chest_index; +} + +rotateroll_box() +{ + angles = 40; + angles2 = 0; + while ( isDefined( self ) ) + { + self rotateroll( angles + angles2, 0.5 ); + wait 0.7; + angles2 = 40; + self rotateroll( angles * -2, 0.5 ); + wait 0.7; + } +} + +verify_chest_is_open() +{ + i = 0; + while ( i < level.open_chest_location.size ) + { + if ( isDefined( level.open_chest_location[ i ] ) ) + { + if ( level.open_chest_location[ i ] == level.chests[ level.chest_index ].script_noteworthy ) + { + level.verify_chest = 1; + return; + } + } + i++; + } + level.verify_chest = 0; +} + +treasure_chest_timeout() +{ + self endon( "user_grabbed_weapon" ); + self.zbarrier endon( "box_hacked_respin" ); + self.zbarrier endon( "box_hacked_rerespin" ); + wait 12; + self notify( "trigger" ); +} + +treasure_chest_lid_open() +{ + openroll = 105; + opentime = 0.5; + self rotateroll( 105, opentime, opentime * 0,5 ); + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); +} + +treasure_chest_lid_close( timedout ) +{ + closeroll = -105; + closetime = 0.5; + self rotateroll( closeroll, closetime, closetime * 0,5 ); + play_sound_at_pos( "close_chest", self.origin ); + self notify( "lid_closed" ); +} + +treasure_chest_chooserandomweapon( player ) +{ + keys = getarraykeys( level.zombie_weapons ); + return keys[ randomint( keys.size ) ]; +} + +treasure_chest_canplayerreceiveweapon( player, weapon, pap_triggers ) +{ + if ( !get_is_in_box( weapon ) ) + { + return 0; + } + if ( isDefined( player ) && player has_weapon_or_upgrade( weapon ) ) + { + return 0; + } + if ( !limited_weapon_below_quota( weapon, player, pap_triggers ) ) + { + return 0; + } + if ( !player player_can_use_content( weapon ) ) + { + return 0; + } + if ( isDefined( level.custom_magic_box_selection_logic ) ) + { + if ( !( [[ level.custom_magic_box_selection_logic ]]( weapon, player, pap_triggers ) ) ) + { + return 0; + } + } + if ( isDefined( player ) && isDefined( level.special_weapon_magicbox_check ) ) + { + return player [[ level.special_weapon_magicbox_check ]]( weapon ); + } + return 1; +} + +treasure_chest_chooseweightedrandomweapon( player ) +{ + keys = array_randomize( getarraykeys( level.zombie_weapons ) ); + if ( isDefined( level.customrandomweaponweights ) ) + { + keys = player [[ level.customrandomweaponweights ]]( keys ); + } + /* +/# + forced_weapon = getDvar( "scr_force_weapon" ); + if ( forced_weapon != "" && isDefined( level.zombie_weapons[ forced_weapon ] ) ) + { + arrayinsert( keys, forced_weapon, 0 ); +#/ + } + */ + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + i = 0; + while ( i < keys.size ) + { + if ( treasure_chest_canplayerreceiveweapon( player, keys[ i ], pap_triggers ) ) + { + return keys[ i ]; + } + i++; + } + return keys[ 0 ]; +} + +weapon_is_dual_wield( name ) +{ + switch( name ) + { + case "cz75dw_upgraded_zm": + case "cz75dw_zm": + case "fivesevendw_upgraded_zm": + case "fivesevendw_zm": + case "hs10_upgraded_zm": + case "m1911_upgraded_zm": + case "microwavegundw_upgraded_zm": + case "microwavegundw_zm": + case "pm63_upgraded_zm": + return 1; + default: + return 0; + } +} + +weapon_show_hint_choke() +{ + level._weapon_show_hint_choke = 0; + while ( 1 ) + { + wait 0.05; + level._weapon_show_hint_choke = 0; + } +} + +decide_hide_show_hint( endon_notify, second_endon_notify, onlyplayer ) +{ + self endon( "death" ); + if ( isDefined( endon_notify ) ) + { + self endon( endon_notify ); + } + if ( isDefined( second_endon_notify ) ) + { + self endon( second_endon_notify ); + } + if ( !isDefined( level._weapon_show_hint_choke ) ) + { + level thread weapon_show_hint_choke(); + } + use_choke = 0; + if ( isDefined( level._use_choke_weapon_hints ) && level._use_choke_weapon_hints == 1 ) + { + use_choke = 1; + } + while ( 1 ) + { + last_update = getTime(); + if ( isDefined( self.chest_user ) && !isDefined( self.box_rerespun ) ) + { + if ( is_placeable_mine( self.chest_user getcurrentweapon() ) || self.chest_user hacker_active() ) + { + self setinvisibletoplayer( self.chest_user ); + } + else + { + self setvisibletoplayer( self.chest_user ); + } + } + else + { + if ( isDefined( onlyplayer ) ) + { + if ( onlyplayer can_buy_weapon() ) + { + self setinvisibletoplayer( onlyplayer, 0 ); + } + else + { + self setinvisibletoplayer( onlyplayer, 1 ); + } + break; + } + else + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ] can_buy_weapon() ) + { + self setinvisibletoplayer( players[ i ], 0 ); + i++; + continue; + } + else + { + self setinvisibletoplayer( players[ i ], 1 ); + } + i++; + } + } + } + if ( use_choke ) + { + while ( level._weapon_show_hint_choke > 4 && getTime() < ( last_update + 150 ) ) + { + wait 0.05; + } + } + else wait 0.1; + level._weapon_show_hint_choke++; + } +} + +get_left_hand_weapon_model_name( name ) +{ + switch( name ) + { + case "microwavegundw_zm": + return getweaponmodel( "microwavegunlh_zm" ); + case "microwavegundw_upgraded_zm": + return getweaponmodel( "microwavegunlh_upgraded_zm" ); + default: + return getweaponmodel( name ); + } +} + +clean_up_hacked_box() +{ + self waittill( "box_hacked_respin" ); + self endon( "box_spin_done" ); + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + self.weapon_model = undefined; + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); +} + +treasure_chest_weapon_spawn( chest, player, respin ) +{ + if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox ) + { + self.owner endon( "box_locked" ); + self thread maps/mp/zombies/_zm_magicbox_lock::clean_up_locked_box(); + } + self endon( "box_hacked_respin" ); + self thread clean_up_hacked_box(); + /* +/# + assert( isDefined( player ) ); +#/ + */ + self.weapon_string = undefined; + modelname = undefined; + rand = undefined; + number_cycles = 40; + if ( isDefined( chest.zbarrier ) ) + { + if ( isDefined( level.custom_magic_box_do_weapon_rise ) ) + { + chest.zbarrier thread [[ level.custom_magic_box_do_weapon_rise ]](); + } + else + { + chest.zbarrier thread magic_box_do_weapon_rise(); + } + } + i = 0; + while ( i < number_cycles ) + { + if ( i < 20 ) + { + wait 0.05; + i++; + continue; + } + else if ( i < 30 ) + { + wait 0.1; + i++; + continue; + } + else if ( i < 35 ) + { + wait 0.2; + i++; + continue; + } + else + { + if ( i < 38 ) + { + wait 0.3; + } + } + i++; + } + if ( isDefined( level.custom_magic_box_weapon_wait ) ) + { + [[ level.custom_magic_box_weapon_wait ]](); + } + if ( isDefined( player.pers_upgrades_awarded[ "box_weapon" ] ) && player.pers_upgrades_awarded[ "box_weapon" ] ) + { + rand = maps/mp/zombies/_zm_pers_upgrades_functions::pers_treasure_chest_choosespecialweapon( player ); + } + else + { + rand = treasure_chest_chooseweightedrandomweapon( player ); + } + self.weapon_string = rand; + wait 0.1; + if ( isDefined( level.custom_magicbox_float_height ) ) + { + v_float = anglesToUp( self.angles ) * level.custom_magicbox_float_height; + } + else + { + v_float = anglesToUp( self.angles ) * 40; + } + self.model_dw = undefined; + self.weapon_model = spawn_weapon_model( rand, undefined, self.origin + v_float, self.angles + vectorScale( ( 0, 1, 0 ), 180 ) ); + if ( weapon_is_dual_wield( rand ) ) + { + self.weapon_model_dw = spawn_weapon_model( rand, get_left_hand_weapon_model_name( rand ), self.weapon_model.origin - vectorScale( ( 0, 1, 0 ), 3 ), self.weapon_model.angles ); + } + if ( getDvar( "magic_chest_movable" ) == "1" && isDefined( chest._box_opened_by_fire_sale ) && !chest._box_opened_by_fire_sale && isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !( self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) ) + { + random = randomint( 100 ); + if ( !isDefined( level.chest_min_move_usage ) ) + { + level.chest_min_move_usage = 4; + } + if ( level.chest_accessed < level.chest_min_move_usage ) + { + chance_of_joker = -1; + } + else chance_of_joker = level.chest_accessed + 20; + if ( level.chest_moves == 0 && level.chest_accessed >= 8 ) + { + chance_of_joker = 100; + } + if ( level.chest_accessed >= 4 && level.chest_accessed < 8 ) + { + if ( random < 15 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_moves > 0 ) + { + if ( level.chest_accessed >= 8 && level.chest_accessed < 13 ) + { + if ( random < 30 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_accessed >= 13 ) + { + if ( random < 50 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + } + if ( isDefined( chest.no_fly_away ) ) + { + chance_of_joker = -1; + } + if ( isDefined( level._zombiemode_chest_joker_chance_override_func ) ) + { + chance_of_joker = [[ level._zombiemode_chest_joker_chance_override_func ]]( chance_of_joker ); + } + if ( chance_of_joker > random ) + { + self.weapon_string = undefined; + self.weapon_model setmodel( level.chest_joker_model ); + self.weapon_model.angles = self.angles + vectorScale( ( 0, 1, 0 ), 90 ); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self.chest_moving = 1; + flag_set( "moving_chest_now" ); + level.chest_accessed = 0; + level.chest_moves++; + } + } + self notify( "randomization_done" ); + if ( flag( "moving_chest_now" ) && level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !( self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) ) + { + if ( isDefined( level.chest_joker_custom_movement ) ) + { + self [[ level.chest_joker_custom_movement ]](); + } + else + { + wait 0.5; + level notify( "weapon_fly_away_start" ); + wait 2; + if ( isDefined( self.weapon_model ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model moveto( v_fly_away, 4, 3 ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model_dw moveto( v_fly_away, 4, 3 ); + } + self.weapon_model waittill( "movedone" ); + self.weapon_model delete(); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self notify( "box_moving" ); + level notify( "weapon_fly_away_end" ); + } + } + else + { + acquire_weapon_toggle( rand, player ); + if ( rand == "tesla_gun_zm" || rand == "ray_gun_zm" ) + { + if ( rand == "ray_gun_zm" ) + { + level.pulls_since_last_ray_gun = 0; + } + if ( rand == "tesla_gun_zm" ) + { + level.pulls_since_last_tesla_gun = 0; + level.player_seen_tesla_gun = 1; + } + } + if ( !isDefined( respin ) ) + { + if ( isDefined( chest.box_hacks[ "respin" ] ) ) + { + self [[ chest.box_hacks[ "respin" ] ]]( chest, player ); + } + } + else + { + if ( isDefined( chest.box_hacks[ "respin_respin" ] ) ) + { + self [[ chest.box_hacks[ "respin_respin" ] ]]( chest, player ); + } + } + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model thread timer_til_despawn( v_float ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model_dw thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model_dw thread timer_til_despawn( v_float ); + } + } + self waittill( "weapon_grabbed" ); + if ( !chest.timedout ) + { + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + } + } + } + self.weapon_string = undefined; + self notify( "box_spin_done" ); +} + +chest_get_min_usage() +{ + min_usage = 4; + return min_usage; +} + +chest_get_max_usage() +{ + max_usage = 6; + players = get_players(); + if ( level.chest_moves == 0 ) + { + if ( players.size == 1 ) + { + max_usage = 3; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 6; + } + } + else if ( players.size == 1 ) + { + max_usage = 4; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 7; + } + return max_usage; +} + +timer_til_despawn( v_float ) +{ + self endon( "kill_weapon_movement" ); + putbacktime = 12; + self moveto( self.origin - ( v_float * 0.85 ), putbacktime, putbacktime * 0.5 ); + wait putbacktime; + if ( isDefined( self ) ) + { + self delete(); + } +} + +treasure_chest_glowfx() +{ + self setclientfield( "magicbox_glow", 1 ); + self waittill_any( "weapon_grabbed", "box_moving" ); + self setclientfield( "magicbox_glow", 0 ); +} + +treasure_chest_give_weapon( weapon_string ) +{ + self.last_box_weapon = getTime(); + self maps/mp/zombies/_zm_weapons::weapon_give( weapon_string, 0, 1 ); +} + +magic_box_teddy_twitches() +{ + self endon( "zbarrier_state_change" ); + self setzbarrierpiecestate( 0, "closed" ); + while ( 1 ) + { + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "opening" ); + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "closing" ); + } +} + +magic_box_initial() +{ + self setzbarrierpiecestate( 1, "open" ); +} + +magic_box_arrives() +{ + self setzbarrierpiecestate( 1, "opening" ); + while ( self getzbarrierpiecestate( 1 ) == "opening" ) + { + wait 0.05; + } + self notify( "arrived" ); +} + +magic_box_leaves() +{ + self setzbarrierpiecestate( 1, "closing" ); + while ( self getzbarrierpiecestate( 1 ) == "closing" ) + { + wait 0.1; + } + self notify( "left" ); +} + +magic_box_opens() +{ + self setzbarrierpiecestate( 2, "opening" ); + while ( self getzbarrierpiecestate( 2 ) == "opening" ) + { + wait 0.1; + } + self notify( "opened" ); +} + +magic_box_closes() +{ + self setzbarrierpiecestate( 2, "closing" ); + while ( self getzbarrierpiecestate( 2 ) == "closing" ) + { + wait 0.1; + } + self notify( "closed" ); +} + +magic_box_do_weapon_rise() +{ + self endon( "box_hacked_respin" ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); + wait_network_frame(); + self zbarrierpieceuseboxriselogic( 3 ); + self zbarrierpieceuseboxriselogic( 4 ); + self showzbarrierpiece( 3 ); + self showzbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "opening" ); + self setzbarrierpiecestate( 4, "opening" ); + while ( self getzbarrierpiecestate( 3 ) != "open" ) + { + wait 0.5; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); +} + +magic_box_do_teddy_flyaway() +{ + self showzbarrierpiece( 3 ); + self setzbarrierpiecestate( 3, "closing" ); +} + +is_chest_active() +{ + curr_state = self.zbarrier get_magic_box_zbarrier_state(); + if ( flag( "moving_chest_now" ) ) + { + return 0; + } + if ( curr_state == "open" || curr_state == "close" ) + { + return 1; + } + return 0; +} + +get_magic_box_zbarrier_state() +{ + return self.state; +} + +set_magic_box_zbarrier_state( state ) +{ + i = 0; + while ( i < self getnumzbarrierpieces() ) + { + self hidezbarrierpiece( i ); + i++; + } + self notify( "zbarrier_state_change" ); + self [[ level.magic_box_zbarrier_state_func ]]( state ); +} + +process_magic_box_zbarrier_state( state ) +{ + switch( state ) + { + case "away": + self showzbarrierpiece( 0 ); + self thread magic_box_teddy_twitches(); + self.state = "away"; + break; + case "arriving": + self showzbarrierpiece( 1 ); + self thread magic_box_arrives(); + self.state = "arriving"; + break; + case "initial": + self showzbarrierpiece( 1 ); + self thread magic_box_initial(); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.owner.unitrigger_stub, ::magicbox_unitrigger_think ); + self.state = "initial"; + break; + case "open": + self showzbarrierpiece( 2 ); + self thread magic_box_opens(); + self.state = "open"; + break; + case "close": + self showzbarrierpiece( 2 ); + self thread magic_box_closes(); + self.state = "close"; + break; + case "leaving": + self showzbarrierpiece( 1 ); + self thread magic_box_leaves(); + self.state = "leaving"; + break; + default: + if ( isDefined( level.custom_magicbox_state_handler ) ) + { + self [[ level.custom_magicbox_state_handler ]]( state ); + } + break; + } +} + +magicbox_host_migration() +{ + level endon( "end_game" ); + level notify( "mb_hostmigration" ); + level endon( "mb_hostmigration" ); + while ( 1 ) + { + level waittill( "host_migration_end" ); + while ( !isDefined( level.chests ) ) + { + continue; + } + _a2101 = level.chests; + _k2101 = getFirstArrayKey( _a2101 ); + while ( isDefined( _k2101 ) ) + { + chest = _a2101[ _k2101 ]; + if ( !is_true( chest.hidden ) ) + { + if ( isDefined( chest ) && isDefined( chest.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], chest.pandora_light, "tag_origin" ); + } + } + wait_network_frame(); + _k2101 = getNextArrayKey( _a2101, _k2101 ); + } + } +} + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perk_electric_cherry.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perk_electric_cherry.gsc new file mode 100644 index 0000000..802beb4 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perk_electric_cherry.gsc @@ -0,0 +1,400 @@ +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/animscripts/shared; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/_utility; + +enable_electric_cherry_perk_for_level() +{ + register_perk_basic_info( "specialty_grenadepulldeath", "electric_cherry", 2000, &"ZM_PRISON_PERK_CHERRY", "zombie_perk_bottle_cherry" ); + register_perk_precache_func( "specialty_grenadepulldeath", ::electic_cherry_precache ); + register_perk_clientfields( "specialty_grenadepulldeath", ::electric_cherry_register_clientfield, ::electric_cherry_set_clientfield ); + register_perk_threads( "specialty_grenadepulldeath", ::electric_cherry_reload_attack, ::electric_cherry_perk_lost ); + register_perk_machine( "specialty_grenadepulldeath", ::electric_cherry_perk_machine_setup, ::electric_cherry_perk_machine_think ); + register_perk_host_migration_func( "specialty_grenadepulldeath", ::electric_cherry_host_migration_func ); + if ( isDefined( level.custom_electric_cherry_perk_threads ) && level.custom_electric_cherry_perk_threads ) + { + level thread [[ level.custom_electric_cherry_perk_threads ]](); + } +} + +init_electric_cherry() +{ + level.custom_laststand_func = ::electric_cherry_laststand; + set_zombie_var( "tesla_head_gib_chance", 50 ); + registerclientfield( "allplayers", "electric_cherry_reload_fx", 9000, 2, "int" ); +} + +electic_cherry_precache() +{ + precacheitem( "zombie_perk_bottle_cherry" ); + precacheshader( "specialty_fastreload_zombies" ); + precachemodel( "p6_zm_vending_electric_cherry_off" ); + precachemodel( "p6_zm_vending_electric_cherry_on" ); + precachestring( &"ZM_PRISON_PERK_CHERRY" ); + level._effect[ "electriccherry" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "electric_cherry_explode" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_electric_cherry_down" ); + level._effect[ "electric_cherry_reload_small" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_electric_cherry_sm" ); + level._effect[ "electric_cherry_reload_medium" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_electric_cherry_player" ); + level._effect[ "electric_cherry_reload_large" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_electric_cherry_lg" ); + level._effect[ "tesla_shock" ] = loadfx( "maps/zombie/fx_zombie_tesla_shock" ); + level._effect[ "tesla_shock_secondary" ] = loadfx( "maps/zombie/fx_zombie_tesla_shock_secondary" ); +} + +electric_cherry_register_clientfield() +{ + registerclientfield( "toplayer", "perk_electric_cherry", 9000, 1, "int" ); +} + +electric_cherry_set_clientfield( state ) +{ + self setclientfieldtoplayer( "perk_electric_cherry", state ); +} + +electric_cherry_perk_machine_setup( use_trigger, perk_machine, bump_trigger, collision ) +{ + use_trigger.script_sound = "mus_perks_cherry_jingle"; + use_trigger.script_string = "electric_cherry_perk"; + use_trigger.script_label = "mus_perks_cherry_sting"; + use_trigger.target = "vending_electriccherry"; + perk_machine.script_string = "electriccherry_perk"; + perk_machine.targetname = "vendingelectric_cherry"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "electriccherry_perk"; + } +} + +electric_cherry_perk_machine_think() +{ + init_electric_cherry(); + while ( 1 ) + { + machine = getentarray( "vendingelectric_cherry", "targetname" ); + machine_triggers = getentarray( "vending_electriccherry", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( "p6_zm_vending_electric_cherry_off" ); + i++; + } + level thread do_initial_power_off_callback( machine, "electriccherry" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "electric_cherry_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( "p6_zm_vending_electric_cherry_on" ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0.3, 0.4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "electriccherry" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_grenadepulldeath_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + level waittill( "electric_cherry_off" ); + array_thread( machine, ::turn_perk_off ); + } +} + +electric_cherry_host_migration_func() +{ + a_electric_cherry_perk_machines = getentarray( "vending_electriccherry", "targetname" ); + _a130 = a_electric_cherry_perk_machines; + _k130 = getFirstArrayKey( _a130 ); + while ( isDefined( _k130 ) ) + { + perk_machine = _a130[ _k130 ]; + if ( isDefined( perk_machine.model ) && perk_machine.model == "p6_zm_vending_electric_cherry_on" ) + { + perk_machine perk_fx( undefined, 1 ); + perk_machine thread perk_fx( "electriccherry" ); + } + _k130 = getNextArrayKey( _a130, _k130 ); + } +} + +electric_cherry_laststand() +{ + visionsetlaststand( "zombie_last_stand", 1 ); + if ( isDefined( self ) ) + { + playfx( level._effect[ "electric_cherry_explode" ], self.origin ); + self playsound( "zmb_cherry_explode" ); + self notify( "electric_cherry_start" ); + wait 0.05; + a_zombies = get_round_enemy_array(); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, 500 ); + i = 0; + while ( i < a_zombies.size ) + { + if ( isalive( self ) ) + { + + if ( a_zombies[ i ].health <= 1000 ) + { + a_zombies[ i ] thread electric_cherry_death_fx(); + if ( isDefined( self.cherry_kills ) ) + { + self.cherry_kills++; + } + self maps/mp/zombies/_zm_score::add_to_player_score( 40 ); + } + else + { + a_zombies[ i ] thread electric_cherry_stun(); + a_zombies[ i ] thread electric_cherry_shock_fx(); + } + wait 0.1; + a_zombies[ i ] dodamage( 1000, self.origin, self, self, "none" ); + } + i++; + } + self notify( "electric_cherry_end" ); + } +} + +electric_cherry_death_fx() +{ + self endon( "death" ); + tag = "J_SpineUpper"; + fx = "tesla_shock"; + if ( self.isdog ) + { + tag = "J_Spine1"; + } + self playsound( "zmb_elec_jib_zombie" ); + network_safe_play_fx_on_tag( "tesla_death_fx", 2, level._effect[ fx ], self, tag ); + if ( isDefined( self.tesla_head_gib_func ) && !self.head_gibbed ) + { + [[ self.tesla_head_gib_func ]](); + } +} + +electric_cherry_shock_fx() +{ + self endon( "death" ); + tag = "J_SpineUpper"; + fx = "tesla_shock_secondary"; + if ( self.isdog ) + { + tag = "J_Spine1"; + } + self playsound( "zmb_elec_jib_zombie" ); + network_safe_play_fx_on_tag( "tesla_shock_fx", 2, level._effect[ fx ], self, tag ); +} + +electric_cherry_stun() +{ + self endon( "death" ); + self notify( "stun_zombie" ); + self endon( "stun_zombie" ); + if ( self.health <= 0 ) + { +/# + iprintln( "trying to stun a dead zombie" ); +#/ + return; + } + if ( self.ai_state != "find_flesh" ) + { + return; + } + self.forcemovementscriptstate = 1; + self.ignoreall = 1; + i = 0; + while ( i < 2 ) + { + self animscripted( self.origin, self.angles, "zm_afterlife_stun" ); + self maps/mp/animscripts/shared::donotetracks( "stunned" ); + i++; + } + self.forcemovementscriptstate = 0; + self.ignoreall = 0; + self setgoalpos( self.origin ); + self thread maps/mp/zombies/_zm_ai_basic::find_flesh(); +} + +electric_cherry_reload_attack() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "stop_electric_cherry_reload_attack" ); + self.wait_on_reload = []; + self.consecutive_electric_cherry_attacks = 0; + while ( 1 ) + { + self waittill( "reload_start" ); + str_current_weapon = self getcurrentweapon(); + while ( isinarray( self.wait_on_reload, str_current_weapon ) ) + { + continue; + } + self.wait_on_reload[ self.wait_on_reload.size ] = str_current_weapon; + self.consecutive_electric_cherry_attacks++; + n_clip_current = self getweaponammoclip( str_current_weapon ); + n_clip_max = weaponclipsize( str_current_weapon ); + n_fraction = n_clip_current / n_clip_max; + perk_radius = linear_map( n_fraction, 1, 0, 32, 128 ); + perk_dmg = linear_map( n_fraction, 1, 0, 1, 1045 ); + self thread check_for_reload_complete( str_current_weapon ); + if ( isDefined( self ) ) + { + switch( self.consecutive_electric_cherry_attacks ) + { + case 0: + case 1: + n_zombie_limit = undefined; + break; + case 2: + n_zombie_limit = 8; + break; + case 3: + n_zombie_limit = 4; + break; + case 4: + n_zombie_limit = 2; + break; + case default: + n_zombie_limit = 0; + } + self thread electric_cherry_cooldown_timer( str_current_weapon ); + if ( isDefined( n_zombie_limit ) && n_zombie_limit == 0 ) + { + continue; + } + self thread electric_cherry_reload_fx( n_fraction ); + self notify( "electric_cherry_start" ); + self playsound( "zmb_cherry_explode" ); + a_zombies = get_round_enemy_array(); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, perk_radius ); + n_zombies_hit = 0; + i = 0; + while ( i < a_zombies.size ) + { + if ( isalive( self ) ) + { + if ( isDefined( n_zombie_limit ) ) + { + if ( n_zombies_hit < n_zombie_limit ) + { + n_zombies_hit++; + } + else + { + break; + } + } + if ( a_zombies[ i ].health <= perk_dmg ) + { + a_zombies[ i ] thread electric_cherry_death_fx(); + if ( isDefined( self.cherry_kills ) ) + { + self.cherry_kills++; + } + self maps/mp/zombies/_zm_score::add_to_player_score( 40 ); + } + else + { + if ( !isDefined( a_zombies[ i ].is_brutus ) ) + { + a_zombies[ i ] thread electric_cherry_stun(); + } + a_zombies[ i ] thread electric_cherry_shock_fx(); + } + wait 0.1; + a_zombies[ i ] dodamage( perk_dmg, self.origin, self, self, "none" ); + } + i++; + } + self notify( "electric_cherry_end" ); + } + } +} + +electric_cherry_cooldown_timer( str_current_weapon ) +{ + self notify( "electric_cherry_cooldown_started" ); + self endon( "electric_cherry_cooldown_started" ); + self endon( "death" ); + self endon( "disconnect" ); + n_reload_time = weaponreloadtime( str_current_weapon ); + if ( self hasperk( "specialty_fastreload" ) ) + { + n_reload_time *= getDvarFloat( "perk_weapReloadMultiplier" ); + } + n_cooldown_time = n_reload_time + 3; + wait n_cooldown_time; + self.consecutive_electric_cherry_attacks = 0; +} + +check_for_reload_complete( weapon ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "player_lost_weapon_" + weapon ); + self thread weapon_replaced_monitor( weapon ); + while ( 1 ) + { + self waittill( "reload" ); + str_current_weapon = self getcurrentweapon(); + if ( str_current_weapon == weapon ) + { + arrayremovevalue( self.wait_on_reload, weapon ); + self notify( "weapon_reload_complete_" + weapon ); + return; + } + else + { + } + } +} + +weapon_replaced_monitor( weapon ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "weapon_reload_complete_" + weapon ); + while ( 1 ) + { + self waittill( "weapon_change" ); + primaryweapons = self getweaponslistprimaries(); + if ( !isinarray( primaryweapons, weapon ) ) + { + self notify( "player_lost_weapon_" + weapon ); + arrayremovevalue( self.wait_on_reload, weapon ); + return; + } + else + { + } + } +} + +electric_cherry_reload_fx( n_fraction ) +{ + if ( n_fraction >= 0.67 ) + { + self setclientfield( "electric_cherry_reload_fx", 1 ); + } + else if ( n_fraction >= 0.33 && n_fraction < 0.67 ) + { + self setclientfield( "electric_cherry_reload_fx", 2 ); + } + else + { + self setclientfield( "electric_cherry_reload_fx", 3 ); + } + wait 1; + self setclientfield( "electric_cherry_reload_fx", 0 ); +} + +electric_cherry_perk_lost() +{ + self notify( "stop_electric_cherry_reload_attack" ); +} + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_tombstone.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_tombstone.gsc new file mode 100644 index 0000000..1833f9b --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_tombstone.gsc @@ -0,0 +1,540 @@ +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_weap_cymbal_monkey; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/_utility; + +init() +{ + onplayerconnect_callback( ::tombstone_player_init ); + level.tombstone_laststand_func = ::tombstone_laststand; + level.tombstone_spawn_func = ::tombstone_spawn; + level thread tombstone_hostmigration(); + if ( isDefined( level.zombiemode_using_tombstone_perk ) && level.zombiemode_using_tombstone_perk ) + { + add_custom_limited_weapon_check( ::is_weapon_available_in_tombstone ); + } +} + +tombstone_player_init() +{ + while ( !isDefined( self.tombstone_index ) ) + { + wait 0.1; + } + level.tombstones[ self.tombstone_index ] = spawnstruct(); +} + +tombstone_spawn() +{ + dc = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_clear() +{ + result = self waittill_any_return( "tombstone_timedout", "tombstone_grabbed" ); + level.tombstones[ self.tombstone_index ] = spawnstruct(); +} + +tombstone_revived( player ) +{ + self endon( "tombstone_timedout" ); + player endon( "disconnect" ); + shown = 1; + while ( isDefined( self ) && isDefined( player ) ) + { + if ( isDefined( player.revivetrigger ) && isDefined( player.revivetrigger.beingrevived ) && player.revivetrigger.beingrevived ) + { + if ( shown ) + { + shown = 0; + self.icon hide(); + } + } + else + { + if ( !shown ) + { + shown = 1; + self.icon show(); + } + } + wait 0.05; + } +} + +tombstone_laststand() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + dc = level.tombstones[ self.tombstone_index ]; + dc.player = self; + dc.weapon = []; + dc.current_weapon = -1; + _a134 = primaries; + index = getFirstArrayKey( _a134 ); + while ( isDefined( index ) ) + { + weapon = _a134[ index ]; + dc.weapon[ index ] = weapon; + dc.stockcount[ index ] = self getweaponammostock( weapon ); + if ( weapon == currentweapon ) + { + dc.current_weapon = index; + } + index = getNextArrayKey( _a134, index ); + } + if ( isDefined( self.hasriotshield ) && self.hasriotshield ) + { + dc.hasriotshield = 1; + } + dc save_weapons_for_tombstone( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + dc.hasclaymore = 1; + dc.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + dc.hasemp = 1; + dc.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + dc.perk = tombstone_save_perks( self ); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + dc.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + dc.grenade = 0; + } + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + dc.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +tombstone_save_perks( ent ) +{ + perk_array = []; + if ( ent hasperk( "specialty_armorvest" ) ) + { + perk_array[ perk_array.size ] = "specialty_armorvest"; + } + if ( ent hasperk( "specialty_deadshot" ) ) + { + perk_array[ perk_array.size ] = "specialty_deadshot"; + } + if ( ent hasperk( "specialty_fastreload" ) ) + { + perk_array[ perk_array.size ] = "specialty_fastreload"; + } + if ( ent hasperk( "specialty_flakjacket" ) ) + { + perk_array[ perk_array.size ] = "specialty_flakjacket"; + } + if ( ent hasperk( "specialty_longersprint" ) ) + { + perk_array[ perk_array.size ] = "specialty_longersprint"; + } + if ( ent hasperk( "specialty_quickrevive" ) ) + { + perk_array[ perk_array.size ] = "specialty_quickrevive"; + } + if ( ent hasperk( "specialty_rof" ) ) + { + perk_array[ perk_array.size ] = "specialty_rof"; + } + return perk_array; +} + +tombstone_grab() +{ + self endon( "tombstone_timedout" ); + wait 1; + while ( isDefined( self ) ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].is_zombie ) + { + i++; + continue; + } + else + { + if ( isDefined( self.player ) && players[ i ] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + _a258 = tombstone_machine_triggers; + _k258 = getFirstArrayKey( _a258 ); + while ( isDefined( _k258 ) ) + { + trigger = _a258[ _k258 ]; + if ( isDefined( trigger.power_on ) || trigger.power_on && isDefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + { + istombstonepowered = 1; + } + _k258 = getNextArrayKey( _a258, _k258 ); + } + if ( istombstonepowered ) + { + dist = distance( players[ i ].origin, self.origin ); + if ( dist < 64 ) + { + playfx( level._effect[ "powerup_grabbed" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave" ], self.origin ); + players[ i ] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[ i ] clientnotify( "dc0" ); + players[ i ] notify( "dance_on_my_grave" ); + } + } + } + } + i++; + } + wait_network_frame(); + } +} + +tombstone_give() +{ + dc = level.tombstones[ self.tombstone_index ]; + while ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + while ( dc.weapon.size > 1 || primaries.size > 1 ) + { + _a310 = primaries; + _k310 = getFirstArrayKey( _a310 ); + while ( isDefined( _k310 ) ) + { + weapon = _a310[ _k310 ]; + self takeweapon( weapon ); + _k310 = getNextArrayKey( _a310, _k310 ); + } + } + i = 0; + while ( i < dc.weapon.size ) + { + if ( !isDefined( dc.weapon[ i ] ) ) + { + i++; + continue; + } + else if ( dc.weapon[ i ] == "none" ) + { + i++; + continue; + } + else + { + weapon = dc.weapon[ i ]; + stock = dc.stockcount[ i ]; + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + if ( i == dc.current_weapon ) + { + self switchtoweapon( weapon ); + } + } + } + i++; + } + } + if ( isDefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps/mp/zombies/_zm_equipment::equipment_give( "riotshield_zm" ); + if ( isDefined( self.player_shield_reset_health ) ) + { + self [[ self.player_shield_reset_health ]](); + } + } + dc restore_weapons_for_tombstone( self ); + if ( isDefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + if ( isDefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + while ( isDefined( dc.perk ) && dc.perk.size > 0 ) + { + i = 0; + while ( i < dc.perk.size ) + { + if ( self hasperk( dc.perk[ i ] ) ) + { + i++; + continue; + } + else if ( dc.perk[ i ] == "specialty_quickrevive" && flag( "solo_game" ) ) + { + i++; + continue; + } + else + { + maps/mp/zombies/_zm_perks::give_perk( dc.perk[ i ] ); + } + i++; + } + } + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade() ) ) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps/mp/zombies/_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } +} + +tombstone_wobble() +{ + self endon( "tombstone_grabbed" ); + self endon( "tombstone_timedout" ); + if ( isDefined( self ) ) + { + wait 1; + playfxontag( level._effect[ "powerup_on" ], self, "tag_origin" ); + self playsound( "zmb_tombstone_spawn" ); + self playloopsound( "zmb_tombstone_looper" ); + } + while ( isDefined( self ) ) + { + self rotateyaw( 360, 3 ); + wait 2.9; + } +} + +tombstone_timeout() +{ + self endon( "tombstone_grabbed" ); + self thread playtombstonetimeraudio(); + wait 48.5; + i = 0; + while ( i < 40 ) + { + if ( i % 2 ) + { + self.icon ghost(); + } + else + { + self.icon show(); + } + if ( i < 15 ) + { + wait 0.5; + i++; + continue; + } + else if ( i < 25 ) + { + wait 0.25; + i++; + continue; + } + else + { + wait 0.1; + } + i++; + } + self notify( "tombstone_timedout" ); + self.icon unlink(); + self.icon delete(); + self delete(); +} + +playtombstonetimeraudio() +{ + self endon( "tombstone_grabbed" ); + self endon( "tombstone_timedout" ); + player = self.player; + self thread playtombstonetimerout( player ); + while ( 1 ) + { + player playsoundtoplayer( "zmb_tombstone_timer_count", player ); + wait 1; + } +} + +playtombstonetimerout( player ) +{ + self endon( "tombstone_grabbed" ); + self waittill( "tombstone_timedout" ); + player playsoundtoplayer( "zmb_tombstone_timer_out", player ); +} + +save_weapons_for_tombstone( player ) +{ + self.tombstone_melee_weapons = []; + i = 0; + while ( i < level._melee_weapons.size ) + { + self save_weapon_for_tombstone( player, level._melee_weapons[ i ].weapon_name ); + i++; + } +} + +save_weapon_for_tombstone( player, weapon_name ) +{ + if ( player hasweapon( weapon_name ) ) + { + self.tombstone_melee_weapons[ weapon_name ] = 1; + } +} + +restore_weapons_for_tombstone( player ) +{ + i = 0; + while ( i < level._melee_weapons.size ) + { + self restore_weapon_for_tombstone( player, level._melee_weapons[ i ].weapon_name ); + i++; + } + self.tombstone_melee_weapons = undefined; +} + +restore_weapon_for_tombstone( player, weapon_name ) +{ + if ( isDefined( weapon_name ) || !isDefined( self.tombstone_melee_weapons ) && !isDefined( self.tombstone_melee_weapons[ weapon_name ] ) ) + { + return; + } + if ( isDefined( self.tombstone_melee_weapons[ weapon_name ] ) && self.tombstone_melee_weapons[ weapon_name ] ) + { + player giveweapon( weapon_name ); + player change_melee_weapon( weapon_name, "none" ); + self.tombstone_melee_weapons[ weapon_name ] = 0; + } +} + +tombstone_hostmigration() +{ + level endon( "end_game" ); + level notify( "tombstone_hostmigration" ); + level endon( "tombstone_hostmigration" ); + while ( 1 ) + { + level waittill( "host_migration_end" ); + tombstones = getentarray( "player_tombstone_model", "script_noteworthy" ); + _a580 = tombstones; + _k580 = getFirstArrayKey( _a580 ); + while ( isDefined( _k580 ) ) + { + model = _a580[ _k580 ]; + playfxontag( level._effect[ "powerup_on" ], model, "tag_origin" ); + _k580 = getNextArrayKey( _a580, _k580 ); + } + } +} + +is_weapon_available_in_tombstone( weapon, player_to_check ) +{ + count = 0; + upgradedweapon = weapon; + if ( isDefined( level.zombie_weapons[ weapon ] ) && isDefined( level.zombie_weapons[ weapon ].upgrade_name ) ) + { + upgradedweapon = level.zombie_weapons[ weapon ].upgrade_name; + } + tombstone_index = 0; + while ( tombstone_index < level.tombstones.size ) + { + dc = level.tombstones[ tombstone_index ]; + if ( !isDefined( dc.weapon ) ) + { + tombstone_index++; + continue; + } + else if ( isDefined( player_to_check ) && dc.player != player_to_check ) + { + tombstone_index++; + continue; + } + else + { + weapon_index = 0; + while ( weapon_index < dc.weapon.size ) + { + if ( !isDefined( dc.weapon[ weapon_index ] ) ) + { + weapon_index++; + continue; + } + else + { + tombstone_weapon = dc.weapon[ weapon_index ]; + if ( tombstone_weapon == weapon || tombstone_weapon == upgradedweapon ) + { + count++; + } + } + weapon_index++; + } + } + tombstone_index++; + } + return count; +} + diff --git a/Fixed Zombies GSCs for compiling/readme.md b/Fixed Zombies GSCs for compiling/readme.md new file mode 100644 index 0000000..a670434 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/readme.md @@ -0,0 +1,25 @@ +**The following gscs compile and run successfully with no known errors:** +patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc +patch_zm/maps/mp/zombies/_zm_tombstone.gsc +patch_zm/maps/mp/zombies/_zm_bot.gsc +patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc +patch_zm/maps/mp/gametypes_zm/_shellshock.gsc + +zm_transit_patch/maps/mp/zm_transit_utility.gsc + +**The following scripts compile and run successfully with no known errors but required minor changes to run** +patch_zm/maps/mp/gametypes_zm/zclassic.gsc + +**The following scripts compile and run successfully with minor errors:** +zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc + +**The following scripts compile and run successfully with major errors:** +zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc + +**The following scripts compile but cause a minidump or other severe error:** +patch_zm/maps/mp/zombies/_zm.gsc +patch_zm/maps/mp/zombies/_zm_powerups.gsc +patch_zm/maps/mp/zombies/_zm_magicbox.gsc + +**notes:** +zm_transit_utility.gsc can be recompiled to fix tombstone diff --git a/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc new file mode 100644 index 0000000..4f993f4 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc @@ -0,0 +1,730 @@ +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_weap_cymbal_monkey; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_game_module_meat_utility; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/gametypes_zm/zmeat; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/_utility; +#include maps/mp/zombies/_zm_spawner; + +main() +{ + maps/mp/gametypes_zm/_zm_gametype::main(); + level.onprecachegametype = ::onprecachegametype; + level.onstartgametype = ::onstartgametype; + level.custom_spectate_permissions = ::setspectatepermissionsgrief; + level._game_module_custom_spawn_init_func = ::custom_spawn_init_func; + //level._game_module_stat_update_func = ::maps/mp/zombies/_zm_stats::grief_custom_stat_update; + level._game_module_player_damage_callback = ::game_module_player_damage_callback; + level.custom_end_screen = ::custom_end_screen; + level.gamemode_map_postinit[ "zgrief" ] = ::postinit_func; + level._supress_survived_screen = 1; + level.game_module_team_name_override_og_x = 155; + level.prevent_player_damage = ::player_prevent_damage; + level._game_module_player_damage_grief_callback = ::game_module_player_damage_grief_callback; + level._grief_reset_message = ::grief_reset_message; + level._game_module_player_laststand_callback = ::grief_laststand_weapon_save; + level.onplayerspawned_restore_previous_weapons = ::grief_laststand_weapons_return; + level.game_module_onplayerconnect = ::grief_onplayerconnect; + level.game_mode_spawn_player_logic = ::game_mode_spawn_player_logic; + level.game_mode_custom_onplayerdisconnect = ::grief_onplayerdisconnect; + maps/mp/gametypes_zm/_zm_gametype::post_gametype_main( "zgrief" ); +} + +grief_onplayerconnect() +{ + self thread move_team_icons(); + self thread zgrief_player_bled_out_msg(); +} + +grief_onplayerdisconnect( disconnecting_player ) +{ + level thread update_players_on_bleedout_or_disconnect( disconnecting_player ); +} + +setspectatepermissionsgrief() +{ + self allowspectateteam( "allies", 1 ); + self allowspectateteam( "axis", 1 ); + self allowspectateteam( "freelook", 0 ); + self allowspectateteam( "none", 1 ); +} + +custom_end_screen() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ].game_over_hud = newclienthudelem( players[ i ] ); + players[ i ].game_over_hud.alignx = "center"; + players[ i ].game_over_hud.aligny = "middle"; + players[ i ].game_over_hud.horzalign = "center"; + players[ i ].game_over_hud.vertalign = "middle"; + players[ i ].game_over_hud.y -= 130; + players[ i ].game_over_hud.foreground = 1; + players[ i ].game_over_hud.fontscale = 3; + players[ i ].game_over_hud.alpha = 0; + players[ i ].game_over_hud.color = ( 1, 1, 1 ); + players[ i ].game_over_hud.hidewheninmenu = 1; + players[ i ].game_over_hud settext( &"ZOMBIE_GAME_OVER" ); + players[ i ].game_over_hud fadeovertime( 1 ); + players[ i ].game_over_hud.alpha = 1; + if ( players[ i ] issplitscreen() ) + { + players[ i ].game_over_hud.fontscale = 2; + players[ i ].game_over_hud.y += 40; + } + players[ i ].survived_hud = newclienthudelem( players[ i ] ); + players[ i ].survived_hud.alignx = "center"; + players[ i ].survived_hud.aligny = "middle"; + players[ i ].survived_hud.horzalign = "center"; + players[ i ].survived_hud.vertalign = "middle"; + players[ i ].survived_hud.y -= 100; + players[ i ].survived_hud.foreground = 1; + players[ i ].survived_hud.fontscale = 2; + players[ i ].survived_hud.alpha = 0; + players[ i ].survived_hud.color = ( 1, 1, 1 ); + players[ i ].survived_hud.hidewheninmenu = 1; + if ( players[ i ] issplitscreen() ) + { + players[ i ].survived_hud.fontscale = 1.5; + players[ i ].survived_hud.y += 40; + } + winner_text = &"ZOMBIE_GRIEF_WIN"; + loser_text = &"ZOMBIE_GRIEF_LOSE"; + if ( level.round_number < 2 ) + { + winner_text = &"ZOMBIE_GRIEF_WIN_SINGLE"; + loser_text = &"ZOMBIE_GRIEF_LOSE_SINGLE"; + } + if ( isDefined( level.host_ended_game ) && level.host_ended_game ) + { + players[ i ].survived_hud settext( &"MP_HOST_ENDED_GAME" ); + } + else + { + if ( isDefined( level.gamemodulewinningteam ) && players[ i ]._encounters_team == level.gamemodulewinningteam ) + { + players[ i ].survived_hud settext( winner_text, level.round_number ); + break; + } + else + { + players[ i ].survived_hud settext( loser_text, level.round_number ); + } + } + players[ i ].survived_hud fadeovertime( 1 ); + players[ i ].survived_hud.alpha = 1; + i++; + } +} + +postinit_func() +{ + level.min_humans = 1; + level.zombie_ai_limit = 24; + level.prevent_player_damage = ::player_prevent_damage; + level.lock_player_on_team_score = 1; + level._zombie_spawning = 0; + level._get_game_module_players = undefined; + level.powerup_drop_count = 0; + level.is_zombie_level = 1; + setmatchtalkflag( "DeadChatWithDead", 1 ); + setmatchtalkflag( "DeadChatWithTeam", 1 ); + setmatchtalkflag( "DeadHearTeamLiving", 1 ); + setmatchtalkflag( "DeadHearAllLiving", 1 ); + setmatchtalkflag( "EveryoneHearsEveryone", 1 ); +} + +grief_game_end_check_func() +{ + return 0; +} + +player_prevent_damage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if ( isDefined( eattacker ) && isplayer( eattacker ) && self != eattacker && !eattacker hasperk( "specialty_noname" ) && isDefined( self.is_zombie ) && !self.is_zombie ) + { + return 1; + } + return 0; +} + +game_module_player_damage_grief_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + penalty = 10; + if ( isDefined( eattacker ) && isplayer( eattacker ) && eattacker != self && eattacker.team != self.team && smeansofdeath == "MOD_MELEE" ) + { + self applyknockback( idamage, vdir ); + } +} + +onprecachegametype() +{ + level.playersuicideallowed = 1; + level.suicide_weapon = "death_self_zm"; + precacheitem( "death_self_zm" ); + precacheshellshock( "grief_stab_zm" ); + precacheshader( "faction_cdc" ); + precacheshader( "faction_cia" ); + precacheshader( "waypoint_revive_cdc_zm" ); + precacheshader( "waypoint_revive_cia_zm" ); + level._effect[ "butterflies" ] = loadfx( "maps/zombie/fx_zmb_impact_noharm" ); + level thread maps/mp/gametypes_zm/_zm_gametype::init(); + maps/mp/gametypes_zm/_zm_gametype::rungametypeprecache( "zgrief" ); +} + +onstartgametype() +{ + level.no_end_game_check = 1; + level._game_module_game_end_check = ::grief_game_end_check_func; + level.round_end_custom_logic = ::grief_round_end_custom_logic; + maps/mp/gametypes_zm/_zm_gametype::setup_classic_gametype(); + maps/mp/gametypes_zm/_zm_gametype::rungametypemain( "zgrief", ::zgrief_main ); +} + +zgrief_main() +{ + level thread maps/mp/zombies/_zm::round_start(); + level thread maps/mp/gametypes_zm/_zm_gametype::kill_all_zombies(); + flag_wait( "initial_blackscreen_passed" ); + level thread maps/mp/zombies/_zm_game_module::wait_for_team_death_and_round_end(); + players = get_players(); + _a302 = players; + _k302 = getFirstArrayKey( _a302 ); + while ( isDefined( _k302 ) ) + { + player = _a302[ _k302 ]; + player.is_hotjoin = 0; + _k302 = getNextArrayKey( _a302, _k302 ); + } + wait 1; + playsoundatposition( "vox_zmba_grief_intro_0", ( 1, 1, 1 ) ); +} + +move_team_icons() +{ + self endon( "disconnect" ); + flag_wait( "initial_blackscreen_passed" ); + wait 0.5; +} + +kill_start_chest() +{ + flag_wait( "initial_blackscreen_passed" ); + wait 2; + start_chest = getstruct( "start_chest", "script_noteworthy" ); + start_chest maps/mp/zombies/_zm_magicbox::hide_chest(); +} + +door_close_zombie_think() +{ + self endon( "death" ); + while ( isalive( self ) ) + { + if ( isDefined( self.enemy ) && isplayer( self.enemy ) ) + { + insamezone = 0; + keys = getarraykeys( level.zones ); + i = 0; + while ( i < keys.size ) + { + if ( self maps/mp/zombies/_zm_zonemgr::entity_in_zone( keys[ i ] ) && self.enemy maps/mp/zombies/_zm_zonemgr::entity_in_zone( keys[ i ] ) ) + { + insamezone = 1; + } + i++; + } + while ( insamezone ) + { + wait 3; + } + nearestzombienode = getnearestnode( self.origin ); + nearestplayernode = getnearestnode( self.enemy.origin ); + if ( isDefined( nearestzombienode ) && isDefined( nearestplayernode ) ) + { + if ( !nodesvisible( nearestzombienode, nearestplayernode ) && !nodescanpath( nearestzombienode, nearestplayernode ) ) + { + self silentlyremovezombie(); + } + } + } + wait 1; + } +} + +silentlyremovezombie() +{ + level.zombie_total++; + playfx( level._effect[ "spawn_cloud" ], self.origin ); + self.skip_death_notetracks = 1; + self.nodeathragdoll = 1; + self dodamage( self.maxhealth * 2, self.origin, self, self, "none", "MOD_SUICIDE" ); + self self_delete(); +} + +zgrief_player_bled_out_msg() +{ + level endon( "end_game" ); + self endon( "disconnect" ); + while ( 1 ) + { + self waittill( "bled_out" ); + level thread update_players_on_bleedout_or_disconnect( self ); + } +} + +show_grief_hud_msg( msg, msg_parm, offset, cleanup_end_game ) +{ + self endon( "disconnect" ); + while ( isDefined( level.hostmigrationtimer ) ) + { + wait 0.05; + } + zgrief_hudmsg = newclienthudelem( self ); + zgrief_hudmsg.alignx = "center"; + zgrief_hudmsg.aligny = "middle"; + zgrief_hudmsg.horzalign = "center"; + zgrief_hudmsg.vertalign = "middle"; + zgrief_hudmsg.y -= 130; + if ( self issplitscreen() ) + { + zgrief_hudmsg.y += 70; + } + if ( isDefined( offset ) ) + { + zgrief_hudmsg.y += offset; + } + zgrief_hudmsg.foreground = 1; + zgrief_hudmsg.fontscale = 5; + zgrief_hudmsg.alpha = 0; + zgrief_hudmsg.color = ( 1, 1, 1 ); + zgrief_hudmsg.hidewheninmenu = 1; + zgrief_hudmsg.font = "default"; + if ( isDefined( cleanup_end_game ) && cleanup_end_game ) + { + level endon( "end_game" ); + zgrief_hudmsg thread show_grief_hud_msg_cleanup(); + } + if ( isDefined( msg_parm ) ) + { + zgrief_hudmsg settext( msg, msg_parm ); + } + else + { + zgrief_hudmsg settext( msg ); + } + zgrief_hudmsg changefontscaleovertime( 0.25 ); + zgrief_hudmsg fadeovertime( 0.25 ); + zgrief_hudmsg.alpha = 1; + zgrief_hudmsg.fontscale = 2; + wait 3.25; + zgrief_hudmsg changefontscaleovertime( 1 ); + zgrief_hudmsg fadeovertime( 1 ); + zgrief_hudmsg.alpha = 0; + zgrief_hudmsg.fontscale = 5; + wait 1; + zgrief_hudmsg notify( "death" ); + if ( isDefined( zgrief_hudmsg ) ) + { + zgrief_hudmsg destroy(); + } +} + +show_grief_hud_msg_cleanup() +{ + self endon( "death" ); + level waittill( "end_game" ); + if ( isDefined( self ) ) + { + self destroy(); + } +} + +grief_reset_message() +{ + msg = &"ZOMBIE_GRIEF_RESET"; + players = get_players(); + if ( isDefined( level.hostmigrationtimer ) ) + { + while ( isDefined( level.hostmigrationtimer ) ) + { + wait 0.05; + } + wait 4; + } + _a697 = players; + _k697 = getFirstArrayKey( _a697 ); + while ( isDefined( _k697 ) ) + { + player = _a697[ _k697 ]; + player thread show_grief_hud_msg( msg ); + _k697 = getNextArrayKey( _a697, _k697 ); + } + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "grief_restarted" ); +} + +grief_laststand_weapon_save( einflictor, attacker, idamage, smeansofdeath, sweapon, vdir, shitloc, psoffsettime, deathanimduration ) +{ + self.grief_savedweapon_weapons = self getweaponslist(); + self.grief_savedweapon_weaponsammo_stock = []; + self.grief_savedweapon_weaponsammo_clip = []; + self.grief_savedweapon_currentweapon = self getcurrentweapon(); + self.grief_savedweapon_grenades = self get_player_lethal_grenade(); + if ( isDefined( self.grief_savedweapon_grenades ) ) + { + self.grief_savedweapon_grenades_clip = self getweaponammoclip( self.grief_savedweapon_grenades ); + } + self.grief_savedweapon_tactical = self get_player_tactical_grenade(); + if ( isDefined( self.grief_savedweapon_tactical ) ) + { + self.grief_savedweapon_tactical_clip = self getweaponammoclip( self.grief_savedweapon_tactical ); + } + i = 0; + while ( i < self.grief_savedweapon_weapons.size ) + { + self.grief_savedweapon_weaponsammo_clip[ i ] = self getweaponammoclip( self.grief_savedweapon_weapons[ i ] ); + self.grief_savedweapon_weaponsammo_stock[ i ] = self getweaponammostock( self.grief_savedweapon_weapons[ i ] ); + i++; + } + if ( isDefined( self.hasriotshield ) && self.hasriotshield ) + { + self.grief_hasriotshield = 1; + } + if ( self hasweapon( "claymore_zm" ) ) + { + self.grief_savedweapon_claymore = 1; + self.grief_savedweapon_claymore_clip = self getweaponammoclip( "claymore_zm" ); + } + if ( isDefined( self.current_equipment ) ) + { + self.grief_savedweapon_equipment = self.current_equipment; + } +} + +grief_laststand_weapons_return() +{ + if ( isDefined( level.isresetting_grief ) && !level.isresetting_grief ) + { + return 0; + } + if ( !isDefined( self.grief_savedweapon_weapons ) ) + { + return 0; + } + primary_weapons_returned = 0; + _a766 = self.grief_savedweapon_weapons; + index = getFirstArrayKey( _a766 ); + while ( isDefined( index ) ) + { + weapon = _a766[ index ]; + if ( isDefined( self.grief_savedweapon_grenades ) || weapon == self.grief_savedweapon_grenades && isDefined( self.grief_savedweapon_tactical ) && weapon == self.grief_savedweapon_tactical ) + { + } + else + { + if ( isweaponprimary( weapon ) ) + { + if ( primary_weapons_returned >= 2 ) + { + break; + } + else primary_weapons_returned++; + } + if ( weapon == "item_meat_zm" ) + { + break; + } + else + { + self giveweapon( weapon, 0, self maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + if ( isDefined( self.grief_savedweapon_weaponsammo_clip[ index ] ) ) + { + self setweaponammoclip( weapon, self.grief_savedweapon_weaponsammo_clip[ index ] ); + } + if ( isDefined( self.grief_savedweapon_weaponsammo_stock[ index ] ) ) + { + self setweaponammostock( weapon, self.grief_savedweapon_weaponsammo_stock[ index ] ); + } + } + } + index = getNextArrayKey( _a766, index ); + } + if ( isDefined( self.grief_savedweapon_grenades ) ) + { + self giveweapon( self.grief_savedweapon_grenades ); + if ( isDefined( self.grief_savedweapon_grenades_clip ) ) + { + self setweaponammoclip( self.grief_savedweapon_grenades, self.grief_savedweapon_grenades_clip ); + } + } + if ( isDefined( self.grief_savedweapon_tactical ) ) + { + self giveweapon( self.grief_savedweapon_tactical ); + if ( isDefined( self.grief_savedweapon_tactical_clip ) ) + { + self setweaponammoclip( self.grief_savedweapon_tactical, self.grief_savedweapon_tactical_clip ); + } + } + if ( isDefined( self.current_equipment ) ) + { + self maps/mp/zombies/_zm_equipment::equipment_take( self.current_equipment ); + } + if ( isDefined( self.grief_savedweapon_equipment ) ) + { + self.do_not_display_equipment_pickup_hint = 1; + self maps/mp/zombies/_zm_equipment::equipment_give( self.grief_savedweapon_equipment ); + self.do_not_display_equipment_pickup_hint = undefined; + } + if ( isDefined( self.grief_hasriotshield ) && self.grief_hasriotshield ) + { + if ( isDefined( self.player_shield_reset_health ) ) + { + self [[ self.player_shield_reset_health ]](); + } + } + if ( isDefined( self.grief_savedweapon_claymore ) && self.grief_savedweapon_claymore ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", self.grief_savedweapon_claymore_clip ); + } + primaries = self getweaponslistprimaries(); + _a859 = primaries; + _k859 = getFirstArrayKey( _a859 ); + while ( isDefined( _k859 ) ) + { + weapon = _a859[ _k859 ]; + if ( isDefined( self.grief_savedweapon_currentweapon ) && self.grief_savedweapon_currentweapon == weapon ) + { + self switchtoweapon( weapon ); + return 1; + } + _k859 = getNextArrayKey( _a859, _k859 ); + } + if ( primaries.size > 0 ) + { + self switchtoweapon( primaries[ 0 ] ); + return 1; + } + return 0; +} + +grief_store_player_scores() +{ + players = get_players(); + _a883 = players; + _k883 = getFirstArrayKey( _a883 ); + while ( isDefined( _k883 ) ) + { + player = _a883[ _k883 ]; + player._pre_round_score = player.score; + _k883 = getNextArrayKey( _a883, _k883 ); + } +} + +grief_restore_player_score() +{ + if ( !isDefined( self._pre_round_score ) ) + { + self._pre_round_score = self.score; + } + if ( isDefined( self._pre_round_score ) ) + { + self.score = self._pre_round_score; + self.pers[ "score" ] = self._pre_round_score; + } +} + +game_mode_spawn_player_logic() +{ + if ( flag( "start_zombie_round_logic" ) && !isDefined( self.is_hotjoin ) ) + { + self.is_hotjoin = 1; + return 1; + } + return 0; +} + +update_players_on_bleedout_or_disconnect( excluded_player ) +{ + other_team = undefined; + players = get_players(); + players_remaining = 0; + _a920 = players; + _k920 = getFirstArrayKey( _a920 ); + while ( isDefined( _k920 ) ) + { + player = _a920[ _k920 ]; + if ( player == excluded_player ) + { + } + else if ( player.team == excluded_player.team ) + { + if ( is_player_valid( player ) ) + { + players_remaining++; + } + break; + } + _k920 = getNextArrayKey( _a920, _k920 ); + } + _a937 = players; + _k937 = getFirstArrayKey( _a937 ); + while ( isDefined( _k937 ) ) + { + player = _a937[ _k937 ]; + if ( player == excluded_player ) + { + } + else if ( player.team != excluded_player.team ) + { + other_team = player.team; + if ( players_remaining < 1 ) + { + player thread show_grief_hud_msg( &"ZOMBIE_ZGRIEF_ALL_PLAYERS_DOWN", undefined, undefined, 1 ); + player delay_thread_watch_host_migrate( 2, ::show_grief_hud_msg, &"ZOMBIE_ZGRIEF_SURVIVE", undefined, 30, 1 ); + break; + } + else + { + player thread show_grief_hud_msg( &"ZOMBIE_ZGRIEF_PLAYER_BLED_OUT", players_remaining ); + } + } + _k937 = getNextArrayKey( _a937, _k937 ); + } + if ( players_remaining == 1 ) + { + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "last_player", excluded_player.team ); + } + if ( !isDefined( other_team ) ) + { + return; + } + if ( players_remaining < 1 ) + { + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "4_player_down", other_team ); + } + else + { + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( players_remaining + "_player_left", other_team ); + } +} + +delay_thread_watch_host_migrate( timer, func, param1, param2, param3, param4, param5, param6 ) +{ + self thread _delay_thread_watch_host_migrate_proc( func, timer, param1, param2, param3, param4, param5, param6 ); +} + +_delay_thread_watch_host_migrate_proc( func, timer, param1, param2, param3, param4, param5, param6 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + wait timer; + if ( isDefined( level.hostmigrationtimer ) ) + { + while ( isDefined( level.hostmigrationtimer ) ) + { + wait 0.05; + } + wait timer; + } + single_thread( self, func, param1, param2, param3, param4, param5, param6 ); +} + +grief_round_end_custom_logic() +{ + waittillframeend; + if ( isDefined( level.gamemodulewinningteam ) ) + { + level notify( "end_round_think" ); + } +} + +custom_spawn_init_func() +{ + array_thread( level.zombie_spawners, ::add_spawn_function, ::zombie_spawn_init ); + array_thread( level.zombie_spawners, ::add_spawn_function, level._zombies_round_spawn_failsafe ); +} + +game_module_player_damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + self.last_damage_from_zombie_or_player = 0; + if ( isDefined( eattacker ) ) + { + if ( isplayer( eattacker ) && eattacker == self ) + { + return; + } + if ( isDefined( eattacker.is_zombie ) || eattacker.is_zombie && isplayer( eattacker ) ) + { + self.last_damage_from_zombie_or_player = 1; + } + } + if ( isDefined( self._being_shellshocked ) || self._being_shellshocked && self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + return; + } + if ( isplayer( eattacker ) && isDefined( eattacker._encounters_team ) && eattacker._encounters_team != self._encounters_team ) + { + if ( isDefined( self.hasriotshield ) && self.hasriotshield && isDefined( vdir ) ) + { + if ( isDefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( self maps/mp/zombies/_zm::player_shield_facing_attacker( vdir, 0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + return; + } + } + else + { + if ( !isDefined( self.riotshieldentity ) ) + { + if ( !self maps/mp/zombies/_zm::player_shield_facing_attacker( vdir, -0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + return; + } + } + } + } + if ( isDefined( level._game_module_player_damage_grief_callback ) ) + { + self [[ level._game_module_player_damage_grief_callback ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + if ( isDefined( level._effect[ "butterflies" ] ) ) + { + if ( isDefined( sweapon ) && weapontype( sweapon ) == "grenade" ) + { + playfx( level._effect[ "butterflies" ], self.origin + vectorScale( ( 1, 1, 1 ), 40 ) ); + } + else + { + playfx( level._effect[ "butterflies" ], vpoint, vdir ); + } + } + self thread do_game_mode_shellshock(); + self playsound( "zmb_player_hit_ding" ); + } +} + +do_game_mode_shellshock() +{ + self endon( "disconnect" ); + self._being_shellshocked = 1; + self shellshock( "grief_stab_zm", 0,75 ); + wait 0.75; + self._being_shellshocked = 0; +} diff --git a/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zm_transit_utility.gsc b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zm_transit_utility.gsc new file mode 100644 index 0000000..375f18f --- /dev/null +++ b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zm_transit_utility.gsc @@ -0,0 +1,279 @@ +#include maps/mp/_compass; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +playercanafford( player, cost ) +{ + if ( !player usebuttonpressed() ) + { + return 0; + } + if ( player in_revive_trigger() ) + { + return 0; + } + if ( isDefined( cost ) ) + { + if ( player.score < cost ) + { + return 0; + } + player maps/mp/zombies/_zm_score::minus_to_player_score( cost ); + } + return 1; +} + +setinvisibletoall() +{ + players = get_players(); + playerindex = 0; + while ( playerindex < players.size ) + { + self setinvisibletoplayer( players[ playerindex ] ); + playerindex++; + } +} + +spawnandlinkfxtotag( effect, ent, tag ) +{ + fxent = spawn( "script_model", ent gettagorigin( tag ) ); + fxent setmodel( "tag_origin" ); + fxent linkto( ent, tag ); + wait_network_frame(); + playfxontag( effect, fxent, "tag_origin" ); + return fxent; +} + +spawnandlinkfxtooffset( effect, ent, offsetorigin, offsetangles ) +{ + fxent = spawn( "script_model", ( 0, 0, 0 ) ); + fxent setmodel( "tag_origin" ); + fxent linkto( ent, "", offsetorigin, offsetangles ); + wait_network_frame(); + playfxontag( effect, fxent, "tag_origin" ); + return fxent; +} + +custom_weapon_wall_prices() +{ + if ( !isDefined( level.zombie_include_weapons ) ) + { + return; + } + weapon_spawns = []; + weapon_spawns = getentarray( "weapon_upgrade", "targetname" ); + i = 0; + while ( i < weapon_spawns.size ) + { + if ( !isDefined( level.zombie_weapons[ weapon_spawns[ i ].zombie_weapon_upgrade ] ) ) + { + i++; + continue; + } + else + { + if ( isDefined( weapon_spawns[ i ].script_int ) ) + { + cost = weapon_spawns[ i ].script_int; + level.zombie_weapons[ weapon_spawns[ i ].zombie_weapon_upgrade ].cost = cost; + } + } + i++; + } +} + +pause_zombie_spawning() +{ + if ( !isDefined( level.spawnpausecount ) ) + { + level.spawnpausecount = 0; + } + level.spawnpausecount++; + flag_clear( "spawn_zombies" ); +} + +try_resume_zombie_spawning() +{ + if ( !isDefined( level.spawnpausecount ) ) + { + level.spawnpausecount = 0; + } + level.spawnpausecount--; + + if ( level.spawnpausecount <= 0 ) + { + level.spawnpausecount = 0; + flag_set( "spawn_zombies" ); + } +} + +automatonspeak( category, type, response, force_variant, override ) +{ + if ( isDefined( level.automaton ) && !is_true( level.automaton.disabled_by_emp ) ) + { + if ( type != "leaving" && type != "leaving_warning" ) + { + level.automaton notify( "want_to_be_speaking" ); + level.automaton waittill( "startspeaking" ); + } + level.automaton maps/mp/zombies/_zm_audio::create_and_play_dialog( category, type, response, force_variant, override ); + } +} + +is_thedouche() +{ + return self.characterindex == 0; +} + +is_theconspiracytheorist() +{ + return self.characterindex == 1; +} + +is_thefarmersdaughter() +{ + return self.characterindex == 2; +} + +is_theelectricalengineer() +{ + return self.characterindex == 3; +} + +get_random_encounter_match( location ) +{ + match_pool = []; + return random( match_pool ); +} + +transit_breakable_glass_init() +{ + glass = getentarray( "transit_glass", "targetname" ); + if ( level.splitscreen && getDvarInt( "splitscreen_playerCount" ) > 2 ) + { + array_delete( glass ); + return; + } + array_thread( glass, ::transit_breakable_glass ); +} + +transit_breakable_glass() +{ + level endon( "intermission" ); + self.health = 99999; + self setcandamage( 1 ); + self.damage_state = 0; + while ( 1 ) + { + self waittill( "damage", amount, attacker, direction, point, dmg_type ); + if ( isplayer( attacker ) ) + { + if ( self.damage_state == 0 ) + { + self glass_gets_destroyed(); + self.damage_state = 1; + self playsound( "fly_glass_break" ); + } + } + } +} + +glass_gets_destroyed() +{ + if ( isDefined( level._effect[ "glass_impact" ] ) ) + { + playfx( level._effect[ "glass_impact" ], self.origin, anglesToForward( self.angles ) ); + } + wait 0.1; + if ( isDefined( self.model ) && self.damage_state == 0 ) + { + self setmodel( self.model + "_broken" ); + self.damage_state = 1; + return; + } + else + { + self delete(); + return; + } +} + +solo_tombstone_removal() +{ + if ( getnumexpectedplayers() > 1 ) + { + return; + } + level notify( "tombstone_removed" ); + level thread maps/mp/zombies/_zm_perks::perk_machine_removal( "specialty_scavenger" ); +} + +sparking_power_lines() +{ + lines = getentarray( "power_line_sparking", "targetname" ); +} + +disconnect_door_zones( zone_a, zone_b, flag_name ) +{ + level endon( "intermission" ); + level endon( "end_game" ); + while ( 1 ) + { + flag_wait( flag_name ); + azone = level.zones[ zone_a ].adjacent_zones[ zone_b ]; + azone maps/mp/zombies/_zm_zonemgr::door_close_disconnect( flag_name ); + } +} + +enable_morse_code() +{ + level clientnotify( "mc1" ); +} + +disable_morse_code() +{ + level clientnotify( "mc0" ); +} + +transit_pathnode_spawning() +{ + precachemodel( "collision_wall_128x128x10_standard" ); + precachemodel( "collision_wall_256x256x10_standard" ); + precachemodel( "collision_clip_64x64x256" ); + minimap_upperl = spawn( "script_origin", ( -12248, 9496, 552 ) ); + minimap_upperl.targetname = "minimap_corner"; + minimap_lowerr = spawn( "script_origin", ( 14472, -8496, -776 ) ); + minimap_lowerr.targetname = "minimap_corner"; + maps/mp/_compass::setupminimap( "compass_map_zm_transit" ); + flag_wait( "start_zombie_round_logic" ); + collision1 = spawn( "script_model", ( 2273, -126, 143 ) ); + collision1 setmodel( "collision_wall_128x128x10_standard" ); + collision1.angles = ( 0, 0, 0 ); + collision1 ghost(); + collision2 = spawn( "script_model", ( 2096, -126, 143 ) ); + collision2 setmodel( "collision_wall_128x128x10_standard" ); + collision2.angles = ( 0, 0, 0 ); + collision2 ghost(); + collision3 = spawn( "script_model", ( 1959, -126, 143 ) ); + collision3 setmodel( "collision_wall_128x128x10_standard" ); + collision3.angles = ( 0, 0, 0 ); + collision3 ghost(); + collision4 = spawn( "script_model", ( 12239, 8509, -688 ) ); + collision4 setmodel( "collision_wall_128x128x10_standard" ); + collision4.angles = ( 0, 0, 0 ); + collision4 ghost(); + collision5 = spawn( "script_model", ( 8320, -6679, 362 ) ); + collision5 setmodel( "collision_wall_256x256x10_standard" ); + collision5.angles = vectorScale( ( 0, 0, 0 ), 300 ); + collision5 ghost(); + collision5 = spawn( "script_model", ( 10068, 7272, -67 ) ); + collision5 setmodel( "collision_clip_64x64x256" ); + collision5.angles = ( 0, 0, 0 ); + collision5 ghost(); +} + diff --git a/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc new file mode 100644 index 0000000..23554ea --- /dev/null +++ b/Fixed Zombies GSCs for compiling/zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc @@ -0,0 +1,935 @@ +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_buildables; +#include maps/mp/gametypes_zm/_weaponobjects; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +init() +{ + if ( !maps/mp/zombies/_zm_weapons::is_weapon_included( "jetgun_zm" ) ) + { + return; + } + maps/mp/zombies/_zm_equipment::register_equipment( "jetgun_zm", &"ZOMBIE_EQUIP_JETGUN_PICKUP_HINT_STRING", &"ZOMBIE_EQUIP_JETGUN_HOWTO", "jetgun_zm_icon", "jetgun", ::jetgun_activation_watcher_thread, undefined, ::dropjetgun, ::pickupjetgun ); + maps/mp/gametypes_zm/_weaponobjects::createretrievablehint( "jetgun", &"ZOMBIE_EQUIP_JETGUN_PICKUP_HINT_STRING" ); + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + level._effect[ "jetgun_overheat" ] = loadfx( "weapon/jet_gun/fx_jetgun_overheat" ); + level._effect[ "jetgun_vortex" ] = loadfx( "weapon/jet_gun/fx_jetgun_on" ); + level._effect[ "jetgun_meat_grinder" ] = loadfx( "weapon/jet_gun/fx_jetgun_kill" ); + set_zombie_var( "jetgun_cylinder_radius", 1024 ); + set_zombie_var( "jetgun_grind_range", 128 ); + set_zombie_var( "jetgun_gib_range", 256 ); + set_zombie_var( "jetgun_gib_damage", 50 ); + set_zombie_var( "jetgun_knockdown_range", 256 ); + set_zombie_var( "jetgun_drag_range", 2048 ); + set_zombie_var( "jetgun_knockdown_damage", 15 ); + set_zombie_var( "powerup_move_dist", 50 ); + set_zombie_var( "powerup_drag_range", 500 ); + level.jetgun_pulled_in_range = int( level.zombie_vars[ "jetgun_drag_range" ] / 8 ) * ( level.zombie_vars[ "jetgun_drag_range" ] / 8 ); + level.jetgun_pulling_in_range = int( level.zombie_vars[ "jetgun_drag_range" ] / 4 ) * ( level.zombie_vars[ "jetgun_drag_range" ] / 4 ); + level.jetgun_inner_range = int( level.zombie_vars[ "jetgun_drag_range" ] / 2 ) * ( level.zombie_vars[ "jetgun_drag_range" ] / 2 ); + level.jetgun_outer_edge = int( level.zombie_vars[ "jetgun_drag_range" ] * level.zombie_vars[ "jetgun_drag_range" ] ); + level.jetgun_gib_refs = []; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "guts"; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "right_arm"; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "left_arm"; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "right_leg"; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "left_leg"; + level.jetgun_gib_refs[ level.jetgun_gib_refs.size ] = "no_legs"; + /* +/# + level thread jetgun_devgui_dvar_think(); + level.zm_devgui_jetgun_never_overheat = ::never_overheat; +#/ + */ + onplayerconnect_callback( ::jetgun_on_player_connect ); +} + +dropjetgun() +{ + item = self maps/mp/zombies/_zm_equipment::placed_equipment_think( "t6_wpn_zmb_jet_gun_world", "jetgun_zm", self.origin + vectorScale( ( 1, 0, 1 ), 30 ), self.angles ); + if ( isDefined( item ) ) + { + item.overheating = self.jetgun_overheating; + item.heatval = self.jetgun_heatval; + item.original_owner = self; + item.owner = undefined; + item.name = "jetgun_zm"; + item.requires_pickup = 1; + } + self.jetgun_overheating = undefined; + self.jetgun_heatval = undefined; + self takeweapon( "jetgun_zm" ); + return item; +} + +pickupjetgun( item ) +{ + item.owner = self; + if ( isDefined( item.overheating ) && isDefined( item.heatval ) ) + { + self.jetgun_overheating = item.overheating; + self.jetgun_heatval = item.heatval; + } + item.overheating = undefined; + item.heatval = undefined; + self setcurrentweaponspinlerp( 0 ); +} + +jetgun_activation_watcher_thread() +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self endon( "jetgun_zm_taken" ); + while ( 1 ) + { + self waittill_either( "jetgun_zm_activate", "jetgun_zm_deactivate" ); + } +} + +jetgun_devgui_dvar_think() +{ +/* +/# + if ( !maps/mp/zombies/_zm_weapons::is_weapon_included( "jetgun_zm" ) ) + { + return; + } + setdvar( "scr_jetgun_cylinder_radius", level.zombie_vars[ "jetgun_cylinder_radius" ] ); + setdvar( "scr_jetgun_grind_range", level.zombie_vars[ "jetgun_grind_range" ] ); + setdvar( "scr_jetgun_drag_range", level.zombie_vars[ "jetgun_drag_range" ] ); + setdvar( "scr_jetgun_gib_range", level.zombie_vars[ "jetgun_gib_range" ] ); + setdvar( "scr_jetgun_gib_damage", level.zombie_vars[ "jetgun_gib_damage" ] ); + setdvar( "scr_jetgun_knockdown_range", level.zombie_vars[ "jetgun_knockdown_range" ] ); + setdvar( "scr_jetgun_knockdown_damage", level.zombie_vars[ "jetgun_knockdown_damage" ] ); + for ( ;; ) + { + level.zombie_vars[ "jetgun_cylinder_radius" ] = getDvarInt( "scr_jetgun_cylinder_radius" ); + level.zombie_vars[ "jetgun_grind_range" ] = getDvarInt( "scr_jetgun_grind_range" ); + level.zombie_vars[ "jetgun_drag_range" ] = getDvarInt( "scr_jetgun_drag_range" ); + level.zombie_vars[ "jetgun_gib_range" ] = getDvarInt( "scr_jetgun_gib_range" ); + level.zombie_vars[ "jetgun_gib_damage" ] = getDvarInt( "scr_jetgun_gib_damage" ); + level.zombie_vars[ "jetgun_knockdown_range" ] = getDvarInt( "scr_jetgun_knockdown_range" ); + level.zombie_vars[ "jetgun_knockdown_damage" ] = getDvarInt( "scr_jetgun_knockdown_damage" ); + wait 0.5; + } +#/ +*/ +} + +jetgun_on_player_connect() +{ + self thread wait_for_jetgun_fired(); + self thread watch_weapon_changes(); + self thread handle_overheated_jetgun(); +} + +get_jetgun_engine_direction() +{ + return self getcurrentweaponspinlerp(); +} + +set_jetgun_engine_direction( nv ) +{ + self setcurrentweaponspinlerp( nv ); +} + +never_overheat() +{ +/* +/# + self notify( "never_overheat" ); + self endon( "never_overheat" ); + self endon( "death_or_disconnect" ); + while ( 1 ) + { + if ( self getcurrentweapon() == "jetgun_zm" ) + { + self setweaponoverheating( 0, 0 ); + } + wait 0.05; + + } +#/ +*/ +} + +watch_overheat() +{ + self endon( "death_or_disconnect" ); + self endon( "weapon_change" ); + if ( self getcurrentweapon() == "jetgun_zm" && isDefined( self.jetgun_overheating ) && isDefined( self.jetgun_heatval ) ) + { + self setweaponoverheating( self.jetgun_overheating, self.jetgun_heatval ); + } + while ( 1 ) + { + if ( self getcurrentweapon() == "jetgun_zm" ) + { + overheating = self isweaponoverheating( 0 ); + heat = self isweaponoverheating( 1 ); + self.jetgun_overheating = overheating; + self.jetgun_heatval = heat; + if ( overheating ) + { + self notify( "jetgun_overheated" ); + } + if ( heat > 75 ) + { + self thread play_overheat_fx(); + } + } + wait 0.05; + } +} + +play_overheat_fx() +{ + if ( isDefined( self.overheat_fx_playing ) && !self.overheat_fx_playing ) + { + self.overheat_fx_playing = 1; + playfxontag( level._effect[ "jetgun_overheat" ], self, "tag_flash" ); + wait 5; + if ( isDefined( self ) ) + { + self.overheat_fx_playing = 0; + } + } +} + +handle_overheated_jetgun() +{ + self endon( "disconnect" ); + while ( 1 ) + { + self waittill( "jetgun_overheated" ); + if ( self getcurrentweapon() == "jetgun_zm" ) + { + if ( isDefined( level.explode_overheated_jetgun ) && level.explode_overheated_jetgun ) + { + self thread maps/mp/zombies/_zm_equipment::equipment_release( "jetgun_zm" ); + weapon_org = self gettagorigin( "tag_weapon" ); + pcount = get_players().size; + pickup_time = 360 / pcount; + maps/mp/zombies/_zm_buildables::player_explode_buildable( "jetgun_zm", weapon_org, 250, 1, pickup_time ); + self.jetgun_overheating = undefined; + self.jetgun_heatval = undefined; + self playsound( "wpn_jetgun_explo" ); + break; + } + else + { + if ( isDefined( level.unbuild_overheated_jetgun ) && level.unbuild_overheated_jetgun ) + { + self thread maps/mp/zombies/_zm_equipment::equipment_release( "jetgun_zm" ); + maps/mp/zombies/_zm_buildables::unbuild_buildable( "jetgun_zm", 1 ); + self.jetgun_overheating = undefined; + self.jetgun_heatval = undefined; + break; + } + else + { + if ( isDefined( level.take_overheated_jetgun ) && level.take_overheated_jetgun ) + { + self thread maps/mp/zombies/_zm_equipment::equipment_release( "jetgun_zm" ); + self.jetgun_overheating = undefined; + self.jetgun_heatval = undefined; + } + } + } + } + } +} + +watch_weapon_changes() +{ + self endon( "disconnect" ); + for ( ;; ) + { + self waittill( "weapon_change", weapon ); + if ( weapon == "jetgun_zm" ) + { + /* +/# + if ( getDvarInt( #"BCDDAAFF" ) > 0 ) + { + self thread zombie_drag_radius(); + + } +#/ + */ + self thread watch_overheat(); + } + } +} + +wait_for_jetgun_fired() +{ + self endon( "disconnect" ); + self waittill( "spawned_player" ); + for ( ;; ) + { + self waittill( "weapon_fired" ); + currentweapon = self getcurrentweapon(); + if ( currentweapon == "jetgun_zm" || currentweapon == "jetgun_upgraded_zm" ) + { + self jetgun_firing(); + } + } +} + +jetgun_network_choke() +{ + level.jetgun_network_choke_count++; + if ( level.jetgun_network_choke_count % 10 ) + { + wait_network_frame(); + wait_network_frame(); + wait_network_frame(); + } +} + +is_jetgun_firing() +{ + return abs( self get_jetgun_engine_direction() ) > 0.2; +} + +jetgun_firing() +{ + if ( !isDefined( self.jetsound_ent ) ) + { + self.jetsound_ent = spawn( "script_origin", self.origin ); + self.jetsound_ent linkto( self, "tag_origin" ); + } + jetgun_fired = 0; + if ( self is_jetgun_firing() && jetgun_fired == 0 ) + { + self.jetsound_ent playloopsound( "wpn_jetgun_effect_plr_loop", 0.8 ); + self.jetsound_ent playsound( "wpn_jetgun_effect_plr_start" ); + self notify( "jgun_snd" ); + } + while ( self is_jetgun_firing() ) + { + jetgun_fired = 1; + self thread jetgun_fired(); + view_pos = self gettagorigin( "tag_flash" ); + view_angles = self gettagangles( "tag_flash" ); + if ( self get_jetgun_engine_direction() < 0 ) + { + playfx( level._effect[ "jetgun_smoke_cloud" ], view_pos - self getplayerviewheight(), anglesToForward( view_angles ), anglesToUp( view_angles ) ); + } + else + { + playfx( level._effect[ "jetgun_smoke_cloud" ], view_pos - self getplayerviewheight(), anglesToForward( view_angles ) * -1, anglesToUp( view_angles ) ); + } + wait 0.25; + } + if ( jetgun_fired == 1 ) + { + self.jetsound_ent stoploopsound( 0.5 ); + self.jetsound_ent playsound( "wpn_jetgun_effect_plr_end" ); + self.jetsound_ent thread sound_ent_cleanup(); + jetgun_fired = 0; + } +} + +sound_ent_cleanup() +{ + self endon( "jgun_snd" ); + wait 4; + if ( isDefined( self.jetsound_ent ) ) + { + self delete(); + } +} + +jetgun_fired() +{ + if ( !self is_jetgun_firing() ) + { + return; + } + origin = self getweaponmuzzlepoint(); + physicsjetthrust( origin, self getweaponforwarddir() * -1, level.zombie_vars[ "jetgun_grind_range" ], self get_jetgun_engine_direction(), 0.85 ); + if ( !isDefined( level.jetgun_knockdown_enemies ) ) + { + level.jetgun_knockdown_enemies = []; + level.jetgun_knockdown_gib = []; + level.jetgun_drag_enemies = []; + level.jetgun_fling_enemies = []; + level.jetgun_grind_enemies = []; + } + powerups = maps/mp/zombies/_zm_powerups::get_powerups(); + if ( isDefined( powerups ) && powerups.size ) + { + self thread try_pull_powerups( powerups ); + } + self jetgun_get_enemies_in_range( self get_jetgun_engine_direction() ); + level.jetgun_network_choke_count = 0; + _a408 = level.jetgun_fling_enemies; + index = getFirstArrayKey( _a408 ); + while ( isDefined( index ) ) + { + zombie = _a408[ index ]; + jetgun_network_choke(); + if ( isDefined( zombie ) ) + { + zombie thread jetgun_fling_zombie( self, index ); + } + index = getNextArrayKey( _a408, index ); + } + _a418 = level.jetgun_drag_enemies; + _k418 = getFirstArrayKey( _a418 ); + while ( isDefined( _k418 ) ) + { + zombie = _a418[ _k418 ]; + jetgun_network_choke(); + if ( isDefined( zombie ) ) + { + zombie.jetgun_owner = self; + zombie thread jetgun_drag_zombie( origin, -1 * self get_jetgun_engine_direction() ); + } + _k418 = getNextArrayKey( _a418, _k418 ); + } + level.jetgun_knockdown_enemies = []; + level.jetgun_knockdown_gib = []; + level.jetgun_drag_enemies = []; + level.jetgun_fling_enemies = []; + level.jetgun_grind_enemies = []; +} + +try_pull_powerups( powerups ) +{ + powerup_move_dist = level.zombie_vars[ "powerup_move_dist" ] * -1 * self get_jetgun_engine_direction(); + powerup_range_squared = level.zombie_vars[ "powerup_drag_range" ] * level.zombie_vars[ "powerup_drag_range" ]; + view_pos = self getweaponmuzzlepoint(); + forward_view_angles = self getweaponforwarddir(); + _a453 = powerups; + _k453 = getFirstArrayKey( _a453 ); + while ( isDefined( _k453 ) ) + { + powerup = _a453[ _k453 ]; + if ( distancesquared( view_pos, powerup.origin ) > powerup_range_squared ) + { + } + else normal = vectornormalize( powerup.origin - view_pos ); + dot = vectordot( forward_view_angles, normal ); + if ( abs( dot ) < 0.7 ) + { + } + else + { + powerup notify( "move_powerup" ); + } + _k453 = getNextArrayKey( _a453, _k453 ); + } +} + +jetgun_get_enemies_in_range( invert ) +{ + view_pos = self getweaponmuzzlepoint(); + zombies = get_array_of_closest( view_pos, get_round_enemy_array(), undefined, 3, level.zombie_vars[ "jetgun_drag_range" ] ); + if ( !isDefined( zombies ) ) + { + } + knockdown_range_squared = level.zombie_vars[ "jetgun_knockdown_range" ] * level.zombie_vars[ "jetgun_knockdown_range" ]; + drag_range_squared = level.zombie_vars[ "jetgun_drag_range" ] * level.zombie_vars[ "jetgun_drag_range" ]; + gib_range_squared = level.zombie_vars[ "jetgun_gib_range" ] * level.zombie_vars[ "jetgun_gib_range" ]; + grind_range_squared = level.zombie_vars[ "jetgun_grind_range" ] * level.zombie_vars[ "jetgun_grind_range" ]; + cylinder_radius_squared = level.zombie_vars[ "jetgun_cylinder_radius" ] * level.zombie_vars[ "jetgun_cylinder_radius" ]; + forward_view_angles = self getweaponforwarddir(); + end_pos = view_pos + vectorScale( forward_view_angles, level.zombie_vars[ "jetgun_knockdown_range" ] ); + /* +/# + if ( getDvarInt( #"BCDDAAFF" ) == 2 ) + { + near_circle_pos = view_pos + vectorScale( forward_view_angles, 2 ); + circle( near_circle_pos, level.zombie_vars[ "jetgun_cylinder_radius" ], ( 1, 0, 1 ), 0, 0, 100 ); + line( near_circle_pos, end_pos, ( 1, 0, 1 ), 1, 0, 100 ); + circle( end_pos, level.zombie_vars[ "jetgun_cylinder_radius" ], ( 1, 0, 1 ), 0, 0, 100 ); + + } +#/ + */ + i = 0; + while ( i < zombies.size ) + { + self jetgun_check_enemies_in_range( zombies[ i ], view_pos, drag_range_squared, gib_range_squared, grind_range_squared, cylinder_radius_squared, forward_view_angles, end_pos, invert ); + i++; + } +} + +jetgun_check_enemies_in_range( zombie, view_pos, drag_range_squared, gib_range_squared, grind_range_squared, cylinder_radius_squared, forward_view_angles, end_pos, invert ) +{ + if ( !isDefined( zombie ) ) + { + return; + } + if ( !isDefined( zombie ) ) + { + return; + } + if ( zombie enemy_killed_by_jetgun() ) + { + return; + } + if ( !isDefined( zombie.ai_state ) || zombie.ai_state != "find_flesh" && zombie.ai_state != "zombieMoveOnBus" ) + { + return; + } + if ( isDefined( zombie.in_the_ground ) && zombie.in_the_ground ) + { + return; + } + if ( isDefined( zombie.is_avogadro ) && zombie.is_avogadro ) + { + return; + } + if ( isDefined( zombie.isdog ) && zombie.isdog ) + { + return; + } + if ( isDefined( zombie.isscreecher ) && zombie.isscreecher ) + { + return; + } + if ( isDefined( self.animname ) && self.animname == "quad_zombie" ) + { + return; + } + test_origin = zombie getcentroid(); + test_range_squared = distancesquared( view_pos, test_origin ); + if ( test_range_squared > drag_range_squared ) + { + zombie jetgun_debug_print( "range", ( 1, 0, 1 ) ); + return; + } + normal = vectornormalize( test_origin - view_pos ); + dot = vectordot( forward_view_angles, normal ); + if ( abs( dot ) < 0.7 ) + { + zombie jetgun_debug_print( "dot", ( 1, 0, 1 ) ); + return; + } + radial_origin = pointonsegmentnearesttopoint( view_pos, end_pos, test_origin ); + if ( distancesquared( test_origin, radial_origin ) > cylinder_radius_squared ) + { + zombie jetgun_debug_print( "cylinder", ( 1, 0, 1 ) ); + return; + } + if ( zombie damageconetrace( view_pos, self ) == 0 ) + { + zombie jetgun_debug_print( "cone", ( 1, 0, 1 ) ); + return; + } + jetgun_blow_suck = invert; + if ( dot <= 0 ) + { + jetgun_blow_suck *= -1; + } + if ( test_range_squared < grind_range_squared ) + { + level.jetgun_fling_enemies[ level.jetgun_fling_enemies.size ] = zombie; + level.jetgun_grind_enemies[ level.jetgun_grind_enemies.size ] = dot < 0; + } + else + { + if ( test_range_squared < drag_range_squared && dot > 0 ) + { + level.jetgun_drag_enemies[ level.jetgun_drag_enemies.size ] = zombie; + } + } +} + +jetgun_debug_print( msg, color ) +{ +/* +/# + if ( !getDvarInt( #"BCDDAAFF" ) ) + { + return; + } + if ( !isDefined( color ) ) + { + color = ( 1, 0, 1 ); + } + print3d( self.origin + vectorScale( ( 1, 0, 1 ), 60 ), msg, color, 1, 1, 40 ); +#/ +*/ +} + +jetgun_debug_print_on_ent( msg, color ) +{ +/* +/# + if ( !getDvarInt( #"BCDDAAFF" ) ) + { + return; + } + if ( !isDefined( color ) ) + { + color = ( 1, 0, 1 ); + } + self notify( "new_jetgun_debug_print_on_ent" ); + self endon( "death" ); + self endon( "jetgun_end_drag_state" ); + self endon( "new_jetgun_debug_print_on_ent" ); + while ( 1 ) + { + print3d( self.origin + vectorScale( ( 1, 0, 1 ), 60 ), msg, color, 1, 1 ); + wait 0.05; + + } +#/ +*/ +} + +try_gibbing() +{ + if ( isDefined( self ) && isDefined( self.a ) && isDefined( self.isscreecher ) && !self.isscreecher ) + { + self.a.gib_ref = random( level.jetgun_gib_refs ); + self thread maps/mp/animscripts/zm_death::do_gib(); + } +} + +jetgun_handle_death_notetracks( note ) +{ + if ( note == "jetgunned" ) + { + self thread jetgun_grind_death_ending(); + } +} + +jetgun_grind_death_ending() +{ + if ( !isDefined( self ) ) + { + return; + } + self hide(); + wait 0.1; + self self_delete(); +} + +jetgun_grind_zombie( player ) +{ + player endon( "death" ); + player endon( "disconnect" ); + self endon( "death" ); + if ( !isDefined( self.jetgun_grind ) ) + { + self.jetgun_grind = 1; + self notify( "grinding" ); + player set_jetgun_engine_direction( 0.5 * player get_jetgun_engine_direction() ); + if ( is_mature() ) + { + if ( isDefined( level._effect[ "zombie_guts_explosion" ] ) ) + { + playfx( level._effect[ "zombie_guts_explosion" ], self gettagorigin( "J_SpineLower" ) ); + } + } + self.nodeathragdoll = 1; + self.handle_death_notetracks = ::jetgun_handle_death_notetracks; + self dodamage( self.health + 666, player.origin, player ); + } +} + +jetgun_fling_zombie( player, index ) +{ + if ( !isDefined( self ) ) + { + return; + } + if ( isDefined( self.jetgun_fling_func ) ) + { + self [[ self.jetgun_fling_func ]]( player ); + return; + } + was_alive = isalive( self ); + if ( was_alive ) + { + self.jetgun_fling = 1; + self notify( "flinging" ); + deathanim = undefined; + if ( is_mature() ) + { + player weaponplayejectbrass(); + } + if ( isDefined( self.has_legs ) && self.has_legs ) + { + if ( isDefined( self.jetgun_drag_state ) && self.jetgun_drag_state == "jetgun_sprint" ) + { + deathanim = "zm_jetgun_sprint_death"; + } + else + { + deathanim = "zm_jetgun_death"; + } + } + else + { + deathanim = "zm_jetgun_death_crawl"; + } + self.deathanim = deathanim; + player playsound( "evt_jetgun_zmb_suck" ); + } + self thread jetgun_grind_zombie( player ); +} + +jetgun_drag_zombie( vdir, speed ) +{ + if ( isDefined( self.jetgun_drag_func ) ) + { + self [[ self.jetgun_drag_func ]]( vdir, speed ); + return; + } + self zombie_do_drag( vdir, speed ); +} + +jetgun_knockdown_zombie( player, gib ) +{ + self endon( "death" ); + return; + if ( isDefined( self.jetgun_knockdown_func ) ) + { + self [[ self.jetgun_knockdown_func ]]( player, gib ); + } + else + { + self dodamage( level.zombie_vars[ "jetgun_knockdown_damage" ], player.origin, player ); + } + if ( gib ) + { + self.a.gib_ref = random( level.jetgun_gib_refs ); + self thread maps/mp/animscripts/zm_death::do_gib(); + } + self.jetgun_handle_pain_notetracks = ::handle_jetgun_pain_notetracks; + self dodamage( level.zombie_vars[ "jetgun_knockdown_damage" ], player.origin, player ); +} + +handle_jetgun_pain_notetracks( note ) +{ + if ( note == "zombie_knockdown_ground_impact" ) + { + playfx( level._effect[ "jetgun_knockdown_ground" ], self.origin, anglesToForward( self.angles ), anglesToUp( self.angles ) ); + } +} + +is_jetgun_damage() +{ + if ( isDefined( self.damageweapon ) && self.damageweapon != "jetgun_zm" && self.damageweapon == "jetgun_upgraded_zm" ) + { + if ( self.damagemod != "MOD_GRENADE" ) + { + return self.damagemod != "MOD_GRENADE_SPLASH"; + } + } +} + +enemy_killed_by_jetgun() +{ + if ( isDefined( self.jetgun_fling ) && !self.jetgun_fling ) + { + if ( isDefined( self.jetgun_grind ) ) + { + return self.jetgun_grind; + } + } +} + +zombie_do_drag( vdir, speed ) +{ + if ( !self zombie_is_in_drag_state() ) + { + self zombie_enter_drag_state( vdir, speed ); + self thread zombie_drag_think(); + } + else + { + self zombie_keep_in_drag_state( vdir, speed ); + } +} + +zombie_is_in_drag_state() +{ + if ( isDefined( self.drag_state ) ) + { + return self.drag_state; + } +} + +zombie_should_stay_in_drag_state() +{ + if ( !isDefined( self ) || !isalive( self ) ) + { + return 0; + } + if ( isDefined( self.jetgun_owner ) || self.jetgun_owner getcurrentweapon() != "jetgun_zm" && !self.jetgun_owner is_jetgun_firing() ) + { + return 0; + } + if ( isDefined( self.drag_state ) && self.drag_state ) + { + return 1; + } + return 0; +} + +zombie_keep_in_drag_state( vdir, speed ) +{ + self.drag_start_time = getTime(); + self.drag_target = vdir; +} + +zombie_enter_drag_state( vdir, speed ) +{ + self.drag_state = 1; + self.jetgun_drag_state = "unaffected"; + if ( isDefined( self.is_traversing ) ) + { + self.was_traversing = self.is_traversing; + } + self notify( "killanimscript" ); + self zombie_keep_in_drag_state( vdir, speed ); + self.zombie_move_speed_pre_jetgun_drag = self.zombie_move_speed; +} + +zombie_exit_drag_state() +{ + self notify( "jetgun_end_drag_state" ); + self.drag_state = 0; + self.jetgun_drag_state = "unaffected"; + self.needs_run_update = 1; + if ( isDefined( self.zombie_move_speed_pre_jetgun_drag ) ) + { + self set_zombie_run_cycle( self.zombie_move_speed_pre_jetgun_drag ); + self.zombie_move_speed_pre_jetgun_drag = undefined; + } + else + { + self set_zombie_run_cycle(); + } + if ( isDefined( self.isdog ) && !self.isdog ) + { + self maps/mp/animscripts/zm_run::moverun(); + } + if ( isDefined( self.was_traversing ) && self.was_traversing ) + { + self traversemode( "gravity" ); + self.a.nodeath = 0; + self maps/mp/animscripts/zm_run::needsupdate(); + if ( !self.isdog ) + { + self maps/mp/animscripts/zm_run::moverun(); + } + self.is_traversing = 0; + self notify( "zombie_end_traverse" ); + if ( is_mature() ) + { + if ( isDefined( level._effect[ "zombie_guts_explosion" ] ) ) + { + playfx( level._effect[ "zombie_guts_explosion" ], self gettagorigin( "J_SpineLower" ) ); + } + } + self.nodeathragdoll = 1; + self dodamage( self.health + 666, self.origin, self ); + } +} + +aiphysicstrace( start, end ) +{ + result = physicstrace( start, end, ( 1, 0, 1 ), ( 1, 0, 1 ), self ); + return result[ "position" ]; +} + +zombie_drag_think() +{ + self endon( "death" ); + self endon( "flinging" ); + self endon( "grinding" ); + while ( self zombie_should_stay_in_drag_state() ) + { + self._distance_to_jetgun_owner = distancesquared( self.origin, self.jetgun_owner.origin ); + jetgun_network_choke(); + if ( self.zombie_move_speed == "sprint" || self._distance_to_jetgun_owner < level.jetgun_pulled_in_range ) + { + self jetgun_drag_set( "jetgun_sprint", "jetgun_walk_fast_crawl" ); + } + else + { + if ( self._distance_to_jetgun_owner < level.jetgun_pulling_in_range ) + { + self jetgun_drag_set( "jetgun_walk_fast", "jetgun_walk_fast" ); + break; + } + else if ( self._distance_to_jetgun_owner < level.jetgun_inner_range ) + { + self jetgun_drag_set( "jetgun_walk", "jetgun_walk_slow_crawl" ); + break; + } + else + { + if ( self._distance_to_jetgun_owner < level.jetgun_outer_edge ) + { + self jetgun_drag_set( "jetgun_walk_slow", "jetgun_walk_slow_crawl" ); + } + } + } + wait 0.1; + } + self thread zombie_exit_drag_state(); +} + +jetgun_drag_set( legsanim, crawlanim ) +{ + self endon( "death" ); + self.needs_run_update = 1; + if ( self.has_legs ) + { + self._had_legs = 1; + self set_zombie_run_cycle( legsanim ); + } + else + { + self._had_legs = 0; + self set_zombie_run_cycle( crawlanim ); + } +/* +/# + if ( self.jetgun_drag_state != legsanim ) + { + self thread jetgun_debug_print_on_ent( legsanim, ( 1, 0, 1 ) ); + + } + self.jetgun_drag_state = legsanim; +#/ +*/ +} + +zombie_drag_radius() +{ +/* +/# + self endon( "death_or_disconnect" ); + self endon( "weapon_change" ); + while ( 1 ) + { + circle( self.origin, level.zombie_vars[ "jetgun_grind_range" ], vectorScale( ( 1, 0, 1 ), 0.5 ) ); + circle( self.origin, level.zombie_vars[ "jetgun_drag_range" ] / 8, ( 1, 0, 1 ) ); + circle( self.origin, level.zombie_vars[ "jetgun_drag_range" ] / 4, ( 1, 0, 1 ) ); + circle( self.origin, level.zombie_vars[ "jetgun_drag_range" ] / 2, ( 1, 0, 1 ) ); + circle( self.origin, level.zombie_vars[ "jetgun_drag_range" ], ( 1, 0, 1 ) ); + wait 0.05; + + } +#/ +*/ +} +