mirror of
https://github.com/JezuzLizard/BO2-Reimagined.git
synced 2025-06-07 21:59:49 -05:00
989 lines
25 KiB
Plaintext
989 lines
25 KiB
Plaintext
#include maps\mp\zombies\_zm_magicbox;
|
|
#include common_scripts\utility;
|
|
#include maps\mp\_utility;
|
|
#include maps\mp\zombies\_zm_utility;
|
|
#include maps\mp\zombies\_zm_weapons;
|
|
#include maps\mp\zombies\_zm_magicbox_lock;
|
|
#include maps\mp\zombies\_zm_unitrigger;
|
|
#include maps\mp\zombies\_zm_audio_announcer;
|
|
#include maps\mp\zombies\_zm_pers_upgrades_functions;
|
|
#include maps\mp\zombies\_zm_score;
|
|
#include maps\mp\zombies\_zm_audio;
|
|
#include maps\mp\_demo;
|
|
#include maps\mp\zombies\_zm_stats;
|
|
|
|
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] maps\mp\zombies\_zm_magicbox::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 ((getDvar("g_gametype") == "zgrief" && getDvarIntDefault("ui_gametype_pro", 0)) || !level.enable_magic)
|
|
{
|
|
foreach (chest in level.chests)
|
|
{
|
|
chest maps\mp\zombies\_zm_magicbox::hide_chest();
|
|
}
|
|
|
|
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
|
|
{
|
|
for (i = 0; i < level.chests.size; i++)
|
|
{
|
|
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.chests = array_swap(level.chests, 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;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (start_chest_found || !isdefined(level.chests[i].script_noteworthy) || !issubstr(level.chests[i].script_noteworthy, start_chest_name))
|
|
{
|
|
level.chests[i] hide_chest();
|
|
continue;
|
|
}
|
|
|
|
level.chests = array_swap(level.chests, 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;
|
|
}
|
|
}
|
|
|
|
if (!isdefined(level.pandora_show_func))
|
|
level.pandora_show_func = ::default_pandora_show_func;
|
|
|
|
level.chests[level.chest_index] thread [[level.pandora_show_func]]();
|
|
}
|
|
|
|
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();
|
|
|
|
while (true)
|
|
{
|
|
if (!isdefined(self.forced_user))
|
|
{
|
|
self waittill("trigger", user);
|
|
|
|
if (user == level)
|
|
continue;
|
|
}
|
|
else
|
|
user = self.forced_user;
|
|
|
|
if (user in_revive_trigger())
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
if (user.is_drinking > 0)
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
if (isdefined(self.disabled) && self.disabled)
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
if (user getcurrentweapon() == "none")
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
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 maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "no_money_box");
|
|
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
else 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 if (user.score < self.zombie_cost)
|
|
{
|
|
play_sound_at_pos("no_purchase", self.origin);
|
|
user maps\mp\zombies\_zm_audio::create_and_play_dialog("general", "no_money_box");
|
|
continue;
|
|
}
|
|
|
|
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);
|
|
|
|
if (isdefined(grabber.is_drinking) && grabber.is_drinking > 0)
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
if (grabber == user && user getcurrentweapon() == "none")
|
|
{
|
|
wait 0.1;
|
|
continue;
|
|
}
|
|
|
|
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();
|
|
|
|
primaries = user getweaponslistprimaries();
|
|
weapon_limit = get_player_weapon_limit(user);
|
|
|
|
if (grabber == user && is_player_valid(user) && !(user.is_drinking > 0) && level.revive_tool != current_weapon && (primaries.size < weapon_limit || (!is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(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");
|
|
break;
|
|
}
|
|
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");
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
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.0;
|
|
|
|
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();
|
|
}
|
|
|
|
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;
|
|
rand = undefined;
|
|
number_cycles = 37;
|
|
|
|
if (isdefined(level.custom_magicbox_float_height))
|
|
v_float = anglestoup(self.angles) * level.custom_magicbox_float_height;
|
|
else
|
|
v_float = anglestoup(self.angles) * 40;
|
|
|
|
if (isdefined(level.custom_magic_box_weapon_wait))
|
|
[[level.custom_magic_box_weapon_wait]]();
|
|
|
|
start_origin = self.origin;
|
|
end_origin = self.origin + v_float;
|
|
angles = (self.angles + (0, 180, 0)) * (-1, 1, -1);
|
|
|
|
if (level.script == "zm_tomb")
|
|
{
|
|
v_move = anglestoright(self.angles) * -20;
|
|
start_origin = self.origin + v_float + v_move;
|
|
angles = self.angles;
|
|
}
|
|
|
|
dw_offset = (anglesToForward(angles) * -3) + (anglesToRight(angles) * -3) + (anglesToUp(angles) * -3);
|
|
|
|
self.weapon_model = spawn("script_model", start_origin);
|
|
self.weapon_model.angles = angles;
|
|
self.weapon_model_dw = spawn("script_model", self.weapon_model.origin + dw_offset);
|
|
self.weapon_model_dw.angles = self.weapon_model.angles;
|
|
self.weapon_model_dw hide();
|
|
|
|
self.weapon_model moveto(end_origin, 3, 2, 0.9);
|
|
self.weapon_model_dw moveto(end_origin + dw_offset, 3, 2, 0.9);
|
|
|
|
for (i = 0; i < number_cycles; i++)
|
|
{
|
|
rand = treasure_chest_chooseweightedrandomweapon(player, rand, 0);
|
|
modelname = getweaponmodel(rand);
|
|
|
|
if (isdefined(self.weapon_model))
|
|
{
|
|
self.weapon_model useweaponmodel(rand, modelname);
|
|
|
|
if (weapondualwieldweaponname(rand) != "none")
|
|
{
|
|
self.weapon_model_dw useweaponmodel(weapondualwieldweaponname(rand), modelname);
|
|
self.weapon_model_dw show();
|
|
}
|
|
else
|
|
{
|
|
self.weapon_model_dw hide();
|
|
}
|
|
}
|
|
|
|
if (i < 20)
|
|
{
|
|
wait 0.05;
|
|
}
|
|
else if (i < 30)
|
|
{
|
|
wait 0.1;
|
|
}
|
|
else if (i < 35)
|
|
{
|
|
wait 0.2;
|
|
}
|
|
else
|
|
{
|
|
wait 0.3;
|
|
}
|
|
}
|
|
|
|
wait 0.1;
|
|
|
|
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;
|
|
|
|
joker_origin = self.weapon_model.origin;
|
|
joker_angles = angles - vectorscale((0, 1, 0), 90.0);
|
|
|
|
if (abs(angles[2]) >= 90)
|
|
{
|
|
joker_angles = angles + vectorscale((0, 1, 0), 90.0);
|
|
joker_angles = (joker_angles[2] + 180, joker_angles[1], joker_angles[0] + 180) * (-1, 1, 1);
|
|
}
|
|
|
|
// delete and respawn the joker model so that it faces the correct angle right away
|
|
self.weapon_model delete();
|
|
self.weapon_model = spawn("script_model", joker_origin);
|
|
self.weapon_model.angles = joker_angles;
|
|
self.weapon_model setmodel(level.chest_joker_model);
|
|
self.weapon_model_dw hide();
|
|
|
|
self.chest_moving = 1;
|
|
flag_set("moving_chest_now");
|
|
level.chest_accessed = 0;
|
|
level.chest_moves++;
|
|
}
|
|
}
|
|
|
|
if (!is_true(self.chest_moving))
|
|
{
|
|
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, rand);
|
|
|
|
modelname = getweaponmodel(rand);
|
|
self.weapon_string = rand;
|
|
self.weapon_model useweaponmodel(rand, modelname);
|
|
|
|
if (weapondualwieldweaponname(rand) != "none")
|
|
{
|
|
self.weapon_model_dw useweaponmodel(weapondualwieldweaponname(rand), modelname);
|
|
self.weapon_model_dw show();
|
|
}
|
|
else
|
|
{
|
|
self.weapon_model_dw hide();
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
treasure_chest_chooseweightedrandomweapon(player, prev_weapon, add_to_acquired = 1)
|
|
{
|
|
keys = array_randomize(getarraykeys(level.zombie_weapons));
|
|
|
|
if (isdefined(level.customrandomweaponweights))
|
|
keys = player [[level.customrandomweaponweights]](keys);
|
|
|
|
pap_triggers = getentarray("specialty_weapupgrade", "script_noteworthy");
|
|
|
|
if (!isDefined(player.random_weapons_acquired))
|
|
{
|
|
player.random_weapons_acquired = [];
|
|
}
|
|
|
|
for (i = 0; i < keys.size; i++)
|
|
{
|
|
if (treasure_chest_canplayerreceiveweapon(player, keys[i], pap_triggers))
|
|
{
|
|
if (!isInArray(player.random_weapons_acquired, keys[i]))
|
|
{
|
|
if (isDefined(prev_weapon) && prev_weapon == keys[i])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (add_to_acquired)
|
|
{
|
|
player.random_weapons_acquired[player.random_weapons_acquired.size] = keys[i];
|
|
}
|
|
|
|
return keys[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isDefined(prev_weapon))
|
|
{
|
|
if (add_to_acquired)
|
|
{
|
|
player.random_weapons_acquired[player.random_weapons_acquired.size] = prev_weapon;
|
|
}
|
|
|
|
return prev_weapon;
|
|
}
|
|
|
|
if (player.random_weapons_acquired.size > 0)
|
|
{
|
|
player.random_weapons_acquired = [];
|
|
return treasure_chest_chooseweightedrandomweapon(player);
|
|
}
|
|
|
|
return keys[0];
|
|
}
|
|
|
|
treasure_chest_move(player_vox)
|
|
{
|
|
level waittill("weapon_fly_away_start");
|
|
players = get_players();
|
|
array_thread(players, maps\mp\zombies\_zm_magicbox::play_crazi_sound);
|
|
|
|
if (isDefined(player_vox))
|
|
{
|
|
player_vox delay_thread(randomintrange(2, 7), maps\mp\zombies\_zm_audio::create_and_play_dialog, "general", "box_move");
|
|
}
|
|
|
|
level waittill("weapon_fly_away_end");
|
|
|
|
if (isDefined(self.zbarrier))
|
|
{
|
|
self maps\mp\zombies\_zm_magicbox::hide_chest(1);
|
|
}
|
|
|
|
wait 0.1;
|
|
|
|
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 maps\mp\zombies\_zm_magicbox::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;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
playfx(level._effect["poltergeist"], level.chests[level.chest_index].zbarrier.origin);
|
|
level.chests[level.chest_index] maps\mp\zombies\_zm_magicbox::show_chest();
|
|
flag_clear("moving_chest_now");
|
|
self.zbarrier.chest_moving = 0;
|
|
}
|
|
|
|
default_box_move_logic()
|
|
{
|
|
index = -1;
|
|
|
|
for (i = 0; i < level.chests.size; i++)
|
|
{
|
|
if (issubstr(level.chests[i].script_noteworthy, "move" + (level.chest_moves + 1)) && i != level.chest_index)
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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.chests = array_swap(level.chests, level.chest_index, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
treasure_chest_timeout()
|
|
{
|
|
self endon("user_grabbed_weapon");
|
|
self.zbarrier endon("box_hacked_respin");
|
|
self.zbarrier endon("box_hacked_rerespin");
|
|
wait level.magicbox_timeout;
|
|
self notify("trigger", level);
|
|
}
|
|
|
|
timer_til_despawn(v_float)
|
|
{
|
|
self endon("kill_weapon_movement");
|
|
self moveto(self.origin - (v_float * 0.85), level.magicbox_timeout, level.magicbox_timeout * 0.5);
|
|
wait level.magicbox_timeout;
|
|
|
|
if (isDefined(self))
|
|
{
|
|
self delete();
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
is_grenade = 0;
|
|
|
|
if (isDefined(self.zombie_weapon_upgrade) && weaponType(self.zombie_weapon_upgrade) == "grenade")
|
|
{
|
|
is_grenade = 1;
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
last_update = gettime();
|
|
|
|
if (isdefined(self.chest_user) && !isdefined(self.box_rerespun))
|
|
{
|
|
primaries = self.chest_user getweaponslistprimaries();
|
|
weapon_limit = get_player_weapon_limit(self.chest_user);
|
|
|
|
if (primaries.size < weapon_limit)
|
|
{
|
|
self setvisibletoplayer(self.chest_user);
|
|
}
|
|
else
|
|
{
|
|
if (is_melee_weapon(self.chest_user getcurrentweapon()) || 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 (is_grenade || onlyplayer can_buy_weapon())
|
|
self setinvisibletoplayer(onlyplayer, 0);
|
|
else
|
|
self setinvisibletoplayer(onlyplayer, 1);
|
|
}
|
|
else
|
|
{
|
|
players = get_players();
|
|
|
|
for (i = 0; i < players.size; i++)
|
|
{
|
|
if (is_grenade || players[i] can_buy_weapon())
|
|
{
|
|
self setinvisibletoplayer(players[i], 0);
|
|
continue;
|
|
}
|
|
|
|
self setinvisibletoplayer(players[i], 1);
|
|
}
|
|
}
|
|
|
|
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++;
|
|
}
|
|
}
|
|
|
|
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 || self.stub.trigger_target.chest_user hacker_active())
|
|
{
|
|
visible = 0;
|
|
}
|
|
else
|
|
{
|
|
primaries = self.stub.trigger_target.chest_user getweaponslistprimaries();
|
|
weapon_limt = get_player_weapon_limit(self.stub.trigger_target.chest_user);
|
|
|
|
if (primaries.size >= weapon_limt && (is_melee_weapon(self.stub.trigger_target.chest_user getcurrentweapon()) || is_placeable_mine(self.stub.trigger_target.chest_user getcurrentweapon())))
|
|
{
|
|
visible = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
is_chest = 0;
|
|
|
|
foreach (chest in level.chests)
|
|
{
|
|
if (self.stub.trigger_target == chest)
|
|
{
|
|
is_chest = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!is_chest && !player can_buy_weapon())
|
|
{
|
|
visible = 0;
|
|
}
|
|
}
|
|
|
|
if (!visible)
|
|
return false;
|
|
|
|
self setvisibletoplayer(player);
|
|
return true;
|
|
}
|
|
|
|
can_buy_weapon()
|
|
{
|
|
if (isdefined(self.is_drinking) && self.is_drinking > 0)
|
|
return false;
|
|
|
|
if (self hacker_active())
|
|
return false;
|
|
|
|
current_weapon = self getcurrentweapon();
|
|
|
|
primaries = self getweaponslistprimaries();
|
|
weapon_limt = get_player_weapon_limit(self);
|
|
|
|
if (primaries.size >= weapon_limt && (is_melee_weapon(current_weapon) || is_placeable_mine(current_weapon) || is_equipment_that_blocks_purchase(current_weapon)))
|
|
return false;
|
|
|
|
if (self in_revive_trigger())
|
|
return false;
|
|
|
|
if (current_weapon == "none")
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
weapon_is_dual_wield(name)
|
|
{
|
|
return weapondualwieldweaponname(name) != "none";
|
|
} |