#include maps\mp\zombies\_zm_perks; #include maps\mp\_utility; #include common_scripts\utility; #include maps\mp\zombies\_zm_utility; #include maps\mp\zombies\_zm_power; init() { level.additionalprimaryweapon_limit = 3; level.perk_purchase_limit = 4; if (!level.createfx_enabled) perks_register_clientfield(); if (!level.enable_magic) return; initialize_custom_perk_arrays(); perk_machine_spawn_init(); vending_weapon_upgrade_trigger = []; vending_triggers = getentarray("zombie_vending", "targetname"); for (i = 0; i < vending_triggers.size; i++) { if (isdefined(vending_triggers[i].script_noteworthy) && vending_triggers[i].script_noteworthy == "specialty_weapupgrade") { vending_weapon_upgrade_trigger[vending_weapon_upgrade_trigger.size] = vending_triggers[i]; arrayremovevalue(vending_triggers, vending_triggers[i]); } } old_packs = getentarray("zombie_vending_upgrade", "targetname"); for (i = 0; i < old_packs.size; i++) vending_weapon_upgrade_trigger[vending_weapon_upgrade_trigger.size] = old_packs[i]; flag_init("pack_machine_in_use"); if (vending_triggers.size < 1) return; if (vending_weapon_upgrade_trigger.size >= 1) array_thread(vending_weapon_upgrade_trigger, ::vending_weapon_upgrade); level.machine_assets = []; if (!isdefined(level.custom_vending_precaching)) level.custom_vending_precaching = ::default_vending_precaching; [[level.custom_vending_precaching]](); if (!isdefined(level.packapunch_timeout)) level.packapunch_timeout = 15; set_zombie_var("zombie_perk_cost", 2000); set_zombie_var("zombie_perk_juggernaut_health", 160); set_zombie_var("zombie_perk_juggernaut_health_upgrade", 190); array_thread(vending_triggers, ::vending_trigger_think); array_thread(vending_triggers, ::electric_perks_dialog); if (isdefined(level.zombiemode_using_doubletap_perk) && level.zombiemode_using_doubletap_perk) level thread turn_doubletap_on(); if (isdefined(level.zombiemode_using_marathon_perk) && level.zombiemode_using_marathon_perk) level thread turn_marathon_on(); if (isdefined(level.zombiemode_using_juggernaut_perk) && level.zombiemode_using_juggernaut_perk) level thread turn_jugger_on(); if (isdefined(level.zombiemode_using_revive_perk) && level.zombiemode_using_revive_perk) level thread turn_revive_on(); if (isdefined(level.zombiemode_using_sleightofhand_perk) && level.zombiemode_using_sleightofhand_perk) level thread turn_sleight_on(); if (isdefined(level.zombiemode_using_deadshot_perk) && level.zombiemode_using_deadshot_perk) level thread turn_deadshot_on(); if (isdefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) level thread turn_tombstone_on(); if (isdefined(level.zombiemode_using_additionalprimaryweapon_perk) && level.zombiemode_using_additionalprimaryweapon_perk) level thread turn_additionalprimaryweapon_on(); if (isdefined(level.zombiemode_using_chugabud_perk) && level.zombiemode_using_chugabud_perk) level thread turn_chugabud_on(); if (level._custom_perks.size > 0) { a_keys = getarraykeys(level._custom_perks); for (i = 0; i < a_keys.size; i++) { if (isdefined(level._custom_perks[a_keys[i]].perk_machine_thread)) level thread [[level._custom_perks[a_keys[i]].perk_machine_thread]](); } } if (isdefined(level._custom_turn_packapunch_on)) level thread [[level._custom_turn_packapunch_on]](); else level thread turn_packapunch_on(); if (isdefined(level.quantum_bomb_register_result_func)) [[level.quantum_bomb_register_result_func]]("give_nearest_perk", ::quantum_bomb_give_nearest_perk_result, 10, ::quantum_bomb_give_nearest_perk_validation); level thread perk_hostmigration(); } vending_trigger_think() { self endon("death"); wait 0.01; perk = self.script_noteworthy; solo = 0; start_on = 0; level.revive_machine_is_solo = 0; if (isdefined(perk) && (perk == "specialty_quickrevive" || perk == "specialty_quickrevive_upgrade")) { flag_wait("start_zombie_round_logic"); solo = use_solo_revive(); self endon("stop_quickrevive_logic"); level.quick_revive_trigger = self; if (solo) { if (!is_true(level.revive_machine_is_solo)) { start_on = 1; players = get_players(); foreach (player in players) { if (!isdefined(player.lives)) player.lives = 0; } level maps\mp\zombies\_zm::set_default_laststand_pistol(1); } level.revive_machine_is_solo = 1; } } self sethintstring(&"ZOMBIE_NEED_POWER"); self setcursorhint("HINT_NOICON"); self usetriggerrequirelookat(); cost = level.zombie_vars["zombie_perk_cost"]; switch (perk) { case "specialty_armorvest_upgrade": case "specialty_armorvest": cost = 2500; break; case "specialty_quickrevive_upgrade": case "specialty_quickrevive": if (solo) cost = 500; else cost = 1500; break; case "specialty_fastreload_upgrade": case "specialty_fastreload": cost = 3000; break; case "specialty_rof_upgrade": case "specialty_rof": cost = 2000; break; case "specialty_longersprint_upgrade": case "specialty_longersprint": cost = 2000; break; case "specialty_deadshot_upgrade": case "specialty_deadshot": cost = 1500; break; case "specialty_additionalprimaryweapon_upgrade": case "specialty_additionalprimaryweapon": cost = 4000; break; } if (isdefined(level._custom_perks[perk]) && isdefined(level._custom_perks[perk].cost)) cost = level._custom_perks[perk].cost; self.cost = cost; if (!start_on) { notify_name = perk + "_power_on"; level waittill(notify_name); } start_on = 0; if (!isdefined(level._perkmachinenetworkchoke)) level._perkmachinenetworkchoke = 0; else level._perkmachinenetworkchoke++; for (i = 0; i < level._perkmachinenetworkchoke; i++) wait_network_frame(); self thread maps\mp\zombies\_zm_audio::perks_a_cola_jingle_timer(); self thread check_player_has_perk(perk); switch (perk) { case "specialty_armorvest_upgrade": case "specialty_armorvest": self sethintstring(&"ZOMBIE_PERK_JUGGERNAUT", cost); break; case "specialty_quickrevive_upgrade": case "specialty_quickrevive": if (solo) self sethintstring(&"ZOMBIE_PERK_QUICKREVIVE_SOLO", cost); else self sethintstring(&"ZOMBIE_PERK_QUICKREVIVE", cost); break; case "specialty_fastreload_upgrade": case "specialty_fastreload": self sethintstring(&"ZOMBIE_PERK_FASTRELOAD", cost); break; case "specialty_rof_upgrade": case "specialty_rof": self sethintstring(&"ZOMBIE_PERK_DOUBLETAP", cost); break; case "specialty_longersprint_upgrade": case "specialty_longersprint": self sethintstring(&"ZOMBIE_PERK_MARATHON", cost); break; case "specialty_deadshot_upgrade": case "specialty_deadshot": self sethintstring(&"ZOMBIE_PERK_DEADSHOT", cost); break; case "specialty_additionalprimaryweapon_upgrade": case "specialty_additionalprimaryweapon": self sethintstring(&"ZOMBIE_PERK_ADDITIONALPRIMARYWEAPON", cost); break; case "specialty_scavenger_upgrade": case "specialty_scavenger": self sethintstring(&"ZOMBIE_PERK_TOMBSTONE", cost); break; case "specialty_finalstand_upgrade": case "specialty_finalstand": self sethintstring(&"ZOMBIE_PERK_CHUGABUD", cost); break; default: self sethintstring(perk + " Cost: " + level.zombie_vars["zombie_perk_cost"]); } if (isdefined(level._custom_perks[perk]) && isdefined(level._custom_perks[perk].hint_string)) self sethintstring(level._custom_perks[perk].hint_string, cost); for (;;) { self waittill("trigger", player); index = maps\mp\zombies\_zm_weapons::get_player_index(player); if (player maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isdefined(player.intermission) && player.intermission) continue; if (player in_revive_trigger()) continue; if (player isthrowinggrenade()) { wait 0.1; continue; } if (player isswitchingweapons()) { wait 0.1; continue; } if (player.is_drinking > 0) { wait 0.1; continue; } if (player hasperk(perk) || player has_perk_paused(perk)) { cheat = 0; if (cheat != 1) { self playsound("evt_perk_deny"); player maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "perk_deny", undefined, 1); continue; } } if (isdefined(level.custom_perk_validation)) { valid = self [[level.custom_perk_validation]](player); if (!valid) continue; } current_cost = cost; if (player maps\mp\zombies\_zm_pers_upgrades_functions::is_pers_double_points_active()) current_cost = player maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_double_points_cost(current_cost); if (player.score < current_cost) { self playsound("evt_perk_deny"); player maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "perk_deny", undefined, 0); continue; } if (player.num_perks >= player get_player_perk_purchase_limit()) { self playsound("evt_perk_deny"); player maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "sigh"); continue; } sound = "evt_bottle_dispense"; playsoundatposition(sound, self.origin); player maps\mp\zombies\_zm_score::minus_to_player_score(current_cost, 1); player.perk_purchased = perk; self thread maps\mp\zombies\_zm_audio::play_jingle_or_stinger(self.script_label); self thread vending_trigger_post_think(player, perk); } } vending_trigger_post_think(player, perk) { player endon("disconnect"); player endon("end_game"); player endon("perk_abort_drinking"); player.pre_temp_weapon = player perk_give_bottle_begin(perk); evt = player waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); if (evt == "weapon_change_complete") player thread wait_give_perk(perk, 1); player perk_give_bottle_end(player.pre_temp_weapon, perk); if (player maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isdefined(player.intermission) && player.intermission) { player.lastactiveweapon = player.pre_temp_weapon; return; } player.pre_temp_weapon = undefined; player notify("burp"); if (isdefined(level.pers_upgrade_cash_back) && level.pers_upgrade_cash_back) player maps\mp\zombies\_zm_pers_upgrades_functions::cash_back_player_drinks_perk(); if (isdefined(level.pers_upgrade_perk_lose) && level.pers_upgrade_perk_lose) player thread maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_perk_lose_bought(); if (isdefined(level.perk_bought_func)) player [[level.perk_bought_func]](perk); player.perk_purchased = undefined; if (is_false(self.power_on)) { wait 1; perk_pause(self.script_noteworthy); } bbprint("zombie_uses", "playername %s playerscore %d round %d name %s x %f y %f z %f type %s", player.name, player.score, level.round_number, perk, self.origin, "perk"); } perk_give_bottle_end(gun, perk) { self endon("perk_abort_drinking"); assert(!is_zombie_perk_bottle(gun)); assert(gun != level.revive_tool); self enable_player_move_states(); weapon = ""; switch (perk) { case "specialty_rof_upgrade": case "specialty_rof": weapon = level.machine_assets["doubletap"].weapon; break; case "specialty_longersprint_upgrade": case "specialty_longersprint": weapon = level.machine_assets["marathon"].weapon; break; case "specialty_flakjacket_upgrade": case "specialty_flakjacket": weapon = level.machine_assets["divetonuke"].weapon; break; case "specialty_armorvest_upgrade": case "specialty_armorvest": weapon = level.machine_assets["juggernog"].weapon; self.jugg_used = 1; break; case "specialty_quickrevive_upgrade": case "specialty_quickrevive": weapon = level.machine_assets["revive"].weapon; break; case "specialty_fastreload_upgrade": case "specialty_fastreload": weapon = level.machine_assets["speedcola"].weapon; self.speed_used = 1; break; case "specialty_deadshot_upgrade": case "specialty_deadshot": weapon = level.machine_assets["deadshot"].weapon; break; case "specialty_additionalprimaryweapon_upgrade": case "specialty_additionalprimaryweapon": weapon = level.machine_assets["additionalprimaryweapon"].weapon; break; case "specialty_scavenger_upgrade": case "specialty_scavenger": weapon = level.machine_assets["tombstone"].weapon; break; case "specialty_finalstand_upgrade": case "specialty_finalstand": weapon = level.machine_assets["whoswho"].weapon; break; } if (isdefined(level._custom_perks[perk]) && isdefined(level._custom_perks[perk].perk_bottle)) weapon = level._custom_perks[perk].perk_bottle; if (self maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isdefined(self.intermission) && self.intermission) { self takeweapon(weapon); return; } self takeweapon(weapon); if (self is_multiple_drinking()) { self decrement_is_drinking(); return; } else if (gun != "none" && !is_equipment_that_blocks_purchase(gun)) { self switchtoweapon(gun); if (is_melee_weapon(gun)) { self decrement_is_drinking(); return; } } else { primaryweapons = self getweaponslistprimaries(); if (isdefined(primaryweapons) && primaryweapons.size > 0) self switchtoweapon(primaryweapons[0]); } self waittill("weapon_change_complete"); if (!self maps\mp\zombies\_zm_laststand::player_is_in_laststand() && !(isdefined(self.intermission) && self.intermission)) self decrement_is_drinking(); } vending_weapon_upgrade() { level endon("Pack_A_Punch_off"); wait 0.01; perk_machine = getent(self.target, "targetname"); self.perk_machine = perk_machine; perk_machine_sound = getentarray("perksacola", "targetname"); packa_rollers = spawn("script_origin", self.origin); packa_timer = spawn("script_origin", self.origin); packa_rollers linkto(self); packa_timer linkto(self); if (isdefined(perk_machine.target)) perk_machine.wait_flag = getent(perk_machine.target, "targetname"); pap_is_buildable = self is_buildable(); if (pap_is_buildable) { self trigger_off(); perk_machine hide(); if (isdefined(perk_machine.wait_flag)) perk_machine.wait_flag hide(); wait_for_buildable("pap"); self trigger_on(); perk_machine show(); if (isdefined(perk_machine.wait_flag)) perk_machine.wait_flag show(); } self usetriggerrequirelookat(); self sethintstring(&"ZOMBIE_NEED_POWER"); self setcursorhint("HINT_NOICON"); power_off = !self maps\mp\zombies\_zm_power::pap_is_on(); if (power_off) { pap_array = []; pap_array[0] = perk_machine; level thread do_initial_power_off_callback(pap_array, "packapunch"); level waittill("Pack_A_Punch_on"); } self enable_trigger(); if (isdefined(level.machine_assets["packapunch"].power_on_callback)) perk_machine thread [[level.machine_assets["packapunch"].power_on_callback]](); self thread vending_machine_trigger_think(); perk_machine playloopsound("zmb_perks_packa_loop"); self thread shutoffpapsounds(perk_machine, packa_rollers, packa_timer); self thread vending_weapon_upgrade_cost(); for (;;) { self.pack_player = undefined; self waittill("trigger", player); index = maps\mp\zombies\_zm_weapons::get_player_index(player); current_weapon = player getcurrentweapon(); if ("microwavegun_zm" == current_weapon) current_weapon = "microwavegundw_zm"; current_weapon = player maps\mp\zombies\_zm_weapons::switch_from_alt_weapon(current_weapon); if (isdefined(level.custom_pap_validation)) { valid = self [[level.custom_pap_validation]](player); if (!valid) continue; } if (!player maps\mp\zombies\_zm_magicbox::can_buy_weapon() || player maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isdefined(player.intermission) && player.intermission || player isthrowinggrenade() || !player maps\mp\zombies\_zm_weapons::can_upgrade_weapon(current_weapon)) { wait 0.1; continue; } if (player isswitchingweapons()) { wait 0.1; if (player isswitchingweapons()) continue; } if (!maps\mp\zombies\_zm_weapons::is_weapon_or_base_included(current_weapon)) continue; current_cost = self.cost; player.restore_ammo = undefined; player.restore_clip = undefined; player.restore_stock = undefined; player_restore_clip_size = undefined; player.restore_max = undefined; upgrade_as_attachment = will_upgrade_weapon_as_attachment(current_weapon); if (upgrade_as_attachment) { current_cost = self.attachment_cost; player.restore_ammo = 1; player.restore_clip = player getweaponammoclip(current_weapon); player.restore_clip_size = weaponclipsize(current_weapon); player.restore_stock = player getweaponammostock(current_weapon); player.restore_max = weaponmaxammo(current_weapon); } if (player maps\mp\zombies\_zm_pers_upgrades_functions::is_pers_double_points_active()) current_cost = player maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_double_points_cost(current_cost); if (!upgrade_as_attachment && player.score < current_cost) { self playsound("evt_perk_deny"); if (isdefined(level.custom_pap_deny_vo_func)) player [[level.custom_pap_deny_vo_func]](); else player maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "perk_deny", undefined, 0); continue; } self.pack_player = player; flag_set("pack_machine_in_use"); maps\mp\_demo::bookmark("zm_player_use_packapunch", gettime(), player); player maps\mp\zombies\_zm_stats::increment_client_stat("use_pap"); player maps\mp\zombies\_zm_stats::increment_player_stat("use_pap"); self thread destroy_weapon_in_blackout(player); self thread destroy_weapon_on_disconnect(player); if (!upgrade_as_attachment) { player maps\mp\zombies\_zm_score::minus_to_player_score(current_cost, 1); } sound = "evt_bottle_dispense"; playsoundatposition(sound, self.origin); self thread maps\mp\zombies\_zm_audio::play_jingle_or_stinger("mus_perks_packa_sting"); player maps\mp\zombies\_zm_audio::create_and_play_dialog("weapon_pickup", "upgrade_wait"); self disable_trigger(); self sethintstring(""); if (!(isdefined(upgrade_as_attachment) && upgrade_as_attachment)) player thread do_player_general_vox("general", "pap_wait", 10, 100); else player thread do_player_general_vox("general", "pap_wait2", 10, 100); player thread do_knuckle_crack(); self.current_weapon = current_weapon; upgrade_name = maps\mp\zombies\_zm_weapons::get_upgrade_weapon(current_weapon, upgrade_as_attachment); player third_person_weapon_upgrade(current_weapon, upgrade_name, packa_rollers, perk_machine, self); self enable_trigger(); self sethintstring(&"ZOMBIE_GET_UPGRADED"); if (isdefined(player)) { self setinvisibletoall(); self setvisibletoplayer(player); self thread wait_for_player_to_take(player, current_weapon, packa_timer, upgrade_as_attachment); } self thread wait_for_timeout(current_weapon, packa_timer, player); self waittill_any("pap_timeout", "pap_taken", "pap_player_disconnected"); self.current_weapon = ""; if (isdefined(self.worldgun) && isdefined(self.worldgun.worldgundw)) self.worldgun.worldgundw delete(); if (isdefined(self.worldgun)) self.worldgun delete(); if (isdefined(level.zombiemode_reusing_pack_a_punch) && level.zombiemode_reusing_pack_a_punch) self sethintstring(&"ZOMBIE_PERK_PACKAPUNCH_ATT", self.cost); else self sethintstring(&"ZOMBIE_PERK_PACKAPUNCH", self.cost); self setvisibletoall(); self.pack_player = undefined; flag_clear("pack_machine_in_use"); } } destroy_weapon_in_blackout(player) { self endon("pap_timeout"); self endon("pap_taken"); self endon("pap_player_disconnected"); level waittill("Pack_A_Punch_off"); if (isDefined(self.worldgun)) { if (isDefined(self.worldgun.worldgundw)) { self.worldgun.worldgundw delete(); } self.worldgun delete(); } self.perk_machine.wait_flag rotateTo(self.perk_machine.angles + (0, 180, 180), 0.25, 0, 0); } give_perk(perk, bought) { self setperk(perk); self.num_perks++; if (isDefined(bought) && bought) { self maps\mp\zombies\_zm_audio::playerexert("burp"); if (isDefined(level.remove_perk_vo_delay) && level.remove_perk_vo_delay) { self maps\mp\zombies\_zm_audio::perk_vox(perk); } else { self delay_thread(1.5, maps\mp\zombies\_zm_audio::perk_vox, perk); } self notify("perk_bought"); } self perk_set_max_health_if_jugg(perk, 1, 0); if (isDefined(level.disable_deadshot_clientfield) && !level.disable_deadshot_clientfield) { if (perk == "specialty_deadshot") { self setclientfieldtoplayer("deadshot_perk", 1); } else { if (perk == "specialty_deadshot_upgrade") { self setclientfieldtoplayer("deadshot_perk", 1); } } } if (perk == "specialty_scavenger") { self.hasperkspecialtytombstone = 1; } players = get_players(); if (use_solo_revive() && perk == "specialty_quickrevive") { self.lives = 1; if (!isDefined(level.solo_lives_given)) { level.solo_lives_given = 0; } if (isDefined(level.solo_game_free_player_quickrevive)) { level.solo_game_free_player_quickrevive = undefined; } else { level.solo_lives_given++; } if (level.solo_lives_given >= 3) { flag_set("solo_revive"); } self thread solo_revive_buy_trigger_move(perk); } if (perk == "specialty_finalstand") { self.hasperkspecialtychugabud = 1; self notify("perk_chugabud_activated"); } if (perk == "specialty_additionalprimaryweapon") { self scripts\zm\replaced\_zm::restore_additionalprimaryweapon(); self notify("perk_additionalprimaryweapon_activated"); } if (isDefined(level._custom_perks[perk]) && isDefined(level._custom_perks[perk].player_thread_give)) { self thread [[level._custom_perks[perk].player_thread_give]](); } self set_perk_clientfield(perk, 1); maps\mp\_demo::bookmark("zm_player_perk", getTime(), self); self maps\mp\zombies\_zm_stats::increment_client_stat("perks_drank"); self maps\mp\zombies\_zm_stats::increment_client_stat(perk + "_drank"); self maps\mp\zombies\_zm_stats::increment_player_stat(perk + "_drank"); self maps\mp\zombies\_zm_stats::increment_player_stat("perks_drank"); if (!isDefined(self.perk_history)) { self.perk_history = []; } self.perk_history = add_to_array(self.perk_history, perk, 0); if (!isDefined(self.perks_active)) { self.perks_active = []; } self.perks_active[self.perks_active.size] = perk; self notify("perk_acquired"); self thread perk_think(perk); } perk_think(perk) { self endon("disconnect"); perk_str = perk + "_stop"; result = self waittill_any_return("fake_death", "death", "player_downed", perk_str); do_retain = 1; if (use_solo_revive() && perk == "specialty_quickrevive") { do_retain = 0; } if (do_retain) { if (is_true(self._retain_perks)) { return; } else if (isDefined(self._retain_perks_array) && is_true(self._retain_perks_array[perk])) { return; } } self unsetperk(perk); self.num_perks--; switch (perk) { case "specialty_armorvest": self setmaxhealth(self.premaxhealth); break; case "specialty_additionalprimaryweapon": if (result == perk_str) { self maps\mp\zombies\_zm::take_additionalprimaryweapon(); } break; case "specialty_deadshot": if (!is_true(level.disable_deadshot_clientfield)) { self setclientfieldtoplayer("deadshot_perk", 0); } break; case "specialty_deadshot_upgrade": if (!is_true(level.disable_deadshot_clientfield)) { self setclientfieldtoplayer("deadshot_perk", 0); } break; case "specialty_scavenger": self.hasperkspecialtytombstone = undefined; break; } if (isDefined(level._custom_perks[perk]) && isDefined(level._custom_perks[perk].player_thread_take)) { self thread [[level._custom_perks[perk].player_thread_take]](); } self set_perk_clientfield(perk, 0); self.perk_purchased = undefined; if (isDefined(level.perk_lost_func)) { self [[level.perk_lost_func]](perk); } if (isDefined(self.perks_active) && isinarray(self.perks_active, perk)) { arrayremovevalue(self.perks_active, perk, 0); } if (isDefined(self.disabled_perks) && isDefined(self.disabled_perks[perk])) { self.disabled_perks[perk] = undefined; } self notify("perk_lost"); } perk_set_max_health_if_jugg(perk, set_premaxhealth, clamp_health_to_max_health) { max_total_health = undefined; if (perk == "specialty_armorvest") { if (set_premaxhealth) { self.premaxhealth = self.maxhealth; } max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; } else if (perk == "specialty_armorvest_upgrade") { if (set_premaxhealth) { self.premaxhealth = self.maxhealth; } max_total_health = level.zombie_vars["zombie_perk_juggernaut_health_upgrade"]; } else if (perk == "jugg_upgrade") { if (set_premaxhealth) { self.premaxhealth = self.maxhealth; } if (self hasperk("specialty_armorvest")) { max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; } else { max_total_health = level.player_starting_health; } } else if (perk == "health_reboot") { if (self hasperk("specialty_armorvest")) { max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; } else { max_total_health = level.player_starting_health; } } if (isDefined(max_total_health)) { if (self maps\mp\zombies\_zm_pers_upgrades_functions::pers_jugg_active()) { max_total_health += level.pers_jugg_upgrade_health_bonus; } if (is_true(level.sudden_death)) { max_total_health -= 100; } missinghealth = self.maxhealth - self.health; self setmaxhealth(max_total_health); self.health -= missinghealth; if (isDefined(clamp_health_to_max_health) && clamp_health_to_max_health == 1) { if (self.health > self.maxhealth) { self.health = self.maxhealth; } } } } set_perk_clientfield(perk, state) { switch (perk) { case "specialty_additionalprimaryweapon": self setclientfieldtoplayer("perk_additional_primary_weapon", state); break; case "specialty_deadshot": self setclientfieldtoplayer("perk_dead_shot", state); break; case "specialty_flakjacket": self setclientfieldtoplayer("perk_dive_to_nuke", state); break; case "specialty_rof": self setclientfieldtoplayer("perk_double_tap", state); break; case "specialty_armorvest": self setclientfieldtoplayer("perk_juggernaut", state); break; case "specialty_movefaster": self setclientfieldtoplayer("perk_marathon", state); break; case "specialty_quickrevive": self setclientfieldtoplayer("perk_quick_revive", state); break; case "specialty_fastreload": self setclientfieldtoplayer("perk_sleight_of_hand", state); break; case "specialty_scavenger": self setclientfieldtoplayer("perk_tombstone", state); break; case "specialty_finalstand": self setclientfieldtoplayer("perk_chugabud", state); break; default: break; } if (isdefined(level._custom_perks[perk]) && isdefined(level._custom_perks[perk].clientfield_set)) self [[level._custom_perks[perk].clientfield_set]](state); } initialize_custom_perk_arrays() { if (!isDefined(level._custom_perks)) { level._custom_perks = []; } level._custom_perks["specialty_movefaster"] = spawnStruct(); level._custom_perks["specialty_movefaster"].cost = 2500; level._custom_perks["specialty_movefaster"].alias = "marathon"; level._custom_perks["specialty_movefaster"].hint_string = &"ZOMBIE_PERK_MARATHON"; level._custom_perks["specialty_movefaster"].perk_bottle = "zombie_perk_bottle_marathon"; level._custom_perks["specialty_movefaster"].perk_machine_thread = ::turn_movefaster_on; struct = spawnStruct(); struct.script_noteworthy = "specialty_longersprint"; struct.scr_zm_ui_gametype = "zstandard"; struct.scr_zm_map_start_location = "town"; struct.origin_offset = (-4, 0, 0); move_perk_machine("zm_transit", "town", "specialty_quickrevive", struct); struct = spawnStruct(); struct.script_noteworthy = "specialty_longersprint"; struct.scr_zm_ui_gametype = "zclassic"; struct.scr_zm_map_start_location = "transit"; move_perk_machine("zm_transit", "town", "specialty_longersprint", struct); struct = spawnStruct(); struct.origin = (1852, -825, -56); struct.angles = (0, 180, 0); struct.script_string = "zgrief"; move_perk_machine("zm_transit", "town", "specialty_scavenger", struct); struct = spawnStruct(); struct.script_noteworthy = "specialty_quickrevive"; struct.scr_zm_ui_gametype = "zgrief"; struct.scr_zm_map_start_location = "street"; move_perk_machine("zm_buried", "street", "specialty_longersprint", struct); struct = spawnStruct(); struct.script_noteworthy = "specialty_fastreload"; struct.scr_zm_ui_gametype = "zgrief"; struct.scr_zm_map_start_location = "street"; struct.origin_offset = (0, -32, 0); move_perk_machine("zm_buried", "street", "specialty_quickrevive", struct); struct = spawnStruct(); struct.script_noteworthy = "specialty_fastreload"; struct.scr_zm_ui_gametype = "zclassic"; struct.scr_zm_map_start_location = "processing"; move_perk_machine("zm_buried", "street", "specialty_fastreload", struct); if (getDvar("g_gametype") == "zgrief" && getDvarIntDefault("ui_gametype_pro", 0)) { remove_pap_machine(); } } remove_pap_machine() { exceptions = array("specialty_armorvest", "specialty_fastreload"); structs = getStructArray("zm_perk_machine", "targetname"); foreach (struct in structs) { if (isDefined(struct.script_noteworthy) && struct.script_noteworthy == "specialty_weapupgrade") { struct.script_string = ""; } } } move_perk_machine(map, location, perk, move_struct) { if (!(level.script == map && level.scr_zm_map_start_location == location)) { return; } perk_struct = undefined; structs = getStructArray("zm_perk_machine", "targetname"); foreach (struct in structs) { if (isDefined(struct.script_noteworthy) && struct.script_noteworthy == perk) { if (isDefined(struct.script_string) && isSubStr(struct.script_string, "perks_" + location)) { perk_struct = struct; break; } } } if (!isDefined(perk_struct)) { return; } if (isDefined(move_struct.script_string)) { gametypes = strTok(move_struct.script_string, " "); foreach (gametype in gametypes) { perk_struct.script_string += " " + gametype + "_perks_" + location; } } if (isDefined(move_struct.origin)) { perk_struct.origin = move_struct.origin; perk_struct.angles = move_struct.angles; return; } foreach (struct in structs) { if (isDefined(struct.script_noteworthy) && struct.script_noteworthy == move_struct.script_noteworthy) { if (isDefined(struct.script_string) && isSubStr(struct.script_string, move_struct.scr_zm_ui_gametype + "_perks_" + move_struct.scr_zm_map_start_location)) { perk_struct.origin = struct.origin; perk_struct.angles = struct.angles; if (isDefined(move_struct.origin_offset)) { perk_struct.origin += move_struct.origin_offset; } break; } } } } turn_movefaster_on() { while (1) { machine = getentarray("vending_marathon", "targetname"); machine_triggers = getentarray("vending_marathon", "target"); i = 0; while (i < machine.size) { machine[i] setmodel(level.machine_assets["marathon"].off_model); i++; } array_thread(machine_triggers, ::set_power_on, 0); level thread do_initial_power_off_callback(machine, "marathon"); level waittill("marathon_on"); i = 0; while (i < machine.size) { machine[i] setmodel(level.machine_assets["marathon"].on_model); 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("marathon_light"); machine[i] thread play_loop_on_machine(); i++; } level notify("specialty_movefaster_power_on"); array_thread(machine_triggers, ::set_power_on, 1); if (isDefined(level.machine_assets["marathon"].power_on_callback)) { array_thread(machine, level.machine_assets["marathon"].power_on_callback); } level waittill("marathon_off"); if (isDefined(level.machine_assets["marathon"].power_off_callback)) { array_thread(machine, level.machine_assets["marathon"].power_off_callback); } array_thread(machine, ::turn_perk_off); } } turn_tombstone_on() { level endon("tombstone_removed"); while (true) { machine = getentarray("vending_tombstone", "targetname"); machine_triggers = getentarray("vending_tombstone", "target"); for (i = 0; i < machine.size; i++) machine[i] setmodel(level.machine_assets["tombstone"].off_model); level thread do_initial_power_off_callback(machine, "tombstone"); array_thread(machine_triggers, ::set_power_on, 0); level waittill("tombstone_on"); for (i = 0; i < machine.size; i++) { machine[i] setmodel(level.machine_assets["tombstone"].on_model); machine[i] vibrate(vectorscale((0, -1, 0), 100.0), 0.3, 0.4, 3); machine[i] playsound("zmb_perks_power_on"); machine[i] thread perk_fx("tombstone_light"); machine[i] thread play_loop_on_machine(); } level notify("specialty_scavenger_power_on"); array_thread(machine_triggers, ::set_power_on, 1); if (isdefined(level.machine_assets["tombstone"].power_on_callback)) array_thread(machine, level.machine_assets["tombstone"].power_on_callback); level waittill("tombstone_off"); if (isdefined(level.machine_assets["tombstone"].power_off_callback)) array_thread(machine, level.machine_assets["tombstone"].power_off_callback); array_thread(machine, ::turn_perk_off); players = get_players(); } } wait_for_player_to_take(player, weapon, packa_timer, upgrade_as_attachment) { current_weapon = self.current_weapon; upgrade_name = self.upgrade_name; upgrade_weapon = upgrade_name; self endon("pap_timeout"); level endon("Pack_A_Punch_off"); while (true) { packa_timer playloopsound("zmb_perks_packa_ticktock"); self waittill("trigger", trigger_player); if (isdefined(level.pap_grab_by_anyone) && level.pap_grab_by_anyone) player = trigger_player; packa_timer stoploopsound(0.05); if (trigger_player == player) { player maps\mp\zombies\_zm_stats::increment_client_stat("pap_weapon_grabbed"); player maps\mp\zombies\_zm_stats::increment_player_stat("pap_weapon_grabbed"); current_weapon = player getcurrentweapon(); primaries = player getweaponslistprimaries(); weapon_limit = get_player_weapon_limit(player); if (is_player_valid(player) && !(player.is_drinking > 0) && level.revive_tool != current_weapon && "none" != current_weapon && !player hacker_active() && (primaries.size < weapon_limit || (!is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(current_weapon)))) { maps\mp\_demo::bookmark("zm_player_grabbed_packapunch", gettime(), player); self notify("pap_taken"); player notify("pap_taken"); player.pap_used = 1; if (!(isdefined(upgrade_as_attachment) && upgrade_as_attachment)) player thread do_player_general_vox("general", "pap_arm", 15, 100); else player thread do_player_general_vox("general", "pap_arm2", 15, 100); weapon_limit = get_player_weapon_limit(player); player maps\mp\zombies\_zm_weapons::take_fallback_weapon(); primaries = player getweaponslistprimaries(); if (isdefined(primaries) && primaries.size >= weapon_limit) player maps\mp\zombies\_zm_weapons::weapon_give(upgrade_weapon); else { player giveweapon(upgrade_weapon, 0, player maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options(upgrade_weapon)); player givestartammo(upgrade_weapon); player notify("weapon_ammo_change"); } player switchtoweapon(upgrade_weapon); if (isdefined(player.restore_ammo) && player.restore_ammo) { new_clip = player.restore_clip + weaponclipsize(upgrade_weapon) - player.restore_clip_size; new_stock = player.restore_stock + weaponmaxammo(upgrade_weapon) - player.restore_max; player setweaponammostock(upgrade_weapon, new_stock); player setweaponammoclip(upgrade_weapon, new_clip); } player.restore_ammo = undefined; player.restore_clip = undefined; player.restore_stock = undefined; player.restore_max = undefined; player.restore_clip_size = undefined; player maps\mp\zombies\_zm_weapons::play_weapon_vo(upgrade_weapon); return; } } wait 0.05; } } check_player_has_perk(perk) { self endon("death"); dist = 16384; while (true) { players = get_players(); for (i = 0; i < players.size; i++) { if (distancesquared(players[i].origin, self.origin) < dist) { if (!players[i] hasperk(perk) && !players[i] has_perk_paused(perk) && !players[i] in_revive_trigger() && !is_equipment_that_blocks_purchase(players[i] getcurrentweapon()) && !players[i] hacker_active() && !players[i].is_drinking) { self setinvisibletoplayer(players[i], 0); continue; } self setinvisibletoplayer(players[i], 1); } } wait 0.05; } } perk_pause(perk) { // disabled } perk_unpause(perk) { // disabled }