Advertisement
Guest User

_zm_magicbox.gsc

a guest
Nov 3rd, 2023
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.41 KB | None | 0 0
  1. #using scripts\codescripts\struct;
  2.  
  3. #using scripts\shared\aat_shared;
  4. #using scripts\shared\array_shared;
  5. #using scripts\shared\clientfield_shared;
  6. #using scripts\shared\demo_shared;
  7. #using scripts\shared\flag_shared;
  8. #using scripts\shared\system_shared;
  9. #using scripts\shared\util_shared;
  10.  
  11. #insert scripts\shared\shared.gsh;
  12. #insert scripts\shared\version.gsh;
  13.  
  14. #using scripts\zm\_zm_audio;
  15. #using scripts\zm\_zm_bgb;
  16. #using scripts\zm\_zm_daily_challenges;
  17. #using scripts\zm\_zm_equipment;
  18. #using scripts\zm\_zm_pack_a_punch_util;
  19. #using scripts\zm\_zm_pers_upgrades_functions;
  20. #using scripts\zm\_zm_score;
  21. #using scripts\zm\_zm_stats;
  22. #using scripts\zm\_zm_unitrigger;
  23. #using scripts\zm\_zm_utility;
  24. #using scripts\zm\_zm_weapons;
  25.  
  26. #insert scripts\zm\_zm_perks.gsh;
  27. #insert scripts\zm\_zm_utility.gsh;
  28.  
  29. #precache( "fx", "zombie/fx_weapon_box_marker_zmb" );
  30. #precache( "fx", "zombie/fx_weapon_box_marker_fl_zmb" );
  31. #precache( "fx", "zombie/fx_barrier_buy_zmb" );
  32.  
  33. //////////////////////////////////////////////////
  34. ///////////// FUNCTION OVERRIDE LIST /////////////
  35. //// If any of these functions are overriden, they will override functionality in this script
  36. // level.custom_magic_box_timer_til_despawn == Custom box movement
  37. // level.custom_magic_box_do_weapon_rise == Custom weapon rise
  38. // level.custom_magic_box_weapon_wait == Custom weapon wait until being taken back into the box
  39. // level.custom_pandora_show_func == Custom map marker
  40. // level.custom_magic_box_fx == Custom FX when box opens and closes
  41. // level.custom_treasure_chest_glowfx == Custom Chest FX
  42. // level.custom_magicbox_float_height == (int) custom float height
  43. //
  44. // If custom_pandora_show_func is defined, then a custom magicbox_host_migration() must be made in the new gsc
  45. //////////////////////////////////////////////////
  46.  
  47. #namespace zm_magicbox;
  48.  
  49. #precache( "triggerstring", "ZOMBIE_TRADE_EQUIP_FILL" );
  50. #precache( "triggerstring", "ZOMBIE_TRADE_WEAPON_FILL" );
  51.  
  52.  
  53. REGISTER_SYSTEM_EX( "zm_magicbox", &__init__, &__main__, undefined )
  54.  
  55. function __init__()
  56. {
  57. level.start_chest_name = "start_chest";
  58.  
  59. level._effect["lght_marker"] = "zombie/fx_weapon_box_marker_zmb";
  60. level._effect["lght_marker_flare"] = "zombie/fx_weapon_box_marker_fl_zmb";
  61. level._effect["poltergeist"] = "zombie/fx_barrier_buy_zmb";
  62.  
  63. clientfield::register( "zbarrier", "magicbox_open_glow", VERSION_SHIP, 1, "int" );
  64. clientfield::register( "zbarrier", "magicbox_closed_glow", VERSION_SHIP, 1, "int" );
  65.  
  66. clientfield::register( "zbarrier", "zbarrier_show_sounds", VERSION_SHIP, 1, "counter");
  67. clientfield::register( "zbarrier", "zbarrier_leave_sounds", VERSION_SHIP, 1, "counter");
  68.  
  69. clientfield::register( "scriptmover", "force_stream", VERSION_TU7, 1, "int" );
  70.  
  71. level thread magicbox_host_migration();
  72. }
  73.  
  74. function __main__()
  75. {
  76. // Set values that may be overwritten by level specific scripts
  77. if( !IsDefined( level.chest_joker_model ) )
  78. {
  79. level.chest_joker_model = "p7_zm_teddybear";
  80. }
  81.  
  82. if( !IsDefined( level.magic_box_zbarrier_state_func ) )
  83. {
  84. level.magic_box_zbarrier_state_func = &process_magic_box_zbarrier_state;
  85. }
  86.  
  87. if (!IsDefined(level.magic_box_check_equipment))
  88. level.magic_box_check_equipment = &default_magic_box_check_equipment;
  89.  
  90. wait(0.05);//wait for initialization stage to end so we can toggle client fields
  91.  
  92. if ( zm_utility::is_Classic() )
  93. {
  94. level.chests = struct::get_array( "treasure_chest_use", "targetname" );
  95. treasure_chest_init( level.start_chest_name );
  96. }
  97. }
  98.  
  99. // for the random weapon chest
  100. //
  101. // The chests need to be setup as follows:
  102. // trigger_use - for the chest
  103. // targets the lid
  104. // lid - script_model. Flips open to reveal the items
  105. // targets the script origin inside the box
  106. // script_origin - inside the box, used for spawning the weapons
  107. // targets the box
  108. // box - script_model of the outer casing of the chest
  109. // rubble - pieces that show when the box isn't there
  110. // script_noteworthy should be the same as the use_trigger + "_rubble"
  111. //
  112. function treasure_chest_init( start_chest_name )
  113. {
  114. level flag::init("moving_chest_enabled");
  115. level flag::init("moving_chest_now");
  116. level flag::init("chest_has_been_used");
  117.  
  118. level.chest_moves = 0;
  119. level.chest_level = 0; // Level 0 = normal chest, 1 = upgraded chest
  120. //level.chests = GetEntArray( "treasure_chest_use", "targetname" );
  121.  
  122. //level.chests = struct::get_array( "treasure_chest_use", "targetname" );
  123.  
  124. if( level.chests.size==0 )
  125. return;
  126.  
  127. for (i=0; i<level.chests.size; i++ )
  128. {
  129. level.chests[i].box_hacks = [];
  130.  
  131. level.chests[i].orig_origin = level.chests[i].origin;
  132. level.chests[i] get_chest_pieces();
  133.  
  134. if ( isDefined( level.chests[i].zombie_cost ) )
  135. {
  136. level.chests[i].old_cost = level.chests[i].zombie_cost;
  137. }
  138. else
  139. {
  140. // default chest cost
  141. level.chests[i].old_cost = 950;
  142. }
  143. }
  144.  
  145. if(!level.enable_magic)
  146. {
  147. foreach(chest in level.chests)
  148. {
  149. chest hide_chest();
  150. }
  151. return;
  152. }
  153.  
  154. level.chest_accessed = 0;
  155.  
  156. if (level.chests.size > 1)
  157. {
  158. level flag::set("moving_chest_enabled");
  159.  
  160. level.chests = array::randomize(level.chests);
  161.  
  162. //determine magic box starting location at random or normal
  163. //init_starting_chest_location();
  164. }
  165. else
  166. {
  167. level.chest_index = 0;
  168. level.chests[0].no_fly_away = true;
  169. }
  170.  
  171. //determine magic box starting location at random or normal
  172. init_starting_chest_location( start_chest_name );
  173.  
  174. array::thread_all( level.chests, &treasure_chest_think );
  175. }
  176.  
  177. function init_starting_chest_location( start_chest_name )
  178. {
  179. level.chest_index = 0;
  180. start_chest_found = false;
  181.  
  182. if( level.chests.size==1 )
  183. {
  184. //Only 1 chest in the map
  185. start_chest_found = true;
  186.  
  187. if(isdefined(level.chests[level.chest_index].zbarrier))
  188. {
  189. level.chests[level.chest_index].zbarrier set_magic_box_zbarrier_state("initial");
  190. level.chests[level.chest_index] thread box_encounter_vo();
  191. }
  192. }
  193. else
  194. {
  195. for( i = 0; i < level.chests.size; i++ )
  196. {
  197. if( isdefined( level.random_pandora_box_start ) && level.random_pandora_box_start == true )
  198. {
  199. //start_exclude is a KVP, just need to add start_exclude 1 to the box script struct to exclude it from the initial random box selection
  200. if ( start_chest_found || (IsDefined( level.chests[i].start_exclude ) && level.chests[i].start_exclude == 1) )
  201. {
  202. level.chests[i] hide_chest();
  203. }
  204. else
  205. {
  206. level.chest_index = i;
  207. level.chests[level.chest_index].hidden = false;
  208. if(isdefined(level.chests[level.chest_index].zbarrier))
  209. {
  210. level.chests[level.chest_index].zbarrier set_magic_box_zbarrier_state("initial");
  211. level.chests[level.chest_index] thread box_encounter_vo();
  212. }
  213. start_chest_found = true;
  214. }
  215.  
  216. }
  217. else
  218. {
  219. // Semi-random implementation (not completely random). The list is randomized
  220. // prior to getting here.
  221. // Pick from any box marked as the "start_chest"
  222. if ( start_chest_found || !IsDefined(level.chests[i].script_noteworthy ) || ( !IsSubStr( level.chests[i].script_noteworthy, start_chest_name ) ) )
  223. {
  224. level.chests[i] hide_chest();
  225. }
  226. else
  227. {
  228. level.chest_index = i;
  229. level.chests[level.chest_index].hidden = false;
  230. if(isdefined(level.chests[level.chest_index].zbarrier))
  231. {
  232. level.chests[level.chest_index].zbarrier set_magic_box_zbarrier_state("initial");
  233. level.chests[level.chest_index] thread box_encounter_vo();
  234. }
  235. start_chest_found = true;
  236. }
  237. }
  238. }
  239. }
  240.  
  241. // Show the beacon
  242. if( !isDefined( level.pandora_show_func ) )
  243. {
  244. if ( isdefined( level.custom_pandora_show_func ) )
  245. {
  246. level.pandora_show_func = level.custom_pandora_show_func;
  247. }
  248. else
  249. {
  250. level.pandora_show_func = &default_pandora_show_func;
  251. }
  252. }
  253.  
  254. level.chests[level.chest_index] thread [[ level.pandora_show_func ]]();
  255. }
  256.  
  257. function set_treasure_chest_cost( cost )
  258. {
  259. level.zombie_treasure_chest_cost = cost;
  260. }
  261.  
  262. //
  263. // Save off the references to all of the chest pieces
  264. // self = trigger
  265. function get_chest_pieces()
  266. {
  267. //self.chest_lid = GetEnt(self.target, "targetname");
  268. //self.chest_origin = GetEnt(self.chest_lid.target, "targetname");
  269.  
  270. // println( "***** LOOKING FOR: " + self.chest_origin.target );
  271.  
  272. self.chest_box = GetEnt( self.script_noteworthy + "_zbarrier", "script_noteworthy" );
  273.  
  274. //TODO fix temp hax to separate multiple instances
  275. self.chest_rubble = [];
  276. rubble = GetEntArray( self.script_noteworthy + "_rubble", "script_noteworthy" );
  277. for ( i=0; i<rubble.size; i++ )
  278. {
  279. if ( DistanceSquared( self.origin, rubble[i].origin ) < 10000 )
  280. {
  281. self.chest_rubble[ self.chest_rubble.size ] = rubble[i];
  282. }
  283. }
  284.  
  285. self.zbarrier = GetEnt(self.script_noteworthy + "_zbarrier", "script_noteworthy");
  286. if(isdefined(self.zbarrier))
  287. {
  288. self.zbarrier ZBarrierPieceUseBoxRiseLogic(3);
  289. self.zbarrier ZBarrierPieceUseBoxRiseLogic(4);
  290. }
  291.  
  292. self.unitrigger_stub = spawnstruct();
  293. self.unitrigger_stub.origin = self.origin + (anglestoright(self.angles) * -22.5);
  294. self.unitrigger_stub.angles = self.angles;
  295. self.unitrigger_stub.script_unitrigger_type = "unitrigger_box_use";
  296. self.unitrigger_stub.script_width = 104;
  297. self.unitrigger_stub.script_height = 50;
  298. self.unitrigger_stub.script_length = 45;
  299. self.unitrigger_stub.trigger_target = self;
  300. zm_unitrigger::unitrigger_force_per_player_triggers(self.unitrigger_stub, true);
  301. self.unitrigger_stub.prompt_and_visibility_func = &boxtrigger_update_prompt;
  302. self.zbarrier.owner = self;
  303.  
  304. }
  305.  
  306. function boxtrigger_update_prompt( player )
  307. {
  308. can_use = self boxstub_update_prompt( player );
  309. if(isdefined(self.hint_string))
  310. {
  311. if (IsDefined(self.hint_parm1))
  312. self SetHintString( self.hint_string, self.hint_parm1 );
  313. else
  314. self SetHintString( self.hint_string );
  315. }
  316. return can_use;
  317. }
  318.  
  319. function boxstub_update_prompt( player )
  320. {
  321. //self setCursorHint( "HINT_NOICON" );
  322.  
  323. if (!self trigger_visible_to_player( player ))
  324. return false;
  325.  
  326. if( isdefined( level.func_magicbox_update_prompt_use_override ) )
  327. {
  328. if( [[ level.func_magicbox_update_prompt_use_override ]]() )
  329. {
  330. return false;
  331. }
  332. }
  333.  
  334. self.hint_parm1 = undefined;
  335. if(IS_TRUE(self.stub.trigger_target.grab_weapon_hint))
  336. {
  337. cursor_hint = "HINT_WEAPON";
  338. cursor_hint_weapon = self.stub.trigger_target.grab_weapon;
  339. self setCursorHint( cursor_hint, cursor_hint_weapon );
  340. if (IsDefined(level.magic_box_check_equipment) && [[level.magic_box_check_equipment]]( cursor_hint_weapon ) )
  341. self.hint_string = &"ZOMBIE_TRADE_EQUIP_FILL";
  342. else
  343. self.hint_string = &"ZOMBIE_TRADE_WEAPON_FILL";
  344. }
  345. else
  346. {
  347. self setCursorHint( "HINT_NOICON" );
  348. self.hint_parm1 = self.stub.trigger_target.zombie_cost;
  349. self.hint_string = zm_utility::get_hint_string( self, "default_treasure_chest" );
  350. }
  351. return true;
  352. }
  353.  
  354. function default_magic_box_check_equipment( weapon )
  355. {
  356. return zm_utility::is_offhand_weapon( weapon );
  357. }
  358.  
  359.  
  360. function trigger_visible_to_player(player)
  361. {
  362. self SetInvisibleToPlayer(player);
  363.  
  364. visible = true;
  365.  
  366. if(IsDefined(self.stub.trigger_target.chest_user) && !IsDefined(self.stub.trigger_target.box_rerespun))
  367. {
  368. if( player != self.stub.trigger_target.chest_user || zm_utility::is_placeable_mine( self.stub.trigger_target.chest_user GetCurrentWeapon() ) || self.stub.trigger_target.chest_user zm_equipment::hacker_active())
  369. {
  370. visible = false;
  371. }
  372. }
  373. else
  374. {
  375. if( !player can_buy_weapon() )
  376. {
  377. visible = false;
  378. }
  379. }
  380.  
  381. // PORTIZ 7/20/16: players could start spinning a weapon, acquire Disorderly Combat from a nearby BGB machine, and then take the weapon.
  382. // separating out Disorderly Combat check since we never want a player to interact with the box while it's enabled
  383. if ( player bgb::is_enabled( "zm_bgb_disorderly_combat" ) )
  384. {
  385. visible = false;
  386. }
  387.  
  388. if(!visible)
  389. {
  390. return false;
  391. }
  392.  
  393. self SetVisibleToPlayer(player);
  394. return true;
  395. }
  396.  
  397. function magicbox_unitrigger_think()
  398. {
  399. self endon("kill_trigger");
  400.  
  401. while ( 1 )
  402. {
  403. self waittill( "trigger", player );
  404. self.stub.trigger_target notify("trigger", player);
  405. }
  406. }
  407.  
  408. function play_crazi_sound()
  409. {
  410. self playlocalsound( level.zmb_laugh_alias );
  411. }
  412.  
  413. //
  414. // Show the chest pieces
  415. // self = chest use_trigger
  416. //
  417. function show_chest()
  418. {
  419. self.zbarrier set_magic_box_zbarrier_state("arriving");
  420. self.zbarrier util::waittill_any_timeout( 5, "arrived");
  421.  
  422. self thread [[ level.pandora_show_func ]]();
  423.  
  424. self.zbarrier clientfield::set( "magicbox_closed_glow", true );
  425.  
  426. //self TriggerEnable( true );
  427. thread zm_unitrigger::register_static_unitrigger(self.unitrigger_stub, &magicbox_unitrigger_think);
  428.  
  429. self.zbarrier clientfield::increment("zbarrier_show_sounds" );
  430.  
  431. self.hidden = false;
  432.  
  433. if(IsDefined(self.box_hacks["summon_box"]))
  434. {
  435. self [[self.box_hacks["summon_box"]]](false);
  436. }
  437.  
  438. }
  439.  
  440. function hide_chest(doBoxLeave)
  441. {
  442. //self TriggerEnable( false );
  443. if(isDefined(self.unitrigger_stub))
  444. {
  445. thread zm_unitrigger::unregister_unitrigger(self.unitrigger_stub);
  446. }
  447. if ( IsDefined( self.pandora_light ) )
  448. {
  449. self.pandora_light delete();
  450. }
  451.  
  452. self.zbarrier clientfield::set( "magicbox_closed_glow", false );
  453.  
  454. self.hidden = true;
  455.  
  456. if(isDefined(self.box_hacks) && IsDefined(self.box_hacks["summon_box"]))
  457. {
  458. self [[self.box_hacks["summon_box"]]](true);
  459. }
  460.  
  461. if(isdefined(self.zbarrier))
  462. {
  463. if(IS_TRUE(doBoxLeave))
  464. {
  465. self.zbarrier clientfield::increment("zbarrier_leave_sounds" );
  466.  
  467. level thread zm_audio::sndAnnouncerPlayVox("boxmove");
  468.  
  469. self.zbarrier thread magic_box_zbarrier_leave();
  470. self.zbarrier waittill("left");
  471.  
  472. playfx( level._effect["poltergeist"], self.zbarrier.origin, AnglesToUp( self.zbarrier.angles ), AnglesToForward( self.zbarrier.angles ) ); // effect has X facing up, Z facing forward
  473.  
  474. //TUEY - Play the 'disappear' sound
  475. playsoundatposition ("zmb_box_poof", self.zbarrier.origin);
  476. }
  477. else
  478. {
  479. self.zbarrier thread set_magic_box_zbarrier_state("away");
  480. }
  481. }
  482. }
  483.  
  484. function magic_box_zbarrier_leave()
  485. {
  486. self set_magic_box_zbarrier_state("leaving");
  487. self waittill("left");
  488. self set_magic_box_zbarrier_state("away");
  489. }
  490.  
  491. function default_pandora_fx_func( )
  492. {
  493. self endon( "death" );
  494.  
  495. self.pandora_light = Spawn( "script_model", self.zbarrier.origin );
  496. self.pandora_light.angles = self.zbarrier.angles + (-90, 0, -90);
  497. // level.pandora_light.angles = (-90, anchorTarget.angles[1] + 180, 0);
  498. self.pandora_light SetModel( "tag_origin" );
  499. if(!IS_TRUE(level._box_initialized))
  500. {
  501. level flag::wait_till("start_zombie_round_logic");
  502. level._box_initialized = true;
  503. }
  504. wait(1);
  505. if ( IsDefined( self ) && IsDefined( self.pandora_light ) )
  506. {
  507. playfxontag(level._effect["lght_marker"], self.pandora_light, "tag_origin");
  508. }
  509.  
  510. }
  511.  
  512.  
  513. //
  514. // Show a column of light
  515. //
  516. function default_pandora_show_func( anchor, anchorTarget, pieces )
  517. {
  518.  
  519. if ( !IsDefined(self.pandora_light) )
  520. {
  521. // Show the column light effect on the box
  522. if( !IsDefined( level.pandora_fx_func ) )
  523. {
  524. level.pandora_fx_func = &default_pandora_fx_func;
  525. }
  526. self thread [[ level.pandora_fx_func ]]();
  527. }
  528.  
  529. playfx( level._effect["lght_marker_flare"],self.pandora_light.origin );
  530.  
  531. //Add this location to the map
  532. //Objective_Add( 0, "active", "Mystery Box", self.chest_lid.origin, "minimap_icon_mystery_box" );
  533. }
  534.  
  535. function unregister_unitrigger_on_kill_think()
  536. {
  537. self notify( "unregister_unitrigger_on_kill_think" );
  538. self endon( "unregister_unitrigger_on_kill_think" );
  539.  
  540. self waittill("kill_chest_think");
  541. thread zm_unitrigger::unregister_unitrigger(self.unitrigger_stub);
  542.  
  543. }
  544.  
  545. function treasure_chest_think()
  546. {
  547. self endon("kill_chest_think");
  548. // waittill someuses uses this
  549. user = undefined;
  550. user_cost = undefined;
  551. self.box_rerespun = undefined;
  552. self.weapon_out = undefined;
  553.  
  554. self thread unregister_unitrigger_on_kill_think();
  555.  
  556. while( 1 )
  557. {
  558. if(!IsDefined(self.forced_user))
  559. {
  560. self waittill( "trigger", user );
  561. if (user == level)
  562. continue;
  563. }
  564. else
  565. {
  566. user = self.forced_user;
  567. }
  568.  
  569. if( user zm_utility::in_revive_trigger() )
  570. {
  571. wait( 0.1 );
  572. continue;
  573. }
  574.  
  575. if( IS_DRINKING(user.is_drinking) )
  576. {
  577. wait( 0.1 );
  578. continue;
  579. }
  580.  
  581. if ( IS_TRUE( self.disabled ) )
  582. {
  583. wait( 0.1 );
  584. continue;
  585. }
  586.  
  587. if( user GetCurrentWeapon() == level.weaponNone )
  588. {
  589. wait( 0.1 );
  590. continue;
  591. }
  592.  
  593. // firesale is in the process of removing this box
  594. if ( IS_TRUE( self.being_removed ) )
  595. {
  596. wait( 0.1 );
  597. continue;
  598. }
  599.  
  600. reduced_cost = undefined;
  601.  
  602. // Make sure the user is a player, and that they can afford it
  603. if( IsDefined(self.auto_open) && zm_utility::is_player_valid( user ) )
  604. {
  605. if(!IsDefined(self.no_charge))
  606. {
  607. user zm_score::minus_to_player_score( self.zombie_cost );
  608. user_cost = self.zombie_cost;
  609. }
  610. else
  611. {
  612. user_cost = 0;
  613. }
  614.  
  615. self.chest_user = user;
  616. break;
  617. }
  618. // Do we have enough money to use the box?
  619. else if( zm_utility::is_player_valid( user ) && user zm_score::can_player_purchase( self.zombie_cost ) )
  620. {
  621. user zm_score::minus_to_player_score( self.zombie_cost );
  622. user_cost = self.zombie_cost;
  623. self.chest_user = user;
  624. break;
  625. }
  626. // Has the box cost been reduced?
  627. else if( IsDefined(reduced_cost) && ( user zm_score::can_player_purchase( reduced_cost ) ) )
  628. {
  629. user zm_score::minus_to_player_score( reduced_cost );
  630. user_cost = reduced_cost;
  631. self.chest_user = user;
  632. break;
  633. }
  634. // Can't afford the box purchase
  635. else if ( !user zm_score::can_player_purchase( self.zombie_cost ) )
  636. {
  637. zm_utility::play_sound_at_pos( "no_purchase", self.origin );
  638. user zm_audio::create_and_play_dialog( "general", "outofmoney" );
  639. continue;
  640. }
  641.  
  642. WAIT_SERVER_FRAME;
  643. }
  644.  
  645. level flag::set("chest_has_been_used");
  646.  
  647. //stat tracking
  648. demo::bookmark( "zm_player_use_magicbox", gettime(), user );
  649. user zm_stats::increment_client_stat( "use_magicbox" );
  650. user zm_stats::increment_player_stat( "use_magicbox" );
  651. user zm_stats::increment_challenge_stat( "SURVIVALIST_BUY_MAGIC_BOX" );
  652. user zm_daily_challenges::increment_magic_box();
  653.  
  654. if ( isDefined( level._magic_box_used_VO ) )
  655. {
  656. user thread [[ level._magic_box_used_VO ]]();
  657. }
  658.  
  659. self thread watch_for_emp_close();
  660.  
  661. self._box_open = true;
  662. self._box_opened_by_fire_sale = false;
  663. if ( IS_TRUE( level.zombie_vars["zombie_powerup_fire_sale_on"] ) && !IsDefined(self.auto_open) && self [[level._zombiemode_check_firesale_loc_valid_func]]())
  664. {
  665. self._box_opened_by_fire_sale = true;
  666. }
  667.  
  668. //open the lid
  669. if(isdefined(self.chest_lid))
  670. {
  671. self.chest_lid thread treasure_chest_lid_open();
  672. }
  673.  
  674. if(isdefined(self.zbarrier))
  675. {
  676. zm_utility::play_sound_at_pos( "open_chest", self.origin );
  677. zm_utility::play_sound_at_pos( "music_chest", self.origin );
  678. self.zbarrier set_magic_box_zbarrier_state("open");
  679. }
  680.  
  681. // SRS 9/3/2008: added to help other functions know if we timed out on grabbing the item
  682. self.timedOut = false;
  683.  
  684. // mario kart style weapon spawning
  685. self.weapon_out = true;
  686. self.zbarrier thread treasure_chest_weapon_spawn( self, user );
  687.  
  688. // the glowfx
  689. if ( isdefined(level.custom_treasure_chest_glowfx ) )
  690. {
  691. self.zbarrier thread [[level.custom_treasure_chest_glowfx]]();
  692. }
  693. else
  694. {
  695. self.zbarrier thread treasure_chest_glowfx();
  696. }
  697.  
  698. // take away usability until model is done randomizing
  699. //self TriggerEnable( false );
  700. thread zm_unitrigger::unregister_unitrigger(self.unitrigger_stub);
  701.  
  702. self.zbarrier util::waittill_any( "randomization_done", "box_hacked_respin" );
  703.  
  704. // refund money from teddy.
  705. if ( level flag::get( "moving_chest_now" ) && !self._box_opened_by_fire_sale && isdefined( user_cost ) )
  706. {
  707. user zm_score::add_to_player_score( user_cost, false, "magicbox_bear" );
  708. }
  709.  
  710. if ( level flag::get( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !self._box_opened_by_fire_sale )
  711. {
  712. //CA AUDIO: 01/12/10 - Changed dialog to use correct function
  713. //self.chest_user zm_audio::create_and_play_dialog( "general", "box_move" );
  714. self thread treasure_chest_move( self.chest_user );
  715. }
  716. else
  717. {
  718. if( !IS_TRUE( self.unbearable_respin ) )
  719. {
  720. // Let the player grab the weapon and re-enable the box //
  721. self.grab_weapon_hint = true;
  722. self.grab_weapon = self.zbarrier.weapon;
  723. self.chest_user = user;
  724. weaponIdx = undefined;
  725. if (isDefined(self.grab_weapon))
  726. {
  727. weaponIdx = MatchRecordGetWeaponIndex(self.grab_weapon);
  728. }
  729.  
  730. if ( isDefined(weaponIdx) )
  731. {
  732. user RecordMapEvent(ZM_MAP_EVENT_MAGIC_BOX_OFFERED, GetTime(), user.origin, level.round_number, weaponIdx);
  733. }
  734.  
  735. // Limit its visibility to the player who bought the box
  736. //self TriggerEnable( true );
  737. thread zm_unitrigger::register_static_unitrigger(self.unitrigger_stub, &magicbox_unitrigger_think);
  738.  
  739. if( isDefined(self.zbarrier) && !IS_TRUE(self.zbarrier.closed_by_emp) )
  740. {
  741. self thread treasure_chest_timeout();
  742. }
  743. }
  744.  
  745. // make sure the guy that spent the money gets the item
  746. // SRS 9/3/2008: ...or item goes back into the box if we time out
  747. while( !IS_TRUE(self.closed_by_emp) )
  748. {
  749. self waittill( "trigger", grabber );
  750. self.weapon_out = undefined;
  751.  
  752. if ( IS_TRUE( level.magic_box_grab_by_anyone ) )
  753. {
  754. if( IsPlayer(grabber) )
  755. {
  756. user = grabber;
  757. }
  758. }
  759.  
  760. if( IsDefined( grabber.is_drinking ) && IS_DRINKING(grabber.is_drinking) )
  761. {
  762. wait( 0.1 );
  763. continue;
  764. }
  765.  
  766. if ( grabber == user && user GetCurrentWeapon() == level.weaponNone )
  767. {
  768. wait( 0.1 );
  769. continue;
  770. }
  771.  
  772. if(grabber != level && (IsDefined(self.box_rerespun) && self.box_rerespun))
  773. {
  774. user = grabber;
  775. }
  776.  
  777. if( grabber == user || grabber == level )
  778. {
  779. self.box_rerespun = undefined;
  780. current_weapon = level.weaponNone;
  781.  
  782. if(zm_utility::is_player_valid(user))
  783. {
  784. current_weapon = user GetCurrentWeapon();
  785. }
  786.  
  787. if( grabber == user &&
  788. zm_utility::is_player_valid( user ) &&
  789. !IS_DRINKING(user.is_drinking) &&
  790. !zm_utility::is_placeable_mine( current_weapon ) &&
  791. !zm_equipment::is_equipment( current_weapon ) &&
  792. !user zm_utility::is_player_revive_tool(current_weapon) &&
  793. !current_weapon.isheroweapon &&
  794. !current_weapon.isgadget )
  795. {
  796. weaponIdx = undefined;
  797. if (isDefined(self.zbarrier) && isDefined(self.zbarrier.weapon))
  798. {
  799. weaponIdx = MatchRecordGetWeaponIndex(self.zbarrier.weapon);
  800. }
  801.  
  802. if (isDefined(weaponidx))
  803. {
  804. user RecordMapEvent(ZM_MAP_EVENT_MAGIC_BOX_TAKEN, GetTime(), user.origin, level.round_number, weaponIdx);
  805. }
  806.  
  807. self notify( "user_grabbed_weapon" );
  808. user notify( "user_grabbed_weapon" );
  809. user thread treasure_chest_give_weapon( self.zbarrier.weapon );
  810.  
  811. demo::bookmark( "zm_player_grabbed_magicbox", gettime(), user );
  812.  
  813. //stat tracking
  814. user zm_stats::increment_client_stat( "grabbed_from_magicbox" );
  815. user zm_stats::increment_player_stat( "grabbed_from_magicbox" );
  816.  
  817. break;
  818. }
  819. else if( grabber == level )
  820. {
  821. // it timed out
  822. self.timedOut = true;
  823. weaponIdx = undefined;
  824. if (isDefined(self.zbarrier) && isDefined(self.zbarrier.weapon))
  825. {
  826. weaponIdx = MatchRecordGetWeaponIndex(self.zbarrier.weapon);
  827. }
  828. if (isDefined(weaponidx))
  829. {
  830. user RecordMapEvent(ZM_MAP_EVENT_MAGIC_BOX_RETURNED, GetTime(), user.origin, level.round_number, weaponIdx);
  831. }
  832. break;
  833. }
  834. }
  835.  
  836. WAIT_SERVER_FRAME;
  837. }
  838.  
  839. self.grab_weapon_hint = false;
  840. self.zbarrier notify( "weapon_grabbed" );
  841.  
  842. if ( !IS_TRUE( self._box_opened_by_fire_sale ) )
  843. {
  844. //increase counter of amount of time weapon grabbed, but not during a fire sale
  845. level.chest_accessed += 1;
  846. }
  847.  
  848. //self TriggerEnable( false );
  849. thread zm_unitrigger::unregister_unitrigger(self.unitrigger_stub);
  850.  
  851. // spend cash here...
  852. // give weapon here...
  853. if(isdefined(self.chest_lid))
  854. {
  855. self.chest_lid thread treasure_chest_lid_close( self.timedOut );
  856. }
  857.  
  858. if(isdefined(self.zbarrier))
  859. {
  860. self.zbarrier set_magic_box_zbarrier_state("close");
  861. zm_utility::play_sound_at_pos( "close_chest", self.origin );
  862. self.zbarrier waittill("closed");
  863.  
  864. wait 1;
  865. }
  866. else
  867. {
  868. wait 3.0;
  869. }
  870.  
  871. // Magic box dissapears and moves to a new spot after a predetermined number of uses
  872. if ( (IS_TRUE( level.zombie_vars["zombie_powerup_fire_sale_on"] ) && self [[level._zombiemode_check_firesale_loc_valid_func]]()) || self == level.chests[level.chest_index] )
  873. {
  874. //self TriggerEnable( true );
  875. thread zm_unitrigger::register_static_unitrigger(self.unitrigger_stub, &magicbox_unitrigger_think);
  876.  
  877. // self setvisibletoall();
  878. }
  879. }
  880.  
  881. self._box_open = false;
  882. self._box_opened_by_fire_sale = false;
  883. self.unbearable_respin = undefined;
  884. self.chest_user = undefined;
  885.  
  886. self notify( "chest_accessed" );
  887.  
  888. self thread treasure_chest_think();
  889. }
  890.  
  891. function watch_for_emp_close()
  892. {
  893. self endon( "chest_accessed" );
  894. self.closed_by_emp = 0;
  895. if (!zm_utility::should_watch_for_emp())
  896. return;
  897. if(isDefined(self.zbarrier))
  898. {
  899. self.zbarrier.closed_by_emp = 0;
  900. }
  901.  
  902. while (1)
  903. {
  904. level waittill("emp_detonate",origin,radius);
  905. if ( DistanceSquared( origin, self.origin) < radius * radius )
  906. {
  907. break;
  908. }
  909. }
  910.  
  911. if (level flag::get("moving_chest_now"))
  912. return;
  913.  
  914. // kill the threads
  915. self.closed_by_emp = 1;
  916. if(isdefined(self.zbarrier))
  917. {
  918. self.zbarrier.closed_by_emp = 1;
  919. self.zbarrier notify("box_hacked_respin");
  920. if(isDefined(self.zbarrier.weapon_model))
  921. {
  922. self.zbarrier.weapon_model notify("kill_weapon_movement");
  923. }
  924. if(IsDefined(self.zbarrier.weapon_model_dw))
  925. {
  926. self.zbarrier.weapon_model_dw notify("kill_weapon_movement");
  927. }
  928. }
  929.  
  930. wait 0.1;
  931.  
  932. self notify( "trigger", level );
  933. }
  934.  
  935.  
  936. function can_buy_weapon()
  937. {
  938. if( IsDefined( self.is_drinking ) && IS_DRINKING(self.is_drinking) )
  939. {
  940. return false;
  941. }
  942.  
  943. if(self zm_equipment::hacker_active())
  944. {
  945. return false;
  946. }
  947.  
  948. current_weapon = self GetCurrentWeapon();
  949. if( zm_utility::is_placeable_mine( current_weapon ) || zm_equipment::is_equipment_that_blocks_purchase( current_weapon ) )
  950. {
  951. return false;
  952. }
  953. if( self zm_utility::in_revive_trigger() )
  954. {
  955. return false;
  956. }
  957.  
  958. if( current_weapon == level.weaponNone )
  959. {
  960. return false;
  961. }
  962.  
  963. if ( current_weapon.isheroweapon || current_weapon.isgadget )
  964. {
  965. return false;
  966. }
  967.  
  968. return true;
  969. }
  970.  
  971. function default_box_move_logic()
  972. {
  973. // Check to see if there's a chest selection we should use for this move
  974. // This is indicated by a script_noteworthy of "moveX*"
  975. // (e.g. move1_chest0, move1_chest1) We will randomly choose between
  976. // one of those two chests for that move number only.
  977. index = -1;
  978. for ( i=0; i<level.chests.size; i++ )
  979. {
  980. // Check to see if there is something that we have a choice to move to for this move number
  981. if ( IsSubStr( level.chests[i].script_noteworthy, ("move"+(level.chest_moves+1)) ) &&
  982. i != level.chest_index )
  983. {
  984. index = i;
  985. break;
  986. }
  987. }
  988.  
  989. if ( index != -1 )
  990. {
  991. level.chest_index = index;
  992. }
  993. else
  994. {
  995. level.chest_index++;
  996. }
  997.  
  998. if (level.chest_index >= level.chests.size)
  999. {
  1000. //PI CHANGE - this way the chests won't move in the same order the second time around
  1001. temp_chest_name = level.chests[level.chest_index - 1].script_noteworthy;
  1002. level.chest_index = 0;
  1003. level.chests = array::randomize(level.chests);
  1004. //in case it happens to randomize in such a way that the chest_index now points to the same location
  1005. // JMA - want to avoid an infinite loop, so we use an if statement
  1006. if (temp_chest_name == level.chests[level.chest_index].script_noteworthy)
  1007. {
  1008. level.chest_index++;
  1009. }
  1010. //END PI CHANGE
  1011. }
  1012. }
  1013.  
  1014. //
  1015. // Chest movement sequence, including lifting the box up and disappearing
  1016. //
  1017. function treasure_chest_move( player_vox )
  1018. {
  1019. level waittill("weapon_fly_away_start");
  1020.  
  1021. players = GetPlayers();
  1022.  
  1023. array::thread_all(players, &play_crazi_sound);
  1024.  
  1025. //Delaying the Player Vox
  1026. if( IsDefined( player_vox ) )
  1027. {
  1028. player_vox util::delay( randomintrange(2,7), undefined, &zm_audio::create_and_play_dialog, "general", "box_move" );
  1029. }
  1030.  
  1031. level waittill("weapon_fly_away_end");
  1032.  
  1033. if(isdefined(self.zbarrier))
  1034. {
  1035. self hide_chest(true);
  1036. }
  1037.  
  1038. wait(0.1);
  1039.  
  1040. post_selection_wait_duration = 7;
  1041.  
  1042. // DCS 072710: check if fire sale went into effect during move, reset with time left.
  1043. if(level.zombie_vars["zombie_powerup_fire_sale_on"] == true && self [[level._zombiemode_check_firesale_loc_valid_func]]())
  1044. {
  1045. current_sale_time = level.zombie_vars["zombie_powerup_fire_sale_time"];
  1046. //IPrintLnBold("need to reset this box spot! Time left is ", current_sale_time);
  1047.  
  1048. util::wait_network_frame();
  1049. self thread fire_sale_fix();
  1050. level.zombie_vars["zombie_powerup_fire_sale_time"] = current_sale_time;
  1051.  
  1052. while(level.zombie_vars["zombie_powerup_fire_sale_time"] > 0)
  1053. {
  1054. wait(0.1);
  1055. }
  1056. }
  1057. else
  1058. {
  1059. post_selection_wait_duration += 5;
  1060. }
  1061. level.verify_chest = false;
  1062.  
  1063.  
  1064. if(IsDefined(level._zombiemode_custom_box_move_logic))
  1065. {
  1066. [[level._zombiemode_custom_box_move_logic]]();
  1067. }
  1068. else
  1069. {
  1070. default_box_move_logic();
  1071. }
  1072.  
  1073. if(IsDefined(level.chests[level.chest_index].box_hacks["summon_box"]))
  1074. {
  1075. level.chests[level.chest_index] [[level.chests[level.chest_index].box_hacks["summon_box"]]](false);
  1076. }
  1077.  
  1078. // Now choose a new location
  1079.  
  1080. //wait for all the chests to reset
  1081. wait(post_selection_wait_duration);
  1082.  
  1083. playfx(level._effect["poltergeist"], level.chests[level.chest_index].zbarrier.origin, AnglesToUp( level.chests[level.chest_index].zbarrier.angles ), AnglesToForward( level.chests[level.chest_index].zbarrier.angles ));
  1084. level.chests[level.chest_index] show_chest();
  1085.  
  1086. level flag::clear("moving_chest_now");
  1087. self.zbarrier.chest_moving = false;
  1088. }
  1089.  
  1090.  
  1091. function fire_sale_fix()
  1092. {
  1093. if( !isdefined ( level.zombie_vars["zombie_powerup_fire_sale_on"] ) )
  1094. {
  1095. return;
  1096. }
  1097.  
  1098. if( level.zombie_vars["zombie_powerup_fire_sale_on"] )
  1099. {
  1100. self.old_cost = 950;
  1101. self thread show_chest();
  1102. self.zombie_cost = 10;
  1103. self.unitrigger_stub zm_utility::unitrigger_set_hint_string( self , "default_treasure_chest", self.zombie_cost );
  1104.  
  1105. util::wait_network_frame();
  1106.  
  1107. level waittill( "fire_sale_off" );
  1108.  
  1109. while(IS_TRUE(self._box_open ))
  1110. {
  1111. wait(.1);
  1112. }
  1113.  
  1114. self hide_chest(true);
  1115.  
  1116. self.zombie_cost = self.old_cost;
  1117. }
  1118. }
  1119.  
  1120. function check_for_desirable_chest_location()
  1121. {
  1122. if( !isdefined( level.desirable_chest_location ) )
  1123. return level.chest_index;
  1124.  
  1125. if( level.chests[level.chest_index].script_noteworthy == level.desirable_chest_location )
  1126. {
  1127. level.desirable_chest_location = undefined;
  1128. return level.chest_index;
  1129. }
  1130. for(i = 0 ; i < level.chests.size; i++ )
  1131. {
  1132. if( level.chests[i].script_noteworthy == level.desirable_chest_location )
  1133. {
  1134. level.desirable_chest_location = undefined;
  1135. return i;
  1136. }
  1137. }
  1138.  
  1139. level.desirable_chest_location = undefined;
  1140. return level.chest_index;
  1141. }
  1142.  
  1143.  
  1144. function rotateroll_box()
  1145. {
  1146. angles = 40;
  1147. angles2 = 0;
  1148. //self endon("movedone");
  1149. while(isdefined(self))
  1150. {
  1151. self RotateRoll(angles + angles2, 0.5);
  1152. wait(0.7);
  1153. angles2 = 40;
  1154. self RotateRoll(angles * -2, 0.5);
  1155. wait(0.7);
  1156. }
  1157.  
  1158.  
  1159.  
  1160. }
  1161. //verify if that magic box is open to players or not.
  1162. function verify_chest_is_open()
  1163. {
  1164.  
  1165. //for(i = 0; i < 5; i++)
  1166. //PI CHANGE - altered so that there can be more than 5 valid chest locations
  1167. for (i = 0; i < level.open_chest_location.size; i++)
  1168. {
  1169. if(isdefined(level.open_chest_location[i]))
  1170. {
  1171. if(level.open_chest_location[i] == level.chests[level.chest_index].script_noteworthy)
  1172. {
  1173. level.verify_chest = true;
  1174. return;
  1175. }
  1176. }
  1177.  
  1178. }
  1179.  
  1180. level.verify_chest = false;
  1181.  
  1182.  
  1183. }
  1184.  
  1185.  
  1186. function treasure_chest_timeout()
  1187. {
  1188. self endon( "user_grabbed_weapon" );
  1189. self.zbarrier endon( "box_hacked_respin" );
  1190. self.zbarrier endon( "box_hacked_rerespin" );
  1191.  
  1192. wait( 12 );
  1193. self notify( "trigger", level );
  1194. }
  1195.  
  1196. function treasure_chest_lid_open()
  1197. {
  1198. openRoll = 105;
  1199. openTime = 0.5;
  1200.  
  1201. self RotateRoll( 105, openTime, ( openTime * 0.5 ) );
  1202.  
  1203. zm_utility::play_sound_at_pos( "open_chest", self.origin );
  1204. zm_utility::play_sound_at_pos( "music_chest", self.origin );
  1205. }
  1206.  
  1207. function treasure_chest_lid_close( timedOut )
  1208. {
  1209. closeRoll = -105;
  1210. closeTime = 0.5;
  1211.  
  1212. self RotateRoll( closeRoll, closeTime, ( closeTime * 0.5 ) );
  1213. zm_utility::play_sound_at_pos( "close_chest", self.origin );
  1214.  
  1215. self notify("lid_closed");
  1216. }
  1217.  
  1218.  
  1219. function treasure_chest_CanPlayerReceiveWeapon( player, weapon, pap_triggers )
  1220. {
  1221. if ( !zm_weapons::get_is_in_box( weapon ) )
  1222. {
  1223. return false;
  1224. }
  1225.  
  1226. if ( IsDefined( player ) && player zm_weapons::has_weapon_or_upgrade( weapon ) )
  1227. {
  1228. return false;
  1229. }
  1230.  
  1231. if ( !zm_weapons::limited_weapon_below_quota( weapon, player, pap_triggers ))
  1232. return false;
  1233.  
  1234. if ( !player zm_weapons::player_can_use_content( weapon ) )
  1235. return false;
  1236.  
  1237. if(isdefined(level.custom_magic_box_selection_logic))
  1238. {
  1239. if(![[level.custom_magic_box_selection_logic]](weapon, player, pap_triggers))
  1240. {
  1241. return false;
  1242. }
  1243. }
  1244.  
  1245. if ( weapon.name == "ray_gun" )
  1246. {
  1247. if ( player zm_weapons::has_weapon_or_upgrade( GetWeapon( "raygun_mark2" ) ) )
  1248. {
  1249. return false;
  1250. }
  1251. }
  1252.  
  1253. if ( weapon.name == "raygun_mark2" )
  1254. {
  1255. if ( player zm_weapons::has_weapon_or_upgrade( GetWeapon( "ray_gun" ) ) )
  1256. {
  1257. return false;
  1258. }
  1259. }
  1260.  
  1261. // enable special level by level weapon checks
  1262. if( IsDefined( player ) && isdefined( level.special_weapon_magicbox_check ) )
  1263. {
  1264. return player [[level.special_weapon_magicbox_check]]( weapon );
  1265. }
  1266.  
  1267. return true;
  1268. }
  1269.  
  1270. function treasure_chest_ChooseWeightedRandomWeapon( player )
  1271. {
  1272. {
  1273. if( level.round_number < 20 )
  1274. {
  1275. if( level.script == "zm_genesis" ) // Revelations Box Patch
  1276. {
  1277. if( !player zm_weapons::has_weapon_or_upgrade( GetWeapon("octobomb" ) ) )
  1278. return GetWeapon( "octobomb");
  1279. if( !player zm_weapons::has_weapon_or_upgrade( GetWeapon("idgun_genesis_0" ) ) )
  1280. return GetWeapon( "idgun_genesis_0");
  1281. }
  1282. }
  1283. }
  1284. keys = array::randomize( GetArrayKeys( level.zombie_weapons ) );
  1285. if (IsDefined(level.CustomRandomWeaponWeights))
  1286. {
  1287. keys = player [[level.CustomRandomWeaponWeights]](keys);
  1288. }
  1289. pap_triggers = zm_pap_util::get_triggers();
  1290. for ( i = 0; i < keys.size; i++ )
  1291. {
  1292. if ( treasure_chest_CanPlayerReceiveWeapon( player, keys[i], pap_triggers ) )
  1293. {
  1294. return keys[i];
  1295. }
  1296. }
  1297.  
  1298. return keys[0];
  1299. }
  1300.  
  1301.  
  1302. function weapon_show_hint_choke()
  1303. {
  1304. level._weapon_show_hint_choke = 0;
  1305.  
  1306. while(1)
  1307. {
  1308. WAIT_SERVER_FRAME;
  1309. level._weapon_show_hint_choke = 0;
  1310. }
  1311. }
  1312.  
  1313. function decide_hide_show_hint( endon_notify, second_endon_notify, onlyplayer, can_buy_weapon_extra_check_func )
  1314. {
  1315. self endon("death");
  1316.  
  1317. if( isDefined( endon_notify ) )
  1318. {
  1319. self endon( endon_notify );
  1320. }
  1321.  
  1322. if( isDefined( second_endon_notify ))
  1323. {
  1324. self endon( second_endon_notify );
  1325. }
  1326.  
  1327. if(!IsDefined(level._weapon_show_hint_choke))
  1328. {
  1329. level thread weapon_show_hint_choke();
  1330. }
  1331.  
  1332. use_choke = false;
  1333.  
  1334. if(IsDefined(level._use_choke_weapon_hints) && level._use_choke_weapon_hints == 1)
  1335. {
  1336. use_choke = true;
  1337. }
  1338.  
  1339.  
  1340. while( true )
  1341. {
  1342.  
  1343. last_update = GetTime();
  1344.  
  1345. if ( IsDefined( self.chest_user ) && !IsDefined( self.box_rerespun ) )
  1346. {
  1347. if ( zm_utility::is_placeable_mine( self.chest_user GetCurrentWeapon() ) || self.chest_user zm_equipment::hacker_active() )
  1348. {
  1349. self SetInvisibleToPlayer( self.chest_user);
  1350. }
  1351. else
  1352. {
  1353. self SetVisibleToPlayer( self.chest_user );
  1354. }
  1355. }
  1356. else if ( IsDefined( onlyplayer ) )
  1357. {
  1358. if ( onlyplayer can_buy_weapon() && ( !IsDefined( can_buy_weapon_extra_check_func ) || onlyplayer [[ can_buy_weapon_extra_check_func ]]( self.weapon ) ) && !onlyplayer bgb::is_enabled( "zm_bgb_disorderly_combat" ) )
  1359. {
  1360. self SetInvisibleToPlayer( onlyplayer, false );
  1361. }
  1362. else
  1363. {
  1364. self SetInvisibleToPlayer( onlyplayer, true );
  1365. }
  1366. }
  1367. else // all players
  1368. {
  1369. players = GetPlayers();
  1370. for ( i = 0; i < players.size; i++ )
  1371. {
  1372. if ( players[ i ] can_buy_weapon() && ( !IsDefined( can_buy_weapon_extra_check_func ) || players[ i ] [[ can_buy_weapon_extra_check_func ]]( self.weapon ) ) && !players[ i ] bgb::is_enabled( "zm_bgb_disorderly_combat" ) )
  1373. {
  1374. self SetInvisibleToPlayer( players[i], false );
  1375. }
  1376. else
  1377. {
  1378. self SetInvisibleToPlayer( players[i], true );
  1379. }
  1380. }
  1381. }
  1382.  
  1383. if(use_choke)
  1384. {
  1385. while((level._weapon_show_hint_choke > 4) && (GetTime() < (last_update + 150)))
  1386. {
  1387. WAIT_SERVER_FRAME;
  1388. }
  1389. }
  1390. else
  1391. {
  1392. wait(0.1);
  1393. }
  1394.  
  1395. level._weapon_show_hint_choke ++;
  1396. }
  1397. }
  1398.  
  1399. function get_left_hand_weapon_model_name( weapon )
  1400. {
  1401. dw_weapon = weapon.dualWieldWeapon;
  1402. if ( dw_weapon != level.weaponNone )
  1403. {
  1404. return dw_weapon.worldModel;
  1405. }
  1406.  
  1407. return weapon.worldModel;
  1408. }
  1409.  
  1410. function clean_up_hacked_box()
  1411. {
  1412. self waittill("box_hacked_respin");
  1413. self endon("box_spin_done");
  1414.  
  1415. if(IsDefined(self.weapon_model))
  1416. {
  1417. self.weapon_model Delete();
  1418. self.weapon_model = undefined;
  1419. }
  1420.  
  1421. if(IsDefined(self.weapon_model_dw))
  1422. {
  1423. self.weapon_model_dw Delete();
  1424. self.weapon_model_dw = undefined;
  1425. }
  1426.  
  1427.  
  1428. self HideZBarrierPiece(3);
  1429. self HideZBarrierPiece(4);
  1430. self SetZBarrierPieceState(3, "closed");
  1431. self SetZBarrierPieceState(4, "closed");
  1432. }
  1433.  
  1434.  
  1435. function treasure_chest_firesale_active()
  1436. {
  1437. return IS_TRUE( level.zombie_vars["zombie_powerup_fire_sale_on"] );
  1438. }
  1439.  
  1440. function treasure_chest_should_move( chest, player )
  1441. {
  1442. // Increase the chance of joker appearing from 0-100 based on amount of the time chest has been opened.
  1443. if( ( GetDvarString( "magic_chest_movable") == "1") &&
  1444. !IS_TRUE( chest._box_opened_by_fire_sale ) &&
  1445. !treasure_chest_firesale_active() &&
  1446. self [[level._zombiemode_check_firesale_loc_valid_func]]() )
  1447. {
  1448. // random change of getting the joker that moves the box
  1449. random = Randomint(100);
  1450.  
  1451. if( !isdefined( level.chest_min_move_usage ) )
  1452. {
  1453. level.chest_min_move_usage = 4;
  1454. }
  1455.  
  1456. if( level.chest_accessed < level.chest_min_move_usage )
  1457. {
  1458. chance_of_joker = -1;
  1459. }
  1460. else
  1461. {
  1462. chance_of_joker = level.chest_accessed + 20;
  1463.  
  1464. // make sure teddy bear appears on the 8th pull if it hasn't moved from the initial spot
  1465. if ( level.chest_moves == 0 && level.chest_accessed >= 8 )
  1466. {
  1467. chance_of_joker = 100;
  1468. }
  1469.  
  1470. // pulls 4 thru 8, there is a 15% chance of getting the teddy bear
  1471. // NOTE: this happens in all cases
  1472. if( level.chest_accessed >= 4 && level.chest_accessed < 8 )
  1473. {
  1474. if( random < 15 )
  1475. {
  1476. chance_of_joker = 100;
  1477. }
  1478. else
  1479. {
  1480. chance_of_joker = -1;
  1481. }
  1482. }
  1483.  
  1484. // after the first magic box move the teddy bear percentages changes
  1485. if ( level.chest_moves > 0 )
  1486. {
  1487. // between pulls 8 thru 12, the teddy bear percent is 30%
  1488. if( level.chest_accessed >= 8 && level.chest_accessed < 13 )
  1489. {
  1490. if( random < 30 )
  1491. {
  1492. chance_of_joker = 100;
  1493. }
  1494. else
  1495. {
  1496. chance_of_joker = -1;
  1497. }
  1498. }
  1499.  
  1500. // after 12th pull, the teddy bear percent is 50%
  1501. if( level.chest_accessed >= 13 )
  1502. {
  1503. if( random < 50 )
  1504. {
  1505. chance_of_joker = 100;
  1506. }
  1507. else
  1508. {
  1509. chance_of_joker = -1;
  1510. }
  1511. }
  1512. }
  1513. }
  1514.  
  1515. if(IsDefined(chest.no_fly_away))
  1516. {
  1517. chance_of_joker = -1;
  1518. }
  1519.  
  1520. if(IsDefined(level._zombiemode_chest_joker_chance_override_func))
  1521. {
  1522. chance_of_joker = [[level._zombiemode_chest_joker_chance_override_func]](chance_of_joker);
  1523. }
  1524.  
  1525. if ( chance_of_joker > random )
  1526. {
  1527. return true;
  1528. }
  1529. }
  1530.  
  1531. return false;
  1532. }
  1533.  
  1534. function spawn_joker_weapon_model( player, model, origin, angles )
  1535. {
  1536. weapon_model = spawn( "script_model", origin );
  1537. if ( isdefined( angles ) )
  1538. {
  1539. weapon_model.angles = angles;
  1540. }
  1541. weapon_model SetModel(model);
  1542. return weapon_model;
  1543. }
  1544.  
  1545.  
  1546. // lock or unlock a weapon model
  1547. function treasure_chest_weapon_locking( player, weapon, onOff )
  1548. {
  1549. if ( isdefined(self.locked_model) )
  1550. {
  1551. self.locked_model delete();
  1552. self.locked_model = undefined;
  1553. }
  1554.  
  1555. if ( onOff )
  1556. {
  1557. if ( weapon == level.weaponNone )
  1558. {
  1559. self.locked_model = spawn_joker_weapon_model( player, level.chest_joker_model, self.origin, (0,0,0) );
  1560. }
  1561. else
  1562. {
  1563. self.locked_model = zm_utility::spawn_buildkit_weapon_model( player, weapon, undefined, self.origin, (0,0,0));
  1564. }
  1565. self.locked_model Ghost();
  1566. self.locked_model clientfield::set( "force_stream", 1 );
  1567. }
  1568. }
  1569.  
  1570. function treasure_chest_weapon_spawn( chest, player, respin )
  1571. {
  1572. self endon("box_hacked_respin");
  1573. self thread clean_up_hacked_box();
  1574. assert(IsDefined(player));
  1575. // spawn the model
  1576. // model = spawn( "script_model", self.origin );
  1577. // model.angles = self.angles +( 0, 90, 0 );
  1578.  
  1579. // floatHeight = 40;
  1580.  
  1581. //move it up
  1582. // model moveto( model.origin +( 0, 0, floatHeight ), 3, 2, 0.9 );
  1583.  
  1584. self.chest_moving = false;
  1585. move_the_box = treasure_chest_should_move( chest, player );
  1586.  
  1587. preferred_weapon = undefined;
  1588.  
  1589. if ( move_the_box )
  1590. {
  1591. preferred_weapon = level.weaponNone;
  1592. }
  1593. // Pick a random weapon
  1594. else
  1595. {
  1596. preferred_weapon = treasure_chest_ChooseWeightedRandomWeapon( player );
  1597. }
  1598.  
  1599. chest treasure_chest_weapon_locking( player, preferred_weapon, true );
  1600.  
  1601. // rotation would go here
  1602.  
  1603. // make with the mario kart
  1604. const FLOAT_HEIGHT = 40;
  1605. const BOX_MOVE_BEAR_FLYAWAY_DISTANCE = 500;
  1606. const BOX_MOVE_BEAR_FLYAWAY_TIME = 4;
  1607. const BOX_MOVE_BEAR_FLYAWAY_ACCEL = 3;
  1608. self.weapon = level.weaponNone;
  1609. modelname = undefined;
  1610. rand = undefined;
  1611. number_cycles = 40;
  1612.  
  1613. if(isdefined(chest.zbarrier))
  1614. {
  1615. if ( IsDefined( level.custom_magic_box_do_weapon_rise ) )
  1616. {
  1617. chest.zbarrier thread [[level.custom_magic_box_do_weapon_rise]]();
  1618. }
  1619. else
  1620. {
  1621. chest.zbarrier thread magic_box_do_weapon_rise();
  1622. }
  1623. }
  1624.  
  1625. for( i = 0; i < number_cycles; i++ )
  1626. {
  1627.  
  1628. if( i < 20 )
  1629. {
  1630. WAIT_SERVER_FRAME;
  1631. }
  1632. else if( i < 30 )
  1633. {
  1634. wait( 0.1 );
  1635. }
  1636. else if( i < 35 )
  1637. {
  1638. wait( 0.2 );
  1639. }
  1640. else if( i < 38 )
  1641. {
  1642. wait( 0.3 );
  1643. }
  1644. }
  1645.  
  1646. if ( IsDefined( level.custom_magic_box_weapon_wait ) )
  1647. {
  1648. [[level.custom_magic_box_weapon_wait]](); // wait to match up with any waits in the custom weapon rise
  1649. }
  1650.  
  1651. //**********************************
  1652. // Pick a random weapon from the box
  1653. //**********************************
  1654.  
  1655. new_firesale = ( move_the_box && treasure_chest_firesale_active() );
  1656.  
  1657. // if the box was scheduled to move and a firesale has started since the box started cycling pick a real weapon
  1658. if ( new_firesale )
  1659. {
  1660. move_the_box = false;
  1661. preferred_weapon = treasure_chest_ChooseWeightedRandomWeapon( player );
  1662. }
  1663.  
  1664. // make sure the player can still get the weapon we picked at the start
  1665. if ( !move_the_box && treasure_chest_CanPlayerReceiveWeapon( player, preferred_weapon, zm_pap_util::get_triggers() ) )
  1666. {
  1667. rand = preferred_weapon;
  1668. }
  1669. // Pick a random weapon
  1670. else
  1671. {
  1672. rand = treasure_chest_ChooseWeightedRandomWeapon( player );
  1673. }
  1674.  
  1675. // forcing box weapons from the devgui is now handled in treasure_chest_ChooseWeightedRandomWeapon
  1676. // this allows us to test box weapon filtering.
  1677. // if you need to give yourself a weapon without filtering you can use
  1678. // set zombie_devgui_gun gunyouwant_zm
  1679.  
  1680. // Here's where the org get it's weapon type for the give function
  1681. self.weapon = rand;
  1682.  
  1683. if ( isdefined( level.func_magicbox_weapon_spawned ) )
  1684. {
  1685. self thread [[ level.func_magicbox_weapon_spawned ]]( self.weapon );
  1686. }
  1687.  
  1688. //util::wait_network_frame();
  1689. wait( 0.1 );
  1690.  
  1691. // get offset for floating weapon
  1692. if ( IsDefined( level.custom_magicbox_float_height ) )
  1693. {
  1694. v_float = AnglesToUp( self.angles ) * level.custom_magicbox_float_height;
  1695. }
  1696. else
  1697. {
  1698. v_float = AnglesToUp( self.angles ) * FLOAT_HEIGHT; // draw vector straight up with reference to the mystery box angles
  1699. }
  1700.  
  1701. self.model_dw = undefined;
  1702.  
  1703. self.weapon_model = zm_utility::spawn_buildkit_weapon_model( player, rand, undefined, self.origin + v_float, (-self.angles[0], self.angles[1] + 180, -self.angles[2]));
  1704.  
  1705. if ( rand.isDualWield )
  1706. {
  1707. dweapon = rand;
  1708. if ( isdefined( rand.dualwieldweapon ) && rand.dualwieldweapon != level.weaponNone )
  1709. {
  1710. dweapon = rand.dualwieldweapon;
  1711. }
  1712.  
  1713. self.weapon_model_dw = zm_utility::spawn_buildkit_weapon_model( player, dweapon, undefined, self.weapon_model.origin - ( 3, 3, 3 ), self.weapon_model.angles );
  1714. }
  1715.  
  1716. if ( move_the_box && !(level.zombie_vars["zombie_powerup_fire_sale_on"] && self [[level._zombiemode_check_firesale_loc_valid_func]]()) )
  1717. {
  1718. self.weapon_model SetModel(level.chest_joker_model);
  1719.  
  1720. if(IsDefined(self.weapon_model_dw))
  1721. {
  1722. self.weapon_model_dw Delete();
  1723. self.weapon_model_dw = undefined;
  1724. }
  1725.  
  1726. if( IsPlayer( chest.chest_user ) && chest.chest_user bgb::is_enabled( "zm_bgb_unbearable" ) )
  1727. {
  1728. level.chest_accessed = 0;
  1729. chest.unbearable_respin = true;
  1730. chest.chest_user notify( "zm_bgb_unbearable", chest );
  1731. chest waittill( "forever" );
  1732. }
  1733.  
  1734. self.chest_moving = true;
  1735. level flag::set("moving_chest_now");
  1736. level.chest_accessed = 0;
  1737.  
  1738. level.chest_moves++;
  1739. }
  1740.  
  1741. self notify( "randomization_done" );
  1742.  
  1743. if (IS_TRUE(self.chest_moving))
  1744. {
  1745. if( IsDefined( level.chest_joker_custom_movement ) )
  1746. {
  1747. self [[ level.chest_joker_custom_movement ]]();
  1748. }
  1749. else
  1750. {
  1751. //record the weapon model origin and delete it, it could have parts hidden based on what weapon spawned
  1752. v_origin = self.weapon_model.origin;
  1753. self.weapon_model Delete();
  1754.  
  1755. //spawn a fresh new model with everything correct
  1756. self.weapon_model = Spawn( "script_model", v_origin );
  1757. self.weapon_model SetModel( level.chest_joker_model );
  1758. self.weapon_model.angles = self.angles + ( 0, 180, 0 );
  1759.  
  1760. wait .5; // we need a wait here before this notify
  1761. level notify("weapon_fly_away_start");
  1762. wait 2;
  1763. if( IsDefined( self.weapon_model ) )
  1764. {
  1765. v_fly_away = self.origin + ( AnglesToUp( self.angles ) * BOX_MOVE_BEAR_FLYAWAY_DISTANCE );
  1766. self.weapon_model MoveTo( v_fly_away, BOX_MOVE_BEAR_FLYAWAY_TIME, BOX_MOVE_BEAR_FLYAWAY_ACCEL );
  1767. }
  1768.  
  1769. if ( IsDefined(self.weapon_model_dw ) )
  1770. {
  1771. v_fly_away = self.origin + ( AnglesToUp( self.angles ) * BOX_MOVE_BEAR_FLYAWAY_DISTANCE );
  1772. self.weapon_model_dw MoveTo( v_fly_away, BOX_MOVE_BEAR_FLYAWAY_TIME, BOX_MOVE_BEAR_FLYAWAY_ACCEL );
  1773. }
  1774.  
  1775. self.weapon_model waittill("movedone");
  1776. self.weapon_model delete();
  1777.  
  1778. if(IsDefined(self.weapon_model_dw))
  1779. {
  1780. self.weapon_model_dw Delete();
  1781. self.weapon_model_dw = undefined;
  1782. }
  1783.  
  1784. self notify( "box_moving" );
  1785. level notify("weapon_fly_away_end");
  1786. }
  1787. }
  1788. else
  1789. {
  1790. if(!IsDefined(respin))
  1791. {
  1792. if(IsDefined(chest.box_hacks["respin"]))
  1793. {
  1794. self [[chest.box_hacks["respin"]]](chest, player);
  1795. }
  1796. }
  1797. else
  1798. {
  1799. if(IsDefined(chest.box_hacks["respin_respin"]))
  1800. {
  1801. self [[chest.box_hacks["respin_respin"]]](chest, player);
  1802. }
  1803. }
  1804.  
  1805. // allow for custom back-into-box movement
  1806. if(IsDefined(level.custom_magic_box_timer_til_despawn))
  1807. {
  1808. self.weapon_model thread [[level.custom_magic_box_timer_til_despawn]]( self );
  1809. }
  1810. else
  1811. {
  1812. // weapon re-enters box
  1813. self.weapon_model thread timer_til_despawn( v_float );
  1814. }
  1815.  
  1816. if(IsDefined(self.weapon_model_dw))
  1817. {
  1818. if(IsDefined(level.custom_magic_box_timer_til_despawn))
  1819. {
  1820. self.weapon_model_dw thread [[level.custom_magic_box_timer_til_despawn]]( self );
  1821. }
  1822. else
  1823. {
  1824. self.weapon_model_dw thread timer_til_despawn( v_float );
  1825. }
  1826. }
  1827.  
  1828. self waittill( "weapon_grabbed" );
  1829.  
  1830. if( !chest.timedOut )
  1831. {
  1832. if(IsDefined(self.weapon_model))
  1833. {
  1834. self.weapon_model Delete();
  1835. }
  1836.  
  1837. if(IsDefined(self.weapon_model_dw))
  1838. {
  1839. self.weapon_model_dw Delete();
  1840. }
  1841. }
  1842. }
  1843.  
  1844. chest treasure_chest_weapon_locking( player, preferred_weapon, false );
  1845.  
  1846. self.weapon = level.weaponNone;
  1847. self notify("box_spin_done");
  1848. }
  1849.  
  1850. //
  1851. //
  1852. function chest_get_min_usage()
  1853. {
  1854. min_usage = 4;
  1855.  
  1856. return( min_usage );
  1857. }
  1858.  
  1859. //
  1860. //
  1861. function chest_get_max_usage()
  1862. {
  1863. max_usage = 6;
  1864.  
  1865. players = GetPlayers();
  1866.  
  1867. // Special case max box pulls before 1st box move
  1868. if( level.chest_moves == 0 )
  1869. {
  1870. if( players.size == 1 )
  1871. {
  1872. max_usage = 3;
  1873. }
  1874. else if( players.size == 2 )
  1875. {
  1876. max_usage = 4;
  1877. }
  1878. else if( players.size == 3 )
  1879. {
  1880. max_usage = 5;
  1881. }
  1882. else
  1883. {
  1884. max_usage = 6;
  1885. }
  1886. }
  1887. // Box has moved, what is the maximum number of times it can move again?
  1888. else
  1889. {
  1890. if( players.size == 1 )
  1891. {
  1892. max_usage = 4;
  1893. }
  1894. else if( players.size == 2 )
  1895. {
  1896. max_usage = 4;
  1897. }
  1898. else if( players.size == 3 )
  1899. {
  1900. max_usage = 5;
  1901. }
  1902. else
  1903. {
  1904. max_usage = 7;
  1905. }
  1906. }
  1907. return( max_usage );
  1908. }
  1909.  
  1910.  
  1911. function timer_til_despawn( v_float )
  1912. {
  1913. self endon("kill_weapon_movement");
  1914. // SRS 9/3/2008: if we timed out, move the weapon back into the box instead of deleting it
  1915. putBackTime = 12;
  1916. self MoveTo( self.origin - ( v_float * 0.85 ), putBackTime, ( putBackTime * 0.5 ) );
  1917. wait( putBackTime );
  1918.  
  1919. if(isdefined(self))
  1920. {
  1921. self Delete();
  1922. }
  1923. }
  1924.  
  1925. function treasure_chest_glowfx()
  1926. {
  1927. self clientfield::set( "magicbox_open_glow", true );
  1928. self clientfield::set( "magicbox_closed_glow", false );
  1929.  
  1930. ret_val = self util::waittill_any_return( "weapon_grabbed", "box_moving" );
  1931.  
  1932. self clientfield::set( "magicbox_open_glow", false );
  1933.  
  1934. if ( "box_moving" != ret_val )
  1935. {
  1936. self clientfield::set( "magicbox_closed_glow", true );
  1937. }
  1938. }
  1939.  
  1940. // self is the player string comes from the randomization function
  1941. function treasure_chest_give_weapon( weapon )
  1942. {
  1943. self.last_box_weapon = GetTime();
  1944.  
  1945. // this function was almost identical to weapon_give() so it calls that instead
  1946.  
  1947. //Audio: Raygun ALWAYS plays this stinger when getting it from the magicbox
  1948. if( weapon.name == "ray_gun" || weapon.name == "raygun_mark2" )
  1949. {
  1950. playsoundatposition( "mus_raygun_stinger", (0,0,0) );
  1951. }
  1952.  
  1953. if( should_upgrade_weapon( self, weapon ) )
  1954. {
  1955. if( self zm_weapons::can_upgrade_weapon( weapon ) )
  1956. {
  1957. weapon = zm_weapons::get_upgrade_weapon( weapon );
  1958. self notify( "zm_bgb_crate_power_used" );
  1959. }
  1960. }
  1961.  
  1962. if( zm_utility::is_hero_weapon( weapon ) && !self HasWeapon( weapon ) )
  1963. {
  1964. self give_hero_weapon( weapon );
  1965. }
  1966. else
  1967. {
  1968. w_give = self zm_weapons::weapon_give(weapon, false, true);
  1969.  
  1970. // make sure no aat given from the box
  1971. if( isdefined(weapon) )
  1972. {
  1973. self thread aat::remove( w_give );
  1974. }
  1975. }
  1976. }
  1977.  
  1978. function give_hero_weapon( weapon )//self = player
  1979. {
  1980. w_previous = self GetCurrentWeapon();
  1981. self zm_weapons::weapon_give( weapon );
  1982. self GadgetPowerSet( 0, 99 );
  1983. self SwitchToWeapon( weapon );
  1984. self waittill( "weapon_change_complete" );
  1985. self SetLowReady( true );
  1986. self SwitchToWeapon( w_previous );
  1987. self util::waittill_any_timeout( 1.0, "weapon_change_complete" );
  1988. self SetLowReady( false );
  1989. self GadgetPowerSet( 0, 100 );
  1990. }
  1991.  
  1992. function should_upgrade_weapon( player, weapon )
  1993. {
  1994. if( isdefined( level.magicbox_should_upgrade_weapon_override ) )
  1995. {
  1996. return [[ level.magicbox_should_upgrade_weapon_override ]]( player, weapon ); // PORTIZ 7/19/2016: pass in player and weapon to check specific conditions
  1997. }
  1998.  
  1999. if( player bgb::is_enabled( "zm_bgb_crate_power" ) )
  2000. {
  2001. return true;
  2002. }
  2003.  
  2004. return false;
  2005. }
  2006.  
  2007. function magic_box_initial()
  2008. {
  2009. self SetZBarrierPieceState(1, "open");
  2010.  
  2011. self clientfield::set( "magicbox_closed_glow", true );
  2012. }
  2013.  
  2014. function magic_box_arrives()
  2015. {
  2016. self SetZBarrierPieceState(1, "opening");
  2017. while(self GetZBarrierPieceState(1) == "opening")
  2018. {
  2019. WAIT_SERVER_FRAME;
  2020. }
  2021. self notify("arrived");
  2022. }
  2023.  
  2024. function magic_box_leaves()
  2025. {
  2026. self SetZBarrierPieceState(1, "closing");
  2027. while(self GetZBarrierPieceState(1) == "closing")
  2028. {
  2029. wait (0.1);
  2030. }
  2031. self notify("left");
  2032. }
  2033.  
  2034. function magic_box_opens()
  2035. {
  2036. self SetZBarrierPieceState(2, "opening");
  2037. while(self GetZBarrierPieceState(2) == "opening")
  2038. {
  2039. wait (0.1);
  2040. }
  2041. self notify("opened");
  2042. }
  2043.  
  2044. function magic_box_closes()
  2045. {
  2046. self SetZBarrierPieceState(2, "closing");
  2047. while(self GetZBarrierPieceState(2) == "closing")
  2048. {
  2049. wait (0.1);
  2050. }
  2051. self notify("closed");
  2052. }
  2053.  
  2054. function magic_box_do_weapon_rise()
  2055. {
  2056. self endon("box_hacked_respin");
  2057.  
  2058. self SetZBarrierPieceState(3, "closed");
  2059. self SetZBarrierPieceState(4, "closed");
  2060.  
  2061. util::wait_network_frame();
  2062.  
  2063. self ZBarrierPieceUseBoxRiseLogic(3);
  2064. self ZBarrierPieceUseBoxRiseLogic(4);
  2065.  
  2066. self ShowZBarrierPiece(3);
  2067. self ShowZBarrierPiece(4);
  2068. self SetZBarrierPieceState(3, "opening");
  2069. self SetZBarrierPieceState(4, "opening");
  2070.  
  2071. while(self GetZBarrierPieceState(3) != "open")
  2072. {
  2073. wait(0.5);
  2074. }
  2075.  
  2076. self HideZBarrierPiece(3);
  2077. self HideZBarrierPiece(4);
  2078.  
  2079. }
  2080.  
  2081. function magic_box_do_teddy_flyaway()
  2082. {
  2083. self ShowZBarrierPiece(3);
  2084. self SetZBarrierPieceState(3, "closing");
  2085. }
  2086.  
  2087. function is_chest_active()
  2088. {
  2089. curr_state = self.zbarrier get_magic_box_zbarrier_state();
  2090.  
  2091. if( level flag::get( "moving_chest_now" ) )
  2092. {
  2093. return false;
  2094. }
  2095.  
  2096. if( curr_state == "open" || curr_state == "close" )
  2097. {
  2098. return true;
  2099. }
  2100.  
  2101. return false;
  2102. }
  2103.  
  2104. function get_magic_box_zbarrier_state()
  2105. {
  2106. return self.state;
  2107. }
  2108.  
  2109. function set_magic_box_zbarrier_state(state)
  2110. {
  2111. for(i = 0; i < self GetNumZBarrierPieces(); i ++)
  2112. {
  2113. self HideZBarrierPiece(i);
  2114. }
  2115. self notify("zbarrier_state_change");
  2116.  
  2117. self [[level.magic_box_zbarrier_state_func]](state);
  2118. }
  2119.  
  2120. function process_magic_box_zbarrier_state(state)
  2121. {
  2122. switch(state)
  2123. {
  2124. case "away":
  2125. self ShowZBarrierPiece(0);
  2126. self.state = "away";
  2127. break;
  2128. case "arriving":
  2129. self ShowZBarrierPiece(1);
  2130. self thread magic_box_arrives();
  2131. self.state = "arriving";
  2132. break;
  2133. case "initial":
  2134. self ShowZBarrierPiece(1);
  2135. self thread magic_box_initial();
  2136. thread zm_unitrigger::register_static_unitrigger(self.owner.unitrigger_stub, &magicbox_unitrigger_think);
  2137. self.state = "initial";
  2138. break;
  2139. case "open":
  2140. self ShowZBarrierPiece(2);
  2141. self thread magic_box_opens();
  2142. self.state = "open";
  2143. break;
  2144. case "close":
  2145. self ShowZBarrierPiece(2);
  2146. self thread magic_box_closes();
  2147. self.state = "close";
  2148. break;
  2149. case "leaving":
  2150. self showZBarrierPiece(1);
  2151. self thread magic_box_leaves();
  2152. self.state = "leaving";
  2153. break;
  2154. default:
  2155. if( IsDefined( level.custom_magicbox_state_handler ) )
  2156. {
  2157. self [[ level.custom_magicbox_state_handler ]]( state );
  2158. }
  2159. break;
  2160. }
  2161. }
  2162.  
  2163. function magicbox_host_migration()
  2164. {
  2165. level endon("end_game");
  2166.  
  2167. level notify("mb_hostmigration");
  2168. level endon("mb_hostmigration");
  2169.  
  2170. while(1)
  2171. {
  2172. level waittill("host_migration_end");
  2173.  
  2174. if(!isDefined(level.chests))
  2175. continue;
  2176.  
  2177. foreach( chest in level.chests )
  2178. {
  2179. if ( !IS_TRUE( chest.hidden ) )
  2180. {
  2181. if ( IsDefined( chest ) && IsDefined( chest.pandora_light ) )
  2182. {
  2183. playfxontag(level._effect["lght_marker"], chest.pandora_light, "tag_origin");
  2184. }
  2185. }
  2186. util::wait_network_frame();
  2187. }
  2188. }
  2189. }
  2190.  
  2191. function box_encounter_vo()
  2192. {
  2193. level flag::wait_till( "initial_blackscreen_passed" );
  2194.  
  2195. self endon("left");
  2196.  
  2197. while (1)
  2198. {
  2199. foreach (player in getPlayers())
  2200. {
  2201. distanceFromPlayerToBox = distance(player.origin, self.origin);
  2202.  
  2203. if (distanceFromPlayerToBox < 400 && player zm_utility::is_player_looking_at(self.origin))
  2204. {
  2205. player zm_audio::create_and_play_dialog( "box", "encounter" );
  2206. return;
  2207. }
  2208. }
  2209. wait 0.5;
  2210. }
  2211. }
  2212.  
  2213.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement