#include maps\mp\zombies\_zm_weap_time_bomb; #include common_scripts\utility; #include maps\mp\_utility; #include maps\mp\zombies\_zm_utility; #include maps\mp\gametypes_zm\_hud_util; #include maps\mp\zombies\_zm_weapons; #include maps\mp\_visionset_mgr; #include maps\mp\zombies\_zm_audio; #include maps\mp\zombies\_zm_blockers; #include maps\mp\zombies\_zm_laststand; #include maps\mp\zombies\_zm_weapon_locker; #include maps\mp\zombies\_zm_magicbox; #include maps\mp\zombies\_zm_perks; #include maps\mp\zombies\_zm_score; #include maps\mp\zombies\_zm_stats; #include maps\mp\zombies\_zm_equipment; #include maps\mp\zombies\_zm; #include maps\mp\zombies\_zm_spawner; #include maps\mp\animscripts\zm_death; #include maps\mp\zombies\_zm_ai_basic; init_time_bomb() { time_bomb_precache(); level thread time_bomb_post_init(); flag_init("time_bomb_round_killed"); flag_init("time_bomb_enemies_restored"); flag_init("time_bomb_zombie_respawning_done"); flag_init("time_bomb_restore_active"); flag_init("time_bomb_restore_done"); flag_init("time_bomb_global_restore_done"); flag_init("time_bomb_detonation_enabled"); flag_init("time_bomb_stores_door_state"); registerclientfield("world", "time_bomb_saved_round_number", 12000, 8, "int"); registerclientfield("world", "time_bomb_lua_override", 12000, 1, "int"); registerclientfield("world", "time_bomb_hud_toggle", 12000, 1, "int"); registerclientfield("toplayer", "sndTimebombLoop", 12000, 2, "int"); maps\mp\zombies\_zm_weapons::register_zombie_weapon_callback("time_bomb_zm", ::player_give_time_bomb); level.zombiemode_time_bomb_give_func = ::player_give_time_bomb; include_weapon("time_bomb_zm", 1); maps\mp\zombies\_zm_weapons::add_limited_weapon("time_bomb_zm", 1); add_time_bomb_to_mystery_box(); register_equipment_for_level("time_bomb_zm"); register_equipment_for_level("time_bomb_detonator_zm"); if (!isdefined(level.round_wait_func)) level.round_wait_func = ::time_bomb_round_wait; level.zombie_round_change_custom = ::time_bomb_custom_round_change; level._effect["time_bomb_set"] = loadfx("weapon/time_bomb/fx_time_bomb_detonate"); level._effect["time_bomb_ammo_fx"] = loadfx("misc/fx_zombie_powerup_on"); level._effect["time_bomb_respawns_enemy"] = loadfx("maps/zombie_buried/fx_buried_time_bomb_spawn"); level._effect["time_bomb_kills_enemy"] = loadfx("maps/zombie_buried/fx_buried_time_bomb_death"); level._time_bomb = spawnstruct(); level._time_bomb.enemy_type = []; register_time_bomb_enemy("zombie", ::is_zombie_round, ::time_bomb_saves_zombie_data, ::time_bomb_respawns_zombies); register_time_bomb_enemy_default("zombie"); level._time_bomb.last_round_restored = -1; flag_set("time_bomb_detonation_enabled"); } player_give_time_bomb() { assert(isplayer(self), "player_give_time_bomb can only be used on players!"); self giveweapon("time_bomb_zm"); self swap_weapon_to_time_bomb(); self thread show_time_bomb_hints(); self thread time_bomb_think(); self thread detonator_think(); self thread time_bomb_inventory_slot_think(); self thread destroy_time_bomb_save_if_user_bleeds_out_or_disconnects(); self thread sndwatchforweapswitch(); } show_time_bomb_hints() { self endon("death_or_disconnect"); self endon("player_lost_time_bomb"); if (!isdefined(self.time_bomb_hints_shown)) self.time_bomb_hints_shown = 0; if (!self.time_bomb_hints_shown) { self.time_bomb_hints_shown = 1; wait 0.5; self show_time_bomb_notification(&"ZOMBIE_TIMEBOMB_PICKUP"); self thread _watch_for_player_switch_to_time_bomb(); wait 3.5; self clean_up_time_bomb_notifications(); } } time_bomb_think() { self notify("_time_bomb_kill_thread"); self endon("_time_bomb_kill_thread"); self endon("death"); self endon("disconnect"); self endon("player_lost_time_bomb"); while (true) { self waittill("grenade_fire", e_grenade, str_grenade_name); if (str_grenade_name == "time_bomb_zm") { if (isdefined(str_grenade_name) && str_grenade_name == "time_bomb_zm") { e_grenade thread setup_time_bomb_detonation_model(); time_bomb_saves_data(0); e_grenade time_bomb_model_init(); self thread swap_weapon_to_detonator(e_grenade); self thread time_bomb_thrown_vo(); } } } } swap_weapon_to_detonator(e_grenade) { self endon("death_or_disconnect"); self endon("player_lost_time_bomb"); b_switch_to_weapon = 0; if (isdefined(e_grenade)) { b_switch_to_weapon = 1; wait 0.4; } self takeweapon("time_bomb_zm"); self giveweapon("time_bomb_detonator_zm"); self setweaponammoclip("time_bomb_detonator_zm", 0); self setweaponammostock("time_bomb_detonator_zm", 0); self setactionslot(2, "weapon", "time_bomb_detonator_zm"); if (b_switch_to_weapon) self switchtoweapon("time_bomb_detonator_zm"); self giveweapon("time_bomb_zm"); } detonator_think() { self notify("_detonator_think_done"); self endon("_detonator_think_done"); self endon("death"); self endon("disconnect"); self endon("player_lost_time_bomb"); debug_time_bomb_print("player picked up detonator"); while (true) { self waittill("detonate"); debug_time_bomb_print("detonate detected! "); if (time_bomb_save_exists() && flag("time_bomb_detonation_enabled")) { level.time_bomb_save_data.player_used = self; level.time_bomb_save_data.time_bomb_model thread detonate_time_bomb(); self notify("player_activates_timebomb"); self thread time_bomb_detonation_vo(); } } } detonate_time_bomb() { if (isdefined(level.time_bomb_save_data.time_bomb_model) && isdefined(level.time_bomb_save_data.time_bomb_model.origin)) playsoundatposition("zmb_timebomb_3d_timer_end", level.time_bomb_save_data.time_bomb_model.origin); if (time_bomb_save_exists()) time_bomb_detonation(); else delete_time_bomb_model(); } time_bomb_detonation() { level setclientfield("time_bomb_lua_override", 1); playsoundatposition("zmb_timebomb_timechange_2d", (0, 0, 0)); _time_bomb_show_overlay(); time_bomb_clears_global_data(); time_bomb_clears_player_data(); wait 4; _time_bomb_kill_all_active_enemies(); delete_time_bomb_model(); _time_bomb_hide_overlay(); level thread set_time_bomb_restore_active(); level setclientfield("time_bomb_lua_override", 0); if (isdefined(level._time_bomb.functionality_override) && level._time_bomb.functionality_override) return; level notify("time_bomb_detonation_complete"); } _time_bomb_show_overlay() { flag_clear("time_bomb_restore_done"); a_players = get_players(); foreach (player in a_players) { maps\mp\_visionset_mgr::vsmgr_activate("overlay", "zombie_time_bomb_overlay", player); player freezecontrols(1); player enableinvulnerability(); } level thread kill_overlay_at_match_end(); } _time_bomb_hide_overlay(n_time_start) { n_time_end = gettime(); if (isdefined(n_time_start)) { n_time_elapsed = (n_time_end - n_time_start) * 0.001; n_delay = 4 - n_time_elapsed; n_delay = clamp(n_delay, 0, 4); if (n_delay > 0) { wait(n_delay); timebomb_wait_for_hostmigration(); } } timebomb_wait_for_hostmigration(); a_players = get_players(); flag_set("time_bomb_restore_done"); foreach (player in a_players) { player freezecontrols(0); player disableInvulnerability(); } } set_time_bomb_restore_active() { flag_set("time_bomb_restore_active"); wait 0.05; flag_clear("time_bomb_restore_active"); } _time_bomb_kill_all_active_enemies() { for (zombies = time_bomb_get_enemy_array(); zombies.size > 0; zombies = time_bomb_get_enemy_array()) { for (i = 0; i < zombies.size; i++) { timebomb_wait_for_hostmigration(); if (isdefined(zombies[i])) zombies[i] thread _kill_time_bomb_enemy(); } } } _kill_time_bomb_enemy() { self dodamage(self.health + 100, self.origin, level.time_bomb_save_data.player_used, level.time_bomb_save_data.player_used, self.origin); self ghost(); playfx(level._effect["time_bomb_kills_enemy"], self.origin); if (isdefined(self) && isdefined(self.anchor)) self.anchor delete(); wait_network_frame(); if (isdefined(self)) { if (isdefined(self.script_mover)) self.script_mover delete(); self delete(); } }