Guest User

BO2 Die Rise One Room Mod Mystery Box

a guest
May 20th, 2020
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
CSS 46.18 KB | None | 0 0
  1. #include maps/mp/zombies/_zm_stats;
  2. #include maps/mp/_demo;
  3. #include maps/mp/zombies/_zm_audio;
  4. #include maps/mp/zombies/_zm_score;
  5. #include maps/mp/zombies/_zm_pers_upgrades_functions;
  6. #include maps/mp/zombies/_zm_audio_announcer;
  7. #include maps/mp/zombies/_zm_unitrigger;
  8. #include maps/mp/zombies/_zm_weapons;
  9. #include maps/mp/zombies/_zm_utility;
  10. #include maps/mp/_utility;
  11. #include common_scripts/utility;
  12.  
  13. init() //checked matches cerberus output
  14. {
  15.     //begin debug code
  16.     level.custom_zm_magicbox_loaded = 1;
  17.     maps/mp/zombies/_zm_bot::init();
  18.     if ( !isDefined( level.debugLogging_zm_magicbox ) )
  19.     {
  20.         level.debugLogging_zm_magicbox = 0;
  21.     }
  22.     //end debug code
  23.     if ( level.debugLogging_zm_magicbox )
  24.     {
  25.         logline7 = "_zm_magicbox.gsc init() is called" + "\n";
  26.         logprint( logline7 );
  27.     }
  28.     if ( !isDefined( level.chest_joker_model ) )
  29.     {
  30.         level.chest_joker_model = "zombie_teddybear";
  31.         precachemodel( level.chest_joker_model );
  32.     }
  33.    
  34.     if ( !isDefined( level.magic_box_zbarrier_state_func ) )
  35.     {
  36.         level.magic_box_zbarrier_state_func = ::process_magic_box_zbarrier_state;
  37.     }
  38.    
  39.     if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox )
  40.     {
  41.         maps/mp/zombies/_zm_magicbox_lock::init();
  42.     }
  43.     if ( is_classic() )
  44.     {
  45.         level.chests = getstructarray( "treasure_chest_use", "targetname" );
  46.         normalChests = level.chests;
  47.         if ( level.script == "zm_highrise" )
  48.         {
  49.             level.chests = [];
  50.             level.chests[ 0 ] = normalChests[ 1 ];
  51.             treasure_chest_init( "ob6_chest" );
  52.         }
  53.         else
  54.         {
  55.             treasure_chest_init( "start_chest" );
  56.         }
  57.         if ( level.debugLogging_zm_magicbox )
  58.         {
  59.             logline7 = "_zm_magicbox.gsc init() calls treasure_chest_init() on start chest" + "\n";
  60.             logprint( logline7 );
  61.         }
  62.     }
  63.     if ( level.createfx_enabled )
  64.     {
  65.         return;
  66.     }
  67.     registerclientfield( "zbarrier", "magicbox_glow", 1000, 1, "int" );
  68.     registerclientfield( "zbarrier", "zbarrier_show_sounds", 9000, 1, "int" );
  69.     registerclientfield( "zbarrier", "zbarrier_leave_sounds", 9000, 1, "int" );
  70.     if ( !isDefined( level.magic_box_check_equipment ) )
  71.     {
  72.         level.magic_box_check_equipment = ::default_magic_box_check_equipment;
  73.     }
  74.     level thread magicbox_host_migration();
  75.     if ( level.debugLogging_zm_magicbox )
  76.     {
  77.         logline1 = "_zm_magicbox.gsc init() has fully parsed" + "\n";
  78.         logprint( logline1 );
  79.     }
  80. }
  81.  
  82. treasure_chest_init( start_chest_name ) //checked changed to match cerberus output
  83. {
  84.     flag_init( "moving_chest_enabled" );
  85.     flag_init( "moving_chest_now" );
  86.     flag_init( "chest_has_been_used" );
  87.     level.chest_moves = 0;
  88.     level.chest_level = 0;
  89.     if ( level.chests.size == 0 )
  90.     {
  91.         return;
  92.     }
  93.     for ( i = 0; i < level.chests.size; i++ )
  94.     {
  95.         level.chests[ i ].box_hacks = [];
  96.         level.chests[ i ].orig_origin = level.chests[ i ].origin;
  97.         level.chests[ i ] get_chest_pieces();
  98.         if ( isDefined( level.chests[ i ].zombie_cost ) )
  99.         {
  100.             level.chests[ i ].old_cost = level.chests[ i ].zombie_cost;
  101.         }
  102.         else
  103.         {
  104.             level.chests[ i ].old_cost = 950;
  105.         }
  106.     }
  107.     if ( !level.enable_magic )
  108.     {
  109.         if ( level.debugLogging_zm_magicbox )
  110.         {
  111.             logline2 = "_zm_magicbox.gsc treasure_chest_init() found that magic is not enabled; calling hide_chest() on each box and returning" + "\n";
  112.             logprint( logline2 );
  113.         }
  114.         foreach( chest in level.chests )
  115.         {
  116.             chest hide_chest();
  117.         }
  118.         return;
  119.     }
  120.     level.chest_accessed = 0;
  121.     if ( level.chests.size > 1 )
  122.     {
  123.         if ( level.debugLogging_zm_magicbox )
  124.         {
  125.             logline3 = "_zm_magicbox.gsc treasure_chest_init() found multiple boxes; enabling moving box; randomizing chests" + "\n";
  126.             logprint( logline3 );
  127.         }
  128.         flag_set( "moving_chest_enabled" );
  129.         level.chests = array_randomize( level.chests );
  130.     }
  131.     else
  132.     {
  133.         if ( level.debugLogging_zm_magicbox )
  134.         {
  135.             logline4 = "_zm_magicbox.gsc treasure_chest_init() found only one box; setting level.chest_index to 0 and level.chests[ 0 ].no_fly_away to 1" + "\n";
  136.             logprint( logline4 );
  137.         }
  138.         level.chest_index = 0;
  139.         level.chests[ 0 ].no_fly_away = 1;
  140.     }
  141.     init_starting_chest_location( start_chest_name );
  142.     array_thread( level.chests, ::treasure_chest_think );
  143. }
  144.  
  145. init_starting_chest_location( start_chest_name ) //checked changed to match cerberus output
  146. {
  147.     level.chest_index = 0;
  148.     start_chest_found = 0;
  149.     if ( level.chests.size == 1 )
  150.     {
  151.         start_chest_found = 1;
  152.         if ( isdefined( level.chests[ level.chest_index ].zbarrier ) )
  153.         {
  154.             level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" );
  155.         }
  156.     }
  157.     i = 0;
  158.     while ( i < level.chests.size )
  159.     {
  160.         if ( isdefined( level.random_pandora_box_start ) && level.random_pandora_box_start == 1 )
  161.         {
  162.             if ( start_chest_found || isdefined(level.chests[ i ].start_exclude ) && level.chests[ i ].start_exclude == 1 )
  163.             {
  164.                 level.chests[ i ] hide_chest();
  165.             }
  166.             else
  167.             {
  168.                 level.chest_index = i;
  169.                 level.chests[ level.chest_index].hidden = 0;
  170.                 if ( isdefined( level.chests[ level.chest_index ].zbarrier ) )
  171.                 {
  172.                     level.chests[level.chest_index].zbarrier set_magic_box_zbarrier_state("initial");
  173.                 }
  174.                 start_chest_found = 1;
  175.             }
  176.             i++;
  177.             continue;
  178.         }
  179.         if ( start_chest_found || !isdefined(level.chests[ i ].script_noteworthy) || !issubstr( level.chests[ i ].script_noteworthy, start_chest_name ) )
  180.         {
  181.             level.chests[i] hide_chest();
  182.             i++;
  183.             continue;
  184.         }
  185.         level.chest_index = i;
  186.         level.chests[ level.chest_index ].hidden = 0;
  187.         if ( isdefined( level.chests[ level.chest_index ].zbarrier ) )
  188.         {
  189.             level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" );
  190.         }
  191.         i++;
  192.         start_chest_found = 1;
  193.     }
  194.     if ( !isdefined( level.pandora_show_func ) )
  195.     {
  196.         level.pandora_show_func = ::default_pandora_show_func;
  197.     }
  198.     level.chests[ level.chest_index ] thread [[ level.pandora_show_func ]]();
  199. }
  200.  
  201. set_treasure_chest_cost( cost ) //checked matches cerberus output
  202. {
  203.     if ( level.debugLogging_zm_magicbox )
  204.     {
  205.         logline5 = "_zm_magicbox.gsc set_treasure_chest_cost() set the cost of the boxes to: " + cost + " \n";
  206.         logprint( logline5 );
  207.     }
  208.     level.zombie_treasure_chest_cost = cost;
  209. }
  210.  
  211. get_chest_pieces() //checked changed to match cerberus output
  212. {
  213.     self.chest_box = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" );
  214.     self.chest_rubble = [];
  215.     rubble = getentarray( self.script_noteworthy + "_rubble", "script_noteworthy" );
  216.     for ( i = 0; i < rubble.size; i++ )
  217.     {
  218.         if ( distancesquared( self.origin, rubble[ i ].origin ) < 10000 )
  219.         {
  220.             self.chest_rubble[ self.chest_rubble.size ] = rubble[ i ];
  221.         }
  222.     }
  223.     self.zbarrier = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" );
  224.     if ( isDefined( self.zbarrier ) )
  225.     {
  226.         self.zbarrier zbarrierpieceuseboxriselogic( 3 );
  227.         self.zbarrier zbarrierpieceuseboxriselogic( 4 );
  228.     }
  229.     self.unitrigger_stub = spawnstruct();
  230.     self.unitrigger_stub.origin = self.origin + anglesToRight( self.angles * -22.5 );
  231.     self.unitrigger_stub.angles = self.angles;
  232.     self.unitrigger_stub.script_unitrigger_type = "unitrigger_box_use";
  233.     self.unitrigger_stub.script_width = 104;
  234.     self.unitrigger_stub.script_height = 50;
  235.     self.unitrigger_stub.script_length = 45;
  236.     self.unitrigger_stub.trigger_target = self;
  237.     unitrigger_force_per_player_triggers( self.unitrigger_stub, 1 );
  238.     self.unitrigger_stub.prompt_and_visibility_func = ::boxtrigger_update_prompt;
  239.     self.zbarrier.owner = self;
  240. }
  241.  
  242. boxtrigger_update_prompt( player ) //checked matches cerberus output
  243. {
  244.     can_use = self boxstub_update_prompt( player );
  245.     if ( isDefined( self.hint_string ) )
  246.     {
  247.         if ( isDefined( self.hint_parm1 ) )
  248.         {
  249.             self sethintstring( self.hint_string, self.hint_parm1 );
  250.         }
  251.         else
  252.         {
  253.             self sethintstring( self.hint_string );
  254.         }
  255.     }
  256.     return can_use;
  257. }
  258.  
  259. boxstub_update_prompt( player ) //checked matches cerberus output
  260. {
  261.     self setcursorhint( "HINT_NOICON" );
  262.     if ( !self trigger_visible_to_player( player ) )
  263.     {
  264.         return 0;
  265.     }
  266.     self.hint_parm1 = undefined;
  267.     if ( isDefined( self.stub.trigger_target.grab_weapon_hint ) && self.stub.trigger_target.grab_weapon_hint )
  268.     {
  269.         if ( isDefined( level.magic_box_check_equipment ) && [[ level.magic_box_check_equipment ]]( self.stub.trigger_target.grab_weapon_name ) )
  270.         {
  271.             self.hint_string = &"ZOMBIE_TRADE_EQUIP";
  272.         }
  273.         else
  274.         {
  275.             self.hint_string = &"ZOMBIE_TRADE_WEAPON";
  276.         }
  277.     }
  278.     else if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox && isDefined( self.stub.trigger_target.is_locked ) && self.stub.trigger_target.is_locked )
  279.     {
  280.         self.hint_string = get_hint_string( self, "locked_magic_box_cost" );
  281.     }
  282.     else
  283.     {
  284.         self.hint_parm1 = self.stub.trigger_target.zombie_cost;
  285.         self.hint_string = get_hint_string( self, "default_treasure_chest" );
  286.     }
  287.     return 1;
  288. }
  289.  
  290. default_magic_box_check_equipment( weapon ) //checked matches cerberus output
  291. {
  292.     return is_offhand_weapon( weapon );
  293. }
  294.  
  295. trigger_visible_to_player( player ) //checked changed to match cerberus output
  296. {
  297.     self setinvisibletoplayer( player );
  298.     visible = 1;
  299.     if ( isDefined( self.stub.trigger_target.chest_user ) && !isDefined( self.stub.trigger_target.box_rerespun ) )
  300.     {
  301.         if ( player != self.stub.trigger_target.chest_user || is_placeable_mine( self.stub.trigger_target.chest_user getcurrentweapon() ) || self.stub.trigger_target.chest_user hacker_active() )
  302.         {
  303.             visible = 0;
  304.         }
  305.     }
  306.     else if ( !player can_buy_weapon() )
  307.     {
  308.         visible = 0;
  309.     }
  310.     if ( !visible )
  311.     {
  312.         return 0;
  313.     }
  314.     self setvisibletoplayer( player );
  315.     return 1;
  316. }
  317.  
  318. magicbox_unitrigger_think() //checked changed to match cerberus output
  319. {
  320.     self endon( "kill_trigger" );
  321.     while ( 1 )
  322.     {
  323.         self waittill( "trigger", player );
  324.         self.stub.trigger_target notify( "trigger", player );
  325.     }
  326. }
  327.  
  328. play_crazi_sound() //checked matches cerberus output
  329. {
  330.     self playlocalsound( level.zmb_laugh_alias );
  331. }
  332.  
  333. show_chest_sound_thread() //checked matches cerberus output
  334. {
  335.     self.zbarrier setclientfield( "zbarrier_show_sounds", 1 );
  336.     wait 1;
  337.     self.zbarrier setclientfield( "zbarrier_show_sounds", 0 );
  338. }
  339.  
  340. show_chest() //checked matches cerberus output
  341. {
  342.     self.zbarrier set_magic_box_zbarrier_state( "arriving" );
  343.     self.zbarrier waittill( "arrived" );
  344.     self thread [[ level.pandora_show_func ]]();
  345.     thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think );
  346.     self thread show_chest_sound_thread();
  347.     self.hidden = 0;
  348.     if ( isDefined( self.box_hacks[ "summon_box" ] ) )
  349.     {
  350.         self [[ self.box_hacks[ "summon_box" ] ]]( 0 );
  351.     }
  352. }
  353.  
  354. hide_chest_sound_thread() //checked matches cerberus output
  355. {
  356.     self.zbarrier setclientfield( "zbarrier_leave_sounds", 1 );
  357.     wait 1;
  358.     self.zbarrier setclientfield( "zbarrier_leave_sounds", 0 );
  359. }
  360.  
  361. hide_chest( doboxleave ) //checked matches cerberus output
  362. {
  363.     if ( isDefined( self.unitrigger_stub ) )
  364.     {
  365.         thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub );
  366.     }
  367.     if ( isDefined( self.pandora_light ) )
  368.     {
  369.         self.pandora_light delete();
  370.     }
  371.     self.hidden = 1;
  372.     if ( isDefined( self.box_hacks ) && isDefined( self.box_hacks[ "summon_box" ] ) )
  373.     {
  374.         self [[ self.box_hacks[ "summon_box" ] ]]( 1 );
  375.     }
  376.     if ( isDefined( self.zbarrier ) )
  377.     {
  378.         if ( isDefined( doboxleave ) && doboxleave )
  379.         {
  380.             self thread hide_chest_sound_thread();
  381.             level thread leaderdialog( "boxmove" );
  382.             self.zbarrier thread magic_box_zbarrier_leave();
  383.             self.zbarrier waittill( "left" );
  384.             playfx( level._effect[ "poltergeist" ], self.zbarrier.origin, anglesToUp( self.angles ), anglesToForward( self.angles ) );
  385.             playsoundatposition( "zmb_box_poof", self.zbarrier.origin );
  386.             return;
  387.         }
  388.         else
  389.         {
  390.             self.zbarrier thread set_magic_box_zbarrier_state( "away" );
  391.         }
  392.     }
  393. }
  394.  
  395. magic_box_zbarrier_leave() //checked matches cerberus output
  396. {
  397.     self set_magic_box_zbarrier_state( "leaving" );
  398.     self waittill( "left" );
  399.     self set_magic_box_zbarrier_state( "away" );
  400. }
  401.  
  402. default_pandora_fx_func() //checked partially changed to match cerberus output
  403. {
  404.     self endon( "death" );
  405.     self.pandora_light = spawn( "script_model", self.zbarrier.origin );
  406.     self.pandora_light.angles = self.zbarrier.angles + vectorScale( ( -1, 0, -1 ), 90 );
  407.     self.pandora_light setmodel( "tag_origin" );
  408.     if ( isDefined( level._box_initialized ) && !level._box_initialized )
  409.     {
  410.         flag_wait( "start_zombie_round_logic" );
  411.         level._box_initialized = 1;
  412.     }
  413.     wait 1;
  414.     if ( isDefined( self ) && isDefined( self.pandora_light ) )
  415.     {
  416.         playfxontag( level._effect[ "lght_marker" ], self.pandora_light, "tag_origin" );
  417.     }
  418. }
  419.  
  420. default_pandora_show_func( anchor, anchortarget, pieces ) //checked matches cerberus output
  421. {
  422.     if ( !isDefined( self.pandora_light ) )
  423.     {
  424.         if ( !isDefined( level.pandora_fx_func ) )
  425.         {
  426.             level.pandora_fx_func = ::default_pandora_fx_func;
  427.         }
  428.         self thread [[ level.pandora_fx_func ]]();
  429.     }
  430.     playfx( level._effect[ "lght_marker_flare" ], self.pandora_light.origin );
  431. }
  432.  
  433. unregister_unitrigger_on_kill_think() //checked matches cerberus output
  434. {
  435.     self notify( "unregister_unitrigger_on_kill_think" );
  436.     self endon( "unregister_unitrigger_on_kill_think" );
  437.     self waittill( "kill_chest_think" );
  438.     thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub );
  439. }
  440.  
  441. treasure_chest_think() //checked changed to match cerberus output
  442. {
  443.     if ( level.debugLogging_zm_magicbox )
  444.     {
  445.         logline6 = "_zm_magicbox.gsc treasure_chest_think() is called" + "\n";
  446.         logprint( logline6 );
  447.     }
  448.     self endon( "kill_chest_think" );
  449.     user = undefined;
  450.     user_cost = undefined;
  451.     self.box_rerespun = undefined;
  452.     self.weapon_out = undefined;
  453.  
  454.     self thread unregister_unitrigger_on_kill_think();
  455.     while ( 1 )
  456.     {
  457.         if ( !isdefined( self.forced_user ) )
  458.         {
  459.             self waittill( "trigger", user );
  460.             if ( user == level )
  461.             {
  462.                 wait 0.1;
  463.                 continue;
  464.             }
  465.         }
  466.         else
  467.         {
  468.             user = self.forced_user;
  469.         }
  470.         if ( user in_revive_trigger() )
  471.         {
  472.             wait 0.1;
  473.             continue;
  474.         }
  475.         if ( user.is_drinking > 0 )
  476.         {
  477.             wait 0.1;
  478.             continue;
  479.         }
  480.         if ( isdefined( self.disabled ) && self.disabled )
  481.         {
  482.             wait 0.1;
  483.             continue;
  484.         }
  485.         if ( user getcurrentweapon() == "none" )
  486.         {
  487.             wait 0.1;
  488.             continue;
  489.         }
  490.         reduced_cost = undefined;
  491.         if ( is_player_valid( user ) && user maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() )
  492.         {
  493.             reduced_cost = int( self.zombie_cost / 2 );
  494.         }
  495.         if ( isdefined( level.using_locked_magicbox ) && level.using_locked_magicbox && isdefined( self.is_locked ) && self.is_locked )
  496.         {
  497.             if ( user.score >= level.locked_magic_box_cost )
  498.             {
  499.                 user maps/mp/zombies/_zm_score::minus_to_player_score( level.locked_magic_box_cost );
  500.                 self.zbarrier set_magic_box_zbarrier_state( "unlocking" );
  501.                 self.unitrigger_stub run_visibility_function_for_all_triggers();
  502.             }
  503.             else
  504.             {
  505.                 user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" );
  506.             }
  507.             wait 0.1 ;
  508.             continue;
  509.         }
  510.         else if ( isdefined( self.auto_open ) && is_player_valid( user ) )
  511.         {
  512.             if ( !isdefined( self.no_charge ) )
  513.             {
  514.                 user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost );
  515.                 user_cost = self.zombie_cost;
  516.             }
  517.             else
  518.             {
  519.                 user_cost = 0;
  520.             }
  521.             self.chest_user = user;
  522.             break;
  523.         }
  524.         else if ( is_player_valid( user ) && user.score >= self.zombie_cost )
  525.         {
  526.             user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost );
  527.             user_cost = self.zombie_cost;
  528.             self.chest_user = user;
  529.             break;
  530.         }
  531.         else if ( isdefined( reduced_cost ) && user.score >= reduced_cost )
  532.         {
  533.             user maps/mp/zombies/_zm_score::minus_to_player_score( reduced_cost );
  534.             user_cost = reduced_cost;
  535.             self.chest_user = user;
  536.             break;
  537.         }
  538.         else if ( user.score < self.zombie_cost )
  539.         {
  540.             play_sound_at_pos( "no_purchase", self.origin );
  541.             user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" );
  542.             wait 0.1;
  543.             continue;
  544.         }
  545.         wait 0.05;
  546.     }
  547.     flag_set( "chest_has_been_used" );
  548.     maps/mp/_demo::bookmark( "zm_player_use_magicbox", getTime(), user );
  549.     user maps/mp/zombies/_zm_stats::increment_client_stat( "use_magicbox" );
  550.     user maps/mp/zombies/_zm_stats::increment_player_stat( "use_magicbox" );
  551.     if ( isDefined( level._magic_box_used_vo ) )
  552.     {
  553.         user thread [[ level._magic_box_used_vo ]]();
  554.     }
  555.     self thread watch_for_emp_close();
  556.     if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox )
  557.     {
  558.         self thread maps/mp/zombies/_zm_magicbox_lock::watch_for_lock();
  559.     }
  560.     self._box_open = 1;
  561.     self._box_opened_by_fire_sale = 0;
  562.     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 ]]() )
  563.     {
  564.         self._box_opened_by_fire_sale = 1;
  565.     }
  566.     if ( isDefined( self.chest_lid ) )
  567.     {
  568.         self.chest_lid thread treasure_chest_lid_open();
  569.     }
  570.     if ( isDefined( self.zbarrier ) )
  571.     {
  572.         play_sound_at_pos( "open_chest", self.origin );
  573.         play_sound_at_pos( "music_chest", self.origin );
  574.         self.zbarrier set_magic_box_zbarrier_state( "open" );
  575.     }
  576.     self.timedout = 0;
  577.     self.weapon_out = 1;
  578.     self.zbarrier thread treasure_chest_weapon_spawn( self, user );
  579.     self.zbarrier thread treasure_chest_glowfx();
  580.     thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub );
  581.     self.zbarrier waittill_any( "randomization_done", "box_hacked_respin" );
  582.     if ( flag( "moving_chest_now" ) && !self._box_opened_by_fire_sale && isDefined( user_cost ) )
  583.     {
  584.         user maps/mp/zombies/_zm_score::add_to_player_score( user_cost, 0 );
  585.     }
  586.     if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !self._box_opened_by_fire_sale )
  587.     {
  588.         self thread treasure_chest_move( self.chest_user );
  589.     }
  590.     else
  591.     {
  592.         self.grab_weapon_hint = 1;
  593.         self.grab_weapon_name = self.zbarrier.weapon_string;
  594.         self.chest_user = user;
  595.         thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think );
  596.         if ( isDefined( self.zbarrier ) && !is_true( self.zbarrier.closed_by_emp ) )
  597.         {
  598.             self thread treasure_chest_timeout();
  599.         }
  600.         while ( isDefined( self.closed_by_emp ) && !self.closed_by_emp )
  601.         {
  602.             self waittill( "trigger", grabber );
  603.             self.weapon_out = undefined;
  604.             if ( isDefined( level.magic_box_grab_by_anyone ) && level.magic_box_grab_by_anyone )
  605.             {
  606.                 if ( isplayer( grabber ) )
  607.                 {
  608.                     user = grabber;
  609.                 }
  610.             }
  611.             if ( level.debugLogging_zm_magicbox )
  612.             {
  613.                 if ( !isDefined( grabber ) )
  614.                 {
  615.                     logline12 = "_zm_magicbox.gsc treasure_chest_think() grabber is undefined" + "\n";
  616.                     logprint( logline12 );
  617.                 }
  618.                 else
  619.                 {
  620.                     logline13 = "_zm_magicbox.gsc treasure_chest_think() grabber is defined as: " + grabber + "\n";
  621.                     logprint( logline13 );
  622.                 }
  623.             }
  624.             if ( isDefined( level.pers_upgrade_box_weapon ) && level.pers_upgrade_box_weapon )
  625.             {
  626.                 self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_box_weapon_used( user, grabber );
  627.             }
  628.             if ( isDefined( grabber.is_drinking ) && grabber.is_drinking > 0 )
  629.             {
  630.                 wait 0.1;
  631.                 continue;
  632.             }
  633.             if ( grabber == user && user getcurrentweapon() == "none" )
  634.             {
  635.                 wait 0.1;
  636.                 continue;
  637.             }
  638.             if ( grabber != level && isDefined( self.box_rerespun ) && self.box_rerespun )
  639.             {
  640.                 user = grabber;
  641.             }
  642.             if ( grabber == user || grabber == level )
  643.             {
  644.                 self.box_rerespun = undefined;
  645.                 current_weapon = "none";
  646.                 if ( is_player_valid( user ) )
  647.                 {
  648.                     current_weapon = user getcurrentweapon();
  649.                 }
  650.                 if ( grabber == user && is_player_valid( user ) && !user.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon )
  651.                 {
  652.                     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" );
  653.                     self notify( "user_grabbed_weapon" );
  654.                     user notify( "user_grabbed_weapon" );
  655.                     user thread treasure_chest_give_weapon( self.zbarrier.weapon_string );
  656.                     maps/mp/_demo::bookmark( "zm_player_grabbed_magicbox", getTime(), user );
  657.                     user maps/mp/zombies/_zm_stats::increment_client_stat( "grabbed_from_magicbox" );
  658.                     user maps/mp/zombies/_zm_stats::increment_player_stat( "grabbed_from_magicbox" );
  659.                     break;
  660.                 }
  661.                 else if ( grabber == level )
  662.                 {
  663.                     unacquire_weapon_toggle( self.zbarrier.weapon_string );
  664.                     self.timedout = 1;
  665.                     if ( is_player_valid( user ) )
  666.                     {
  667.                         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" );
  668.                     }
  669.                     break;
  670.                 }
  671.             }
  672.             wait 0.05;
  673.         }
  674.         self.grab_weapon_hint = 0;
  675.         self.zbarrier notify( "weapon_grabbed" );
  676.         if ( isDefined( self._box_opened_by_fire_sale ) && !self._box_opened_by_fire_sale )
  677.         {
  678.             level.chest_accessed += 1;
  679.         }
  680.         if ( level.chest_moves > 0 && isDefined( level.pulls_since_last_ray_gun ) )
  681.         {
  682.             level.pulls_since_last_ray_gun += 1;
  683.         }
  684.         if ( isDefined( level.pulls_since_last_tesla_gun ) )
  685.         {
  686.             level.pulls_since_last_tesla_gun += 1;
  687.         }
  688.         thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub );
  689.         if ( isDefined( self.chest_lid ) )
  690.         {
  691.             self.chest_lid thread treasure_chest_lid_close( self.timedout );
  692.         }
  693.         if ( isDefined( self.zbarrier ) )
  694.         {
  695.             self.zbarrier set_magic_box_zbarrier_state( "close" );
  696.             play_sound_at_pos( "close_chest", self.origin );
  697.             self.zbarrier waittill( "closed" );
  698.             wait 1;
  699.         }
  700.         else
  701.         {
  702.             wait 3;
  703.         }
  704.         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 ] )
  705.         {
  706.             thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think );
  707.         }
  708.     }
  709.     self._box_open = 0;
  710.     self._box_opened_by_fire_sale = 0;
  711.     self.chest_user = undefined;
  712.     self notify( "chest_accessed" );
  713.     self thread treasure_chest_think();
  714. }
  715.  
  716. watch_for_emp_close() //checked changed to match cerberus output
  717. {
  718.     self endon( "chest_accessed" );
  719.     self.closed_by_emp = 0;
  720.     if ( !should_watch_for_emp() )
  721.     {
  722.         return;
  723.     }
  724.     if ( isDefined( self.zbarrier ) )
  725.     {
  726.         self.zbarrier.closed_by_emp = 0;
  727.     }
  728.     while ( 1 )
  729.     {
  730.         level waittill( "emp_detonate", origin, radius );
  731.         if ( distancesquared( origin, self.origin ) < ( radius * radius ) )
  732.         {
  733.             break;
  734.         }
  735.     }
  736.     if ( flag( "moving_chest_now" ) )
  737.     {
  738.         return;
  739.     }
  740.     self.closed_by_emp = 1;
  741.     if ( isDefined( self.zbarrier ) )
  742.     {
  743.         self.zbarrier.closed_by_emp = 1;
  744.         self.zbarrier notify( "box_hacked_respin" );
  745.         if ( isDefined( self.zbarrier.weapon_model ) )
  746.         {
  747.             self.zbarrier.weapon_model notify( "kill_weapon_movement" );
  748.         }
  749.         if ( isDefined( self.zbarrier.weapon_model_dw ) )
  750.         {
  751.             self.zbarrier.weapon_model_dw notify( "kill_weapon_movement" );
  752.         }
  753.     }
  754.     wait 0.1;
  755.     self notify( "trigger" );
  756. }
  757.  
  758. can_buy_weapon() //checked matches cerberus output
  759. {
  760.     if ( isDefined( self.is_drinking ) && self.is_drinking > 0 )
  761.     {
  762.         return 0;
  763.     }
  764.     if ( self hacker_active() )
  765.     {
  766.         return 0;
  767.     }
  768.     current_weapon = self getcurrentweapon();
  769.     if ( is_placeable_mine( current_weapon ) || is_equipment_that_blocks_purchase( current_weapon ) )
  770.     {
  771.         return 0;
  772.     }
  773.     if ( self in_revive_trigger() )
  774.     {
  775.         return 0;
  776.     }
  777.     if ( current_weapon == "none" )
  778.     {
  779.         return 0;
  780.     }
  781.     return 1;
  782. }
  783.  
  784. default_box_move_logic() //checked changed to match cerberus output
  785. {
  786.     index = -1;
  787.     for ( i = 0; i < level.chests.size; i++ )
  788.     {
  789.         if ( issubstr( level.chests[ i ].script_noteworthy, "move" + level.chest_moves + 1 ) && i != level.chest_index )
  790.         {
  791.             index = i;
  792.             break;
  793.         }
  794.     }
  795.     if ( index != -1 )
  796.     {
  797.         level.chest_index = index;
  798.     }
  799.     else
  800.     {
  801.         level.chest_index++;
  802.     }
  803.     if ( level.chest_index >= level.chests.size )
  804.     {
  805.         temp_chest_name = level.chests[ level.chest_index - 1 ].script_noteworthy;
  806.         level.chest_index = 0;
  807.         level.chests = array_randomize( level.chests );
  808.         if ( temp_chest_name == level.chests[ level.chest_index ].script_noteworthy )
  809.         {
  810.             level.chest_index++;
  811.         }
  812.     }
  813. }
  814.  
  815. treasure_chest_move( player_vox ) //checked changed to match cerberus output
  816. {
  817.     level waittill( "weapon_fly_away_start" );
  818.     players = get_players();
  819.     array_thread( players, ::play_crazi_sound );
  820.     if ( isDefined( player_vox ) )
  821.     {
  822.         player_vox delay_thread( randomintrange( 2, 7 ), ::create_and_play_dialog, "general", "box_move" );
  823.     }
  824.     level waittill( "weapon_fly_away_end" );
  825.     if ( isDefined( self.zbarrier ) )
  826.     {
  827.         self hide_chest( 1 );
  828.     }
  829.     wait 0.1;
  830.     post_selection_wait_duration = 7;
  831.     if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() )
  832.     {
  833.         current_sale_time = level.zombie_vars[ "zombie_powerup_fire_sale_time" ];
  834.         wait_network_frame();
  835.         self thread fire_sale_fix();
  836.         level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = current_sale_time;
  837.         while ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 )
  838.         {
  839.             wait 0.1;
  840.         }
  841.     }
  842.     else
  843.     {
  844.         post_selection_wait_duration += 5;
  845.     }
  846.     level.verify_chest = 0;
  847.     if ( isDefined( level._zombiemode_custom_box_move_logic ) )
  848.     {
  849.         [[ level._zombiemode_custom_box_move_logic ]]();
  850.     }
  851.     else
  852.     {
  853.         default_box_move_logic();
  854.     }
  855.     if ( isDefined( level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ) )
  856.     {
  857.         level.chests[ level.chest_index ] [[ level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ]]( 0 );
  858.     }
  859.     wait post_selection_wait_duration;
  860.     playfx( level._effect[ "poltergeist" ], level.chests[ level.chest_index ].zbarrier.origin );
  861.     level.chests[ level.chest_index ] show_chest();
  862.     flag_clear( "moving_chest_now" );
  863.     self.zbarrier.chest_moving = 0;
  864. }
  865.  
  866. fire_sale_fix() //checked matches cerberus output
  867. {
  868.     if ( !isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) )
  869.     {
  870.         return;
  871.     }
  872.     if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] )
  873.     {
  874.         self.old_cost = 950;
  875.         self thread show_chest();
  876.         self.zombie_cost = 10;
  877.         self.unitrigger_stub unitrigger_set_hint_string( self, "default_treasure_chest", self.zombie_cost );
  878.         wait_network_frame();
  879.         level waittill( "fire_sale_off" );
  880.         while ( isDefined( self._box_open ) && self._box_open )
  881.         {
  882.             wait 0.1;
  883.         }
  884.         self hide_chest( 1 );
  885.         self.zombie_cost = self.old_cost;
  886.     }
  887. }
  888.  
  889. check_for_desirable_chest_location() //checked changed to match cerberus output
  890. {
  891.     if ( !isDefined( level.desirable_chest_location ) )
  892.     {
  893.         return level.chest_index;
  894.     }
  895.     if ( level.chests[ level.chest_index ].script_noteworthy == level.desirable_chest_location )
  896.     {
  897.         level.desirable_chest_location = undefined;
  898.         return level.chest_index;
  899.     }
  900.     for ( i = 0; i < level.chests.size; i++ )
  901.     {
  902.         if ( level.chests[ i ].script_noteworthy == level.desirable_chest_location )
  903.         {
  904.             level.desirable_chest_location = undefined;
  905.             return i;
  906.         }
  907.     }
  908.     /*
  909. /#
  910.     iprintln( level.desirable_chest_location + " is an invalid box location!" );
  911. #/
  912.     */
  913.     level.desirable_chest_location = undefined;
  914.     return level.chest_index;
  915. }
  916.  
  917. rotateroll_box() //checked matches cerberus output
  918. {
  919.     angles = 40;
  920.     angles2 = 0;
  921.     while ( isDefined( self ) )
  922.     {
  923.         self rotateroll( angles + angles2, 0.5 );
  924.         wait 0.7;
  925.         angles2 = 40;
  926.         self rotateroll( angles * -2, 0.5 );
  927.         wait 0.7;
  928.     }
  929. }
  930.  
  931. verify_chest_is_open() //checked changed to match cerberus output
  932. {
  933.     for ( i = 0; i < level.open_chest_location.size; i++ )
  934.     {
  935.         if ( isDefined( level.open_chest_location[ i ] ) )
  936.         {
  937.             if ( level.open_chest_location[ i ] == level.chests[ level.chest_index ].script_noteworthy )
  938.             {
  939.                 level.verify_chest = 1;
  940.                 return;
  941.             }
  942.         }
  943.     }
  944.     level.verify_chest = 0;
  945. }
  946.  
  947. treasure_chest_timeout() //checked changed to match cerberus output
  948. {
  949.     self endon( "user_grabbed_weapon" );
  950.     self.zbarrier endon( "box_hacked_respin" );
  951.     self.zbarrier endon( "box_hacked_rerespin" );
  952.     wait 12;
  953.     self notify( "trigger", level );
  954. }
  955.  
  956. treasure_chest_lid_open() //checked matches cerberus output
  957. {
  958.     openroll = 105;
  959.     opentime = 0.5;
  960.     self rotateroll( 105, opentime, opentime * 0.5 );
  961.     play_sound_at_pos( "open_chest", self.origin );
  962.     play_sound_at_pos( "music_chest", self.origin );
  963. }
  964.  
  965. treasure_chest_lid_close( timedout ) //checked matches cerberus output
  966. {
  967.     closeroll = -105;
  968.     closetime = 0.5;
  969.     self rotateroll( closeroll, closetime, closetime * 0.5 );
  970.     play_sound_at_pos( "close_chest", self.origin );
  971.     self notify( "lid_closed" );
  972. }
  973.  
  974. treasure_chest_chooserandomweapon( player ) //checked matches cerberus output
  975. {
  976.     keys = getarraykeys( level.zombie_weapons );
  977.     return keys[ randomint( keys.size ) ];
  978. }
  979.  
  980. treasure_chest_canplayerreceiveweapon( player, weapon, pap_triggers ) //checked matches cerberus output
  981. {
  982.     if ( !get_is_in_box( weapon ) )
  983.     {
  984.         return 0;
  985.     }
  986.     if ( isDefined( player ) && player has_weapon_or_upgrade( weapon ) )
  987.     {
  988.         return 0;
  989.     }
  990.     if ( !limited_weapon_below_quota( weapon, player, pap_triggers ) )
  991.     {
  992.         return 0;
  993.     }
  994.     if ( !player player_can_use_content( weapon ) )
  995.     {
  996.         return 0;
  997.     }
  998.     if ( isDefined( level.custom_magic_box_selection_logic ) )
  999.     {
  1000.         if ( !( [[ level.custom_magic_box_selection_logic ]]( weapon, player, pap_triggers ) ) )
  1001.         {
  1002.             return 0;
  1003.         }
  1004.     }
  1005.     if ( isDefined( player ) && isDefined( level.special_weapon_magicbox_check ) )
  1006.     {
  1007.         return player [[ level.special_weapon_magicbox_check ]]( weapon );
  1008.     }
  1009.     return 1;
  1010. }
  1011.  
  1012. treasure_chest_chooseweightedrandomweapon( player ) //checked changed to match cerberus output
  1013. {
  1014.     keys = array_randomize( getarraykeys( level.zombie_weapons ) );
  1015.     if ( isDefined( level.customrandomweaponweights ) )
  1016.     {
  1017.         keys = player [[ level.customrandomweaponweights ]]( keys );
  1018.     }
  1019.     /*
  1020. /#
  1021.     forced_weapon = getDvar( "scr_force_weapon" );
  1022.     if ( forced_weapon != "" && isDefined( level.zombie_weapons[ forced_weapon ] ) )
  1023.     {
  1024.         arrayinsert( keys, forced_weapon, 0 );
  1025. #/
  1026.     }
  1027.     */
  1028.     pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" );
  1029.     for ( i = 0; i < keys.size; i++ )
  1030.     {
  1031.         if ( treasure_chest_canplayerreceiveweapon( player, keys[ i ], pap_triggers ) )
  1032.         {
  1033.             return keys[ i ];
  1034.         }
  1035.     }
  1036.     return keys[ 0 ];
  1037. }
  1038.  
  1039. weapon_is_dual_wield( name ) //checked matches cerberus output
  1040. {
  1041.     switch( name )
  1042.     {
  1043.         case "cz75dw_upgraded_zm":
  1044.         case "cz75dw_zm":
  1045.         case "fivesevendw_upgraded_zm":
  1046.         case "fivesevendw_zm":
  1047.         case "hs10_upgraded_zm":
  1048.         case "m1911_upgraded_zm":
  1049.         case "microwavegundw_upgraded_zm":
  1050.         case "microwavegundw_zm":
  1051.         case "pm63_upgraded_zm":
  1052.             return 1;
  1053.         default:
  1054.             return 0;
  1055.     }
  1056. }
  1057.  
  1058. weapon_show_hint_choke() //checked matches cerberus output
  1059. {
  1060.     level._weapon_show_hint_choke = 0;
  1061.     while ( 1 )
  1062.     {
  1063.         wait 0.05;
  1064.         level._weapon_show_hint_choke = 0;
  1065.     }
  1066. }
  1067.  
  1068. decide_hide_show_hint( endon_notify, second_endon_notify, onlyplayer ) //checked changed to match cerberus output
  1069. {
  1070.     self endon( "death" );
  1071.     if ( isDefined( endon_notify ) )
  1072.     {
  1073.         self endon( endon_notify );
  1074.     }
  1075.     if ( isDefined( second_endon_notify ) )
  1076.     {
  1077.         self endon( second_endon_notify );
  1078.     }
  1079.     if ( !isDefined( level._weapon_show_hint_choke ) )
  1080.     {
  1081.         level thread weapon_show_hint_choke();
  1082.     }
  1083.     use_choke = 0;
  1084.     if ( isDefined( level._use_choke_weapon_hints ) && level._use_choke_weapon_hints == 1 )
  1085.     {
  1086.         use_choke = 1;
  1087.     }
  1088.     while ( 1 )
  1089.     {
  1090.         last_update = getTime();
  1091.         if ( isDefined( self.chest_user ) && !isDefined( self.box_rerespun ) )
  1092.         {
  1093.             if ( is_placeable_mine( self.chest_user getcurrentweapon() ) || self.chest_user hacker_active() )
  1094.             {
  1095.                 self setinvisibletoplayer( self.chest_user );
  1096.             }
  1097.             else
  1098.             {
  1099.                 self setvisibletoplayer( self.chest_user );
  1100.             }
  1101.             break;
  1102.         }
  1103.         if ( isDefined( onlyplayer ) )
  1104.         {
  1105.             if ( onlyplayer can_buy_weapon() )
  1106.             {
  1107.                 self setinvisibletoplayer( onlyplayer, 0 );
  1108.             }
  1109.             else
  1110.             {
  1111.                 self setinvisibletoplayer( onlyplayer, 1 );
  1112.             }
  1113.             break;
  1114.         }
  1115.         players = get_players();
  1116.         i = 0;
  1117.         while ( i < players.size )
  1118.         {
  1119.             if ( players[ i ] can_buy_weapon() )
  1120.             {
  1121.                 self setinvisibletoplayer( players[ i ], 0 );
  1122.                 i++;
  1123.                 continue;
  1124.             }
  1125.             self setinvisibletoplayer( players[ i ], 1 );
  1126.             i++;
  1127.         }
  1128.         if ( use_choke )
  1129.         {
  1130.             while ( level._weapon_show_hint_choke > 4 && getTime() < ( last_update + 150 ) )
  1131.             {
  1132.                 wait 0.05;
  1133.             }
  1134.         }
  1135.         else
  1136.         {
  1137.             wait 0.1;
  1138.         }
  1139.         level._weapon_show_hint_choke++;
  1140.     }
  1141. }
  1142.  
  1143. get_left_hand_weapon_model_name( name ) //checked matches cerberus output
  1144. {
  1145.     switch( name )
  1146.     {
  1147.         case "microwavegundw_zm":
  1148.             return getweaponmodel( "microwavegunlh_zm" );
  1149.         case "microwavegundw_upgraded_zm":
  1150.             return getweaponmodel( "microwavegunlh_upgraded_zm" );
  1151.         default:
  1152.             return getweaponmodel( name );
  1153.     }
  1154. }
  1155.  
  1156. clean_up_hacked_box() //checked matches cerberus output
  1157. {
  1158.     self waittill( "box_hacked_respin" );
  1159.     self endon( "box_spin_done" );
  1160.     if ( isDefined( self.weapon_model ) )
  1161.     {
  1162.         self.weapon_model delete();
  1163.         self.weapon_model = undefined;
  1164.     }
  1165.     if ( isDefined( self.weapon_model_dw ) )
  1166.     {
  1167.         self.weapon_model_dw delete();
  1168.         self.weapon_model_dw = undefined;
  1169.     }
  1170.     self hidezbarrierpiece( 3 );
  1171.     self hidezbarrierpiece( 4 );
  1172.     self setzbarrierpiecestate( 3, "closed" );
  1173.     self setzbarrierpiecestate( 4, "closed" );
  1174. }
  1175.  
  1176. treasure_chest_weapon_spawn( chest, player, respin ) //checked changed to match cerberus output
  1177. {
  1178.     if ( isDefined( level.using_locked_magicbox ) && level.using_locked_magicbox )
  1179.     {
  1180.         self.owner endon( "box_locked" );
  1181.         self thread maps/mp/zombies/_zm_magicbox_lock::clean_up_locked_box();
  1182.     }
  1183.     self endon( "box_hacked_respin" );
  1184.     self thread clean_up_hacked_box();
  1185.     /*
  1186. /#
  1187.     assert( isDefined( player ) );
  1188. #/
  1189.     */
  1190.     self.weapon_string = undefined;
  1191.     modelname = undefined;
  1192.     rand = undefined;
  1193.     number_cycles = 40;
  1194.     if ( isDefined( chest.zbarrier ) )
  1195.     {
  1196.         if ( isDefined( level.custom_magic_box_do_weapon_rise ) )
  1197.         {
  1198.             chest.zbarrier thread [[ level.custom_magic_box_do_weapon_rise ]]();
  1199.         }
  1200.         else
  1201.         {
  1202.             chest.zbarrier thread magic_box_do_weapon_rise();
  1203.         }
  1204.     }
  1205.     i = 0;
  1206.     while ( i < number_cycles )
  1207.     {
  1208.         if ( i < 20 )
  1209.         {
  1210.             wait 0.05;
  1211.             i++;
  1212.             continue;
  1213.         }
  1214.         if ( i < 30 )
  1215.         {
  1216.             wait 0.1;
  1217.             i++;
  1218.             continue;
  1219.         }
  1220.         if ( i < 35 )
  1221.         {
  1222.             wait 0.2;
  1223.             i++;
  1224.             continue;
  1225.         }
  1226.         if ( i < 40 )
  1227.         {
  1228.             wait 0.15;
  1229.             i++;
  1230.         }
  1231.     }
  1232.     if ( level.debugLogging_zm_magicbox )
  1233.     {
  1234.         logline8 = "_zm_magicbox.gsc treasure_chest_weapon_spawn() completed weapon cycling" + " \n";
  1235.         logprint( logline8 );
  1236.     }
  1237.     if ( isDefined( level.custom_magic_box_weapon_wait ) )
  1238.     {
  1239.         [[ level.custom_magic_box_weapon_wait ]]();
  1240.     }
  1241.     if ( isDefined( player.pers_upgrades_awarded[ "box_weapon" ] ) && player.pers_upgrades_awarded[ "box_weapon" ] )
  1242.     {
  1243.         rand = maps/mp/zombies/_zm_pers_upgrades_functions::pers_treasure_chest_choosespecialweapon( player );
  1244.         if ( level.debugLogging_zm_magicbox )
  1245.         {
  1246.             logline9 = "_zm_magicbox.gsc treasure_chest_weapon_spawn() chose random weapon based on the box perma perk; box chose: " + rand + " \n";
  1247.             logprint( logline9 );
  1248.         }
  1249.     }
  1250.     else
  1251.     {
  1252.         rand = treasure_chest_chooseweightedrandomweapon( player );
  1253.         if ( level.debugLogging_zm_magicbox )
  1254.         {
  1255.             logline10 = "_zm_magicbox.gsc treasure_chest_weapon_spawn() chose random weapon based on treasure_chest_chooseweightedrandomweapon(); box chose: " + rand + " \n";
  1256.             logprint( logline10 );
  1257.         }
  1258.     }
  1259.    
  1260.     self.weapon_string = rand;
  1261.     wait 0.1;
  1262.     if ( isDefined( level.custom_magicbox_float_height ) )
  1263.     {
  1264.         v_float = anglesToUp( self.angles ) * level.custom_magicbox_float_height;
  1265.     }
  1266.     else
  1267.     {
  1268.         v_float = anglesToUp( self.angles ) * 40;
  1269.     }
  1270.     self.model_dw = undefined;
  1271.     self.weapon_model = spawn_weapon_model( rand, undefined, self.origin + v_float, self.angles + vectorScale( ( 0, 1, 0 ), 180 ) );
  1272.     if ( weapon_is_dual_wield( rand ) )
  1273.     {
  1274.         self.weapon_model_dw = spawn_weapon_model( rand, get_left_hand_weapon_model_name( rand ), self.weapon_model.origin - vectorScale( ( 0, 1, 0 ), 3 ), self.weapon_model.angles );
  1275.     }
  1276.     if ( level.debugLogging_zm_magicbox )
  1277.     {
  1278.         logline11 = "_zm_magicbox.gsc treasure_chest_weapon_spawn() spawns in the weapon model" + " \n";
  1279.         logprint( logline11 );
  1280.     }
  1281.     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 ]]() )
  1282.     {
  1283.         random = randomint( 100 );
  1284.         if ( !isDefined( level.chest_min_move_usage ) )
  1285.         {
  1286.             level.chest_min_move_usage = 4;
  1287.         }
  1288.         if ( level.chest_accessed < level.chest_min_move_usage )
  1289.         {
  1290.             chance_of_joker = -1;
  1291.         }
  1292.         else
  1293.         {
  1294.             chance_of_joker = level.chest_accessed + 20;
  1295.             if ( level.chest_moves == 0 && level.chest_accessed >= 8 )
  1296.             {
  1297.                 chance_of_joker = 100;
  1298.             }
  1299.             if ( level.chest_accessed >= 4 && level.chest_accessed < 8 )
  1300.             {
  1301.                 if ( random < 15 )
  1302.                 {
  1303.                     chance_of_joker = 100;
  1304.                 }
  1305.                 else
  1306.                 {
  1307.                     chance_of_joker = -1;
  1308.                 }
  1309.             }
  1310.             if ( level.chest_moves > 0 )
  1311.             {
  1312.                 if ( level.chest_accessed >= 8 && level.chest_accessed < 13 )
  1313.                 {
  1314.                     if ( random < 30 )
  1315.                     {
  1316.                         chance_of_joker = 100;
  1317.                     }
  1318.                     else
  1319.                     {
  1320.                         chance_of_joker = -1;
  1321.                     }
  1322.                 }
  1323.                 if ( level.chest_accessed >= 13 )
  1324.                 {
  1325.                     if ( random < 50 )
  1326.                     {
  1327.                         chance_of_joker = 100;
  1328.                     }
  1329.                     else
  1330.                     {
  1331.                         chance_of_joker = -1;
  1332.                     }
  1333.                 }
  1334.             }
  1335.         }
  1336.         if ( isDefined( chest.no_fly_away ) )
  1337.         {
  1338.             chance_of_joker = -1;
  1339.         }
  1340.         if ( isDefined( level._zombiemode_chest_joker_chance_override_func ) )
  1341.         {
  1342.             chance_of_joker = [[ level._zombiemode_chest_joker_chance_override_func ]]( chance_of_joker );
  1343.         }
  1344.         if ( chance_of_joker > random )
  1345.         {
  1346.             self.weapon_string = undefined;
  1347.             self.weapon_model setmodel( level.chest_joker_model );
  1348.             self.weapon_model.angles = self.angles + vectorScale( ( 0, 1, 0 ), 90 );
  1349.             if ( isDefined( self.weapon_model_dw ) )
  1350.             {
  1351.                 self.weapon_model_dw delete();
  1352.                 self.weapon_model_dw = undefined;
  1353.             }
  1354.             self.chest_moving = 1;
  1355.             flag_set( "moving_chest_now" );
  1356.             level.chest_accessed = 0;
  1357.             level.chest_moves++;
  1358.         }
  1359.     }
  1360.     self notify( "randomization_done" );
  1361.     if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() )
  1362.     {
  1363.         if ( isDefined( level.chest_joker_custom_movement ) )
  1364.         {
  1365.             self [[ level.chest_joker_custom_movement ]]();
  1366.         }
  1367.         else
  1368.         {
  1369.             wait 0.5;
  1370.             level notify( "weapon_fly_away_start" );
  1371.             wait 2;
  1372.             if ( isDefined( self.weapon_model ) )
  1373.             {
  1374.                 v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 );
  1375.                 self.weapon_model moveto( v_fly_away, 4, 3 );
  1376.             }
  1377.             if ( isDefined( self.weapon_model_dw ) )
  1378.             {
  1379.                 v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 );
  1380.                 self.weapon_model_dw moveto( v_fly_away, 4, 3 );
  1381.             }
  1382.             self.weapon_model waittill( "movedone" );
  1383.             self.weapon_model delete();
  1384.             if ( isDefined( self.weapon_model_dw ) )
  1385.             {
  1386.                 self.weapon_model_dw delete();
  1387.                 self.weapon_model_dw = undefined;
  1388.             }
  1389.             self notify( "box_moving" );
  1390.             level notify( "weapon_fly_away_end" );
  1391.         }
  1392.     }
  1393.     else
  1394.     {
  1395.         acquire_weapon_toggle( rand, player );
  1396.         if ( rand == "tesla_gun_zm" || rand == "ray_gun_zm" )
  1397.         {
  1398.             if ( rand == "ray_gun_zm" )
  1399.             {
  1400.                 level.pulls_since_last_ray_gun = 0;
  1401.             }
  1402.             if ( rand == "tesla_gun_zm" )
  1403.             {
  1404.                 level.pulls_since_last_tesla_gun = 0;
  1405.                 level.player_seen_tesla_gun = 1;
  1406.             }
  1407.         }
  1408.         if ( !isDefined( respin ) )
  1409.         {
  1410.             if ( isDefined( chest.box_hacks[ "respin" ] ) )
  1411.             {
  1412.                 self [[ chest.box_hacks[ "respin" ] ]]( chest, player );
  1413.             }
  1414.         }
  1415.         else
  1416.         {
  1417.             if ( isDefined( chest.box_hacks[ "respin_respin" ] ) )
  1418.             {
  1419.                 self [[ chest.box_hacks[ "respin_respin" ] ]]( chest, player );
  1420.             }
  1421.         }
  1422.         if ( isDefined( level.custom_magic_box_timer_til_despawn ) )
  1423.         {
  1424.             self.weapon_model thread [[ level.custom_magic_box_timer_til_despawn ]]( self );
  1425.         }
  1426.         else
  1427.         {
  1428.             self.weapon_model thread timer_til_despawn( v_float );
  1429.         }
  1430.         if ( isDefined( self.weapon_model_dw ) )
  1431.         {
  1432.             if ( isDefined( level.custom_magic_box_timer_til_despawn ) )
  1433.             {
  1434.                 self.weapon_model_dw thread [[ level.custom_magic_box_timer_til_despawn ]]( self );
  1435.             }
  1436.             else
  1437.             {
  1438.                 self.weapon_model_dw thread timer_til_despawn( v_float );
  1439.             }
  1440.         }
  1441.         self waittill( "weapon_grabbed" );
  1442.         if ( !chest.timedout )
  1443.         {
  1444.             if ( isDefined( self.weapon_model ) )
  1445.             {
  1446.                 self.weapon_model delete();
  1447.             }
  1448.             if ( isDefined( self.weapon_model_dw ) )
  1449.             {
  1450.                 self.weapon_model_dw delete();
  1451.             }
  1452.         }
  1453.     }
  1454.     self.weapon_string = undefined;
  1455.     self notify( "box_spin_done" );
  1456. }
  1457.  
  1458. chest_get_min_usage() //checked matches cerberus output
  1459. {
  1460.     min_usage = 4;
  1461.     return min_usage;
  1462. }
  1463.  
  1464. chest_get_max_usage() //checked matches cerberus output
  1465. {
  1466.     max_usage = 6;
  1467.     players = get_players();
  1468.     if ( level.chest_moves == 0 )
  1469.     {
  1470.         if ( players.size == 1 )
  1471.         {
  1472.             max_usage = 3;
  1473.         }
  1474.         else if ( players.size == 2 )
  1475.         {
  1476.             max_usage = 4;
  1477.         }
  1478.         else if ( players.size == 3 )
  1479.         {
  1480.             max_usage = 5;
  1481.         }
  1482.         else
  1483.         {
  1484.             max_usage = 6;
  1485.         }
  1486.     }
  1487.     else if ( players.size == 1 )
  1488.     {
  1489.         max_usage = 4;
  1490.     }
  1491.     else if ( players.size == 2 )
  1492.     {
  1493.         max_usage = 4;
  1494.     }
  1495.     else if ( players.size == 3 )
  1496.     {
  1497.         max_usage = 5;
  1498.     }
  1499.     else
  1500.     {
  1501.         max_usage = 7;
  1502.     }
  1503.     return max_usage;
  1504. }
  1505.  
  1506. timer_til_despawn( v_float ) //checked matches cerberus output
  1507. {
  1508.     self endon( "kill_weapon_movement" );
  1509.     putbacktime = 12;
  1510.     self moveto( self.origin - ( v_float * 0.85 ), putbacktime, putbacktime * 0.5 );
  1511.     wait putbacktime;
  1512.     if ( isDefined( self ) )
  1513.     {
  1514.         self delete();
  1515.     }
  1516. }
  1517.  
  1518. treasure_chest_glowfx() //checked matches cerberus output
  1519. {
  1520.     self setclientfield( "magicbox_glow", 1 );
  1521.     self waittill_any( "weapon_grabbed", "box_moving" );
  1522.     self setclientfield( "magicbox_glow", 0 );
  1523. }
  1524.  
  1525. treasure_chest_give_weapon( weapon_string ) //checked matches cerberus output
  1526. {
  1527.     self.last_box_weapon = getTime();
  1528.     self maps/mp/zombies/_zm_weapons::weapon_give( weapon_string, 0, 1 );
  1529. }
  1530.  
  1531. magic_box_teddy_twitches() //checked matches cerberus output
  1532. {
  1533.     self endon( "zbarrier_state_change" );
  1534.     self setzbarrierpiecestate( 0, "closed" );
  1535.     while ( 1 )
  1536.     {
  1537.         wait randomfloatrange( 180, 1800 );
  1538.         self setzbarrierpiecestate( 0, "opening" );
  1539.         wait randomfloatrange( 180, 1800 );
  1540.         self setzbarrierpiecestate( 0, "closing" );
  1541.     }
  1542. }
  1543.  
  1544. magic_box_initial() //checked matches cerberus output
  1545. {
  1546.     self setzbarrierpiecestate( 1, "open" );
  1547. }
  1548.  
  1549. magic_box_arrives()
  1550. {
  1551.     self setzbarrierpiecestate( 1, "opening" );
  1552.     while ( self getzbarrierpiecestate( 1 ) == "opening" )
  1553.     {
  1554.         wait 0.05;
  1555.     }
  1556.     self notify( "arrived" );
  1557. }
  1558.  
  1559. magic_box_leaves() //checked matches cerberus output
  1560. {
  1561.     self setzbarrierpiecestate( 1, "closing" );
  1562.     while ( self getzbarrierpiecestate( 1 ) == "closing" )
  1563.     {
  1564.         wait 0.1;
  1565.     }
  1566.     self notify( "left" );
  1567. }
  1568.  
  1569. magic_box_opens() //checked matches cerberus output
  1570. {
  1571.     self setzbarrierpiecestate( 2, "opening" );
  1572.     while ( self getzbarrierpiecestate( 2 ) == "opening" )
  1573.     {
  1574.         wait 0.1;
  1575.     }
  1576.     self notify( "opened" );
  1577. }
  1578.  
  1579. magic_box_closes() //checked matches cerberus output
  1580. {
  1581.     self setzbarrierpiecestate( 2, "closing" );
  1582.     while ( self getzbarrierpiecestate( 2 ) == "closing" )
  1583.     {
  1584.         wait 0.1;
  1585.     }
  1586.     self notify( "closed" );
  1587. }
  1588.  
  1589. magic_box_do_weapon_rise() //checked matches cerberus output
  1590. {
  1591.     self endon( "box_hacked_respin" );
  1592.     self setzbarrierpiecestate( 3, "closed" );
  1593.     self setzbarrierpiecestate( 4, "closed" );
  1594.     wait_network_frame();
  1595.     self zbarrierpieceuseboxriselogic( 3 );
  1596.     self zbarrierpieceuseboxriselogic( 4 );
  1597.     self showzbarrierpiece( 3 );
  1598.     self showzbarrierpiece( 4 );
  1599.     self setzbarrierpiecestate( 3, "opening" );
  1600.     self setzbarrierpiecestate( 4, "opening" );
  1601.     while ( self getzbarrierpiecestate( 3 ) != "open" )
  1602.     {
  1603.         wait 0.5;
  1604.     }
  1605.     self hidezbarrierpiece( 3 );
  1606.     self hidezbarrierpiece( 4 );
  1607. }
  1608.  
  1609. magic_box_do_teddy_flyaway() //checked matches cerberus output
  1610. {
  1611.     self showzbarrierpiece( 3 );
  1612.     self setzbarrierpiecestate( 3, "closing" );
  1613. }
  1614.  
  1615. is_chest_active() //checked matches cerberus output
  1616. {
  1617.     curr_state = self.zbarrier get_magic_box_zbarrier_state();
  1618.     if ( flag( "moving_chest_now" ) )
  1619.     {
  1620.         return 0;
  1621.     }
  1622.     if ( curr_state == "open" || curr_state == "close" )
  1623.     {
  1624.         return 1;
  1625.     }
  1626.     return 0;
  1627. }
  1628.  
  1629. get_magic_box_zbarrier_state() //checked matches cerberus output
  1630. {
  1631.     return self.state;
  1632. }
  1633.  
  1634. set_magic_box_zbarrier_state( state ) //checked changed to match cerberus output
  1635. {
  1636.     for ( i = 0; i < self getnumzbarrierpieces(); i++ )
  1637.     {
  1638.         self hidezbarrierpiece( i );
  1639.     }
  1640.     self notify( "zbarrier_state_change" );
  1641.     self [[ level.magic_box_zbarrier_state_func ]]( state );
  1642. }
  1643.  
  1644. process_magic_box_zbarrier_state( state ) //checked matches cerberus output
  1645. {
  1646.     switch( state )
  1647.     {
  1648.         case "away":
  1649.             self showzbarrierpiece( 0 );
  1650.             self thread magic_box_teddy_twitches();
  1651.             self.state = "away";
  1652.             break;
  1653.         case "arriving":
  1654.             self showzbarrierpiece( 1 );
  1655.             self thread magic_box_arrives();
  1656.             self.state = "arriving";
  1657.             break;
  1658.         case "initial":
  1659.             self showzbarrierpiece( 1 );
  1660.             self thread magic_box_initial();
  1661.             thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.owner.unitrigger_stub, ::magicbox_unitrigger_think );
  1662.             self.state = "initial";
  1663.             break;
  1664.         case "open":
  1665.             self showzbarrierpiece( 2 );
  1666.             self thread magic_box_opens();
  1667.             self.state = "open";
  1668.             break;
  1669.         case "close":
  1670.             self showzbarrierpiece( 2 );
  1671.             self thread magic_box_closes();
  1672.             self.state = "close";
  1673.             break;
  1674.         case "leaving":
  1675.             self showzbarrierpiece( 1 );
  1676.             self thread magic_box_leaves();
  1677.             self.state = "leaving";
  1678.             break;
  1679.         default:
  1680.             if ( isDefined( level.custom_magicbox_state_handler ) )
  1681.             {
  1682.                 self [[ level.custom_magicbox_state_handler ]]( state );
  1683.             }
  1684.             break;
  1685.     }
  1686. }
  1687.  
  1688. magicbox_host_migration() //checked changed to match cerberus output
  1689. {
  1690.     level endon( "end_game" );
  1691.     level notify( "mb_hostmigration" );
  1692.     level endon( "mb_hostmigration" );
  1693.     while ( 1 )
  1694.     {
  1695.         level waittill( "host_migration_end" );
  1696.         while ( !isDefined( level.chests ) )
  1697.         {
  1698.             wait 0.1;
  1699.         }
  1700.         foreach ( chest in level.chests )
  1701.         {
  1702.             if ( !is_true( chest.hidden ) )
  1703.             {
  1704.                 if ( isdefined( chest ) && isdefined( chest.pandora_light ) )
  1705.                 {
  1706.                     playfxontag( level._effect[ "lght_marker" ], chest.pandora_light, "tag_origin" );
  1707.                 }
  1708.             }
  1709.             wait_network_frame();
  1710.         }
  1711.     }
  1712. }
Add Comment
Please, Sign In to add comment