#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(); if (grabber == user && is_player_valid(user) && !(user.is_drinking > 0) && !is_melee_weapon(current_weapon) && !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"); 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); if (level.script == "zm_tomb") { v_move = anglestoright(self.angles) * -20; start_origin = self.origin + v_float + v_move; angles = self.angles; } // angle is opposite of what it should be on upside down box if (angles[2] < 0) { angles = (angles[0], angles[1], -360 - angles[2]); } 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_angles = angles - vectorscale((0, 1, 0), 90.0); if (angles[2] < 0) { joker_angles = angles + vectorscale((0, 1, 0), 90.0); } // delete and respawn the joker model so that it faces the correct angle right away origin = self.weapon_model.origin; self.weapon_model delete(); self.weapon_model = spawn("script_model", 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)) { 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 || is_melee_weapon(self.stub.trigger_target.chest_user getcurrentweapon()) || is_placeable_mine(self.stub.trigger_target.chest_user getcurrentweapon()) || self.stub.trigger_target.chest_user hacker_active()) 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(); if (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; }