‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\aat_shared;
4 #using scripts\shared\ai_puppeteer_shared;
5 #using scripts\shared\archetype_shared\archetype_shared;
6 #using scripts\shared\array_shared;
7 #using scripts\shared\callbacks_shared;
8 #using scripts\shared\clientfield_shared;
9 #using scripts\shared\demo_shared;
10 #using scripts\shared\flag_shared;
11 #using scripts\shared\hud_util_shared;
12 #using scripts\shared\laststand_shared;
13 #using scripts\shared\lui_shared;
14 #using scripts\shared\math_shared;
15 #using scripts\shared\scoreevents_shared;
16 #using scripts\shared\system_shared;
17 #using scripts\shared\util_shared;
18 #using scripts\shared\visionset_mgr_shared;
19 #using scripts\zm\gametypes\_globallogic;
20 #using scripts\zm\gametypes\_globallogic_vehicle;
21 
22 #using scripts\zm\_bb;
23 
24 #using scripts\shared\ai\systems\gib;
25 
26 #insert scripts\shared\shared.gsh;
27 #insert scripts\shared\version.gsh;
28 #insert scripts\shared\ai\systems\gib.gsh;
29 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
30 
31 #using scripts\zm\gametypes\_weapons;
32 #using scripts\zm\gametypes\_zm_gametype;
33 #using scripts\zm\gametypes\_globallogic_spawn;
34 #using scripts\zm\gametypes\_globallogic_player;
35 
36 #using scripts\zm\_util;
37 #using scripts\zm\_zm_attackables;
38 #using scripts\zm\_zm_audio;
39 #using scripts\zm\_zm_bgb;
40 #using scripts\zm\_zm_bgb_token;
41 #using scripts\zm\_zm_blockers;
42 #using scripts\zm\_zm_bot;
43 #using scripts\zm\_zm_daily_challenges;
44 #using scripts\zm\_zm_equipment;
45 #using scripts\zm\_zm_ffotd;
46 #using scripts\zm\_zm_game_module;
47 //#using scripts\zm\_zm_hero_weapon;
48 #using scripts\zm\_zm_laststand;
49 #using scripts\zm\_zm_melee_weapon;
50 #using scripts\zm\_zm_perks;
51 #using scripts\zm\_zm_pers_upgrades;
52 #using scripts\zm\_zm_pers_upgrades_functions;
53 #using scripts\zm\_zm_pers_upgrades_system;
54 #using scripts\zm\_zm_placeable_mine;
55 #using scripts\zm\_zm_player;
56 #using scripts\zm\_zm_powerups;
57 #using scripts\zm\_zm_score;
58 #using scripts\zm\_zm_spawner;
59 #using scripts\zm\_zm_stats;
60 #using scripts\zm\_zm_timer;
61 #using scripts\zm\_zm_unitrigger;
62 #using scripts\zm\_zm_utility;
63 #using scripts\zm\_zm_weapons;
64 #using scripts\zm\_zm_zonemgr;
65 #using scripts\shared\ai_shared;
66 
67 // AATs
68 #insert scripts\shared\aat_zm.gsh;
69 #using scripts\zm\aats\_zm_aat_blast_furnace;
70 #using scripts\zm\aats\_zm_aat_dead_wire;
71 #using scripts\zm\aats\_zm_aat_fire_works;
72 #using scripts\zm\aats\_zm_aat_thunder_wall;
73 #using scripts\zm\aats\_zm_aat_turned;
74 
75 #using scripts\zm\craftables\_zm_craftables;
76 
77 #using scripts\shared\ai\zombie_death;
78 #using scripts\shared\ai\zombie_utility;
79 
80 #insert scripts\shared\ai\zombie.gsh;
81 #insert scripts\zm\_zm_laststand.gsh;
82 #insert scripts\zm\_zm_perks.gsh;
83 #insert scripts\zm\_zm_utility.gsh;
84 
85 #precache( "material", "hud_chalk_1" );
86 #precache( "material", "hud_chalk_2" );
87 #precache( "material", "hud_chalk_3" );
88 #precache( "material", "hud_chalk_4" );
89 #precache( "material", "hud_chalk_5" );
90 
91 #precache( "material", "zom_icon_community_pot" );
92 #precache( "material", "zom_icon_community_pot_strip" );
93 
94 #precache( "material","zom_icon_player_life");
95 
96 #precache( "string", "ZOMBIE_WEAPONCOSTAMMO" );
97 #precache( "string", "ZOMBIE_ROUND" );
98 #precache( "string", "SCRIPT_PLUS" );
99 #precache( "string", "ZOMBIE_GAME_OVER" );
100 #precache( "string", "ZOMBIE_SURVIVED_ROUND" );
101 #precache( "string", "ZOMBIE_SURVIVED_ROUNDS" );
102 #precache( "string", "ZOMBIE_SURVIVED_NOMANS" );
103 #precache( "string", "ZOMBIE_EXTRA_LIFE" );
104 #precache( "string", "ZOMBIE_UNDEFINED" );
105 #precache( "triggerstring", "ZOMBIE_ELECTRIC_SWITCH" );
106 #precache( "triggerstring", "ZOMBIE_NEED_POWER" );
107 // Random Treasure Chest
108 #precache( "string", "ZOMBIE_RANDOM_WEAPON_COST" );
109 // Weapons
110 #precache( "string", "ZOMBIE_WEAPON_COSTONLYFILL_500" );
111 #precache( "triggerstring", "ZOMBIE_WEAPON_COSTONLYFILL_2000" );
112 #precache( "triggerstring", "ZOMBIE_WEAPONAMMOONLY_250" );
113 #precache( "triggerstring", "ZOMBIE_WEAPONCOSTAMMO_UPGRADE_500_250" );
114 // Barrier Pieces
115 #precache( "string", "ZOMBIE_BUTTON_BUY_BACK_BARRIER_10" );
116 #precache( "string", "ZOMBIE_BUTTON_BUY_BACK_BARRIER_20" );
117 #precache( "string", "ZOMBIE_BUTTON_BUY_BACK_BARRIER_50" );
118 #precache( "string", "ZOMBIE_BUTTON_BUY_BACK_BARRIER_100" );
119 // REWARD Barrier Pieces
120 #precache( "string", "ZOMBIE_BUTTON_REWARD_BARRIER" );
121 // Debris
122 #precache( "string", "ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_COST" );
123 // Doors
124 #precache( "string", "ZOMBIE_BUTTON_BUY_OPEN_DOOR_COST" );
125 #precache( "string", "ZOMBIE_BUTTON_BUY_CLOSE_DOOR" );
126 
127 #precache( "triggerstring", "ZOMBIE_BUTTON_REWARD_BARRIER" );
128 
129 #precache( "fx", "_t6/maps/zombie/fx_zombie_bar_break" );
130 #precache( "fx", "_t6/maps/zombie/fx_zombie_bar_break_lite" );
131 #precache( "fx", "_t6/maps/zombie/fx_fog_zombie_amb" );
132 #precache( "fx", "zombie/fx_weapon_box_open_glow_zmb" );
133 #precache( "fx", "zombie/fx_weapon_box_closed_glow_zmb" );
134 #precache( "fx", "zombie/fx_glow_eye_orange" );
135 #precache( "fx", "zombie/fx_bul_flesh_head_fatal_zmb" );
136 #precache( "fx", "zombie/fx_bul_flesh_head_nochunks_zmb" );
137 #precache( "fx", "zombie/fx_bul_flesh_neck_spurt_zmb" );
138 #precache( "fx", "_t6/maps/zombie/fx_zombie_tesla_neck_spurt" );
139 #precache( "fx", "zombie/fx_blood_torso_explo_zmb" );
140 #precache( "fx", "zombie/fx_blood_torso_explo_lg_zmb" );
141 #precache( "fx", "zombie/fx_spawn_dirt_hand_burst_zmb" );
142 #precache( "fx", "zombie/fx_spawn_dirt_body_billowing_zmb" );
143 #precache( "fx", "zombie/fx_spawn_dirt_body_dustfalling_zmb" );
144 #precache( "fx", "zombie/fx_fire_torso_zmb" );
145 #precache( "fx", "_t6/explosions/fx_default_explosion" );
146 #precache( "fx", "_t6/maps/zombie/fx_zmb_tanzit_upgrade" );
147 
148 #precache( "menu", "StartMenu_Main" );
149 #precache( "menu", "InitialBlack" );
150 
151 #precache( "eventstring", "force_scoreboard" );
152 #precache( "eventstring", "open_ingame_menu" );
153 #precache( "eventstring", "play_promo_anim" );
154 
155 #precache( "string", "ZOMBIE_REVIVING_SOLO", "ZOMBIE_PLAYER_NAME_0" );
156 #precache( "string", "ZOMBIE_REVIVING_SOLO", "ZOMBIE_PLAYER_NAME_1" );
157 #precache( "string", "ZOMBIE_REVIVING_SOLO", "ZOMBIE_PLAYER_NAME_2" );
158 #precache( "string", "ZOMBIE_REVIVING_SOLO", "ZOMBIE_PLAYER_NAME_3" );
159 
160 #namespace zm;
161 
162 function autoexec ‪ignore_systems()
163 {
164  //shutdown unwanted systems - doing it in an autoexec is the only clean way to do it
165  ‪system::ignore("gadget_clone");
166  ‪system::ignore("gadget_armor");
167  ‪system::ignore("gadget_heat_wave");
168  ‪system::ignore("gadget_resurrect");
169  ‪system::ignore("gadget_shock_field");
170  ‪system::ignore("gadget_active_camo");
171  ‪system::ignore("gadget_mrpukey");
172  ‪system::ignore("gadget_misdirection");
173  ‪system::ignore("gadget_smokescreen");
174  ‪system::ignore("gadget_firefly_swarm");
175  ‪system::ignore("gadget_immolation");
176  ‪system::ignore("gadget_forced_malfunction");
177  ‪system::ignore("gadget_sensory_overload");
178  ‪system::ignore("gadget_rapid_strike");
179  ‪system::ignore("gadget_unstoppable_force");
180  ‪system::ignore("gadget_overdrive");
181  ‪system::ignore("gadget_concussive_wave");
182  ‪system::ignore("gadget_ravage_core");
183  ‪system::ignore("gadget_es_strike");
184  ‪system::ignore("gadget_cacophany");
185  ‪system::ignore("gadget_iff_override");
186  ‪system::ignore("gadget_security_breach");
187  ‪system::ignore("gadget_surge");
188  ‪system::ignore("gadget_exo_breakdown");
189  ‪system::ignore("gadget_servo_shortout");
190  ‪system::ignore("gadget_system_overload");
191  ‪system::ignore("gadget_cleanse");
192  ‪system::ignore("gadget_flashback");
193  ‪system::ignore("gadget_combat_efficiency");
194  ‪system::ignore("gadget_other");
195  ‪system::ignore("gadget_camo");
196  ‪system::ignore("gadget_vision_pulse");
197  ‪system::ignore("gadget_speed_burst");
198  ‪system::ignore("gadget_thief");
199  ‪system::ignore("replay_gun");
200  ‪system::ignore("spike_charge_siegebot");
201  ‪system::ignore("siegebot");
202  ‪system::ignore("amws");
203 
204 }
205 
206 
207 
208 ‪REGISTER_SYSTEM( "zm", &‪__init__, undefined )
209 
210 function ‪__init__()
211 {
212  ‪DEFAULT(level.zombie_vars,[]);
213 }
214 
215 function ‪init()
216 {
217  //New movement disabled for Zombies
218  SetDvar( "doublejump_enabled", 0 );
219  SetDvar( "juke_enabled", 0 );
220  SetDvar( "playerEnergy_enabled", 0 );
221  SetDvar( "wallrun_enabled", 0 );
222  SetDvar( "sprintLeap_enabled", 0 );
223  SetDvar( "traverse_mode", 2 );
224  SetDvar( "weaponrest_enabled", 0 );
225 
226  //we dont care about CP movie skipping logic in ZM
227  SetDvar( "ui_allowDisplayContinue", true );
228 
229  if ( !IsDefined( level.killstreakWeapons ) )
230  {
231  level.killstreakWeapons = [];
232  }
233 
234  level.weaponNone = GetWeapon( "none" );
235  level.weaponNull = GetWeapon( "weapon_null" );
236  level.weaponBaseMelee = GetWeapon( "knife" );
237  level.weaponBaseMeleeHeld = GetWeapon( "knife_held" );
238  level.weaponBallisticKnife = GetWeapon( "knife_ballistic" );
239  ‪DEFAULT(level.weaponRiotshield,GetWeapon( "riotshield" ));
240  level.weaponReviveTool = GetWeapon( "syrette" );
241  level.weaponZMDeathThroe = GetWeapon( "death_throe" );
242  level.weaponZMFists = GetWeapon( "zombie_fists" );
243 
244  ‪DEFAULT( level.giveCustomLoadout, &‪zm_weapons::give_start_weapons );
245 
246  level.projectiles_should_ignore_world_pause = true;
247 
248  level.player_out_of_playable_area_monitor = true;
249  level.player_too_many_weapons_monitor = true;
250  level.player_too_many_weapons_monitor_func = &‪player_too_many_weapons_monitor;
251 
252  level.player_too_many_players_check = true;
253  level.player_too_many_players_check_func = &‪player_too_many_players_check;
254 
255  level._use_choke_weapon_hints = 1;
256  level._use_choke_blockers = 1;
257 
258  level.speed_change_round = 15;
259 
260  level.passed_introscreen = false;
261 
262  if(!isdefined(level.custom_ai_type))
263  {
264  level.custom_ai_type = [];
265  }
266 
267  level.custom_ai_spawn_check_funcs = [];
268 
269  // put things you'd like to be able to turn off in here above this line
270  level thread ‪zm_ffotd::main_start();
271 
272  level.zombiemode = true;
273  level.reviveFeature = false;
274  level.swimmingFeature = false;
275  level.calc_closest_player_using_paths = false;
276  level.zombie_melee_in_water = true;
277  level.put_timed_out_zombies_back_in_queue = true;
278  level.use_alternate_poi_positioning = true;
279  level.zmb_laugh_alias = "zmb_laugh_child";
280  level.sndAnnouncerIsRich = true;
281 
282  level.scr_zm_ui_gametype = GetDvarString( "ui_gametype" );
283  level.scr_zm_ui_gametype_group = "";//GetDvarString( "ui_zm_gamemodegroup" );
284  level.scr_zm_map_start_location = "";//GetDvarString( "ui_zm_mapstartlocation" );
285 
286  level.curr_gametype_affects_rank = false;
287  gametype = toLower( GetDvarString( "g_gametype" ) );
288  if ( "zclassic" == gametype || "zstandard" == gametype )
289  {
290  level.curr_gametype_affects_rank = true;
291  }
292 
293  level.grenade_multiattack_bookmark_count = 1;
294  ‪demo::initActorBookmarkParams( 3, 6000, 6000 );
295 
296  // set up any gameplay modes
297 /* level.GAME_MODULE_CLASSIC_INDEX = 0;
298  zm_game_module::register_game_module(level.GAME_MODULE_CLASSIC_INDEX,"classic",undefined,undefined);
299  zm_game_module::set_current_game_module(level.scr_zm_game_module); */
300 
301  // Allowing custom round_spawn_failsafe function to be set here.
302  if( !isdefined( level._zombies_round_spawn_failsafe ) )
303  {
304  level._zombies_round_spawn_failsafe = &‪zombie_utility::round_spawn_failsafe;
305  }
306 
307  level.func_get_zombie_spawn_delay = &‪get_zombie_spawn_delay;
308  level.func_get_delay_between_rounds = &‪get_delay_between_rounds;
309 
310  level.zombie_visionset = "zombie_neutral";
311 
312  level.wait_and_revive = false;
313 
314  if(GetDvarString("anim_intro") == "1")
315  {
316  level.zombie_anim_intro = 1;
317  }
318  else
319  {
320  level.zombie_anim_intro = 0;
321  }
322 
324 
326 
327  level._ZOMBIE_GIB_PIECE_INDEX_ALL = 0;
328  level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_ARM = 1;
329  level._ZOMBIE_GIB_PIECE_INDEX_LEFT_ARM = 2;
330  level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_LEG = 3;
331  level._ZOMBIE_GIB_PIECE_INDEX_LEFT_LEG = 4;
332  level._ZOMBIE_GIB_PIECE_INDEX_HEAD = 5;
333  level._ZOMBIE_GIB_PIECE_INDEX_GUTS = 6;
334  level._ZOMBIE_GIB_PIECE_INDEX_HAT = 7;
335 
336  //Limit zombie to 24 max, must have for network purposes
337  if ( !isdefined( level.zombie_ai_limit ) )
338  {
339  level.zombie_ai_limit = 24;
340  }
341  if ( !isdefined( level.zombie_actor_limit ) )
342  {
343  level.zombie_actor_limit = 31;
344  }
345 
346  ‪init_flags();
347  ‪init_dvars();
348  ‪init_strings();
350  ‪init_sounds();
353 
355 
356  level thread ‪drive_client_connected_notifies();
357 
358  // load map defaults
359 
360  //Systems
366 
367  //Grab all static poi in the map
368  level.zombie_poi_array = getEntArray( "zombie_poi", "script_noteworthy" );
369 
370 
372 
373  // ww: init the pistols in the game so last stand has the importance order
374  level thread ‪last_stand_pistol_rank_init();
375 
376  level thread ‪post_all_players_connected();
377 
379 
381 
383 
384  // STATS_TODO: will check if the following is needed later
386 
387  if ( GetPlayers().size <= 1 )
388  {
389  incrementCounter( "global_solo_games", 1 );
390  }
391  else if( ‪IS_TRUE(level.systemLink) )
392  {
393  incrementCounter( "global_systemlink_games", 1 );
394  }
395  else if ( GetDvarInt( "splitscreen_playerCount" ) == GetPlayers().size )
396  {
397  incrementCounter( "global_splitscreen_games", 1 );
398  }
399  else // coop game
400  {
401  incrementCounter( "global_coop_games", 1 );
402  }
403 
405 
406  //self LUINotifyEvent( &"score_event", 3, label, score, rampageBonus );
407 
408  // Initialize persistent upgrades
409  //zm_pers_upgrades::pers_upgrade_init();
410 
412 
413  level thread ‪zm_ffotd::main_end();
415  level thread ‪onAllPlayersReady();
416  level thread ‪startUnitriggers();
417 
419  ‪printHashIDs();
420 }
421 
422 function ‪post_main()
423 {
424  level thread ‪init_custom_ai_type();
425 }
426 
427 function ‪cheat_enabled( val )
428 {
429  if ( GetDvarInt( "zombie_cheat" ) >= val )
430  {
431 /#
432  return true;
433 #/
434  }
435 
436  return false;
437 }
438 
439 
440 function ‪set_round_number( new_round )
441 {
442  if ( new_round > 255 )
443  new_round = 255;
444  level.round_number = new_round;
445 }
446 
448 {
449  return level.round_number;
450 }
451 
452 
454 {
455  level ‪flag::wait_till_any( ‪array( "start_zombie_round_logic", "start_encounters_match_logic" ) );
456  level thread ‪zm_unitrigger::main();
457 }
458 
460 {
461  while(1)
462  {
463  level waittill("connected", player);
465  player ‪callback::callback( #"on_player_connect" );
466  }
467 }
468 
469 function ‪fade_out_intro_screen_zm( hold_black_time, fade_out_time, destroyed_afterwards )
470 {
471  ‪lui::screen_fade_out( 0, undefined );
472 
473  if( IsDefined( hold_black_time ) )
474  {
475  wait hold_black_time;
476  }
477  else
478  {
479  wait 0.2;
480  }
481 
482  if( !IsDefined( fade_out_time ) )
483  {
484  fade_out_time = 1.5;
485  }
486 
487  array::thread_all(GetPlayers(), &‪initialBlackEnd);
488  level ‪clientfield::set( "sndZMBFadeIn", 1 );
489  ‪lui::screen_fade_in( fade_out_time, undefined );
490 
491  //level notify("fade_introblack");
492 
493  wait 1.6;
494 
495  level.passed_introscreen = true;
496 
497  players = GetPlayers();
498  for(i = 0; i < players.size; i++)
499  {
500  if( IsDefined( level.customHudReveal ) )
501  {
502  players[i] thread [[level.customHudReveal]]();
503  }
504  else
505  {
506  players[i] ‪ShowHudAndPlayPromo();
507  }
508 
509  if(!‪IS_TRUE(level.host_ended_game))
510  {
511  if (isdefined(level.player_movement_suppressed))
512  {
513  players[i] FreezeControls(level.player_movement_suppressed);
514  /# println(" Unfreeze controls 4"); #/
515 
516  }
517  else
518  {
519  if(!‪IS_TRUE(players[i].hostMigrationControlsFrozen))
520  {
521  players[i] FreezeControls(false);
522 
523  /# println(" Unfreeze controls 5"); #/
524  }
525  }
526  }
527  }
528  // level notify("fade_in_complete");
529 
530  level ‪flag::set("initial_blackscreen_passed");
531  level ‪clientfield::set("gameplay_started", 1);
532 }
533 
535 {
536  self setClientUIVisibilityFlag( "hud_visible", 1 );
537  self setClientUIVisibilityFlag( "weapon_hud_visible", 1 );
538 
539  if( !‪IS_TRUE( self.seen_promo_anim ) && SessionModeIsOnlineGame() )
540  {
541  self LUINotifyEvent( &"play_promo_anim", 0 );
542  self.seen_promo_anim = true;
543  }
544 }
545 
547 {
548 
549  timeOut = GetTime() + 5000; // 5 second time out.
550 
551  while(IsLoadingCinematicPlaying() || (GetNumExpectedPlayers() == 0 && (GetTime() < timeOut)))
552  {
553  wait(0.1);
554  }
555 
556  /# println( "ZM >> player_count_expected=" + GetNumExpectedPlayers()); #/
557  player_count_actual = 0;
558  while( (GetNumConnectedPlayers() < GetNumExpectedPlayers()) || (player_count_actual != GetNumExpectedPlayers()) )
559  {
560  players = GetPlayers();
561  player_count_actual = 0;
562  for( i = 0; i < players.size; i++ )
563  {
564  players[i] FreezeControls( true );
565  if( players[i].sessionstate == "playing" )
566  {
567  player_count_actual++;
568  }
569  }
570 
571  /# println( "ZM >> Num Connected =" + GetNumConnectedPlayers() + " Expected : " + GetNumExpectedPlayers()); #/
572  wait( 0.1 );
573  }
574 
575  SetInitialPlayersConnected();
576 
577  level ‪flag::set( "all_players_connected" );
578  SetDvar( "all_players_are_connected", "1" );
579 
580  /# println( "ZM >> We have all players - START ZOMBIE LOGIC" ); #/
581 
582 
583 
584  //Check to see if we should spawn some bots to help
585  if ( (1 == GetNumConnectedPlayers()) && (GetDvarInt( "scr_zm_enable_bots" )==1) )
586  {
587  level thread ‪add_bots();
588  level ‪flag::set("initial_players_connected");
589  }
590  else
591  {
592  players = GetPlayers();
593  if ( players.size == 1 )
594  {
595  level ‪flag::set( "solo_game" );
596  level.solo_lives_given = 0;
597  foreach ( player in players )
598  {
599  player.lives = 0;
600  }
602  }
603 
604  level ‪flag::set("initial_players_connected");
605 
606  array::thread_all(GetPlayers(), &‪initialBlack);
607 
608  while ( !AreTexturesLoaded() )
609  {
611  }
612 
613  if ( isdefined(level.added_initial_streamer_blackscreen) )
614  {
615  wait(level.added_initial_streamer_blackscreen);
616  }
617 
618  //level flag::set( "start_zombie_round_logic" );
619  thread ‪start_zombie_logic_in_x_sec( 3.0 );
620  }
621 
623 
624  n_black_screen = 5.0;
625  level thread ‪fade_out_intro_screen_zm( n_black_screen, 1.5, true );
626  wait n_black_screen;
627 
628  // Reset the start time
629  level.n_gameplay_start_time = GetTime();
630  ‪clientfield::set( "game_start_time", level.n_gameplay_start_time );
631 }
632 
633 function ‪initialBlack()
634 {
635  self CloseMenu( "InitialBlack" );
636  self OpenMenu( "InitialBlack" );
637 }
638 
640 {
641  self CloseMenu( "InitialBlack" );
642 // self clientfield::set_to_player( "sndLevelStartSnapOff", 1 );
643 }
644 
645 
646 
647 function ‪start_zombie_logic_in_x_sec( time_to_wait )
648 {
649  wait( time_to_wait );
650  level ‪flag::set( "start_zombie_round_logic" );
651 }
652 
653 
655 {
656  aliveplayers = [];
657 
658  // Make a list of fully connected, non-spectating, alive players
659  for(i = 0; i < level.players.size; i++)
660  {
661  if ( !isdefined( level.players[i] ) )
662  continue;
663  player = level.players[i];
664 
665  if ( player.sessionstate != "playing" || player == self )
666  continue;
667 
668  aliveplayers[aliveplayers.size] = player;
669  }
670  return aliveplayers;
671 }
672 
673 function ‪updatePlayerNum( player )
674 {
675  if(!Isdefined(player.playernum))
676  {
677  if(player.team == "allies")
678  {
679  player.playernum = ‪zm_utility::get_game_var("_team1_num");
680  ‪zm_utility::set_game_var("_team1_num", player.playernum + 1);
681  }
682  else
683  {
684  player.playernum = ‪zm_utility::get_game_var("_team2_num");
685  ‪zm_utility::set_game_var("_team2_num", player.playernum + 1);
686  }
687  }
688 }
689 
690 function ‪getFreeSpawnpoint(spawnpoints, player)
691 {
692  // There are no valid spawnpoints in the map
693  if(!isdefined(spawnpoints))
694  {
695 /#
696  iprintlnbold( "ZM >> No free spawn points in map" );
697 #/
698  return undefined;
699  }
700 
701  // only should happen on initial spawn.
702 
703  if(!isdefined(game["spawns_randomized"]))
704  {
705  game["spawns_randomized"] = true;
706 
707  spawnpoints = array::randomize(spawnpoints);
708 
709  random_chance = randomint(100);
710  if(random_chance > 50)
711  {
712  ‪zm_utility::set_game_var("side_selection", 1);
713  }
714  else
715  {
716  ‪zm_utility::set_game_var("side_selection", 2);
717  }
718  }
719 
720  side_selection = ‪zm_utility::get_game_var("side_selection");
721 
722  // used in vs. games where you switch sides on next round.
723  if( ‪zm_utility::get_game_var("switchedsides"))
724  {
725  if(side_selection == 2)
726  {
727  side_selection = 1;
728  }
729  else if(side_selection == 1)
730  {
731  side_selection = 2;
732  }
733  }
734 
735  if(IsDefined(player) && IsDefined(player.team))
736  {
737  i = 0;
738  while(IsDefined(spawnpoints) && i < spawnpoints.size)
739  {
740  If(side_selection == 1)
741  {
742  if(player.team != "allies" && (IsDefined(spawnpoints[i].script_int) && spawnpoints[i].script_int == 1))
743  {
744  ArrayRemoveValue(spawnpoints, spawnpoints[i]);
745  i=0;
746  }
747  else if(player.team == "allies" && (IsDefined(spawnpoints[i].script_int) && spawnpoints[i].script_int == 2))
748  {
749  ArrayRemoveValue(spawnpoints, spawnpoints[i]);
750  i=0;
751  }
752  else
753  {
754  i++;
755  }
756  }
757  else
758  {
759  if(player.team == "allies" && (IsDefined(spawnpoints[i].script_int) && spawnpoints[i].script_int == 1))
760  {
761  ArrayRemoveValue(spawnpoints, spawnpoints[i]);
762  i=0;
763  }
764  else if(player.team != "allies" && (IsDefined(spawnpoints[i].script_int) && spawnpoints[i].script_int == 2))
765  {
766  ArrayRemoveValue(spawnpoints, spawnpoints[i]);
767  i=0;
768  }
769  else
770  {
771  i++;
772  }
773  }
774  }
775  }
776 
777  ‪updatePlayerNum( player );
778 
779  for( j = 0; j < spawnpoints.size; j++ )
780  {
781  if(!IsDefined(spawnpoints[j].en_num))
782  {
783  for( m = 0; m < spawnpoints.size; m++ )
784  {
785  spawnpoints[m].en_num = m;
786  }
787  }
788 
789  if( spawnpoints[j].en_num == player.playernum)
790  {
791  return spawnpoints[j];
792  }
793  }
794 
795  return spawnpoints[0];
796 }
797 
798 
800 {
801  exterior_goals =‪struct::get_array( "exterior_goal", "targetname" );
802  for( i = 0; i < exterior_goals.size; i++ )
803  {
804  if( !IsDefined( exterior_goals[i].target ) ) // If the exterior_goal entity has no targets defined then return
805  {
806  continue;
807  }
808  targets = GetEntArray( exterior_goals[i].target, "targetname" ); // Grab all the pieces that are targeted by the exterior_goal
809 
810  for( j = 0; j < targets.size; j++ ) // count total targets of exterior_goal
811  {
812  targets[j] ‪zm_utility::self_delete();
813  }
814  }
815 
816  if(isdefined(level.level_createfx_callback_thread))
817  {
818  level thread [[level.level_createfx_callback_thread]]();
819  }
820 }
821 
822 
823 
824 function ‪add_bots()
825 {
826  //Wait for the host!
827  host = util::GetHostPlayer();
828  while ( !IsDefined( host ) )
829  {
831  host = util::GetHostPlayer();
832  }
833 
834  wait( 4.0 );
835 
836  //Then spawn bots
837  ‪zbot_spawn();
838  SetDvar("bot_AllowMovement", "1");
839  SetDvar("bot_PressAttackBtn", "1");
840  SetDvar("bot_PressMeleeBtn", "1");
841 
842  //Wait until bots are spawned
843  while( GetPlayers().size<2 )
844  {
846  }
847 
848  //Unfreeze all players
849  players = GetPlayers();
850  for( i = 0; i < players.size; i++ )
851  {
852  players[i] FreezeControls( false );
853  /# println(" Unfreeze controls 6"); #/
854 
855  }
856 
857  level.numberBotsAdded = 1;
858  level ‪flag::set( "start_zombie_round_logic" );
859 }
860 
861 function ‪zbot_spawn()
862 {
863  player = util::GetHostPlayer();
864 
865  //spawnPoints =struct::get_array( "initial_spawn_points", "targetname" );
866  //spawnPoint = getFreeSpawnpoint( spawnPoints, player );
867 
868  bot = AddTestClient();
869  if ( !IsDefined( bot ) )
870  {
871  /# println( "Could not add test client" ); #/
872  return;
873  }
874 
875 
876  spawnPoint = bot ‪zm_gametype::onFindValidSpawnPoint();
877 
878  bot.pers["isBot"] = true;
879  bot.equipment_enabled = false;
880  yaw = spawnPoint.angles[1];
881 
882  return bot;
883 }
884 
886 {
887  level thread ‪end_game();
888 
889  level ‪flag::wait_till( "start_zombie_round_logic" );
890 
891  ‪zm_utility::increment_zm_dash_counter( "start_per_game", 1 );
892  ‪zm_utility::increment_zm_dash_counter( "start_per_player", level.players.size );
894 
895  level.dash_counter_start_player_count = level.players.size;
896 /#
897  println( "sessions: mapname=", level.script, " gametype zom isserver 1 player_count=", GetPlayers().size );
898 #/
899  // Start the Zombie MODE!
900  level thread ‪round_end_monitor();
901 
902  if(!level.zombie_anim_intro)
903  {
904  if(isDefined(level._round_start_func))
905  {
906  level thread [[level._round_start_func]]();
907  }
908  }
909 
910  level thread ‪players_playing();
911 
912  DisableGrenadeSuicide();
913  level.startInvulnerableTime = GetDvarInt( "player_deathInvulnerableTime" );
914 }
915 
917 {
918  level thread ‪first_consumables_used_watcher();
920 }
921 
923 {
924  level ‪flag::init( "first_consumables_used" );
925 
926  level ‪flag::wait_till( "first_consumables_used" );
927 
928  ‪zm_utility::increment_zm_dash_counter( "first_consumables_used", 1 );
930 }
931 
933 {
934  while( true )
935  {
936  level waittill( "start_of_round" );
937 
938  if( !IsDefined( level.dash_counter_round_reached_5 ) && level.round_number >= 5 )
939  {
940  level.dash_counter_round_reached_5 = true;
942  }
943 
944  if( !IsDefined( level.dash_counter_round_reached_10 ) && level.round_number >= 10 )
945  {
946  level.dash_counter_round_reached_10 = true;
947  ‪zm_utility::increment_zm_dash_counter( "reached_10", 1 );
948  return;
949  }
950  }
951 }
952 
954 {
955  //wait( 0.1 );
956 // waittillframeend;
957 
958  if( isDefined( level.custom_ai_type ) )
959  {
960  for( i = 0; i < level.custom_ai_type.size; i++ )
961  {
962  [[ level.custom_ai_type[i] ]]();
963  }
964  }
965 }
966 
968 {
969  if( isDefined( self.enemy.curr_pay_turret ) )
970  {
971  self.enemy doDamage( GetDvarInt( "ai_meleeDamage" ), self.origin, self, self, "none", "melee" );
972  }
973 }
974 
975 /*------------------------------------
976 function chrisp - adding vo to track players ammo
977 ------------------------------------*/
979 {
980  self notify( "stop_ammo_tracking" );
981  self endon( "disconnect" );
982  self endon( "stop_ammo_tracking" );
983 
984  ammoLowCount = 0;
985  ammoOutCount = 0;
986 
987  while ( 1 )
988  {
989  wait( .5 );
990  weapon = self getcurrentweapon();
991 
992  if ( weapon == level.weaponNone || weapon.skiplowammovox )
993  {
994  continue;
995  }
996 
997  if( weapon.type == "grenade" )
998  {
999  continue;
1000  }
1001 
1002  if ( self GetAmmoCount( weapon ) > 5 || self ‪laststand::player_is_in_laststand() )
1003  {
1004  ammoOutCount = 0;
1005  ammoLowCount = 0;
1006  continue;
1007  }
1008 
1009  if ( self GetAmmoCount( weapon ) > 0 )
1010  {
1011  if ( ammoLowCount < 1 )
1012  {
1013  self ‪zm_audio::create_and_play_dialog( "general", "ammo_low" );
1014  ammoLowCount++;
1015  }
1016  }
1017  else
1018  {
1019  if ( ammoOutCount < 1 )
1020  {
1021  wait ( .5 );
1022 
1023  if( (self getcurrentweapon() ) !== weapon ) //This prevents "ammo out" vo from playing in the case that we swap a weapon from the box.
1024  {
1025  continue;
1026  }
1027 
1028  self ‪zm_audio::create_and_play_dialog( "general", "ammo_out" );
1029  ammoOutCount++;
1030  }
1031  }
1032  wait( 20 );
1033  }
1034 }
1035 
1036 /*------------------------------------
1037 function audio plays when more than 1 player connects
1038 ------------------------------------*/
1039 function ‪spawn_vo()
1040 {
1041  //not sure if we need this
1042  wait(1);
1043 
1044  players = GetPlayers();
1045 
1046  //just pick a random player for now and play some vo
1047  if(players.size > 1)
1048  {
1049  player = array::random(players);
1050  index = ‪zm_utility::get_player_index(player);
1051  player thread ‪spawn_vo_player(index,players.size);
1052  }
1053 
1054 }
1055 
1056 function ‪spawn_vo_player(index,num)
1057 {
1058  sound = "plr_" + index + "_vox_" + num +"play";
1059  self PlaySoundWithNotify(sound, "sound_done");
1060  self waittill("sound_done");
1061 }
1062 
1064 {
1065  if ( isDefined( level.precacheCustomCharacters ) )
1066  {
1067  self [[ level.precacheCustomCharacters ]]();
1068  }
1069 }
1070 
1072 {
1073  level.player_killed_shellshock = "zombie_death";
1074 }
1075 
1077 {
1078  ‪zm_utility::add_zombie_hint( "undefined", &"ZOMBIE_UNDEFINED" );
1079 
1080  // Random Treasure Chest
1081  ‪zm_utility::add_zombie_hint( "default_treasure_chest", &"ZOMBIE_RANDOM_WEAPON_COST" );
1082 
1083  // Barrier Pieces
1084  ‪zm_utility::add_zombie_hint( "default_buy_barrier_piece_10", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_10" );
1085  ‪zm_utility::add_zombie_hint( "default_buy_barrier_piece_20", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_20" );
1086  ‪zm_utility::add_zombie_hint( "default_buy_barrier_piece_50", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_50" );
1087  ‪zm_utility::add_zombie_hint( "default_buy_barrier_piece_100", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_100" );
1088 
1089  // REWARD Barrier Pieces
1090  ‪zm_utility::add_zombie_hint( "default_reward_barrier_piece", &"ZOMBIE_BUTTON_REWARD_BARRIER" );
1091 
1092  // Areas
1093  ‪zm_utility::add_zombie_hint( "default_buy_area", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_COST" );
1094 }
1095 
1096 function ‪init_sounds()
1097 {
1098  ‪zm_utility::add_sound( "end_of_round", "mus_zmb_round_over" );
1099  ‪zm_utility::add_sound( "end_of_game", "mus_zmb_game_over" ); //Had to remove this and add a music state switch so that we can add other musical elements.
1100  ‪zm_utility::add_sound( "chalk_one_up", "mus_zmb_chalk" );
1101  ‪zm_utility::add_sound( "purchase", "zmb_cha_ching" );
1102  ‪zm_utility::add_sound( "no_purchase", "zmb_no_cha_ching" );
1103 
1104  // Zombification
1105  // TODO need to vary these up
1106  ‪zm_utility::add_sound( "playerzombie_usebutton_sound", "zmb_zombie_vocals_attack" );
1107  ‪zm_utility::add_sound( "playerzombie_attackbutton_sound", "zmb_zombie_vocals_attack" );
1108  ‪zm_utility::add_sound( "playerzombie_adsbutton_sound", "zmb_zombie_vocals_attack" );
1109 
1110  // Head gib
1111  ‪zm_utility::add_sound( "zombie_head_gib", "zmb_zombie_head_gib" );
1112 
1113  // Blockers
1114  ‪zm_utility::add_sound( "rebuild_barrier_piece", "zmb_repair_boards" );
1115  ‪zm_utility::add_sound( "rebuild_barrier_metal_piece", "zmb_metal_repair" );
1116  ‪zm_utility::add_sound( "rebuild_barrier_hover", "zmb_boards_float" );
1117  ‪zm_utility::add_sound( "debris_hover_loop", "zmb_couch_loop" );
1118  ‪zm_utility::add_sound( "break_barrier_piece", "zmb_break_boards" );
1119  ‪zm_utility::add_sound( "grab_metal_bar", "zmb_bar_pull" );
1120  ‪zm_utility::add_sound( "break_metal_bar", "zmb_bar_break" );
1121  ‪zm_utility::add_sound( "drop_metal_bar", "zmb_bar_drop" );
1122  ‪zm_utility::add_sound("blocker_end_move", "zmb_board_slam");
1123  ‪zm_utility::add_sound( "barrier_rebuild_slam", "zmb_board_slam" );
1124  ‪zm_utility::add_sound( "bar_rebuild_slam", "zmb_bar_repair" );
1125  ‪zm_utility::add_sound( "zmb_rock_fix", "zmb_break_rock_barrier_fix" );
1126  ‪zm_utility::add_sound( "zmb_vent_fix", "evt_vent_slat_repair" );
1127  ‪zm_utility::add_sound ("zmb_barrier_debris_move", "zmb_barrier_debris_move");
1128 
1129  // Doors
1130  ‪zm_utility::add_sound( "door_slide_open", "zmb_door_slide_open" );
1131  ‪zm_utility::add_sound( "door_rotate_open", "zmb_door_slide_open" );
1132 
1133  // Debris
1134  ‪zm_utility::add_sound( "debris_move", "zmb_weap_wall" );
1135 
1136  // Random Weapon Chest
1137  ‪zm_utility::add_sound( "open_chest", "zmb_lid_open" );
1138  ‪zm_utility::add_sound( "music_chest", "zmb_music_box" );
1139  ‪zm_utility::add_sound( "close_chest", "zmb_lid_close" );
1140 
1141  // Weapons on walls
1142  ‪zm_utility::add_sound( "weapon_show", "zmb_weap_wall" );
1143 
1144  ‪zm_utility::add_sound( "break_stone", "evt_break_stone" );
1145 }
1146 
1148 {
1149  // Variables
1150  // used to a check in last stand for players to become zombies
1151  level.is_zombie_level = true;
1152  level.default_laststandpistol = GetWeapon( "pistol_standard" );
1153  level.default_solo_laststandpistol = GetWeapon( "pistol_standard_upgraded" );
1154  level.super_ee_weapon = GetWeapon( "pistol_burst" );
1155  level.laststandpistol = level.default_laststandpistol; // so we dont get the uber colt when we're knocked out
1156  level.start_weapon = level.default_laststandpistol;
1157  level.first_round = true;
1158  level.start_round = GetGametypeSetting( "startRound" );
1159  level.round_number = level.start_round;
1160  level.enable_magic = GetGametypeSetting( "magic" );
1161  level.headshots_only = GetGametypeSetting( "headshotsonly" );
1162  level.player_starting_points = level.round_number * 500;
1163  level.round_start_time = 0;
1164  level.pro_tips_start_time = 0;
1165  level.intermission = false;
1166  level.dog_intermission = false;
1167  level.zombie_total = 0; // Total number of zombies left to spawn
1168  level.zombie_respawns = 0; // Total number of zombies that need to be respawned due to cleanup
1169  level.total_zombies_killed = 0;
1170  level.hudelem_count = 0;
1171  level.zm_loc_types = [];
1172  level.zm_loc_types[ "zombie_location" ] = []; // List of normal zombie spawners (other types will be added in the zone manager)
1173 
1174  level.zm_variant_type_max = [];
1175  level.zm_variant_type_max[ "walk" ] = [];
1176  level.zm_variant_type_max[ "run" ] = [];
1177  level.zm_variant_type_max[ "sprint" ] = [];
1178  level.zm_variant_type_max[ "super_sprint" ] = [];
1179  level.zm_variant_type_max[ "walk" ][ "down" ] = 14;
1180  level.zm_variant_type_max[ "walk" ][ "up" ] = 16;
1181  level.zm_variant_type_max[ "run" ][ "down" ] = 13;
1182  level.zm_variant_type_max[ "run" ][ "up" ] = 12;
1183  level.zm_variant_type_max[ "sprint" ][ "down" ] = 9;
1184  level.zm_variant_type_max[ "sprint" ][ "up" ] = 8;
1185  level.zm_variant_type_max[ "super_sprint" ][ "down" ] = 1;
1186  level.zm_variant_type_max[ "super_sprint" ][ "up" ] = 1;
1187  level.zm_variant_type_max[ "burned" ][ "down" ] = 1;
1188  level.zm_variant_type_max[ "burned" ][ "up" ] = 1;
1189  level.zm_variant_type_max[ "jump_pad_super_sprint" ][ "down" ] = 1;
1190  level.zm_variant_type_max[ "jump_pad_super_sprint" ][ "up" ] = 1;
1191 
1192  level.current_zombie_array = [];
1193  level.current_zombie_count = 0;
1194  level.zombie_total_subtract = 0;
1195  level.destructible_callbacks = [];
1196 
1197  foreach( team in level.teams )
1198  {
1199  ‪DEFAULT( level.zombie_vars[ team ], [] );
1200  }
1201 
1202  difficulty = 1;
1203  column = int(difficulty) + 1;
1204 
1205  //#######################################################################
1206  // zombie_utility::set_zombie_var( identifier, value, float, column );
1207 
1208  // AI
1209  ‪zombie_utility::set_zombie_var( "zombie_health_increase", 100, false, column ); // cumulatively add this to the zombies' starting health each round (up to round 10)
1210  ‪zombie_utility::set_zombie_var( "zombie_health_increase_multiplier",0.1, true, column ); // after round 10 multiply the zombies' starting health by this amount
1211  ‪zombie_utility::set_zombie_var( "zombie_health_start", 150, false, column ); // starting health of a zombie at round 1
1212  ‪zombie_utility::set_zombie_var( "zombie_spawn_delay", 2.0, true, column ); // Time to wait between spawning zombies. This is modified based on the round number.
1213  ‪zombie_utility::set_zombie_var( "zombie_new_runner_interval", 10, false, column ); // Interval between changing walkers who are too far away into runners
1214  ‪zombie_utility::set_zombie_var( "zombie_move_speed_multiplier", 4, false, column ); // Multiply by the round number to give the base speed value. 0-40 = walk, 41-70 = run, 71+ = sprint
1215  ‪zombie_utility::set_zombie_var( "zombie_move_speed_multiplier_easy", 2, false, column ); // Multiply by the round number to give the base speed value. 0-40 = walk, 41-70 = run, 71+ = sprint
1216 
1217  ‪zombie_utility::set_zombie_var( "zombie_max_ai", 24, false, column ); // Base number of zombies per player (modified by round #)
1218  ‪zombie_utility::set_zombie_var( "zombie_ai_per_player", 6, false, column ); // additional zombie modifier for each player in the game
1219  ‪zombie_utility::set_zombie_var( "below_world_check", -1000 ); // Check height to see if a zombie has fallen through the world.
1220 
1221  // Round
1222  ‪zombie_utility::set_zombie_var( "spectators_respawn", true ); // Respawn in the spectators in between rounds
1223  ‪zombie_utility::set_zombie_var( "zombie_use_failsafe", true ); // Will slowly kill zombies who are stuck
1224  ‪zombie_utility::set_zombie_var( "zombie_between_round_time", 10 ); // How long to pause after the round ends
1225  ‪zombie_utility::set_zombie_var( "zombie_intermission_time", 15 ); // Length of time to show the end of game stats
1226  ‪zombie_utility::set_zombie_var( "game_start_delay", 0, false, column ); // How much time to give people a break before starting spawning
1227 
1228  // Life and death
1229  ‪zombie_utility::set_zombie_var( "player_base_health", 100 ); // Base health of a player
1230 
1231  ‪zombie_utility::set_zombie_var( "penalty_no_revive", 0.10, true, column ); // Percentage of money you lose if you let a teammate die
1232  ‪zombie_utility::set_zombie_var( "penalty_died", 0.0, true, column ); // Percentage of money lost if you die
1233  ‪zombie_utility::set_zombie_var( "penalty_downed", 0.05, true, column ); // Percentage of money lost if you go down // ww: told to remove downed point loss
1234 
1235  ‪zombie_utility::set_zombie_var( "zombie_score_kill_4player", 50 ); // Individual Points for a zombie kill in a 4 player game
1236  ‪zombie_utility::set_zombie_var( "zombie_score_kill_3player", 50 ); // Individual Points for a zombie kill in a 3 player game
1237  ‪zombie_utility::set_zombie_var( "zombie_score_kill_2player", 50 ); // Individual Points for a zombie kill in a 2 player game
1238  ‪zombie_utility::set_zombie_var( "zombie_score_kill_1player", 50 ); // Individual Points for a zombie kill in a 1 player game
1239 
1240  ‪zombie_utility::set_zombie_var( "zombie_score_damage_normal", 10 ); // points gained for a hit with a non-automatic weapon
1241  ‪zombie_utility::set_zombie_var( "zombie_score_damage_light", 10 ); // points gained for a hit with an automatic weapon
1242 
1243  ‪zombie_utility::set_zombie_var( "zombie_score_bonus_melee", 80 ); // Bonus points for a melee kill
1244  ‪zombie_utility::set_zombie_var( "zombie_score_bonus_head", 50 ); // Bonus points for a head shot kill
1245  ‪zombie_utility::set_zombie_var( "zombie_score_bonus_neck", 20 ); // Bonus points for a neck shot kill
1246  ‪zombie_utility::set_zombie_var( "zombie_score_bonus_torso", 10 ); // Bonus points for a torso shot kill
1247  ‪zombie_utility::set_zombie_var( "zombie_score_bonus_burn", 10 ); // Bonus points for a burn kill
1248 
1249  ‪zombie_utility::set_zombie_var( "zombie_flame_dmg_point_delay", 500 );
1250 
1251  ‪zombie_utility::set_zombie_var( "zombify_player", false ); // Default to not zombify the player till further support
1252 
1253  if ( IsSplitScreen() )
1254  {
1255  ‪zombie_utility::set_zombie_var( "zombie_timer_offset", 280 ); // hud offsets
1256  }
1257 
1258  level thread ‪init_player_levelvars();
1259 
1260  level.gamedifficulty = GetGametypeSetting( "zmDifficulty" );
1261 
1262  if( level.gamedifficulty == 0 ) //easy
1263  {
1264  level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier_easy"];
1265  }
1266  else //normal
1267  {
1268  level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"];
1269  }
1270 
1271  //Make sure we only have walker zombies in round 1
1272  if ( level.round_number == 1 )
1273  {
1274  level.zombie_move_speed = 1;
1275  }
1276 
1277  level.speed_change_max = 0;
1278  level.speed_change_num = 0;
1279 
1280  ‪set_round_number( level.round_number );
1281 }
1282 
1284 {
1285  level ‪flag::wait_till( "start_zombie_round_logic" );
1286 
1287  difficulty = 1;
1288  column = int(difficulty) + 1;
1289 
1290  for(i = 0; i < 8; i ++)
1291  {
1292  points = 500;
1293 
1294  if(i > 3)
1295  {
1296  points = 3000; // Dont change the behavior of grief.
1297  }
1298 
1299  points = ‪zombie_utility::set_zombie_var( ("zombie_score_start_"+ (i+1) +"p"), points, false, column );
1300  }
1301 }
1302 
1303 function ‪init_dvars()
1304 {
1305 //t6.5todo: move these dvars out of script, dangerous to leave them here like this
1306 
1307  if( GetDvarString( "zombie_debug" ) == "" )
1308  {
1309  SetDvar( "zombie_debug", "0" );
1310  }
1311 
1312  if( GetDvarString( "scr_zm_enable_bots" ) == "" )
1313  {
1314  SetDvar( "scr_zm_enable_bots", "0" );
1315  }
1316 
1317  if( GetDvarString( "zombie_cheat" ) == "" )
1318  {
1319  SetDvar( "zombie_cheat", "0" );
1320  }
1321 
1322  if ( GetDvarString("zombiemode_debug_zombie_count") == "" )
1323  {
1324  SetDvar("zombiemode_debug_zombie_count", "0");
1325  }
1326 
1327  if ( level.script != "zombie_cod5_prototype" )
1328  {
1329  SetDvar( "magic_chest_movable", "1" );
1330  }
1331 
1332  SetDvar( "revive_trigger_radius", "75" );
1333 
1334  SetDvar( "scr_deleteexplosivesonspawn", "0" );
1335 }
1336 
1337 
1339 {
1340  level.callbackPlayerDamage = &‪Callback_PlayerDamage;
1341  level.overridePlayerDamage = &‪player_damage_override; //_cheat;
1342  level.callbackPlayerKilled = &‪player_killed_override;
1343 
1344  level.playerlaststand_func = &‪player_laststand;
1345  level.callbackPlayerLastStand = &‪Callback_PlayerLastStand;
1346 
1347  level.prevent_player_damage = &‪player_prevent_damage;
1348 
1349  level.callbackActorKilled = &‪actor_killed_override;
1350  level.callbackActorDamage = &‪actor_damage_override_wrapper;
1351 
1352  level.callbackVehicleDamage = &‪vehicle_damage_override;
1353  level.callbackVehicleKilled = &‪globallogic_vehicle::Callback_VehicleKilled;
1354  level.callbackVehicleRadiusDamage = &‪globallogic_vehicle::Callback_VehicleRadiusDamage;
1355 
1356  level.custom_introscreen = &‪zombie_intro_screen;
1357  level.custom_intermission = &‪player_intermission;
1358 
1359  level.global_damage_func = &‪zm_spawner::zombie_damage;
1360  level.global_damage_func_ads = &‪zm_spawner::zombie_damage_ads;
1361 
1362  level.reset_clientdvars = &‪onPlayerConnect_clientDvars;
1363 
1364  level.zombie_last_stand = &‪last_stand_pistol_swap;
1365  level.zombie_last_stand_pistol_memory = &‪last_stand_save_pistol_ammo;
1366  level.zombie_last_stand_ammo_return = &‪last_stand_restore_pistol_ammo;
1367 
1368  level.player_becomes_zombie = &‪zombify_player;
1369 
1370  level.validate_enemy_path_length = &‪zm_utility::default_validate_enemy_path_length;
1371 }
1372 
1373 function ‪Callback_PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
1374 {
1375  self endon( "disconnect" );
1376  //self Callback("on_player_last_stand");
1377  ‪zm_laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
1378 }
1379 
1380 function ‪CodeCallback_DestructibleEvent( event, param1, param2, param3 )
1381 {
1382  if( event == "broken" )
1383  {
1384  notify_type = param1;
1385  attacker = param2;
1386  weapon = param3;
1387 
1388  if ( IsDefined( level.destructible_callbacks[ notify_type ] ) )
1389  {
1390  self thread [[level.destructible_callbacks[ notify_type ]]]( notify_type, attacker );
1391  }
1392 
1393  self notify( event, notify_type, attacker );
1394  }
1395  else if( event == "breakafter" )
1396  {
1397  piece = param1;
1398  time = param2;
1399  ‪damage = param3;
1400  self thread ‪breakAfter( time, ‪damage, piece );
1401  }
1402 }
1403 
1404 function ‪breakAfter( time, ‪damage, piece )
1405 {
1406  self notify( "breakafter" );
1407  self endon( "breakafter" );
1408 
1409  wait time;
1410 
1411  // this does not work in mp. DoDamage does not take a piece for mp.
1412  self dodamage( ‪damage, self.origin, undefined, /*piece*/undefined );
1413 }
1414 
1415 function ‪Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
1416 {
1417  startedInLastStand = 0;
1418  if ( isPlayer(self) )
1419  {
1420  startedInLastStand = self ‪laststand::player_is_in_laststand();
1421  }
1422 
1423  /# println( "ZM Callback_PlayerDamage"+iDamage+"\n"); #/
1424  if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && (eAttacker.sessionteam == self.sessionteam) && !eAttacker HasPerk( "specialty_playeriszombie" ) && !‪IS_TRUE( self.‪is_zombie ) )
1425  {
1426  self ‪process_friendly_fire_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
1427  if ( self != eAttacker )
1428  {
1429  //one player shouldn't damage another player, grenades, airstrikes called in by another player
1430  /# println("Exiting - players can't hurt each other."); #/
1431 
1432 
1433  return;
1434  }
1435  else if ( sMeansOfDeath != "MOD_GRENADE_SPLASH"
1436  && sMeansOfDeath != "MOD_GRENADE"
1437  && sMeansOfDeath != "MOD_EXPLOSIVE"
1438  && sMeansOfDeath != "MOD_PROJECTILE"
1439  && sMeansOfDeath != "MOD_PROJECTILE_SPLASH"
1440  && sMeansOfDeath != "MOD_BURNED"
1441  && sMeansOfDeath != "MOD_SUICIDE" )
1442  {
1443  /# println("Exiting - damage type verbotten."); #/
1444  //player should be able to damage they're selves with grenades and stuff
1445  //otherwise don't damage the player, so like airstrikes won't kill the player
1446  return;
1447  }
1448  }
1449 
1450  // Notify the player of a zombie swipe if the persistent Insta Kill upgrade is active
1451  if( ‪IS_TRUE(level.pers_upgrade_insta_kill) )
1452  {
1453  self ‪zm_pers_upgrades_functions::pers_insta_kill_melee_swipe( sMeansOfDeath, eAttacker );
1454  }
1455 
1456  if( IsDefined( self.overridePlayerDamage ) )
1457  {
1458  iDamage = self [[self.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
1459  }
1460  else if( IsDefined( level.overridePlayerDamage ) )
1461  {
1462  iDamage = self [[level.overridePlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
1463  }
1464 
1465  Assert(IsDefined(iDamage), "You must return a value from a damage override function.");
1466 
1467 // self Callback("on_player_damage");
1468 
1470  {
1471  // save out and restore the maxHealth, because setting health below modifies it
1472  maxHealth = self.maxHealth;
1473 
1474  // increase health by damage, because it will be subtracted back out below in finishActorDamage
1475  self.health += iDamage;
1476 
1477  // restore the maxHealth to what it was
1478  self.maxHealth = maxHealth;
1479  }
1480 
1481  // DtP: When player is diving to prone away from the grenade, the damage is reduced
1482 
1483  // player is diving
1484  if( isdefined( self.divetoprone ) && self.divetoprone == 1 )
1485  {
1486  // grenade splash damage
1487  if( sMeansOfDeath == "MOD_GRENADE_SPLASH" )
1488  {
1489  // if the player is at least 32 units away
1490  dist = Distance2d(vPoint, self.origin);
1491  if( dist > 32 )
1492  {
1493  // if player is diving away
1494  ‪dot_product = vectordot( AnglesToForward( self.angles ), vDir );
1495  if( ‪dot_product > 0 )
1496  {
1497  // grenade is behind player
1498  iDamage = int( iDamage * 0.5 ); // halves damage
1499  }
1500  }
1501  }
1502  }
1503 
1504 /# println("CB PD"); #/
1505 
1506  // players can only hurt themselves, zombie players can hurt any other player and be hurt by human players
1507 /* if ( isdefined( eAttacker ) && isPlayer( eAttacker ) && !eAttacker HasPerk( "specialty_playeriszombie" ) && !IS_TRUE( self.is_zombie ) )
1508  {
1509  if ( self != eAttacker )
1510  {
1511  //one player shouldn't damage another player, grenades, airstrikes called in by another player
1512  println("Exiting - players can't hurt each other.");
1513  return;
1514  }
1515  else if ( sMeansOfDeath != "MOD_GRENADE_SPLASH"
1516  && sMeansOfDeath != "MOD_GRENADE"
1517  && sMeansOfDeath != "MOD_EXPLOSIVE"
1518  && sMeansOfDeath != "MOD_PROJECTILE"
1519  && sMeansOfDeath != "MOD_PROJECTILE_SPLASH"
1520  && sMeansOfDeath != "MOD_BURNED"
1521  && sMeansOfDeath != "MOD_SUICIDE" )
1522  {
1523  println("Exiting - damage type verbotten.");
1524  //player should be able to damage they're selves with grenades and stuff
1525  //otherwise don't damage the player, so like airstrikes won't kill the player
1526  return;
1527  }
1528  }*/
1529 
1530  if ( isdefined( level.prevent_player_damage ) )
1531  {
1532  if ( self [[ level.prevent_player_damage ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime ) )
1533  {
1534  return;
1535  }
1536  }
1537 
1538 
1539  iDFlags = iDFlags | level.iDFLAGS_NO_KNOCKBACK;
1540 
1541  //damage should have been reduced to 0 if it really was a riotshield hit
1542  if( iDamage > 0 && sHitLoc == "riotshield" )
1543  {
1544  sHitLoc = "torso_upper";
1545  }
1546 
1547 /# PrintLn("Finishplayerdamage wrapper."); #/
1548  wasDowned = 0;
1549  if ( isPlayer(self))
1550  {
1551  wasDowned = !startedInLastStand && self ‪laststand::player_is_in_laststand();
1552  }
1553 
1554  /#
1555  if(IsDefined(eAttacker))
1556  {
1557  Record3DText( "D:" + iDamage + " H: " + self.health + " A: " + eAttacker GetEntityNumber(), self.origin, ‪RED, "Script", self );
1558  }
1559  else
1560  {
1561  Record3DText( "D:" + iDamage + " H: " + self.health + " A: undefined", self.origin, ‪RED, "Script", self );
1562  }
1563  #/
1564 
1565  self ‪finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
1566 }
1567 
1568 function ‪finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal )
1569 {
1570  self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal );
1571 
1572  // the MP version of finishPlayerDamage does not take 11 parameters
1573  // the 11 parameter version in SP does not take these parameters (10 is modelIndex and 11 is pOffsetTime)
1574  //surface = "flesh";
1575  //self finishPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, surface );
1576 
1577 }
1578 
1580 {
1581  if (!isdefined(level.player_friendly_fire_callbacks))
1582  level.player_friendly_fire_callbacks = [];
1583  level.player_friendly_fire_callbacks[level.player_friendly_fire_callbacks.size] = ‪callback;
1584 }
1585 
1586 function ‪process_friendly_fire_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex )
1587 {
1588  if (isdefined(level.player_friendly_fire_callbacks))
1589  {
1590  foreach( ‪callback in level.player_friendly_fire_callbacks )
1591  {
1592  self [[‪callback]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex );
1593  }
1594  }
1595 }
1596 
1597 function ‪init_flags()
1598 {
1599  level ‪flag::init( "solo_game" );
1600  level ‪flag::init( "start_zombie_round_logic" );
1601  level ‪flag::init( "start_encounters_match_logic" );
1602  level ‪flag::init( "spawn_point_override" );
1603  level ‪flag::init( "crawler_round" );
1604  level ‪flag::init( "spawn_zombies", true );
1605  level ‪flag::init( "special_round" );
1606  level ‪flag::init( "dog_round" );
1607  level ‪flag::init( "raps_round" );
1608  level ‪flag::init( "begin_spawning" );
1609  level ‪flag::init( "end_round_wait" );
1610  level ‪flag::init( "wait_and_revive" );
1611  level ‪flag::init( "instant_revive" );
1612  level ‪flag::init( "initial_blackscreen_passed" );
1613  level ‪flag::init( "initial_players_connected" );
1614 
1615  level ‪flag::init( "power_on" );
1616  //DCS: this will init all zone controlling power switch flags.
1617  power_trigs = GetEntArray( "use_elec_switch", "targetname" );
1618  foreach(trig in power_trigs)
1619  {
1620  if(IsDefined(trig.script_int))
1621  {
1622  level ‪flag::init("power_on" + trig.script_int);
1623  }
1624  }
1625 }
1626 
1628 {
1629  // Client fields for actors
1630 
1631  ‪clientfield::register("actor", "zombie_riser_fx", ‪VERSION_SHIP, 1, "int");
1632 
1633  if ( ‪IS_TRUE( level.use_water_risers ) )
1634  {
1635  ‪clientfield::register("actor", "zombie_riser_fx_water", ‪VERSION_SHIP, 1, "int");
1636  }
1637 
1638  if ( ‪IS_TRUE( level.use_foliage_risers ) )
1639  {
1640  ‪clientfield::register("actor", "zombie_riser_fx_foliage", ‪VERSION_SHIP, 1, "int");
1641  }
1642 
1643  if ( ‪IS_TRUE( level.use_low_gravity_risers ) )
1644  {
1645  ‪clientfield::register("actor", "zombie_riser_fx_lowg", ‪VERSION_SHIP, 1, "int");
1646  }
1647 
1648  ‪clientfield::register("actor", "zombie_has_eyes", ‪VERSION_SHIP, 1, "int");
1649  ‪clientfield::register("actor", "zombie_ragdoll_explode", ‪VERSION_SHIP, 1, "int");
1650  ‪clientfield::register("actor", "zombie_gut_explosion", ‪VERSION_SHIP, 1, "int");
1651  ‪clientfield::register("actor", "sndZombieContext", ‪VERSION_SHIP_OBSOLETE, 1, "int");
1652  ‪clientfield::register("actor", "zombie_keyline_render", ‪VERSION_SHIP, 1, "int");
1653 
1654  bits = 4;
1655  trigs = GetEntArray( "use_elec_switch", "targetname" );
1656  if ( IsDefined( trigs ) )
1657  {
1658  bits = GetMinBitCountForNum( trigs.size + 1 );
1659  }
1660  ‪clientfield::register("world", "zombie_power_on", ‪VERSION_SHIP, bits, "int");
1661  ‪clientfield::register("world", "zombie_power_off", ‪VERSION_SHIP, bits, "int");
1662 
1663  ‪clientfield::register("world", "round_complete_time", ‪VERSION_SHIP, 20, "int");
1664  ‪clientfield::register("world", "round_complete_num", ‪VERSION_SHIP, 8, "int");
1665  ‪clientfield::register("world", "game_end_time", ‪VERSION_SHIP, 20, "int");
1666  ‪clientfield::register("world", "quest_complete_time", ‪VERSION_SHIP, 20, "int");
1667  ‪clientfield::register("world", "game_start_time", ‪VERSION_TU15_FFOTD_090816_0, 20, "int" );
1668 }
1669 
1670 function ‪init_fx()
1671 {
1672  level.createfx_callback_thread = &‪delete_in_createfx;
1673 
1674 // level._effect["wood_chunk_destory"] = "_t6/impacts/fx_large_woodhit" ;
1675  level._effect["fx_zombie_bar_break"] = "_t6/maps/zombie/fx_zombie_bar_break";
1676  level._effect["fx_zombie_bar_break_lite"] = "_t6/maps/zombie/fx_zombie_bar_break_lite";
1677 
1678  if ( !‪IS_TRUE( level.FX_exclude_edge_fog ) )
1679  {
1680  level._effect["edge_fog"] = "_t6/maps/zombie/fx_fog_zombie_amb";
1681  }
1682 
1683  level._effect["chest_light"] = "zombie/fx_weapon_box_open_glow_zmb";
1684  level._effect["chest_light_closed"] = "zombie/fx_weapon_box_closed_glow_zmb";
1685 
1686  if ( !‪IS_TRUE( level.FX_exclude_default_eye_glow ) )
1687  {
1688  level._effect["eye_glow"] = "zombie/fx_glow_eye_orange";
1689  }
1690 
1691  level._effect["headshot"] = "zombie/fx_bul_flesh_head_fatal_zmb";
1692  level._effect["headshot_nochunks"] = "zombie/fx_bul_flesh_head_nochunks_zmb";
1693  level._effect["bloodspurt"] = "zombie/fx_bul_flesh_neck_spurt_zmb";
1694 
1695  if ( !‪IS_TRUE( level.FX_exclude_tesla_head_light ) )
1696  {
1697  level._effect["tesla_head_light"] = "_t6/maps/zombie/fx_zombie_tesla_neck_spurt";
1698  }
1699  level._effect["zombie_guts_explosion"] = "zombie/fx_blood_torso_explo_lg_zmb";
1700 
1701 
1702  level._effect["rise_burst_water"] = "zombie/fx_spawn_dirt_hand_burst_zmb";
1703  level._effect["rise_billow_water"] = "zombie/fx_spawn_dirt_body_billowing_zmb";
1704  level._effect["rise_dust_water"] = "zombie/fx_spawn_dirt_body_dustfalling_zmb";
1705 
1706  level._effect["rise_burst"] = "zombie/fx_spawn_dirt_hand_burst_zmb";
1707  level._effect["rise_billow"] = "zombie/fx_spawn_dirt_body_billowing_zmb";
1708  level._effect["rise_dust"] = "zombie/fx_spawn_dirt_body_dustfalling_zmb";
1709 
1710  level._effect["fall_burst"] = "zombie/fx_spawn_dirt_hand_burst_zmb";
1711  level._effect["fall_billow"] = "zombie/fx_spawn_dirt_body_billowing_zmb";
1712  level._effect["fall_dust"] = "zombie/fx_spawn_dirt_body_dustfalling_zmb";
1713 
1714  // Flamethrower
1715  level._effect["character_fire_death_sm"] = "zombie/fx_fire_torso_zmb";
1716  level._effect["character_fire_death_torso"] = "zombie/fx_fire_torso_zmb";
1717 
1718  if ( !‪IS_TRUE( level.fx_exclude_default_explosion ) )
1719  {
1720  level._effect["def_explosion"] = "_t6/explosions/fx_default_explosion";
1721  }
1722 // level._effect["betty_explode"] = "_t6/weapon/bouncing_betty/fx_explosion_betty_generic";
1723 
1724 // level._effect["default_weapon_glow"] = "_t6/maps/zombie/fx_zmb_tranzit_weapon_glow";
1725 
1726  if ( !‪IS_TRUE( level.disable_fx_upgrade_aquired ) )
1727  {
1728  level._effect["upgrade_aquired"] = "_t6/maps/zombie/fx_zmb_tanzit_upgrade";
1729  }
1730 }
1731 
1732 // Handles the intro screen
1733 function ‪zombie_intro_screen( string1, string2, string3, string4, string5 )
1734 {
1735  level ‪flag::wait_till( "start_zombie_round_logic" );
1736 }
1737 
1739 {
1740  // initialize level.players_playing
1741  players = GetPlayers();
1742  level.players_playing = players.size;
1743 
1744  wait( 20 );
1745 
1746  players = GetPlayers();
1747  level.players_playing = players.size;
1748 }
1749 
1750 
1751 //
1752 // NETWORK SECTION ====================================================================== //
1753 //
1754 
1756 {
1757  self SetClientCompass( 0 );
1758  self SetClientThirdPerson( 0 );
1759  self resetFov();
1760  self SetClientThirdPersonAngle( 0 );
1761  self SetClientUIVisibilityFlag( "weapon_hud_visible", 1 );
1762  self SetClientMiniScoreboardHide( 1 );
1763  self SetClientHUDHardcore( 0 );
1764  self SetClientPlayerPushAmount( 1 );
1765 
1766  self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );
1767 
1769 }
1770 
1771 
1772 
1773 function ‪checkForAllDead(excluded_player)
1774 {
1775  players = GetPlayers();
1776  count = 0;
1777  for( i = 0; i < players.size; i++ )
1778  {
1779  if(isDefined(excluded_player) && excluded_player == players[i])
1780  {
1781  continue;
1782  }
1783  if( !(players[i] ‪laststand::player_is_in_laststand()) && !(players[i].sessionstate == "spectator") )
1784  {
1785  count++;
1786  }
1787  }
1788 
1789  if( count==0 && !‪IS_TRUE( level.no_end_game_check ) )
1790  {
1791  level notify( "end_game" );
1792  }
1793 }
1794 
1795 
1796 //
1797 // Runs when the player spawns into the map
1798 // self is the player.surprise!
1799 //
1801 {
1802  self endon( "disconnect" );
1803  self notify("stop_onPlayerSpawned");
1804  self endon("stop_onPlayerSpawned");
1805 
1806  for( ;; )
1807  {
1808  self waittill( "spawned_player" );
1809 
1810  if(!‪IS_TRUE(level.host_ended_game))
1811  {
1812  self freezecontrols( false );
1813  /# println(" Unfreeze controls 7"); #/
1814 
1815  }
1816  self.hits = 0;
1817 
1819 
1820  lethal_grenade = self ‪zm_utility::get_player_lethal_grenade();
1821  if( !self HasWeapon( lethal_grenade ) )
1822  {
1823  self GiveWeapon( lethal_grenade );
1824  self SetWeaponAmmoClip( lethal_grenade, 0 );
1825  }
1826 
1827  self RecordPlayerReviveZombies( self );
1828 
1829 /#
1830  if ( GetDvarInt( "zombie_cheat" ) >= 1 && GetDvarInt( "zombie_cheat" ) <= 3 )
1831  {
1832  self EnableInvulnerability();
1833  }
1834 #/
1835 
1836  self SetActionSlot( 3, "altMode" );
1837  self PlayerKnockback( false );
1838 
1839  self SetClientThirdPerson( 0 );
1840  self resetFov();
1841  self SetClientThirdPersonAngle( 0 );
1842 
1843  self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );
1844 
1845  self cameraactivate(false);
1846 
1847  self.num_perks = 0;
1848  self.on_lander_last_stand = undefined;
1849  self setblur(0, 0.1);
1850  self.zmbDialogQueue = [];
1851  self.zmbDialogActive = false;
1852  self.zmbDialogGroups = [];
1853  self.zmbDialogGroup = "";
1854 
1855  if ( ‪IS_TRUE( level.player_out_of_playable_area_monitor ) )
1856  {
1858  }
1859 
1860  if ( ‪IS_TRUE( level.player_too_many_weapons_monitor ) )
1861  {
1862  self thread [[level.player_too_many_weapons_monitor_func]]();
1863  }
1864 
1865  if ( ‪IS_TRUE( level.player_too_many_players_check ) )
1866  {
1867  level thread [[level.player_too_many_players_check_func]]();
1868  }
1869 
1870  self.disabled_perks = [];
1871 
1872  if( isdefined( self.player_initialized ) )
1873  {
1874  if( self.player_initialized == false )
1875  {
1876  self.player_initialized = true;
1877 
1878  //t6.5todo self freezecontrols( true ); // first spawn only, intro_black_screen will pull them out of it
1879 
1880  self giveweapon( self ‪zm_utility::get_player_lethal_grenade() );
1881  self setweaponammoclip( self ‪zm_utility::get_player_lethal_grenade(), 0);
1882  self SetClientUIVisibilityFlag( "weapon_hud_visible", 1 );
1883  self SetClientMiniScoreboardHide( 0 );
1884  // ww: set the is_drinking variable
1885  self.is_drinking = 0;
1886 
1887  self thread ‪player_zombie_breadcrumb();
1888 
1889  self thread ‪player_monitor_travel_dist();
1890  self thread ‪player_monitor_time_played();
1891 
1892  if(isDefined(level.custom_player_track_ammo_count))
1893  {
1894  self thread [[level.custom_player_track_ammo_count]]();
1895  }
1896  else
1897  {
1898  self thread ‪player_track_ammo_count();
1899  }
1900 
1901  self thread ‪zm_utility::shock_onpain();
1902 
1903  self thread ‪player_grenade_watcher();
1905 
1906  if(isDefined(level.zm_gamemodule_spawn_func))
1907  {
1908  self thread [[level.zm_gamemodule_spawn_func]]();
1909  }
1910 
1911  self thread ‪player_spawn_protection();
1912  if(!isDefined(self.lives))
1913  {
1914  self.lives = 0;
1915  }
1916  }
1917  }
1918  }
1919 }
1920 
1922 {
1923  self endon("disconnect");
1925  x = 0;
1926  while( x < 60 )
1927  {
1928  x++;
1929  wait(.05);
1930  }
1932 }
1933 
1934 function ‪spawn_life_brush( origin, radius, height )
1935 {
1936  life_brush = ‪spawn( "trigger_radius", origin, 0, radius, height );
1937  life_brush.script_noteworthy = "life_brush";
1938 
1939  return life_brush;
1940 }
1941 
1942 
1944 {
1945  life_brushes = getentarray( "life_brush", "script_noteworthy" );
1946 
1947  if ( !IsDefined( life_brushes ) )
1948  {
1949  return false;
1950  }
1951 
1952  for ( i = 0; i < life_brushes.size; i++ )
1953  {
1954 
1955  if ( self IsTouching( life_brushes[i] ) )
1956  {
1957  return true;
1958  }
1959  }
1960 
1961  return false;
1962 }
1963 
1964 
1965 function ‪spawn_kill_brush( origin, radius, height )
1966 {
1967  kill_brush = ‪spawn( "trigger_radius", origin, 0, radius, height );
1968  kill_brush.script_noteworthy = "kill_brush";
1969 
1970  return kill_brush;
1971 }
1972 
1973 
1975 {
1976  kill_brushes = getentarray( "kill_brush", "script_noteworthy" );
1977 
1978  self.kill_brush = undefined;
1979 
1980  if ( !IsDefined( kill_brushes ) )
1981  {
1982  return false;
1983  }
1984 
1985  for ( i = 0; i < kill_brushes.size; i++ )
1986  {
1987 
1988  if ( self IsTouching( kill_brushes[i] ) )
1989  {
1990  self.kill_brush = kill_brushes[i];
1991  return true;
1992  }
1993  }
1994 
1995  return false;
1996 }
1997 
1998 
2000 {
2002 
2003  playable_area = getentarray( "player_volume", "script_noteworthy" );
2004 
2005  if( !IsDefined( playable_area ) )
2006  {
2007  return false;
2008  }
2009 
2010  for ( i = 0; i < playable_area.size; i++ )
2011  {
2012  if ( ‪zm_zonemgr::zone_is_enabled( playable_area[i].targetname ) && self IsTouching( playable_area[i] ) )
2013  {
2014  return true;
2015  }
2016  }
2017 
2018  return false;
2019 }
2020 
2021 
2023 {
2024 /#
2025  if ( ‪IS_TRUE( level.check_kill_thread_every_frame ) )
2026  {
2027  return 0.05;
2028  }
2029 #/
2030 
2031  return 3;
2032 }
2033 
2034 
2036 {
2037  self notify( "stop_player_out_of_playable_area_monitor" );
2038  self endon( "stop_player_out_of_playable_area_monitor" );
2039  self endon( "disconnect" );
2040  level endon( "end_game" );
2041 
2042  while(!isDefined(self.characterindex))
2043  {
2044  wait(.05);
2045  }
2046  // load balancing
2047  wait( (0.15 * self.characterindex) );
2048 
2049  while ( true )
2050  {
2051  // skip over players in spectate, otherwise Sam keeps laughing every 3 seconds since their corpse is still invisibly in a kill area
2052  if ( self.sessionstate == "spectator" )
2053  {
2055  continue;
2056  }
2057 
2058  if(‪IS_TRUE(level.hostmigration_occured))
2059  {
2061  continue;
2062  }
2063 
2064  if ( !self ‪in_life_brush() && (self ‪in_kill_brush() || !self ‪in_enabled_playable_area() || ( isdefined(level.player_out_of_playable_area_override) && ‪IS_TRUE( self [[level.player_out_of_playable_area_override]]() ) ) ) )
2065  {
2066  if ( !isdefined( level.player_out_of_playable_area_monitor_callback ) || self [[level.player_out_of_playable_area_monitor_callback]]() )
2067  {
2068 /#
2069  if ( ‪IS_TRUE( level.kill_thread_test_mode ) )
2070  {
2071  PrintTopRightln( "out of playable area: " + self.origin );
2073  continue;
2074  }
2075 
2076  if ( self isinmovemode( "ufo", "noclip" ) || ‪IS_TRUE( level.disable_kill_thread ) || GetDvarInt( "zombie_cheat" ) > 0 )
2077  {
2079  continue;
2080  }
2081 #/
2082 
2083  //track the cheaters
2084  self ‪zm_stats::increment_map_cheat_stat( "cheat_out_of_playable" );
2085  self ‪zm_stats::increment_client_stat( "cheat_out_of_playable",false );
2086  self ‪zm_stats::increment_client_stat( "cheat_total",false );
2087 
2088  self playlocalsound( level.zmb_laugh_alias );
2089 
2090  wait( 0.5 );
2091 
2092  if ( GetPlayers().size == 1 && level ‪flag::get( "solo_game" ) && ‪IS_TRUE( self.waiting_to_revive ) )
2093  {
2094  level notify( "end_game" );
2095  }
2096  else
2097  {
2098  self DisableInvulnerability();
2099  self.lives = 0;
2100  self dodamage( self.health + 1000, self.origin );
2101  self.bleedout_time = 0;
2102  }
2103  }
2104  }
2105 
2107  }
2108 }
2109 
2110 
2112 {
2113  return 3;
2114 }
2115 
2116 
2118 {
2119  self endon( "player_too_many_weapons_monitor_takeaway_sequence_done" );
2120 
2121  self ‪util::waittill_any( "player_downed", "replace_weapon_powerup" );
2122 
2123  for ( i = 0; i < primary_weapons_to_take.size; i++ )
2124  {
2125  self TakeWeapon( primary_weapons_to_take[i] );
2126  }
2127 
2128  self ‪zm_score::player_reduce_points( "take_all" );
2129  self ‪zm_utility::give_start_weapon( false );
2131  {
2133  }
2134  else if ( level ‪flag::get( "solo_game" ) )
2135  {
2136  self.score_lost_when_downed = 0;
2137  }
2138 
2139  self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" );
2140 }
2141 
2142 
2143 function ‪player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take )
2144 {
2145  self thread ‪player_too_many_weapons_monitor_takeaway_simultaneous( primary_weapons_to_take );
2146 
2147  self endon( "player_downed" );
2148  self endon( "replace_weapon_powerup" );
2149 
2151  score_decrement = ‪zm_utility::round_up_to_ten( int( self.score / (primary_weapons_to_take.size + 1) ) );
2152 
2153  for ( i = 0; i < primary_weapons_to_take.size; i++ )
2154  {
2155  self playlocalsound( level.zmb_laugh_alias );
2156  self SwitchToWeapon( primary_weapons_to_take[i] );
2157  self ‪zm_score::player_reduce_points( "take_specified", score_decrement );
2158  wait( 3 );
2159 
2160  self TakeWeapon( primary_weapons_to_take[i] );
2161  }
2162 
2163  self playlocalsound( level.zmb_laugh_alias );
2164  self ‪zm_score::player_reduce_points( "take_all" );
2165  wait( 1 );
2166  self ‪zm_utility::give_start_weapon( true );
2168 
2169  self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" );
2170 }
2171 
2173 {
2174  self notify( "stop_player_too_many_weapons_monitor" );
2175  self endon( "stop_player_too_many_weapons_monitor" );
2176  self endon( "disconnect" );
2177  level endon( "end_game" );
2178 
2179  // load balancing
2180  scalar = self.characterindex;
2181 
2182  if ( !isdefined( scalar ) )
2183  {
2184  scalar = self GetEntityNumber();
2185  }
2186 
2187  wait( (0.15 * scalar) );
2188 
2189  while ( true )
2190  {
2191  if ( self ‪zm_utility::has_powerup_weapon() || self ‪laststand::player_is_in_laststand() || self.sessionstate == "spectator" || isdefined( self.laststandpistol ) )
2192  {
2194  continue;
2195  }
2196 
2197 /#
2198  if ( GetDvarInt( "zombie_cheat" ) > 0 )
2199  {
2201  continue;
2202  }
2203 #/
2204 
2205  weapon_limit = ‪zm_utility::get_player_weapon_limit( self );
2206 
2207  primaryWeapons = self GetWeaponsListPrimaries();
2208 
2209  if ( primaryWeapons.size > weapon_limit )
2210  {
2212  primaryWeapons = self GetWeaponsListPrimaries();
2213  }
2214 
2215  primary_weapons_to_take = [];
2216  for ( i = 0; i < primaryWeapons.size; i++ )
2217  {
2218  if ( ‪zm_weapons::is_weapon_included( primaryWeapons[i] ) || ‪zm_weapons::is_weapon_upgraded( primaryWeapons[i] ) )
2219  {
2220  primary_weapons_to_take[primary_weapons_to_take.size] = primaryWeapons[i];
2221  }
2222  }
2223 
2224  if ( primary_weapons_to_take.size > weapon_limit )
2225  {
2226  if ( !isdefined( level.player_too_many_weapons_monitor_callback ) || self [[level.player_too_many_weapons_monitor_callback]]( primary_weapons_to_take ) )
2227  {
2228  //track the cheaters
2229  self ‪zm_stats::increment_map_cheat_stat( "cheat_too_many_weapons" );
2230  self ‪zm_stats::increment_client_stat( "cheat_too_many_weapons",false );
2231  self ‪zm_stats::increment_client_stat( "cheat_total",false );
2232 
2233 
2234  self thread ‪player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take );
2235  self waittill( "player_too_many_weapons_monitor_takeaway_sequence_done" );
2236  }
2237  }
2238 
2240  }
2241 }
2242 
2243 
2245 {
2246  self endon("disconnect");
2247  self notify("stop_player_monitor_travel_dist");
2248  self endon("stop_player_monitor_travel_dist");
2249 
2250  prevpos = self.origin;
2251  while(1)
2252  {
2253  wait .1;
2254 
2255  self.pers["distance_traveled"] += distance( self.origin, prevpos ) ;
2256  prevpos = self.origin;
2257  }
2258 }
2259 
2261 {
2262  self endon( "disconnect" );
2263  self notify("stop_player_monitor_time_played");
2264  self endon("stop_player_monitor_time_played");
2265 
2266  level ‪flag::wait_till( "start_zombie_round_logic" );
2267 
2268  for ( ;; )
2269  {
2270  wait ( 1.0 );
2271  ‪zm_stats::increment_client_stat( "time_played_total" );
2272  }
2273 }
2274 
2276 {
2277  self endon( "disconnect" );
2278 
2279  waittillframeend;
2280 
2281  if ( !IsDefined( grenade ) )
2282  {
2283  return;
2284  }
2285 
2286  inflictorEntNum = grenade getEntityNumber();
2287  inflictorEntType = grenade getEntityType();
2288  inflictorBirthTime = 0;
2289  if ( isDefined( grenade.birthTime ) )
2290  inflictorBirthTime = grenade.birthTime;
2291 
2292  ret_val = grenade ‪util::waittill_any_ex( 15, "explode", "death", self, "disconnect" );
2293 
2294  if ( !IsDefined( self ) || (IsDefined( ret_val ) && "timeout" == ret_val) )
2295  {
2296  return;
2297  }
2298 
2299  self.grenade_multiattack_count = 0;
2300  self.grenade_multiattack_ent = undefined;
2301  self.grenade_multikill_count = 0; // Black Ops 3 - TU1 Fix; track multikill count in addition to multiattack, for the Five-for-One Challenge
2302 
2303  waittillframeend;
2304 
2305  if ( !IsDefined( self ) )
2306  {
2307  return;
2308  }
2309 
2310  count = level.grenade_multiattack_bookmark_count;
2311  if ( ‪IS_TRUE( grenade.grenade_multiattack_bookmark_count ) )
2312  {
2313  count = grenade.grenade_multiattack_bookmark_count;
2314  }
2315 
2316  bookmark_string = "zm_player_grenade_multiattack";
2317  if ( ‪IS_TRUE( grenade.use_grenade_special_long_bookmark ) )
2318  {
2319  bookmark_string = "zm_player_grenade_special_long";
2320  }
2321  else if ( ‪IS_TRUE( grenade.use_grenade_special_bookmark ) )
2322  {
2323  bookmark_string = "zm_player_grenade_special";
2324  }
2325 
2326  if ( count <= self.grenade_multiattack_count && IsDefined( self.grenade_multiattack_ent ) )
2327  {
2328  addDemoBookmark( bookmark_string, gettime(), self GetEntityNumber(), 255, 0, inflictorEntNum, inflictorEntType, inflictorBirthTime, false, self.grenade_multiattack_ent GetEntityNumber() );
2329  }
2330 
2331  if ( 5 <= self.grenade_multikill_count ) // Black Ops 3 - TU1 Fix; track multikill count in addition to multiattack, for the Five-for-One Challenge
2332  {
2333  self ‪zm_stats::increment_challenge_stat( "ZOMBIE_HUNTER_EXPLOSION_MULTIKILL" );
2334  }
2335 
2336  self.grenade_multiattack_count = 0;
2337  self.grenade_multikill_count = 0; // Black Ops 3 - TU1 Fix; track multikill count in addition to multiattack, for the Five-for-One Challenge
2338 }
2339 
2340 
2342 {
2343  self endon( "disconnect" );
2344 
2345  self notify("stop_player_grenade_watcher");
2346  self endon("stop_player_grenade_watcher");
2347 
2348  self.grenade_multiattack_count = 0;
2349  self.grenade_multikill_count = 0; //this was added to "player_grenade_multiattack_bookmark_watcher" for TU1, but not added here, which was causing a SRE.
2350 
2351  while ( 1 )
2352  {
2353  self waittill( "grenade_fire", grenade, weapon );
2354 
2355  if( isdefined( grenade ) && isalive( grenade ) )
2356  {
2357  grenade.team = self.team;
2358  }
2359 
2360  self thread ‪player_grenade_multiattack_bookmark_watcher( grenade );
2361 
2362  if ( isdefined( level.grenade_watcher ) )
2363  {
2364  self [[ level.grenade_watcher ]]( grenade, weapon );
2365  }
2366  }
2367 }
2368 
2369 function ‪player_prevent_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime )
2370 {
2371  if( !isdefined( eInflictor ) || !isdefined( eAttacker ) )
2372  {
2373  return false;
2374  }
2375 
2376  if ( eInflictor == self || eAttacker == self )
2377  {
2378  return false;
2379  }
2380 
2381  if ( isdefined( eInflictor ) && isdefined( eInflictor.team ) )
2382  {
2383  if (!‪IS_TRUE(eInflictor.damage_own_team))
2384  if ( eInflictor.team == self.team )
2385  {
2386  return true;
2387  }
2388  }
2389 
2390  return false;
2391 }
2392 
2393 //
2394 // Keep track of players going down and getting revived
2396 {
2397  self endon( "disconnect" );
2398  self notify("stop_player_revive_monitor");
2399  self endon("stop_player_revive_monitor");
2400 
2401  while (1)
2402  {
2403  self waittill( "player_revived", reviver );
2404 
2405  self playsoundtoplayer( "zmb_character_revived", self );
2406 
2407  if(‪IS_TRUE(level.isresetting_grief))
2408  {
2409  continue;
2410  }
2411 
2412  //self laststand_giveback_player_perks();
2413 
2414  if ( IsDefined(reviver) )
2415  {
2416  if( reviver != self )
2417  {
2418  if( ‪math::cointoss() )
2419  self ‪zm_audio::create_and_play_dialog( "general", "revive_up" );
2420  else
2421  reviver ‪zm_audio::create_and_play_dialog( "general", "revive_support" );
2422  }
2423  else
2424  {
2425  self ‪zm_audio::create_and_play_dialog( "general", "revive_up" );
2426  }
2427 
2428  //reviver maps\_zombiemode_rank::giveRankXp( "revive" );
2429  //maps\_zombiemode_challenges::doMissionCallback( "zm_revive", reviver );
2430 
2431  // Check to see how much money you lost from being down.
2432  points = self.score_lost_when_downed;
2433 
2434  if ( !isdefined( points ) )
2435  {
2436  points = 0;
2437  }
2438 
2439  /# println( "ZM >> LAST STAND - points = " + points); #/
2440 
2441  reviver ‪zm_score::player_add_points( "reviver", points );
2442  self.score_lost_when_downed = 0;
2443 
2444  if ( IsPlayer( reviver ) && reviver != self )
2445  {
2446  reviver ‪zm_stats::increment_challenge_stat( "SURVIVALIST_REVIVE" );
2447  }
2448  }
2449  }
2450 }
2451 
2452 
2453 // self = a player
2454 // If the player has just 1 perk, they wil always get it back
2455 // If the player has more than 1 perk, they will lose a single perk
2457 {
2458  if ( IsDefined( self.laststand_perks ) )
2459  {
2460  // Calculate a lost perk index
2461  lost_perk_index = int( -1 );
2462  if( self.laststand_perks.size > 1 )
2463  {
2464  lost_perk_index = RandomInt( self.laststand_perks.size-1 );
2465  }
2466 
2467  // Give the player back their perks
2468  for ( i=0; i<self.laststand_perks.size; i++ )
2469  {
2470  if ( self HasPerk( self.laststand_perks[i] ) )
2471  {
2472  continue;
2473  }
2474  if( i == lost_perk_index )
2475  {
2476  continue;
2477  }
2478 
2479  ‪zm_perks::give_perk( self.laststand_perks[i] );
2480  }
2481  }
2482 }
2483 
2485 {
2486  self endon( "death" );
2487  self endon( "player_revived" );
2488 
2489  keep_checking = true;
2490  while( keep_checking )
2491  {
2492  self waittill( "remote_revive", reviver );
2493 
2494  //Check the remote reviver is on the same team
2495  if( reviver.team == self.team )
2496  keep_checking = false;
2497  }
2498 
2499  self ‪zm_laststand::remote_revive( reviver );
2500 }
2501 
2502 function ‪player_laststand( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
2503 {
2504 /# println( "ZM >> LAST STAND - player_laststand called" ); #/
2505 
2506  b_alt_visionset = false;
2507 
2508  self AllowJump(false);
2509 
2510  currWeapon = self GetCurrentWeapon();
2511 
2512  self AddWeaponStat( currWeapon, "deathsDuringUse", 1 );
2513 
2514  // Grab the perks if we have the player persistent ability "perk lose"
2515  if( ‪IS_TRUE(self.pers_upgrades_awarded["perk_lose"]) )
2516  {
2518  }
2519 
2520  players = GetPlayers();
2521  if ( players.size == 1 && level ‪flag::get( "solo_game" ) )
2522  {
2523  if ( self.lives > 0 && self HasPerk(‪PERK_QUICK_REVIVE) )
2524  {
2525  self thread ‪wait_and_revive();
2526  }
2527  }
2528 
2530 
2531  self thread ‪remote_revive_watch();
2532 
2534 
2535  // Turns out we need to do this after all, but we don't want to change _laststand.gsc postship, so I'm doing it here manually instead
2536  self DisableOffhandWeapons();
2537 
2539 
2540  if( sMeansOfDeath != "MOD_SUICIDE" && sMeansOfDeath != "MOD_FALLING" )
2541  {
2542  if( !‪IS_TRUE(self.‪intermission) )
2543  self ‪zm_audio::create_and_play_dialog( "general", "revive_down" );
2544  else
2545  {
2546  if(isDefined(level.custom_player_death_vo_func) && !self [[level.custom_player_death_vo_func]]() )
2547  {
2548  self ‪zm_audio::create_and_play_dialog( "general", "exert_death" );
2549  }
2550  }
2551  }
2552 
2553  if( IsDefined( level._zombie_minigun_powerup_last_stand_func ) )
2554  {
2555  self thread [[level._zombie_minigun_powerup_last_stand_func]]();
2556  }
2557 
2558  if( IsDefined( level._zombie_tesla_powerup_last_stand_func ) )
2559  {
2560  self thread [[level._zombie_tesla_powerup_last_stand_func]]();
2561  }
2562 
2563  if ( self HasPerk( ‪PERK_ELECTRIC_CHERRY ) )
2564  {
2565  b_alt_visionset = true;
2566 
2567  if ( IsDefined( level.custom_laststand_func ) )
2568  {
2569  self thread [[ level.custom_laststand_func ]]();
2570  }
2571  }
2572 
2573  if( IsDefined( self.‪intermission ) && self.intermission )
2574  {
2575  //maps\_zombiemode_challenges::doMissionCallback( "playerDied", self );
2576 
2577  wait(.5);
2578  self stopsounds();
2579 
2580  level waittill( "forever" );
2581  }
2582 
2583  if ( !( b_alt_visionset ) )
2584  {
2585  ‪visionset_mgr::activate( "visionset", ‪ZM_LASTSTAND_VISIONSET, self, 1 );
2586  }
2587 }
2588 
2589 
2590 function ‪failsafe_revive_give_back_weapons(excluded_player)
2591 {
2592  for ( i = 0; i < 10; i++ )
2593  {
2595 
2596  players = GetPlayers();
2597  foreach(player in players )
2598  {
2599  if (player == excluded_player|| !isdefined( player.reviveProgressBar ) || player ‪zm_laststand::is_reviving_any() )
2600  {
2601  continue;
2602  }
2603 
2604  // he's not reviving anyone but he still has revive stuff up, clean it all up
2605  /#
2606  iprintlnbold( "FAILSAFE CLEANING UP REVIVE HUD AND GUN" );
2607  #/
2608  // pass in "none" since we have no idea what the weapon they should be showing is
2609  player ‪zm_laststand::revive_give_back_weapons( level.weaponNone );
2610 
2611  if ( isdefined( player.reviveProgressBar ) )
2612  {
2613  player.reviveProgressBar ‪hud::destroyElem();
2614  }
2615 
2616  if ( isdefined( player.reviveTextHud ) )
2617  {
2618  player.reviveTextHud ‪destroy();
2619  }
2620  }
2621  }
2622 }
2623 
2625 {
2626  points =‪struct::get_array( "intermission", "targetname" );
2627 
2628  if( points.size < 1 )
2629  {
2630  return;
2631  }
2632  points = array::randomize( points );
2633 
2634  point = points[0];
2635 
2636  SetDemoIntermissionPoint( point.origin, point.angles );
2637 }
2638 
2639 
2641 {
2642  self endon( "disconnect" );
2643  self endon( "spawned_spectator" );
2644  self notify( "spawned" );
2645  self notify( "end_respawn" );
2646 
2647  if( level.intermission )
2648  {
2649  return;
2650  }
2651 
2652  if( IsDefined( level.no_spectator ) && level.no_spectator )
2653  {
2654  wait( 3 );
2655  ExitLevel();
2656  }
2657 
2658  // The check_for_level_end looks for this
2659  self.is_zombie = true;
2660 
2661  //failsafe against losing viewarms due to the thread returning them getting an endon from "zombified"
2662  level thread ‪failsafe_revive_give_back_weapons(self);
2663 
2664  // Remove all reviving abilities
2665  self notify ( "zombified" );
2666 
2667  if( isdefined( self.revivetrigger ) )
2668  {
2669  self.revivetrigger delete();
2670  self.revivetrigger = undefined;
2671  }
2672 
2673  self.zombification_time = GetTime(); //set time when player died
2674 
2675  resetTimeout();
2676 
2677  // Stop shellshock and rumble
2678  self StopShellshock();
2679  self StopRumble( "damage_heavy" );
2680 
2681  self.sessionstate = "spectator";
2682  self.spectatorclient = -1;
2683 
2684  self.maxhealth = self.health;
2685  self.shellshocked = false;
2686  self.inWater = false;
2687  self.friendlydamage = undefined;
2688  self.hasSpawned = true;
2689  self.spawnTime = GetTime();
2690  self.afk = false;
2691 
2692 /# println( "*************************Zombie Spectator***" ); #/
2693  self detachAll();
2694 
2695  if( isdefined( level.custom_spectate_permissions ) )
2696  {
2697  self [[level.custom_spectate_permissions]]();
2698  }
2699  else
2700  {
2701  self ‪setSpectatePermissions( true );
2702  }
2703  self thread ‪spectator_thread();
2704 
2705  self ‪Spawn( self.origin, self.angles );
2706  self notify( "spawned_spectator" );
2707 }
2708 
2710 {
2711  self AllowSpectateTeam( "allies", isOn && self.team == "allies" );
2712  self AllowSpectateTeam( "axis", isOn && self.team == "axis" );
2713  self AllowSpectateTeam( "freelook", false );
2714  self AllowSpectateTeam( "none", false );
2715 }
2716 
2718 {
2719  self endon( "disconnect" );
2720  self endon( "spawned_player" );
2721 
2722 /* we are not currently supporting the shared screen tech
2723  if( self IsSplitScreen() )
2724  {
2725  last_alive = undefined;
2726  players = GetPlayers();
2727 
2728  for( i = 0; i < players.size; i++ )
2729  {
2730  if( !players[i].is_zombie )
2731  {
2732  last_alive = players[i];
2733  }
2734  }
2735 
2736  share_screen( last_alive, true );
2737 
2738  return;
2739  }
2740 */
2741 
2742 // self thread spectator_toggle_3rd_person();
2743 }
2744 
2746 {
2747  self endon( "disconnect" );
2748  self endon( "spawned_player" );
2749 
2750  third_person = true;
2751  self ‪set_third_person( true );
2752 }
2753 
2754 
2755 function ‪set_third_person( value )
2756 {
2757  if( value )
2758  {
2759  self SetClientThirdPerson( 1 );
2760  self SetClientThirdPersonAngle( 354 );
2761 
2762  self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
2763  }
2764  else
2765  {
2766  self SetClientThirdPerson( 0 );
2767  self SetClientThirdPersonAngle( 0 );
2768 
2769  self setDepthOfField( 0, 0, 512, 4000, 4, 0 );
2770  }
2771  self resetFov();
2772 }
2773 
2775 {
2776  level endon( "between_round_over" );
2777 
2778  players = GetPlayers();
2779 
2780 
2781  //If everyone is in last stand or spectate then revive all
2782  laststand_count = 0;
2783  foreach(player in players)
2784  {
2785  if( !‪zm_utility::is_player_valid( player ) )
2786  {
2787  laststand_count ++;
2788  }
2789  }
2790 
2791  if( laststand_count == players.size )
2792  {
2793  for ( i = 0; i < players.size; i++ )
2794  {
2795  if ( players[i] ‪laststand::player_is_in_laststand() && players[i].revivetrigger.beingRevived == 0 )
2796  {
2797  players[i] ‪zm_laststand::auto_revive( players[i] );
2798  }
2799  }
2800  }
2801 }
2802 
2803 // ww: arrange the last stand pistols so when it come time to choose which one they are inited
2805 {
2806  level.pistol_values = [];
2807 
2808  // ww: in a solo game the ranking of the pistols is a bit different based on the upgraded 1911 swap
2809  // any pistol ranked level.pistol_value_solo_replace_below or lower will be ignored and the player will be given the upgraded 1911
2810  level.pistol_values[ level.pistol_values.size ] = level.default_laststandpistol;
2811  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "pistol_burst" );
2812  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "pistol_fullauto" );
2813  level.pistol_value_solo_replace_below = level.pistol_values.size-1; // EO: anything scoring lower than this should be replaced
2814  level.pistol_values[ level.pistol_values.size ] = level.default_solo_laststandpistol;
2815  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "pistol_burst_upgraded" );
2816  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "pistol_fullauto_upgraded" );
2817  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "ray_gun" );
2818  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "raygun_mark2" );
2819  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "ray_gun_upgraded" );
2820  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "raygun_mark2_upgraded" );
2821  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "raygun_mark3" );
2822  level.pistol_values[ level.pistol_values.size ] = GetWeapon( "raygun_mark3_upgraded" );
2823 }
2824 
2826 {
2827  if ( self ‪zm_utility::has_powerup_weapon() )
2828  {
2829  // this will force the laststand module to switch us to any primary weapon, since we will no longer have this after revive
2830  self.lastActiveWeapon = level.weaponNone;
2831  }
2832 
2833  // PORTIZ: chance to override the player's last stand pistol, but only if the override is stronger than the current one
2834  if ( isdefined( self.w_min_last_stand_pistol_override ) )
2835  {
2837  }
2838 
2839  if ( !self HasWeapon( self.laststandpistol ) )
2840  {
2841  self GiveWeapon( self.laststandpistol );
2842  }
2843  ammoclip = self.laststandpistol.clipSize;
2844  doubleclip = ammoclip * 2;
2845 
2846  if( ‪IS_TRUE( self._special_solo_pistol_swap ) || (self.laststandpistol == level.default_solo_laststandpistol && !self.hadpistol) )
2847  {
2848  self._special_solo_pistol_swap = 0;
2849  self.hadpistol = false;
2850  self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
2851  }
2852  else if( level ‪flag::get("solo_game") && self.laststandpistol == level.default_solo_laststandpistol )
2853  {
2854  self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
2855  }
2856  else if ( self.laststandpistol == level.default_laststandpistol )
2857  {
2858  self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
2859  }
2860  else if ( !isdefined( self.stored_weapon_info ) || !isdefined( self.stored_weapon_info[ self.laststandpistol ] ) )
2861  {
2862  self SetWeaponAmmoStock( self.laststandpistol, doubleclip ); // PORTIZ: in the case that we awarded a temporary last stand weapon, just set the stock and skip the ammo tracking
2863  }
2864  else if ( self.laststandpistol.name == "ray_gun" || self.laststandpistol.name == "ray_gun_upgraded" )
2865  {
2866  if ( self.stored_weapon_info[ self.laststandpistol ].total_amt >= ammoclip )
2867  {
2868  self SetWeaponAmmoClip( self.laststandpistol, ammoclip );
2869  self.stored_weapon_info[ self.laststandpistol ].given_amt = ammoclip;
2870  }
2871  else
2872  {
2873  self SetWeaponAmmoClip( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].total_amt );
2874  self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt;
2875  }
2876  self SetWeaponAmmoStock( self.laststandpistol, 0 );
2877  }
2878  else
2879  {
2880  if ( self.stored_weapon_info[ self.laststandpistol ].stock_amt >= doubleclip )
2881  {
2882  self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
2883  self.stored_weapon_info[ self.laststandpistol ].given_amt = doubleclip + self.stored_weapon_info[ self.laststandpistol ].clip_amt + self.stored_weapon_info[ self.laststandpistol ].left_clip_amt;
2884  }
2885  else
2886  {
2887  self SetWeaponAmmoStock( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].stock_amt );
2888  self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt;
2889  }
2890  }
2891 
2892  self SwitchToWeapon( self.laststandpistol );
2893 }
2894 
2895 // PORTIZ: this runs if self.w_min_last_stand_pistol_override is defined, and just before the player is given his last stand pistol.
2897 {
2898  for( i = 0; i < level.pistol_values.size; i++ )
2899  {
2900  if( level.pistol_values[i] == self.w_min_last_stand_pistol_override )
2901  {
2902  n_min_last_stand_pistol_value = i; // find the value corresponding to our override weapon
2903  break;
2904  }
2905  }
2906 
2907  for( k = 0; k < level.pistol_values.size; k++ )
2908  {
2909  if( level.pistol_values[k] == self.laststandpistol )
2910  {
2911  n_default_last_stand_pistol_value = k; // find the value corresponding to our default last stand weapon
2912  break;
2913  }
2914  }
2915 
2916  if ( n_min_last_stand_pistol_value > n_default_last_stand_pistol_value )
2917  {
2918  self.hadpistol = false;
2919  self.laststandpistol = self.w_min_last_stand_pistol_override;
2920  }
2921 }
2922 
2923 // ww: make sure the player has the best pistol when they go in to last stand
2925 {
2926  pistol_array = [];
2927 
2928  current_weapons = self GetWeaponsListPrimaries();
2929 
2930  for( i = 0; i < current_weapons.size; i++ )
2931  {
2932  // make sure the weapon is a pistol
2933  wclass = current_weapons[i].weapClass;
2934  if ( current_weapons[i].isBallisticKnife )
2935  {
2936  wclass = "knife";
2937  }
2938 
2939  if ( wclass == "pistol" || wclass == "pistolspread" || wclass == "pistol spread" )
2940  {
2941  if ( (current_weapons[i] != level.default_solo_laststandpistol && !level ‪flag::get("solo_game") ) || (!level ‪flag::get("solo_game") && current_weapons[i] != level.default_solo_laststandpistol ))
2942  {
2943  if( (current_weapons[i] != self.laststandpistol) || (self.laststandpistol != level.default_laststandpistol) )
2944  {
2945  if ( self GetAmmoCount( current_weapons[i] ) <= 0 )
2946  {
2947  continue;
2948  }
2949  }
2950  }
2951 
2952  pistol_array_index = pistol_array.size; // set up the spot in the array
2953  pistol_array[ pistol_array_index ] = SpawnStruct(); // struct to store info on
2954 
2955  pistol_array[ pistol_array_index ].weapon = current_weapons[i];
2956  pistol_array[ pistol_array_index ].value = 0; // add a value in case a new weapon is introduced that hasn't been set up in level.pistol_values
2957 
2958  // compare the current weapon to the level.pistol_values to see what the value is
2959  for( j = 0; j < level.pistol_values.size; j++ )
2960  {
2961  if( level.pistol_values[j] == current_weapons[i].rootWeapon )
2962  {
2963  pistol_array[ pistol_array_index ].value = j;
2964  break;
2965  }
2966  }
2967  }
2968  }
2969 
2970  self.laststandpistol = ‪last_stand_compare_pistols( pistol_array );
2971 }
2972 
2973 // ww: compares the array passed in for the highest valued pistol
2974 function ‪last_stand_compare_pistols( struct_array )
2975 {
2976  if( !IsArray( struct_array ) || struct_array.size <= 0 )
2977  {
2978  self.hadpistol = false;
2979 
2980  //array will be empty if the pistol had no ammo...so lets see if the player had the pistol
2981  if(isDefined(self.stored_weapon_info))
2982  {
2983  stored_weapon_info = GetArrayKeys( self.stored_weapon_info );
2984  for( j = 0; j < stored_weapon_info.size; j++ )
2985  {
2986  if( stored_weapon_info[ j ].rootWeapon == level.laststandpistol)
2987  {
2988  self.hadpistol = true;
2989  return stored_weapon_info[ j ];
2990  }
2991  }
2992  }
2993 
2994  return level.laststandpistol; // nothing in the array then give the level last stand pistol
2995  }
2996 
2997  highest_score_pistol = struct_array[0]; // first time through give the first one to the highest score
2998 
2999  for( i = 1; i < struct_array.size; i++ )
3000  {
3001  if( struct_array[i].value > highest_score_pistol.value )
3002  {
3003  highest_score_pistol = struct_array[i];
3004  }
3005  }
3006 
3007  if( level ‪flag::get( "solo_game" ) )
3008  {
3009  self._special_solo_pistol_swap = 0; // ww: this way the weapon knows to pack texture when given
3010  if( highest_score_pistol.value <= level.pistol_value_solo_replace_below )
3011  {
3012  self.hadpistol = false;
3013  self._special_solo_pistol_swap = 1;
3014 
3015  if ( ‪IS_TRUE( level.force_solo_quick_revive ) && ( !self HasPerk( ‪PERK_QUICK_REVIVE ) ) )
3016  {
3017  return highest_score_pistol.weapon; // ar: gun won't be replaced
3018  }
3019  else
3020  {
3021  return level.laststandpistol; // ww: if it scores too low the player gets the 1911 upgraded
3022  }
3023  }
3024  else
3025  {
3026  return highest_score_pistol.weapon; // ww: gun is high in ranking and won't be replaced
3027  }
3028  }
3029  else // ww: happens when not in solo
3030  {
3031  return highest_score_pistol.weapon;
3032  }
3033 
3034 }
3035 
3036 // ww: override function for saving player pistol ammo count
3038 {
3039  weapon_inventory = self GetWeaponsList( true );
3040  self.stored_weapon_info = [];
3041 
3042  for( i = 0; i < weapon_inventory.size; i++ )
3043  {
3044  weapon = weapon_inventory[i];
3045 
3046  wclass = weapon.weapClass;
3047  if ( weapon.isBallisticKnife )
3048  {
3049  wclass = "knife";
3050  }
3051 
3052  if ( wclass == "pistol" || wclass == "pistolspread" || wclass == "pistol spread" )
3053  {
3054  self.stored_weapon_info[ weapon ] = SpawnStruct();
3055  self.stored_weapon_info[ weapon ].clip_amt = self GetWeaponAmmoClip( weapon );
3056  self.stored_weapon_info[ weapon ].left_clip_amt = 0;
3057  dual_wield_weapon = weapon.dualWieldWeapon;
3058  if ( level.weaponNone != dual_wield_weapon )
3059  {
3060  self.stored_weapon_info[ weapon ].left_clip_amt = self GetWeaponAmmoClip( dual_wield_weapon );
3061  }
3062  self.stored_weapon_info[ weapon ].stock_amt = self GetWeaponAmmoStock( weapon );
3063  self.stored_weapon_info[ weapon ].total_amt = self.stored_weapon_info[ weapon ].clip_amt + self.stored_weapon_info[ weapon ].left_clip_amt + self.stored_weapon_info[ weapon ].stock_amt;
3064  self.stored_weapon_info[ weapon ].given_amt = 0;
3065  }
3066  }
3067 
3069 }
3070 
3071 // ww: override to restore the player's pistol ammo after being picked up
3073 {
3074  self.weapon_taken_by_losing_specialty_additionalprimaryweapon = level.weaponNone;
3075 
3076  if ( !IsDefined( self.stored_weapon_info ) )
3077  {
3078  return;
3079  }
3080 
3081  weapon_inventory = self GetWeaponsList( true );
3082  weapon_to_restore = GetArrayKeys( self.stored_weapon_info );
3083 
3084  for( i = 0; i < weapon_inventory.size; i++ )
3085  {
3086  weapon = weapon_inventory[i];
3087 
3088  if ( weapon != self.laststandpistol )
3089  {
3090  continue;
3091  }
3092 
3093  // for this loop, weapon == self.laststandpistol
3094  for( j = 0; j < weapon_to_restore.size; j++ )
3095  {
3096  if ( weapon == weapon_to_restore[j] )
3097  {
3098  dual_wield_weapon = weapon_to_restore[j].dualWieldWeapon;
3099  if ( weapon != level.default_laststandpistol )
3100  {
3101  last_clip = self GetWeaponAmmoClip( weapon );
3102  last_left_clip = 0;
3103  if ( level.weaponNone != dual_wield_weapon )
3104  {
3105  last_left_clip = self GetWeaponAmmoClip( dual_wield_weapon );
3106  }
3107  last_stock = self GetWeaponAmmoStock( weapon );
3108  last_total = last_clip + last_left_clip + last_stock;
3109 
3110  used_amt = self.stored_weapon_info[ weapon ].given_amt - last_total;
3111 
3112  if ( used_amt >= self.stored_weapon_info[ weapon ].stock_amt )
3113  {
3114  used_amt -= self.stored_weapon_info[ weapon ].stock_amt;
3115  self.stored_weapon_info[ weapon ].stock_amt = 0;
3116 
3117  self.stored_weapon_info[ weapon ].clip_amt -= used_amt;
3118  if ( self.stored_weapon_info[ weapon ].clip_amt < 0 )
3119  {
3120  self.stored_weapon_info[ weapon ].clip_amt = 0;
3121  }
3122  }
3123  else
3124  {
3125  new_stock_amt = self.stored_weapon_info[ weapon ].stock_amt - used_amt;
3126  if ( new_stock_amt < self.stored_weapon_info[ weapon ].stock_amt )
3127  {
3128  self.stored_weapon_info[ weapon ].stock_amt = new_stock_amt;
3129  }
3130  }
3131  }
3132 
3133  self SetWeaponAmmoClip( weapon, self.stored_weapon_info[weapon].clip_amt );
3134  if ( level.weaponNone != dual_wield_weapon )
3135  {
3136  self SetWeaponAmmoClip( dual_wield_weapon, self.stored_weapon_info[weapon].left_clip_amt );
3137  }
3138  self SetWeaponAmmoStock( weapon, self.stored_weapon_info[weapon].stock_amt );
3139  break;
3140  }
3141  }
3142  }
3143 }
3144 
3146 {
3147  self endon( "disconnect" );
3148  self endon( "bled_out" );
3149  self endon( "player_revived" );
3150 
3151  self waittill ( "grenade_fire", grenade, weapon );
3152 
3153  if ( isdefined(self.lsgsar_lethal) && weapon == self.lsgsar_lethal )
3154  {
3155  self.lsgsar_lethal_nade_amt--;
3156  }
3157 
3158  if ( isdefined(self.lsgsar_tactical) && weapon == self.lsgsar_tactical )
3159  {
3160  self.lsgsar_tactical_nade_amt--;
3161  }
3162 }
3163 
3164 // ww: zeros out the player's grenades until they revive
3166 {
3167  if(‪IS_TRUE(level.isresetting_grief)) //don't do this for Grief when resetting the round
3168  {
3169  return;
3170  }
3171  self endon( "disconnect" );
3172  self endon ("bled_out");
3173 
3174  self.lsgsar_lethal_nade_amt = 0;
3175  self.lsgsar_has_lethal_nade = false;
3176  self.lsgsar_tactical_nade_amt = 0;
3177  self.lsgsar_has_tactical_nade = false;
3178  self.lsgsar_lethal = undefined;
3179  self.lsgsar_tactical = undefined;
3180 
3181  if (self IsThrowingGrenade())
3182  {
3183  self thread ‪last_stand_take_thrown_grenade();
3184  }
3185 
3187  if ( weapon != level.weaponNone )
3188  {
3189  self.lsgsar_has_lethal_nade = true;
3190  self.lsgsar_lethal = weapon;
3191  self.lsgsar_lethal_nade_amt = self GetWeaponAmmoClip( weapon );
3192  self SetWeaponAmmoClip( weapon, 0 );
3193  self TakeWeapon( weapon );
3194  }
3195 
3197  if ( weapon != level.weaponNone )
3198  {
3199  self.lsgsar_has_tactical_nade = true;
3200  self.lsgsar_tactical = weapon;
3201  self.lsgsar_tactical_nade_amt = self GetWeaponAmmoClip( weapon );
3202  self SetWeaponAmmoClip( weapon, 0 );
3203  self TakeWeapon( weapon );
3204  }
3205 
3206  self waittill( "player_revived" );
3207 
3208  if ( self.lsgsar_has_lethal_nade )
3209  {
3210  self ‪zm_utility::set_player_lethal_grenade( self.lsgsar_lethal );
3211  self GiveWeapon( self.lsgsar_lethal );
3212  self SetWeaponAmmoClip( self.lsgsar_lethal, self.lsgsar_lethal_nade_amt );
3213  }
3214 
3215  if ( self.lsgsar_has_tactical_nade )
3216  {
3217  self ‪zm_utility::set_player_tactical_grenade( self.lsgsar_tactical );
3218  self GiveWeapon( self.lsgsar_tactical );
3219  self SetWeaponAmmoClip( self.lsgsar_tactical, self.lsgsar_tactical_nade_amt );
3220  }
3221 
3222  self.lsgsar_lethal_nade_amt = undefined;
3223  self.lsgsar_has_lethal_nade = undefined;
3224  self.lsgsar_tactical_nade_amt = undefined;
3225  self.lsgsar_has_tactical_nade = undefined;
3226  self.lsgsar_lethal = undefined;
3227  self.lsgsar_tactical = undefined;
3228 
3229 }
3230 
3232 {
3233  level endon( "between_round_over" );
3234 
3235  if( !IsDefined( level.zombie_vars["spectators_respawn"] ) || !level.zombie_vars["spectators_respawn"] )
3236  {
3237  return;
3238  }
3239 
3240  while( 1 )
3241  {
3242  players = GetPlayers();
3243  for( i = 0; i < players.size; i++ )
3244  {
3245  e_player = players[i];
3246  e_player ‪spectator_respawn_player();
3247  }
3248 
3249  wait( 1 );
3250  }
3251 }
3252 
3254 {
3255  if( self.sessionstate == "spectator" && IsDefined( self.‪spectator_respawn ))
3256  {
3257  if( !IsDefined( level.custom_spawnPlayer ) )
3258  {
3259  // Custom spawn call for when they respawn from spectator
3260  level.custom_spawnPlayer = &‪spectator_respawn;
3261  }
3262 
3263  self [[level.spawnPlayer]]();
3265  if (isDefined(level.script) && level.round_number > 6 && self.score < 1500)
3266  {
3267  self.old_score = self.score;
3268  if(isDefined(level.spectator_respawn_custom_score))
3269  {
3270  self [[level.spectator_respawn_custom_score]]();
3271  }
3272  self.score = 1500;
3273  }
3274  }
3275 }
3276 
3278 {
3279 /# println( "*************************Respawn Spectator***" ); #/
3280  assert( IsDefined( self.‪spectator_respawn ) );
3281 
3282  origin = self.spectator_respawn.origin;
3283  angles = self.spectator_respawn.angles;
3284 
3285  self ‪setSpectatePermissions( false );
3286 
3287  new_origin = undefined;
3288 
3289 
3290  if ( isdefined( level.check_valid_spawn_override ) )
3291  {
3292  new_origin = [[ level.check_valid_spawn_override ]]( self );
3293  }
3294 
3295  if ( !isdefined( new_origin ) )
3296  {
3297  new_origin = ‪check_for_valid_spawn_near_team( self,true );
3298  }
3299 
3300 
3301  if( IsDefined( new_origin ) )
3302  {
3303  if(!isDefined(new_origin.angles))
3304  {
3305  angles = (0, 0, 0);
3306  }
3307  else
3308  {
3309  angles = new_origin.angles;
3310  }
3311  self ‪Spawn( new_origin.origin, angles );
3312  }
3313  else
3314  {
3315  self ‪Spawn( origin, angles );
3316  }
3317 
3318 
3319  if ( IsDefined( self ‪zm_utility::get_player_placeable_mine() ) )
3320  {
3321  self TakeWeapon( self ‪zm_utility::get_player_placeable_mine() );
3322  self ‪zm_utility::set_player_placeable_mine( level.weaponNone );
3323  }
3324 
3325  self ‪zm_equipment::take();
3326 
3327  self.is_burning = undefined;
3328  self.abilities = [];
3329 
3330  // The check_for_level_end looks for this
3331  self.is_zombie = false;
3333 
3334  self ‪clientfield::set( "zmbLastStand", 0 );
3335  self RevivePlayer();
3336 
3337  self notify( "spawned_player" );
3338  self ‪callback::callback( #"on_player_spawned" );
3339 
3340  if(IsDefined(level._zombiemode_post_respawn_callback))
3341  {
3342  self thread [[level._zombiemode_post_respawn_callback]]();
3343  }
3344 
3345  // Penalize the player when we respawn, since he 'died'
3346  self ‪zm_score::player_reduce_points( "died" );
3347 
3349 
3350  self thread ‪player_zombie_breadcrumb();
3351 
3352  self thread ‪zm_perks::return_retained_perks();
3353 
3354  return true;
3355 }
3356 
3357 
3358 //*****************************************************************************
3359 //*****************************************************************************
3360 
3361 function ‪check_for_valid_spawn_near_team( revivee, return_struct )
3362 {
3363  // if level override is detected, use it instead of normal respawn logic
3364  if ( IsDefined( level.check_for_valid_spawn_near_team_callback ) )
3365  {
3366  spawn_location = [[ level.check_for_valid_spawn_near_team_callback ]](revivee, return_struct);
3367  return spawn_location;
3368  }
3369  else // normal respawn logic below here
3370  {
3371  players = GetPlayers();
3373 
3374  closest_group = undefined;
3375  closest_distance = 100000000;
3376  backup_group = undefined;
3377  backup_distance = 100000000;
3378 
3379  if( spawn_points.size == 0 )
3380  return undefined;
3381 
3382  a_enabled_zone_entities = ‪zm_zonemgr::get_active_zones_entities();
3383 
3384  // Look for the closest group that is within the specified ideal distances
3385  // If we can't find one within a valid area, use the closest unlocked group.
3386  for( i = 0; i < players.size; i++ )
3387  {
3388  if( ‪zm_utility::is_player_valid( players[i],undefined,true ) && (players[i] != self) )
3389  {
3390  for( j = 0 ; j < spawn_points.size; j++ )
3391  {
3392  if( isdefined(spawn_points[j].script_int) )
3393  ideal_distance = spawn_points[j].script_int;
3394  else
3395  ideal_distance = 1000;
3396 
3397  // Safety check, check the spawn point is inside an enabled zone
3398  // There have been cases where a spawn point has the wrong zone KVP on it compared to the zone it exists inside
3399  if ( ‪zm_utility::check_point_in_enabled_zone( spawn_points[j].origin, false, a_enabled_zone_entities ) == false )
3400  {
3401  continue;
3402  }
3403 
3404  if ( spawn_points[j].locked == false )
3405  {
3406  plyr_dist = DistanceSquared( players[i].origin, spawn_points[j].origin );
3407  if( plyr_dist < ( ideal_distance * ideal_distance ) )
3408  {
3409  if ( plyr_dist < closest_distance )
3410  {
3411  closest_distance = plyr_dist;
3412  closest_group = j;
3413  }
3414  }
3415  else
3416  {
3417  if ( plyr_dist < backup_distance )
3418  {
3419  backup_group = j;
3420  backup_distance = plyr_dist;
3421  }
3422  }
3423  }
3424  }
3425  }
3426 
3427  // If we don't have a closest_group, let's use the backup
3428  if( !IsDefined( closest_group ) )
3429  {
3430  closest_group = backup_group;
3431  }
3432 
3433  if( IsDefined( closest_group ) )
3434  {
3435  spawn_location = ‪get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct );
3436  if( IsDefined(spawn_location) )
3437  {
3438  return( spawn_location );
3439  }
3440  }
3441  }
3442 
3443  return undefined;
3444  }
3445 }
3446 
3447 
3448 //*****************************************************************************
3449 //*****************************************************************************
3450 
3451 function ‪get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct )
3452 {
3453  spawn_array =‪struct::get_array( spawn_points[closest_group].target, "targetname" );
3454  spawn_array = array::randomize(spawn_array);
3455 
3456  for( k = 0; k < spawn_array.size; k++ )
3457  {
3458  if(IsDefined(spawn_array[k].plyr) && spawn_array[k].plyr == revivee GetEntityNumber())
3459  {
3460  if(positionWouldTelefrag(spawn_array[k].origin))
3461  {
3462  spawn_array[k].plyr = undefined;
3463  break;
3464  }
3465  else if(‪IS_TRUE(return_struct))
3466  {
3467  return spawn_array[k];
3468  }
3469  else
3470  {
3471  return spawn_array[k].origin;
3472  }
3473  }
3474  }
3475 
3476  for( k = 0; k < spawn_array.size; k++ )
3477  {
3478  if(positionWouldTelefrag(spawn_array[k].origin))
3479  {
3480  continue;
3481  }
3482  if(!IsDefined(spawn_array[k].plyr) || spawn_array[k].plyr == revivee GetEntityNumber())
3483  {
3484  spawn_array[k].plyr = revivee GetEntityNumber();
3485  if(‪IS_TRUE(return_struct))
3486  {
3487  return spawn_array[k];
3488  }
3489  else
3490  {
3491  return spawn_array[k].origin;
3492  }
3493  }
3494  }
3495 
3496  if(‪IS_TRUE(return_struct))
3497  {
3498  return spawn_array[0];
3499  }
3500 
3501  return spawn_array[0].origin;
3502 }
3503 
3504 
3505 //*****************************************************************************
3506 //*****************************************************************************
3507 
3508 function ‪check_for_valid_spawn_near_position( revivee, v_position, return_struct )
3509 {
3511 
3512  if( spawn_points.size == 0 )
3513  {
3514  return( undefined );
3515  }
3516 
3517  closest_group = undefined;
3518  closest_distance = 100000000;
3519  backup_group = undefined;
3520  backup_distance = 100000000;
3521 
3522  for( i=0 ; i<spawn_points.size; i++ )
3523  {
3524  if( IsDefined(spawn_points[i].script_int) )
3525  {
3526  ideal_distance = spawn_points[i].script_int;
3527  }
3528  else
3529  {
3530  ideal_distance = 1000;
3531  }
3532 
3533  if ( spawn_points[i].locked == false )
3534  {
3535  dist = DistanceSquared( v_position, spawn_points[i].origin );
3536  if( dist < ( ideal_distance * ideal_distance ) )
3537  {
3538  if ( dist < closest_distance )
3539  {
3540  closest_distance = dist;
3541  closest_group = i;
3542  }
3543  }
3544  else
3545  {
3546  if ( dist < backup_distance )
3547  {
3548  backup_group = i;
3549  backup_distance = dist;
3550  }
3551  }
3552  }
3553  // If we don't have a closest_group, let's use the backup
3554  if ( !IsDefined( closest_group ) )
3555  {
3556  closest_group = backup_group;
3557  }
3558  }
3559 
3560  if( IsDefined( closest_group ) )
3561  {
3562  spawn_location = ‪get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct );
3563  if( IsDefined(spawn_location) )
3564  {
3565  return( spawn_location );
3566  }
3567  }
3568 
3569  return undefined;
3570 }
3571 
3572 
3573 
3574 //*****************************************************************************
3575 // Get a valid spawn point within the (min_distance, max_distance) ranges
3576 //*****************************************************************************
3577 
3578 function ‪check_for_valid_spawn_within_range( revivee, v_position, return_struct, min_distance, max_distance )
3579 {
3581 
3582  if( spawn_points.size == 0 )
3583  {
3584  return( undefined );
3585  }
3586 
3587  closest_group = undefined;
3588  closest_distance = 100000000;
3589 
3590  for( i=0 ; i<spawn_points.size; i++ )
3591  {
3592  if ( spawn_points[i].locked == false )
3593  {
3594  dist = Distance( v_position, spawn_points[i].origin );
3595  if( (dist >= min_distance) && (dist <= max_distance) )
3596  {
3597  if( dist < closest_distance )
3598  {
3599  closest_distance = dist;
3600  closest_group = i;
3601  }
3602  }
3603  }
3604  }
3605 
3606  if( IsDefined( closest_group ) )
3607  {
3608  spawn_location = ‪get_valid_spawn_location( revivee, spawn_points, closest_group, return_struct );
3609  if( IsDefined(spawn_location) )
3610  {
3611  return( spawn_location );
3612  }
3613  }
3614 
3615  return undefined;
3616 }
3617 
3618 
3619 //*****************************************************************************
3620 //*****************************************************************************
3621 
3622 function ‪get_players_on_team(exclude)
3623 {
3624  teammates = [];
3625 
3626  players = GetPlayers();
3627  for(i=0;i<players.size;i++)
3628  {
3629  //check to see if other players on your team are alive and not waiting to be revived
3630  if(players[i].spawn_side == self.spawn_side && !isDefined(players[i].revivetrigger) && players[i] != exclude )
3631  {
3632  teammates[teammates.size] = players[i];
3633  }
3634  }
3635 
3636  return teammates;
3637 }
3638 
3639 
3640 
3641 function ‪get_safe_breadcrumb_pos( player )
3642 {
3643  players = GetPlayers();
3644  valid_players = [];
3645 
3646  min_dist = 150 * 150;
3647  for( i = 0; i < players.size; i++ )
3648  {
3649  if( !‪zm_utility::is_player_valid( players[i] ) )
3650  {
3651  continue;
3652  }
3653 
3654  valid_players[valid_players.size] = players[i];
3655  }
3656 
3657  for( i = 0; i < valid_players.size; i++ )
3658  {
3659  count = 0;
3660  for( q = 1; q < player.zombie_breadcrumbs.size; q++ )
3661  {
3662  if( DistanceSquared( player.zombie_breadcrumbs[q], valid_players[i].origin ) < min_dist )
3663  {
3664  continue;
3665  }
3666 
3667  count++;
3668  if( count == valid_players.size )
3669  {
3670  return player.zombie_breadcrumbs[q];
3671  }
3672  }
3673  }
3674 
3675  return undefined;
3676 }
3677 
3679 {
3680  level endon( "intermission" );
3681  level endon( "end_of_round" );
3682  level endon( "restart_round" );
3683 /#
3684  level endon( "kill_round" );
3685 #/
3686 
3687  if( level.intermission )
3688  {
3689  return;
3690  }
3691 
3692  if ( ‪cheat_enabled( 2 ) )
3693  {
3694  return;
3695  }
3696 
3697  if( level.zm_loc_types[ "zombie_location" ].size < 1 )
3698  {
3699  ASSERTMSG( "No active spawners in the map. Check to see if the zone is active and if it's pointing to spawners." );
3700  return;
3701  }
3702 
3703  ‪zombie_utility::ai_calculate_health( level.round_number );
3704 
3705  count = 0;
3706 
3707  //CODER MOD: TOMMY K
3708  players = GetPlayers();
3709  for( i = 0; i < players.size; i++ )
3710  {
3711  players[i].zombification_time = 0;
3712  }
3713 
3714  // Now set the total for the new round, except when it's already been set by the kill counter
3715  if ( !( IsDefined( level.kill_counter_hud ) && level.zombie_total > 0 ) )
3716  {
3717  level.zombie_total = ‪get_zombie_count_for_round( level.round_number, level.players.size );
3718  level.zombie_respawns = 0; // reset number of zombies needing respawn
3719  level notify( "zombie_total_set" );
3720  }
3721 
3722  if ( IsDefined( level.zombie_total_set_func ) )
3723  {
3724  level thread [[ level.zombie_total_set_func ]]();
3725  }
3726 
3727  if ( level.round_number < 10 || level.speed_change_max > 0 )
3728  {
3729  level thread ‪zombie_utility::zombie_speed_up();
3730  }
3731 
3732  old_spawn = undefined;
3733  while( 1 )
3734  {
3735  while( ‪zombie_utility::get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 )
3736  {
3737  wait( 0.1 );
3738  }
3739 
3740  while ( ‪zombie_utility::get_current_actor_count() >= level.zombie_actor_limit )
3741  {
3743  wait( 0.1 );
3744  }
3745 
3746  // if we're using something that can pause the world, wait until finished to continue spawning
3747  if(‪flag::exists("world_is_paused"))
3748  {
3749  level ‪flag::wait_till_clear("world_is_paused");
3750  }
3751 
3752  // added ability to pause zombie spawning
3753  level ‪flag::wait_till( "spawn_zombies" );
3754 
3755  //Not great fix for this being zero - which it should NEVER be! (2 days to ship - PETER)
3756  while( level.zm_loc_types[ "zombie_location" ].size <= 0 )
3757  {
3758  wait( 0.1 );
3759  }
3760 
3762 
3763  if ( ‪IS_TRUE(level.hostMigrationTimer) )
3764  {
3766  continue;
3767  }
3768 
3769  // Run custom round spawn logic - returns TRUE if we spawned something, FALSE if we need to spawn a zombie.
3770  if ( isdefined( level.fn_custom_round_ai_spawn ) )
3771  {
3772  if ( [[ level.fn_custom_round_ai_spawn ]]() )
3773  {
3774  // we handled the spawn
3776  continue;
3777  }
3778  }
3779 
3780  if( IsDefined( level.zombie_spawners ) )
3781  {
3782  // Check for custom zombie spawner selection
3783  if ( isdefined( level.fn_custom_zombie_spawner_selection ) )
3784  {
3785  spawner = [[ level.fn_custom_zombie_spawner_selection ]]();
3786  }
3787 
3788  // Default zombie spawner selection
3789  else
3790  {
3791  if( ‪IS_TRUE( level.use_multiple_spawns ) )
3792  {
3793  if( isdefined( level.spawner_int ) && ‪IS_TRUE( level.zombie_spawn[level.spawner_int].size ) )
3794  {
3795  spawner = array::random( level.zombie_spawn[level.spawner_int] );
3796  }
3797  else
3798  {
3799  spawner = array::random( level.zombie_spawners );
3800  }
3801  }
3802  else
3803  {
3804  spawner = array::random( level.zombie_spawners );
3805  }
3806  }
3807 
3808  ai = ‪zombie_utility::spawn_zombie( spawner, spawner.targetname );
3809  }
3810 
3811  if( IsDefined( ai ) )
3812  {
3813  level.zombie_total--;
3814  if ( level.zombie_respawns > 0 )
3815  {
3816  level.zombie_respawns--;
3817  }
3818 
3820  count++;
3821 
3822  if ( ai ‪ai::has_behavior_attribute( "can_juke" ) )
3823  {
3824  ai ‪ai::set_behavior_attribute("can_juke", false);
3825  }
3826 
3827  // Get zombies into the map quicker if they're respawning from cleanup
3828  if ( level.zombie_respawns > 0 )//&& level.zombie_vars["zombie_spawn_delay"] > 1.0 )
3829  {
3830  wait 0.1;
3831  }
3832  else
3833  {
3834  wait( level.zombie_vars["zombie_spawn_delay"] );
3835  }
3836  }
3837 
3839  }
3840 }
3841 
3842 function ‪get_zombie_count_for_round( n_round, n_player_count )
3843 {
3844  max = level.zombie_vars["zombie_max_ai"];
3845 
3846  multiplier = n_round / 5;
3847  if( multiplier < 1 )
3848  {
3849  multiplier = 1;
3850  }
3851 
3852  // After round 10, exponentially have more AI attack the player
3853  if( n_round >= 10 )
3854  {
3855  multiplier *= n_round * 0.15;
3856  }
3857 
3858  if( n_player_count == 1 )
3859  {
3860  max += int( ( 0.5 * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
3861  }
3862  else
3863  {
3864  max += int( ( ( n_player_count - 1 ) * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
3865  }
3866 
3867  if( !isDefined( level.max_zombie_func ) )
3868  {
3869  level.max_zombie_func = &‪zombie_utility::default_max_zombie_func;
3870  }
3871 
3872  n_zombie_count = [[ level.max_zombie_func ]]( max, n_round );
3873 
3874  return n_zombie_count;
3875 }
3876 
3877 // Add custom ai (quads, etc.) to zombie spawner arrays for spawning
3879 {
3880  foreach ( str_id, s in level.custom_ai_spawn_check_funcs )
3881  {
3882  if ( [[ s.func_check ]]() )
3883  {
3884  a_spawners = [[ s.func_get_spawners ]]();
3885  level.zombie_spawners = ArrayCombine( level.zombie_spawners, a_spawners, false, false );
3886 
3887  if ( ‪IS_TRUE( level.use_multiple_spawns ) )
3888  {
3889  foreach ( sp in a_spawners )
3890  {
3891  if ( IsDefined( sp.script_int ) )
3892  {
3893  if ( !IsDefined( level.zombie_spawn[ sp.script_int ] ) )
3894  {
3895  level.zombie_spawn[ sp.script_int ] = [];
3896  }
3897 
3898  if ( !IsInArray( level.zombie_spawn[ sp.script_int ], sp ) )
3899  {
3900  ‪ARRAY_ADD( level.zombie_spawn[ sp.script_int ], sp );
3901  }
3902  }
3903  }
3904  }
3905 
3906  if ( IsDefined( s.func_get_locations ) )
3907  {
3908  a_locations = [[ s.func_get_locations ]]();
3909  level.zm_loc_types[ "zombie_location" ] = ArrayCombine( level.zm_loc_types[ "zombie_location" ], a_locations, false, false );
3910  }
3911  }
3912  else
3913  {
3914  a_spawners = [[ s.func_get_spawners ]]();
3915 
3916  foreach ( sp in a_spawners )
3917  {
3918  ArrayRemoveValue( level.zombie_spawners, sp );
3919  }
3920 
3921  if ( ‪IS_TRUE( level.use_multiple_spawns ) )
3922  {
3923  foreach ( sp in a_spawners )
3924  {
3925  if ( IsDefined( sp.script_int ) && IsDefined( level.zombie_spawn[ sp.script_int ] ) )
3926  {
3927  ArrayRemoveValue( level.zombie_spawn[ sp.script_int ], sp );
3928  }
3929  }
3930  }
3931 
3932  if ( IsDefined( s.func_get_locations ) )
3933  {
3934  a_locations = [[ s.func_get_locations ]]();
3935 
3936  foreach ( s_loc in a_locations )
3937  {
3938  ArrayRemoveValue( level.zm_loc_types[ "zombie_location" ], s_loc );
3939  }
3940  }
3941  }
3942  }
3943 }
3944 
3945 function ‪register_custom_ai_spawn_check( str_id, func_check, func_get_spawners, func_get_locations )
3946 {
3947  if ( !IsDefined( level.custom_ai_spawn_check_funcs[str_id] ) )
3948  {
3949  level.custom_ai_spawn_check_funcs[ str_id ] = SpawnStruct();
3950  }
3951 
3952  level.custom_ai_spawn_check_funcs[ str_id ].func_check = func_check;
3953  level.custom_ai_spawn_check_funcs[ str_id ].func_get_spawners = func_get_spawners;
3954  level.custom_ai_spawn_check_funcs[ str_id ].func_get_locations = func_get_locations;
3955 }
3956 
3957 // TESTING: spawn one zombie at a time
3959 {
3960  while (true)
3961  {
3962  spawn_point = array::random( level.zm_loc_types[ "zombie_location" ] ); // grab a random spawner
3963 
3964  spawner = array::random(level.zombie_spawners);
3965  ai = ‪zombie_utility::spawn_zombie( spawner,spawner.targetname,spawn_point);
3966 
3967  ai waittill("death");
3968 
3969  wait 5;
3970  }
3971 }
3972 
3973 
3975 
3976 // round_text( text )
3977 // {
3978 // if( level.first_round )
3979 // {
3980 // intro = true;
3981 // }
3982 // else
3983 // {
3984 // intro = false;
3985 // }
3986 //
3987 // hud = create_simple_hud();
3988 // hud.horzAlign = "center";
3989 // hud.vertAlign = "middle";
3990 // hud.alignX = "center";
3991 // hud.alignY = "middle";
3992 // hud.y = -100;
3993 // hud.foreground = 1;
3994 // hud.fontscale = 16.0;
3995 // hud.alpha = 0;
3996 // hud.color = ( 1, 1, 1 );
3997 //
3998 // hud SetText( text );
3999 // hud FadeOverTime( 1.5 );
4000 // hud.alpha = 1;
4001 // wait( 1.5 );
4002 //
4003 // if( intro )
4004 // {
4005 // wait( 1 );
4006 // level notify( "intro_change_color" );
4007 // }
4008 //
4009 // hud FadeOverTime( 3 );
4010 // //hud.color = ( 0.8, 0, 0 );
4011 // hud.color = ( 0.21, 0, 0 );
4012 // wait( 3 );
4013 //
4014 // if( intro )
4015 // {
4016 // level waittill( "intro_hud_done" );
4017 // }
4018 //
4019 // hud FadeOverTime( 1.5 );
4020 // hud.alpha = 0;
4021 // wait( 1.5 );
4022 // hud destroy();
4023 // }
4024 
4025 
4026 // Allows the round to be paused. Displays a countdown timer.
4027 //
4029 {
4030  if ( !IsDefined( ‪delay ) )
4031  {
4032  ‪delay = 30;
4033  }
4034 
4035  level.countdown_hud = ‪zm_utility::create_counter_hud();
4036  level.countdown_hud SetValue( ‪delay );
4037  level.countdown_hud.color = ( 1, 1, 1 );
4038  level.countdown_hud.alpha = 1;
4039  level.countdown_hud FadeOverTime( 2.0 );
4040  wait( 2.0 );
4041 
4042  level.countdown_hud.color = ( 0.21, 0, 0 );
4043  level.countdown_hud FadeOverTime( 3.0 );
4044  wait(3);
4045 
4046  while (‪delay >= 1)
4047  {
4048  wait (1);
4049  ‪delay--;
4050  level.countdown_hud SetValue( ‪delay );
4051  }
4052 
4053  // Zero! Play end sound
4054  players = GetPlayers();
4055  for (i=0; i<players.size; i++ )
4056  {
4057  players[i] playlocalsound( "zmb_perks_packa_ready" );
4058  }
4059 
4060  level.countdown_hud FadeOverTime( 1.0 );
4061  level.countdown_hud.color = (1,1,1);
4062  level.countdown_hud.alpha = 0;
4063  wait( 1.0 );
4064 
4065  level.countdown_hud ‪zm_utility::destroy_hud();
4066 }
4067 
4068 
4069 // Zombie spawning
4070 //
4071 function ‪round_start()
4072 {
4073  if ( !isdefined( level.zombie_spawners) || level.zombie_spawners.size == 0 )
4074  {
4075  /#PrintLn("***Warning: No spawners found for this level.***");#/
4076  level ‪flag::set( "begin_spawning" );
4077  return;
4078  }
4079 /# PrintLn( "ZM >> round_start start" ); #/
4080 
4081  if ( IsDefined(level.round_prestart_func) )
4082  {
4083  [[ level.round_prestart_func ]]();
4084  }
4085  else
4086  {
4087  n_delay = 2;
4088 
4089  if ( IsDefined( level.zombie_round_start_delay ) )
4090  {
4091  n_delay = level.zombie_round_start_delay;
4092  }
4093 
4094  wait n_delay;
4095  }
4096 
4097  level.zombie_health = level.zombie_vars["zombie_health_start"];
4098 
4099  if( GetDvarInt( "scr_writeconfigstrings" ) == 1 )
4100  {
4101  wait(5);
4102  ExitLevel();
4103  return;
4104  }
4105 
4106  if ( level.zombie_vars["game_start_delay"] > 0 )
4107  {
4108  ‪round_pause( level.zombie_vars["game_start_delay"] );
4109  }
4110 
4111  level ‪flag::set( "begin_spawning" );
4112 
4113  if( !isDefined(level.round_spawn_func) )
4114  {
4115  level.round_spawn_func = &‪round_spawning;
4116  }
4117 
4118  if(!IsDefined(level.move_spawn_func))
4119  {
4120  level.move_spawn_func = &‪zm_utility::move_zombie_spawn_location;
4121  }
4122 
4123 /#
4124  if (GetDvarInt( "zombie_rise_test") )
4125  {
4126  level.round_spawn_func = &‪round_spawning_test; // FOR TESTING, one zombie at a time, no round advancement
4127  }
4128 #/
4129 
4130  if ( !isDefined(level.round_wait_func) )
4131  {
4132  level.round_wait_func = &‪round_wait;
4133  }
4134 
4135  if ( !IsDefined(level.round_think_func) )
4136  {
4137  level.round_think_func = &‪round_think;
4138  }
4139 
4140 
4141  level thread [[ level.round_think_func ]]();
4142 }
4143 
4144 //
4145 // Lets the players know that you need power to open these
4147 {
4148  self endon ("warning_dialog");
4149  ‪timer = 0;
4150 
4151  while(1)
4152  {
4154  players = GetPlayers();
4155  for(i = 0; i < players.size; i++)
4156  {
4157  dist = distancesquared(players[i].origin, self.origin );
4158  if(dist > 70*70)
4159  {
4160  ‪timer =0;
4161  continue;
4162  }
4163  while(dist < 70*70 && ‪timer < 3)
4164  {
4165  wait(0.5);
4166  ‪timer++;
4167  }
4168  if(dist > 70*70 && ‪timer >= 3)
4169  {
4170  self playsound("door_deny");
4171 
4172  players[i] ‪zm_audio::create_and_play_dialog( "general", "outofmoney" );
4173  wait(3);
4174  self notify ("warning_dialog");
4175  //iprintlnbold("warning_given");
4176  }
4177  }
4178  }
4179 }
4180 
4182 {
4183  players = GetPlayers();
4184  if( !IsDefined( players[0] ) )
4185  {
4186  level waittill( "first_player_ready" );
4187  }
4188 }
4189 
4190 //
4191 // Set the current round number hud display
4193 {
4194  level endon("end_game");
4195  if( isdefined(level.noRoundNumber) && level.noRoundNumber==true )
4196  {
4197  return;
4198  }
4199 
4200  if(!IsDefined(level.doground_nomusic))
4201  {
4202  level.doground_nomusic = 0;
4203  }
4204 
4205  if( level.first_round )
4206  {
4207  intro = true;
4208  if( isdefined( level._custom_intro_vox ) )
4209  {
4210  level thread [[level._custom_intro_vox]]();
4211  }
4212  else
4213  {
4214  level thread ‪play_level_start_vox_delayed();
4215  };
4216  }
4217  else
4218  {
4219  intro = false;
4220  }
4221 
4222  //Round Number Specific Lines
4223  if( level.round_number == 5 || level.round_number == 10 || level.round_number == 20 || level.round_number == 35 || level.round_number == 50 )
4224  {
4225  players = GetPlayers();
4226  rand = RandomIntRange(0,players.size);
4227  players[rand] thread ‪zm_audio::create_and_play_dialog( "general", "round_" + level.round_number );
4228  }
4229 
4230  if( intro )
4231  {
4232  if(‪IS_TRUE(level.host_ended_game))
4233  {
4234  return;
4235  }
4236 
4237  wait( 6.25 );
4238  level notify( "intro_hud_done" );
4239  wait( 2 );
4240 
4241  }
4242  else
4243  {
4244  wait( 2.5 );
4245  }
4246 
4247  ReportMTU(level.round_number); // In network debug instrumented builds, causes network spike report to generate.
4248 }
4249 
4250 
4251 // Flash the round display at the end of the round
4252 //
4253 function ‪round_over()
4254 {
4255  if( isdefined(level.noRoundNumber) && level.noRoundNumber==true )
4256  {
4257  return;
4258  }
4259 
4260  time = [[level.func_get_delay_between_rounds]]();
4261 
4262  players = GetPlayers();
4263  for ( player_index = 0; player_index < players.size; player_index++ )
4264  {
4265  if ( !IsDefined( players[player_index].pers["previous_distance_traveled"] ) )
4266  {
4267  players[player_index].pers["previous_distance_traveled"] = 0;
4268  }
4269  distanceThisRound = int( players[player_index].pers["distance_traveled"] - players[player_index].pers["previous_distance_traveled"] );
4270  players[player_index].pers["previous_distance_traveled"] = players[player_index].pers["distance_traveled"];
4271  players[player_index] IncrementPlayerStat("distance_traveled", distanceThisRound );
4272  if ( players[player_index].pers["team"] != "spectator" )
4273  {
4274  players[player_index] ‪recordRoundEndStats();
4275  }
4276  }
4277  RecordZombieRoundEnd();
4278  // waiting for the Pulse from lua
4279  wait( time );
4280 }
4281 
4283 {
4284  return( level.zombie_vars["zombie_between_round_time"] );
4285 }
4286 
4287 function ‪recordPlayerRoundWeapon(weapon, statname)
4288 {
4289  if (isDefined(weapon))
4290  {
4291  weaponIdx = GetBaseWeaponItemIndex(weapon);
4292  if (isDefined(weaponIdx))
4293  {
4294  self incrementplayerstat(statname, weaponIdx);
4295  }
4296  }
4297 }
4298 
4299 function ‪recordPrimaryWeaponsStats(base_stat_name, max_weapons)
4300 {
4301  current_weapons = self GetWeaponsListPrimaries();
4302  for (index = 0; index < max_weapons && index < current_weapons.size; index++)
4303  {
4304  ‪recordPlayerRoundWeapon(current_weapons[index], base_stat_name + index);
4305  }
4306 }
4307 
4308 function ‪recordRoundStartStats() //self == player
4309 {
4310  zoneName = self ‪zm_utility::get_current_zone();
4311  if( IsDefined(zoneName) )
4312  {
4313  self RecordZombieZone("startingZone", zoneName);
4314  }
4315 
4316  self incrementplayerstat("score", self.score);
4317  primaryWeapon = self GetCurrentWeapon();
4318 
4319  self ‪recordPrimaryWeaponsStats("roundStartPrimaryWeapon", 3);
4320  self RecordMapEvent(‪ZM_MAP_EVENT_ROUND_START, GetTime(), self.origin, level.round_number);
4321 }
4322 
4323 function ‪recordRoundEndStats() //self == player
4324 {
4325  zoneName = self ‪zm_utility::get_current_zone();
4326  if( IsDefined(zoneName) )
4327  {
4328  self RecordZombieZone( "endingZone", zoneName );
4329  }
4330 
4331  self ‪recordPrimaryWeaponsStats("roundEndPrimaryWeapon", 3);
4332  self RecordMapEvent(‪ZM_MAP_EVENT_ROUND_END, GetTime(), self.origin, level.round_number);
4333 }
4334 
4335 function ‪round_think( restart = false )
4336 {
4337 /# PrintLn( "ZM >> round_think start" ); #/
4338 
4339  level endon("end_round_think");
4340 
4341  if(!‪IS_TRUE(restart))
4342  {
4343  // Wait for blackscreen to end if in use
4344  if ( IsDefined( level.initial_round_wait_func ))
4345  [[level.initial_round_wait_func]]();
4346 
4347  if(!‪IS_TRUE(level.host_ended_game))
4348  {
4349  //unfreeze the players controls now
4350  players = GetPlayers();
4351  foreach(player in players)
4352  {
4353  if(!‪IS_TRUE(player.hostMigrationControlsFrozen))
4354  {
4355  player FreezeControls(false);
4356  /# println(" Unfreeze controls 8"); #/
4357  }
4358 
4359  // set the initial round_number
4360  player ‪zm_stats::set_global_stat( "rounds", level.round_number );
4361  }
4362  }
4363  }
4364 
4365  SetRoundsPlayed( level.round_number );
4366 
4367  for( ;; )
4368  {
4370  //designed by prod DT#36173
4371  maxreward = 50 * level.round_number;
4372  if ( maxreward > 500 )
4373  maxreward = 500;
4374  level.zombie_vars["rebuild_barrier_cap_per_round"] = maxreward;
4376 
4377  level.pro_tips_start_time = GetTime();
4378  level.zombie_last_run_time = GetTime(); // Resets the last time a zombie ran
4379 
4380  if ( IsDefined( level.zombie_round_change_custom ) )
4381  {
4382  [[ level.zombie_round_change_custom ]]();
4383  }
4384  else
4385  {
4386  if( !‪IS_TRUE( level.sndMusicSpecialRound ) )
4387  {
4388  if( ‪IS_TRUE(level.sndGotoRoundOccurred))
4389  level.sndGotoRoundOccurred = false;
4390  else if( level.round_number == 1 )
4391  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_start_first" );
4392  else if( level.round_number <= 5 )
4393  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_start" );
4394  else
4395  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_start_short" );
4396  }
4397  ‪round_one_up();
4398  // round_text( &"ZOMBIE_ROUND_BEGIN" );
4399  }
4400 
4402 
4403  players = GetPlayers();
4404  array::thread_all( players, &‪zm_blockers::rebuild_barrier_reward_reset );
4405 
4406  if(!‪IS_TRUE(level.headshots_only) && !restart ) //no grenades for headshot only mode, or when grief restarts the round after everyone dies
4407  {
4408  level thread ‪award_grenades_for_survivors();
4409  }
4410 
4411  /# PrintLn( "ZM >> round_think, round="+level.round_number+", player_count=" + players.size ); #/
4412 
4413  level.round_start_time = GetTime();
4414 
4415  //Not great fix for this being zero - which it should NEVER be! (post ship - PETER)
4416  while( level.zm_loc_types[ "zombie_location" ].size <= 0 )
4417  {
4418  wait( 0.1 );
4419  }
4420 
4421  /#
4422  //Reset spawn counter for zones
4423  zkeys = GetArrayKeys( level.zones );
4424  for ( i = 0; i < zkeys.size; i++ )
4425  {
4426  zoneName = zkeys[i];
4427  level.zones[zoneName].round_spawn_count = 0;
4428  }
4429  #/
4430 
4431  level thread [[level.round_spawn_func]]();
4432 
4433  level notify( "start_of_round" );
4434  RecordZombieRoundStart();
4435 
4436  players = GetPlayers();
4437  for ( index = 0; index < players.size; index++ )
4438  {
4439  players[index] ‪recordRoundStartStats();
4440  }
4441  if(isDefined(level.round_start_custom_func))
4442  {
4443  [[level.round_start_custom_func]]();
4444  }
4445 
4446  [[level.round_wait_func]]();
4447 
4448  level.first_round = false;
4449  level notify( "end_of_round" );
4450 
4451  UploadStats();
4452 
4453  if(isDefined(level.round_end_custom_logic))
4454  {
4455  [[level.round_end_custom_logic]]();
4456  }
4457 
4458  players = GetPlayers();
4459 
4460  // PORTIZ 7/27/16: now that no_end_game_check is being used more regularly, I was tempted to remove/change this because it seems to arbitrarily add
4461  // the revival of last stand players on top of whatever mechanic toggled the bool in the first place. however, it doesn't seem to do harm, and I'd rather avoid
4462  // affecting these core systems if possible. for example, is there badness if a round transitions/starts and ALL players are in last stand? this can be revisited if
4463  // any specific bugs/exploits arise from it...
4464  if( ‪IS_TRUE(level.no_end_game_check) )
4465  {
4466  level thread ‪last_stand_revive();
4467  level thread ‪spectators_respawn();
4468  }
4469  else if ( 1 != players.size )
4470  {
4471  level thread ‪spectators_respawn();
4472  //level thread last_stand_revive();
4473  }
4474 
4475  players = GetPlayers();
4476  array::thread_all( players, &‪zm_pers_upgrades_system::round_end );
4477 
4478  if ( int(level.round_number / 5) * 5 == level.round_number )
4479  {
4480  level ‪clientfield::set( "round_complete_time", int( ( level.time - level.n_gameplay_start_time + 500 ) / 1000 ) );
4481  level ‪clientfield::set( "round_complete_num", level.round_number );
4482  }
4483 
4484  //
4485  // Increase the zombie move speed
4486  //level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"];
4487 
4488  if( level.gamedifficulty == 0 ) //easy
4489  {
4490  level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier_easy"];
4491  }
4492  else //normal
4493  {
4494  level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"];
4495  }
4496 
4498  SetRoundsPlayed( ‪get_round_number() );
4499 
4500  // Here's the difficulty increase over time area
4501  //level.zombie_vars["zombie_spawn_delay"] = get_zombie_spawn_delay( level.round_number );
4502  level.zombie_vars["zombie_spawn_delay"] = [[level.func_get_zombie_spawn_delay]]( ‪get_round_number() );
4503 
4504  // round_text( &"ZOMBIE_ROUND_END" );
4505 
4506  matchUTCTime = GetUTC();
4507 
4508  players = GetPlayers(); // delay in round_over allows a player that leaves during that time to remain in the players array - leading to round based SRES. Bad.
4509  foreach(player in players)
4510  {
4511  if ( level.curr_gametype_affects_rank && ‪get_round_number() > (3 + level.start_round) )
4512  {
4513  player ‪zm_stats::add_client_stat( "weighted_rounds_played",‪get_round_number() );
4514  }
4515  player ‪zm_stats::set_global_stat( "rounds", ‪get_round_number() );
4516 
4517  // update the game played time
4518  player ‪zm_stats::update_playing_utc_time( matchUTCTime );
4519 
4520  // Reset the health if necessary
4521  player ‪zm_perks::perk_set_max_health_if_jugg( "health_reboot", true, true );
4522 
4523  //XP event stuff
4524  for ( i = 0; i < 4; i++ )
4525  {
4526  player.number_revives_per_round[i] = 0;
4527  }
4528 
4529  if ( IsAlive( player ) && player.sessionstate != "spectator" && !‪IS_TRUE( level.skip_alive_at_round_end_xp ) )
4530  {
4531  player ‪zm_stats::increment_challenge_stat( "SURVIVALIST_SURVIVE_ROUNDS" );
4532 
4533  score_number = ‪get_round_number() - 1;
4534  if ( score_number < 1 )
4535  {
4536  score_number = 1;
4537  }
4538  else if ( score_number > 20 )
4539  {
4540  score_number = 20;
4541  }
4542  ‪scoreevents::processScoreEvent( ("alive_at_round_end_" + score_number), player );
4543  }
4544  }
4545 
4546  if( isdefined( level.check_quickrevive_hotjoin ) )
4547  {
4548  [[ level.check_quickrevive_hotjoin ]]();
4549  }
4550 
4551  level.round_number = ‪get_round_number();
4552 
4553  level ‪round_over();
4554 
4555  level notify( "between_round_over" );
4556 
4557  level.skip_alive_at_round_end_xp = false;
4558 
4559  restart = false;
4560  }
4561 }
4562 
4563 
4565 {
4566  players = GetPlayers();
4567 
4568  for (i = 0; i < players.size; i++)
4569  {
4570  if (!players[i].‪is_zombie && !‪IS_TRUE(players[i].altbody) && !players[i] ‪laststand::player_is_in_laststand() )
4571  {
4572  lethal_grenade = players[i] ‪zm_utility::get_player_lethal_grenade();
4573  if( !players[i] HasWeapon( lethal_grenade ) )
4574  {
4575  players[i] GiveWeapon( lethal_grenade );
4576  players[i] SetWeaponAmmoClip( lethal_grenade, 0 );
4577  }
4578 
4579  frac = players[i] GetFractionMaxAmmo( lethal_grenade );
4580  if ( frac < .25 )
4581  {
4582  players[i] SetWeaponAmmoClip( lethal_grenade, 2 );
4583  }
4584  else if ( frac < .5 )
4585  {
4586  players[i] SetWeaponAmmoClip( lethal_grenade, 3 );
4587  }
4588  else
4589  {
4590  players[i] SetWeaponAmmoClip( lethal_grenade, 4 );
4591  }
4592  }
4593  }
4594 }
4595 
4596 
4597 // Calculate the correct spawn delay for the round number
4598 function ‪get_zombie_spawn_delay( n_round )
4599 {
4600  if ( n_round > 60 ) // Don't let this loop too many times
4601  {
4602  n_round = 60;
4603  }
4604 
4605  // Decay rate
4606  n_multiplier = 0.95;
4607  // Base delay
4608  switch( level.players.size )
4609  {
4610  case 1:
4611  n_delay = 2.0; // 0.95 == 0.1 @ round 60
4612  break;
4613  case 2:
4614  n_delay = 1.5; // 0.95 == 0.1 @ round 54
4615  break;
4616  case 3:
4617  n_delay = 0.89; // 0.95 == 0.1 @ round 60
4618  break;
4619  case 4:
4620  n_delay = 0.67; // 0.95 == 0.1 @ round 60
4621  break;
4622  }
4623 
4624  for( i=1; i<n_round; i++ )
4625  {
4626  n_delay *= n_multiplier;
4627 
4628  if ( n_delay <= 0.1 )
4629  {
4630  n_delay = 0.1;
4631  break;
4632  }
4633  }
4634 
4635  return n_delay;
4636 }
4637 
4638 
4639 /#
4641 {
4642  level notify( "failsafe_debug_stop" );
4643  level endon( "failsafe_debug_stop" );
4644 
4645  start = GetTime();
4646  level.chunk_time = 0;
4647 
4648  while ( 1 )
4649  {
4650  level.failsafe_time = GetTime() - start;
4651 
4652  if ( isdefined( self.lastchunk_destroy_time ) )
4653  {
4654  level.chunk_time = GetTime() - self.lastchunk_destroy_time;
4655  }
4657  }
4658 }
4659 #/
4660 
4661 /#
4663 {
4664  while ( true )
4665  {
4666  if( GetDvarInt("zombiemode_debug_zombie_count") )
4667  {
4668  if( !isdefined( level.debug_zombie_count_hud ) )
4669  {
4670  level.debug_zombie_count_hud= NewDebugHudElem();
4671  level.debug_zombie_count_hud.alignX = "right";
4672  level.debug_zombie_count_hud.x = 100;
4673  level.debug_zombie_count_hud.y = 10;
4674  level.debug_zombie_count_hud SetText( "COUNTS" );
4675  }
4676 
4678  number_to_kill = level.zombie_total;
4679  level.debug_zombie_count_hud SetText( "ALIVE=" + currentCount + " / TOGO=" + number_to_kill );
4680  //println( "ALIVE=" + currentCount + " / TOGO=" + number_to_kill );
4681  }
4682  else
4683  {
4684  if( isdefined( level.debug_zombie_count_hud ) )
4685  {
4686  level.debug_zombie_count_hud Destroy();
4687  level.debug_zombie_count_hud = undefined;
4688  }
4689  }
4690 
4691  wait( 0.1 );
4692  }
4693 }
4694 #/
4695 
4696 
4697 // Waits for the time and the ai to die
4698 function ‪round_wait()
4699 {
4700  level endon("restart_round");
4701 /#
4702  level endon( "kill_round" );
4703 #/
4704 
4705 /#
4706  if (GetDvarInt( "zombie_rise_test") )
4707  {
4708  level waittill("forever"); // TESTING: don't advance rounds
4709  }
4710 #/
4711 
4712  if ( ‪cheat_enabled( 2 ) )
4713  {
4714  level waittill("forever");
4715  }
4716 
4717 /#
4718  if ( GetDvarInt( "zombie_default_max" ) == 0 )
4719  {
4720  level waittill( "forever" );
4721  }
4722 #/
4723 
4724  wait( 1 );
4725 
4726 /#
4727  level thread ‪print_zombie_counts();
4728  level thread ‪sndMusicOnKillRound();
4729 #/
4730 
4731  while( 1 )
4732  {
4733  should_wait = ( ‪zombie_utility::get_current_zombie_count() > 0 || level.zombie_total > 0 || level.intermission );
4734  if( !should_wait )
4735  {
4736  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_end" );
4737  return;
4738  }
4739 
4740  if( level ‪flag::get( "end_round_wait" ) )
4741  {
4742  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_end" );
4743  return;
4744  }
4745  wait( 1.0 );
4746  }
4747 }
4748 //To make sure music plays when using debug to switch rounds
4750 {
4751  level endon( "end_of_round" );
4752 
4753  level waittill( "kill_round" );
4754  level thread ‪zm_audio::sndMusicSystem_PlayState( "round_end" );
4755 }
4756 
4757 
4758 
4759 function ‪zombify_player() // self = player
4760 {
4762 
4763  self RecordPlayerDeathZombies();
4764 
4765  if ( IsDefined( level.deathcard_spawn_func ) )
4766  {
4767  self [[level.deathcard_spawn_func]]();
4768  }
4769 
4770  if( isdefined( level.func_clone_plant_respawn ) && isdefined( self.s_clone_plant ) )
4771  {
4772  self [[level.func_clone_plant_respawn]]();
4773  return;
4774  }
4775 
4776  if( !IsDefined( level.zombie_vars["zombify_player"] ) || !level.zombie_vars["zombify_player"] )
4777  {
4778  self thread ‪spawnSpectator();
4779  return;
4780  }
4781 
4782  self.ignoreme = true;
4783  self.is_zombie = true;
4784  self.zombification_time = GetTime();
4785 
4786  self.team = level.zombie_team;
4787  self notify( "zombified" );
4788 
4789  if( IsDefined( self.revivetrigger ) )
4790  {
4791  self.revivetrigger Delete();
4792  }
4793  self.revivetrigger = undefined;
4794 
4795  self setMoveSpeedScale( 0.3 );
4796  self reviveplayer();
4797 
4798  self TakeAllWeapons();
4799  self DisableWeaponCycling();
4800  self DisableOffhandWeapons();
4801 
4802  self thread ‪zombie_utility::zombie_eye_glow();
4803 
4804  self thread ‪playerzombie_player_damage();
4805  self thread ‪playerzombie_soundboard();
4806 }
4807 
4809 {
4810  self endon( "death" );
4811  self endon( "disconnect" );
4812 
4813  self thread ‪playerzombie_infinite_health(); // manually keep regular health up
4814  self.zombiehealth = level.zombie_health;
4815 
4816  // enable PVP damage on this guy
4817  // self EnablePvPDamage();
4818 
4819  while( 1 )
4820  {
4821  self waittill( "damage", amount, attacker, directionVec, point, type );
4822 
4823  if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
4824  {
4826  continue;
4827  }
4828 
4829  self.zombiehealth -= amount;
4830 
4831  if( self.zombiehealth <= 0 )
4832  {
4833  // "down" the zombie
4834  self thread ‪playerzombie_downed_state();
4835  self waittill( "playerzombie_downed_state_done" );
4836  self.zombiehealth = level.zombie_health;
4837  }
4838  }
4839 }
4840 
4842 {
4843  self endon( "death" );
4844  self endon( "disconnect" );
4845 
4846  downTime = 15;
4847 
4848  ‪startTime = GetTime();
4849  endTime = ‪startTime +( downTime * 1000 );
4850 
4851  self thread ‪playerzombie_downed_hud();
4852 
4853  self.playerzombie_soundboard_disable = true;
4855  self DisableWeapons();
4856  self AllowStand( false );
4857  self AllowCrouch( false );
4858  self AllowProne( true );
4859 
4860  while( GetTime() < endTime )
4861  {
4863  }
4864 
4865  self.playerzombie_soundboard_disable = false;
4866  self thread ‪zombie_utility::zombie_eye_glow();
4867  self EnableWeapons();
4868  self AllowStand( true );
4869  self AllowCrouch( false );
4870  self AllowProne( false );
4871 
4872  self notify( "playerzombie_downed_state_done" );
4873 }
4874 
4876 {
4877  self endon( "death" );
4878  self endon( "disconnect" );
4879 
4880  text = NewClientHudElem( self );
4881  text.alignX = "center";
4882  text.alignY = "middle";
4883  text.horzAlign = "user_center";
4884  text.vertAlign = "user_bottom";
4885  text.foreground = true;
4886  text.font = "default";
4887  text.fontScale = 1.8;
4888  text.alpha = 0;
4889  text.color = ( 1.0, 1.0, 1.0 );
4890  text SetText( &"ZOMBIE_PLAYERZOMBIE_DOWNED" );
4891 
4892  text.y = -113;
4893  if( self IsSplitScreen() )
4894  {
4895  text.y = -137;
4896  }
4897 
4898  text FadeOverTime( 0.1 );
4899  text.alpha = 1;
4900 
4901  self waittill( "playerzombie_downed_state_done" );
4902 
4903  text FadeOverTime( 0.1 );
4904  text.alpha = 0;
4905 }
4906 
4908 {
4909  self endon( "death" );
4910  self endon( "disconnect" );
4911 
4912  bighealth = 100000;
4913 
4914  while( 1 )
4915  {
4916  if( self.health < bighealth )
4917  {
4918  self.health = bighealth;
4919  }
4920 
4921  wait( 0.1 );
4922  }
4923 }
4924 
4926 {
4927  self endon( "death" );
4928  self endon( "disconnect" );
4929 
4930  self.playerzombie_soundboard_disable = false;
4931 
4932  self.buttonpressed_use = false;
4933  self.buttonpressed_attack = false;
4934  self.buttonpressed_ads = false;
4935 
4936  self.useSound_waitTime = 3 * 1000; // milliseconds
4937  self.useSound_nextTime = GetTime();
4938  useSound = "playerzombie_usebutton_sound";
4939 
4940  self.attackSound_waitTime = 3 * 1000;
4941  self.attackSound_nextTime = GetTime();
4942  attackSound = "playerzombie_attackbutton_sound";
4943 
4944  self.adsSound_waitTime = 3 * 1000;
4945  self.adsSound_nextTime = GetTime();
4946  adsSound = "playerzombie_adsbutton_sound";
4947 
4948  self.inputSound_nextTime = GetTime(); // don't want to be able to do all sounds at once
4949 
4950  while( 1 )
4951  {
4952  if( self.playerzombie_soundboard_disable )
4953  {
4955  continue;
4956  }
4957 
4958  if( self UseButtonPressed() )
4959  {
4960  if( self ‪can_do_input( "use" ) )
4961  {
4962  self thread ‪playerzombie_play_sound( useSound );
4963  self thread ‪playerzombie_waitfor_buttonrelease( "use" );
4964  self.useSound_nextTime = GetTime() + self.useSound_waitTime;
4965  }
4966  }
4967  else if( self AttackButtonPressed() )
4968  {
4969  if( self ‪can_do_input( "attack" ) )
4970  {
4971  self thread ‪playerzombie_play_sound( attackSound );
4972  self thread ‪playerzombie_waitfor_buttonrelease( "attack" );
4973  self.attackSound_nextTime = GetTime() + self.attackSound_waitTime;
4974  }
4975  }
4976  else if( self AdsButtonPressed() )
4977  {
4978  if( self ‪can_do_input( "ads" ) )
4979  {
4980  self thread ‪playerzombie_play_sound( adsSound );
4981  self thread ‪playerzombie_waitfor_buttonrelease( "ads" );
4982  self.adsSound_nextTime = GetTime() + self.adsSound_waitTime;
4983  }
4984  }
4985 
4987  }
4988 }
4989 
4990 function ‪can_do_input( inputType )
4991 {
4992  if( GetTime() < self.inputSound_nextTime )
4993  {
4994  return false;
4995  }
4996 
4997  canDo = false;
4998 
4999  switch( inputType )
5000  {
5001  case "use":
5002  if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_use )
5003  {
5004  canDo = true;
5005  }
5006  break;
5007 
5008  case "attack":
5009  if( GetTime() >= self.attackSound_nextTime && !self.buttonpressed_attack )
5010  {
5011  canDo = true;
5012  }
5013  break;
5014 
5015  case "ads":
5016  if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_ads )
5017  {
5018  canDo = true;
5019  }
5020  break;
5021 
5022  default:
5023  ASSERTMSG( "can_do_input(): didn't recognize inputType of " + inputType );
5024  break;
5025  }
5026 
5027  return canDo;
5028 }
5029 
5031 {
5032  self ‪zm_utility::play_sound_on_ent( alias );
5033 }
5034 
5036 {
5037  if( inputType != "use" && inputType != "attack" && inputType != "ads" )
5038  {
5039  ASSERTMSG( "playerzombie_waitfor_buttonrelease(): inputType of " + inputType + " is not recognized." );
5040  return;
5041  }
5042 
5043  notifyString = "waitfor_buttonrelease_" + inputType;
5044  self notify( notifyString );
5045  self endon( notifyString );
5046 
5047  if( inputType == "use" )
5048  {
5049  self.buttonpressed_use = true;
5050  while( self UseButtonPressed() )
5051  {
5053  }
5054  self.buttonpressed_use = false;
5055  }
5056 
5057  else if( inputType == "attack" )
5058  {
5059  self.buttonpressed_attack = true;
5060  while( self AttackButtonPressed() )
5061  {
5063  }
5064  self.buttonpressed_attack = false;
5065  }
5066 
5067  else if( inputType == "ads" )
5068  {
5069  self.buttonpressed_ads = true;
5070  while( self AdsButtonPressed() )
5071  {
5073  }
5074  self.buttonpressed_ads = false;
5075  }
5076 }
5077 
5079 {
5080  self notify( "new_ignore_attacker" );
5081  self endon( "new_ignore_attacker" );
5082  self endon( "disconnect" );
5083 
5084  if( !isDefined( level.ignore_enemy_timer ) )
5085  {
5086  level.ignore_enemy_timer = 0.4;
5087  }
5088 
5089  wait( level.ignore_enemy_timer );
5090 
5091  self.ignoreAttacker = undefined;
5092 }
5093 
5094 function ‪player_damage_override_cheat( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime )
5095 {
5096  ‪player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5097  return 0;
5098 }
5099 
5100 
5101 //
5102 // player_damage_override
5103 // MUST return the value of the damage override
5104 //
5105 // MM (08/10/09) - Removed calls to PlayerDamageWrapper because it's always called in
5106 // Callback_PlayerDamage now. We just need to return the damage.
5107 //
5108 function ‪player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime )
5109 {
5110  iDamage = self ‪check_player_damage_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5111 
5112  if( self.scene_takedamage === false )
5113  {
5114  return 0;
5115  }
5116 
5117  if ( IsDefined( eAttacker ) && ‪IS_TRUE( eAttacker.b_aat_fire_works_weapon ) )
5118  {
5119  return 0;
5120  }
5121 
5122  if ( ‪IS_TRUE( self.use_adjusted_grenade_damage ) )
5123  {
5124  self.use_adjusted_grenade_damage = undefined;
5125  if( ( self.health > iDamage ) )
5126  {
5127  return iDamage;
5128  }
5129  }
5130 
5131  if ( !iDamage )
5132  {
5133  return 0;
5134  }
5135 
5136  // WW (8/20/10) - Sledgehammer fix for Issue 43492. This should stop the player from taking any damage while in laststand
5138  {
5139  return 0;
5140  }
5141 
5142  if ( isDefined( eInflictor ) )
5143  {
5144  if ( ‪IS_TRUE( eInflictor.water_damage ) )
5145  {
5146  return 0;
5147  }
5148  }
5149 
5150  if ( isDefined( eAttacker ) )
5151  {
5152  if( ‪IS_EQUAL( eAttacker.owner, self ) )
5153  {
5154  return 0;
5155  }
5156 
5157  if( isDefined( self.ignoreAttacker ) && self.ignoreAttacker == eAttacker )
5158  {
5159  return 0;
5160  }
5161 
5162  // AR (5/30/12) - Stop Zombie players from damaging other Zombie players
5163  if ( ‪IS_TRUE( self.‪is_zombie ) && ‪IS_TRUE( eAttacker.is_zombie ) )
5164  {
5165  return 0;
5166  }
5167 
5168  if( (isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie) )
5169  {
5170  self.ignoreAttacker = eAttacker;
5171  self thread ‪remove_ignore_attacker();
5172 
5173  if ( isdefined( eAttacker.custom_damage_func ) )
5174  {
5175  iDamage = eAttacker [[ eAttacker.custom_damage_func ]]( self );
5176  }
5177  }
5178 
5179  eAttacker notify( "hit_player" );
5180 
5181  if ( isdefined( eAttacker ) && isdefined( eAttacker.func_mod_damage_override ) )
5182  {
5183  sMeansOfDeath = eAttacker [[ eAttacker.func_mod_damage_override ]]( eInflictor, sMeansOfDeath, weapon );
5184  }
5185 
5186  if( sMeansOfDeath != "MOD_FALLING" )
5187  {
5188  self thread ‪playSwipeSound( sMeansOfDeath, eattacker );
5189  if( ‪IS_TRUE(eattacker.is_zombie) || IsPlayer(eAttacker) )
5190  self PlayRumbleOnEntity( "damage_heavy" );
5191 
5192  if( ‪IS_TRUE(eattacker.is_zombie) )
5193  {
5194  self ‪zm_audio::create_and_play_dialog( "general", "attacked" );
5195  }
5196 
5197  canExert = true;
5198 
5199  if ( ‪IS_TRUE( level.pers_upgrade_flopper ) )
5200  {
5201  // If the player has persistent flopper power, then no exert on explosion
5202  if ( ‪IS_TRUE( self.pers_upgrades_awarded[ "flopper" ] ) )
5203  {
5204  canExert = ( sMeansOfDeath != "MOD_PROJECTILE_SPLASH" && sMeansOfDeath != "MOD_GRENADE" && sMeansOfDeath != "MOD_GRENADE_SPLASH" );
5205  }
5206  }
5207 
5208  if ( ‪IS_TRUE( canExert ) )
5209  {
5210  if(RandomIntRange(0,1) == 0 )
5211  {
5212  self thread ‪zm_audio::playerExert( "hitmed" );
5213  //self thread zm_audio::create_and_play_dialog( "general", "hitmed" );
5214  }
5215  else
5216  {
5217  self thread ‪zm_audio::playerExert( "hitlrg" );
5218  //self thread zm_audio::create_and_play_dialog( "general", "hitlrg" );
5219  }
5220  }
5221  }
5222  }
5223 
5224  //Audio(RG:2/1/2016) adding underwater drowning exert.
5225  if ( isDefined( sMeansOfDeath) && sMeansOfDeath == "MOD_DROWN")
5226  {
5227  self thread ‪zm_audio::playerExert( "drowning", true );
5228  self.voxDrowning = true;
5229  }
5230 
5231  if( isdefined( level.perk_damage_override ) )
5232  {
5233  foreach( func in level.perk_damage_override )
5234  {
5235  n_damage = self [[ func ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5236  if( isdefined( n_damage ) )
5237  {
5238  iDamage = n_damage;
5239  }
5240  }
5241  }
5242  finalDamage = iDamage;
5243 
5244 
5245  // claymores and freezegun shatters, like bouncing betties, harm no players
5246  if ( ‪zm_utility::is_placeable_mine( weapon ) )
5247  {
5248  return 0;
5249  }
5250 
5251  if ( isDefined( self.‪player_damage_override ) )
5252  {
5253  self thread [[ self.player_damage_override ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5254  }
5255 
5256  // exploding quads should not kill player
5257  if ( IsDefined( eInflictor ) && IsDefined( eInflictor.archetype ) && eInflictor.archetype == ‪ARCHETYPE_ZOMBIE_QUAD )
5258  {
5259  if ( sMeansOfDeath == "MOD_EXPLOSIVE" )
5260  {
5261  if ( self.health > 75 )
5262  {
5263  return 75;
5264  }
5265  }
5266  }
5267 
5268  // Players can't die from cooked grenade if trhey have the bgb Danger Closet
5269  if ( sMeansOfDeath == "MOD_SUICIDE" && self ‪bgb::is_enabled( "zm_bgb_danger_closest" ) )
5270  {
5271  return 0;
5272  }
5273 
5274  if ( sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" || sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" || sMeansOfDeath == "MOD_EXPLOSIVE" )
5275  {
5276  if( self ‪bgb::is_enabled( "zm_bgb_danger_closest" ) )
5277  {
5278  return 0;
5279  }
5280 
5281  // player explosive splash damage (caps explosive damage), fixes raygun damage being fatal (or grenades) when damaging yourself
5282  if ( !‪IS_TRUE( self.‪is_zombie ) )
5283  {
5284  // Don't do this for projectile damage coming from zombies
5285  if ( !isdefined( eAttacker ) || ( !‪IS_TRUE( eAttacker.is_zombie ) && !‪IS_TRUE( eAttacker.b_override_explosive_damage_cap ) ) )
5286  {
5287  // Only do it for ray gun
5288  if( isdefined(weapon.name) && ((weapon.name == "ray_gun") || ( weapon.name == "ray_gun_upgraded" )) )
5289  {
5290  // Clamp it, we don't want to increase the damage from player raygun splash damage or grenade splash damage
5291  // Don't create more damage than we are trying to apply
5292  if ( ( self.health > 25 ) && ( iDamage > 25 ) )
5293  {
5294  return 25;
5295  }
5296  }
5297  else if ( ( self.health > 75 ) && ( iDamage > 75 ) )
5298  {
5299  return 75;
5300  }
5301  }
5302  }
5303  }
5304 
5305  if( iDamage < self.health )
5306  {
5307  if ( IsDefined( eAttacker ) )
5308  {
5309  if( IsDefined( level.custom_kill_damaged_VO ) )
5310  {
5311  eAttacker thread [[ level.custom_kill_damaged_VO ]]( self );
5312  }
5313  else
5314  {
5315  eAttacker.sound_damage_player = self;
5316  }
5317 
5318  if( ‪IS_TRUE( eAttacker.missingLegs ) )
5319  {
5320  self ‪zm_audio::create_and_play_dialog( "general", "crawl_hit" );
5321  }
5322  }
5323 
5324  // MM (08/10/09)
5325  return finalDamage;
5326  }
5327 
5328  //player died
5329  if( isdefined( eAttacker ) )
5330  {
5331  if(isDefined(eAttacker.animname) && eAttacker.animname == "zombie_dog")
5332  {
5333  self ‪zm_stats::increment_client_stat( "killed_by_zdog" );
5334  self ‪zm_stats::increment_player_stat( "killed_by_zdog" );
5335  }
5336  else if(‪IS_TRUE(eAttacker.is_avogadro))
5337  {
5338  self ‪zm_stats::increment_client_stat( "killed_by_avogadro", false );
5339  self ‪zm_stats::increment_player_stat( "killed_by_avogadro" );
5340  }
5341  }
5342 
5343  self thread ‪clear_path_timers();
5344 
5345  if( level.intermission )
5346  {
5347  level waittill( "forever" );
5348  }
5349 
5350  // AR (3/7/12) - Keep track of which player killed player in Zombify modes like Cleansed / Turned
5351  // Confirmed with Alex
5352  if ( level.scr_zm_ui_gametype == "zcleansed" && iDamage > 0 )
5353  {
5354  if ( IsDefined( eAttacker ) && IsPlayer( eAttacker ) && eAttacker.team != self.team && ( ( !‪IS_TRUE( self.laststand ) && !self ‪laststand::player_is_in_laststand() ) || !IsDefined( self.last_player_attacker ) ) )
5355  {
5356  // Restore Health To Zombie Player
5357  //--------------------------------
5358  if ( IsDefined( eAttacker.maxhealth ) && ‪IS_TRUE( eAttacker.is_zombie ) )
5359  {
5360  eAttacker.health = eAttacker.maxhealth;
5361  }
5362 
5363  //self.last_player_attacker = eAttacker;
5364 
5365  if ( IsDefined( level.player_kills_player ) )
5366  {
5367  self thread [[ level.player_kills_player]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5368  }
5369  }
5370  }
5371 
5372  if ( self.lives > 0 && self HasPerk( ‪PERK_WHOSWHO ) )
5373  {
5374  self.lives--;
5375  if ( IsDefined( level.whoswho_laststand_func ) )
5376  {
5377  self thread [[ level.whoswho_laststand_func]]();
5378  return 0;
5379  }
5380  }
5381 
5382  players = GetPlayers();
5383  count = 0;
5384  for( i = 0; i < players.size; i++ )
5385  {
5386  if( players[i] == self || players[i].‪is_zombie || players[i] ‪laststand::player_is_in_laststand() || players[i].sessionstate == "spectator" )
5387  {
5388  count++;
5389  }
5390  }
5391 
5392  if( count < players.size || (isDefined(level._game_module_game_end_check) && ![[level._game_module_game_end_check]]()) )
5393  {
5394  if ( IsDefined( self.lives ) && self.lives > 0 && ‪IS_TRUE( level.force_solo_quick_revive ) && self HasPerk( ‪PERK_QUICK_REVIVE ) )
5395  {
5396  self thread ‪wait_and_revive();
5397  }
5398 
5399  // MM (08/10/09)
5400  return finalDamage;
5401  }
5402 
5403  // PORTIZ 7/27/16: added level.no_end_game_check here, because if it's true by this point, this function will end up returning finalDamage anyway. additionally,
5404  // no_end_game_check has been updated to support incrementing/decrementing, which makes it more robust than a single level.check_end_solo_game_override as more
5405  // mechanics are introduced that require solo players to go into last stand instead of losing the game immediately
5406  if ( players.size == 1 && level ‪flag::get( "solo_game" ) )
5407  {
5408  if ( ‪IS_TRUE( level.no_end_game_check ) || ( isdefined( level.check_end_solo_game_override ) && [[level.check_end_solo_game_override]]() ) )
5409  {
5410  return finalDamage;
5411  }
5412  else if ( self.lives == 0 || !self HasPerk( ‪PERK_QUICK_REVIVE ) )
5413  {
5414  self.intermission = true;
5415  }
5416  }
5417 
5418 
5419 
5420 
5421  // WW (01/05/11): When a two players enter a system link game and the client drops the host will be treated as if it was a solo game
5422  // when it wasn't. This led to SREs about undefined and int being compared on death (self.lives was never defined on the host). While
5423  // adding the check for the solo game flag we found that we would have to create a complex OR inside of the if check below. By breaking
5424  // the conditions out in to their own variables we keep the complexity without making it look like a mess.
5425  solo_death = ( players.size == 1 && level ‪flag::get( "solo_game" ) && ( self.lives == 0 || !self HasPerk(‪PERK_QUICK_REVIVE) ) ); // there is only one player AND the flag is set AND self.lives equals 0
5426  non_solo_death = ( ( count > 1 || ( players.size == 1 && !level ‪flag::get( "solo_game" ) ) ) /*&& !level.is_zombie_level*/ ); // the player size is greater than one OR ( players.size equals 1 AND solo flag isn't set ) AND not a zombify game level
5427  if ( (solo_death || non_solo_death) && !‪IS_TRUE(level.no_end_game_check ) ) // if only one player on their last life or any game that started with more than one player
5428  {
5429  level notify("stop_suicide_trigger");
5430  self AllowProne( true ); //just in case
5431  self thread ‪zm_laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime );
5432  if( !isdefined( vDir ) )
5433  {
5434  vDir = ( 1.0, 0.0, 0.0 );
5435  }
5436  self FakeDamageFrom(vDir);
5437 
5438  level notify("last_player_died");
5439  if ( isdefined(level.custom_player_fake_death) )
5440  self thread [[level.custom_player_fake_death]](vDir, sMeansOfDeath);
5441  else
5442  self thread ‪player_fake_death();
5443  }
5444 
5445  if( count == players.size && !‪IS_TRUE( level.no_end_game_check ) )
5446  {
5447  if ( players.size == 1 && level ‪flag::get( "solo_game" ))
5448  {
5449  if ( self.lives == 0 || !self HasPerk(‪PERK_QUICK_REVIVE) ) // && !self laststand::player_is_in_laststand()
5450  {
5451  self.lives = 0;
5452  level notify("pre_end_game");
5454  if(level ‪flag::get("dog_round"))
5455  {
5456  ‪increment_dog_round_stat( "lost" );
5457 
5458  }
5459  level notify( "end_game" );
5460  }
5461  else
5462  {
5463  return finalDamage;
5464  }
5465  }
5466  else
5467  {
5468  level notify("pre_end_game");
5470  if(level ‪flag::get("dog_round"))
5471  {
5472  ‪increment_dog_round_stat( "lost" );
5473 
5474  }
5475  level notify( "end_game" );
5476  }
5477  return 0; // MM (09/16/09) Need to return something
5478  }
5479  else
5480  {
5481  // MM (08/10/09)
5482 
5483  surface = "flesh";
5484 
5485  return finalDamage;
5486  }
5487 }
5488 
5490 {
5491  zombies = GetAITeamArray( level.zombie_team );
5492  foreach( zombie in zombies )
5493  {
5494  if ( isdefined( zombie.favoriteenemy ) && ( zombie.favoriteenemy == self ) )
5495  {
5496  zombie.zombie_path_timer = 0;
5497  }
5498  }
5499 }
5500 
5501 
5502 function ‪check_player_damage_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime )
5503 {
5504  if ( !isdefined( level.player_damage_callbacks ) )
5505  {
5506  return iDamage;
5507  }
5508 
5509  for ( i = 0; i < level.player_damage_callbacks.size; i++ )
5510  {
5511  newDamage = self [[ level.player_damage_callbacks[i] ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime );
5512  if ( -1 != newDamage )
5513  {
5514  return newDamage;
5515  }
5516  }
5517 
5518  return iDamage;
5519 }
5520 
5521 
5523 {
5524  if ( !isdefined( level.player_damage_callbacks ) )
5525  {
5526  level.player_damage_callbacks = [];
5527  }
5528 
5529  level.player_damage_callbacks[level.player_damage_callbacks.size] = func;
5530 }
5531 
5532 
5534 {
5535 
5536  self endon( "remote_revive" );
5537  level ‪flag::set( "wait_and_revive" );
5538  level.wait_and_revive = true;
5539 
5540  if ( isdefined( self.waiting_to_revive ) && self.waiting_to_revive == true )
5541  {
5542  return;
5543  }
5544 
5545  // Grab the perks if we have the player persistent ability "perk lose"
5546  if( ‪IS_TRUE(self.pers_upgrades_awarded["perk_lose"]) )
5547  {
5549  }
5550 
5551  self.waiting_to_revive = true;
5552  self.lives--;
5553 
5554  if ( isdefined( level.exit_level_func ) )
5555  {
5556  self thread [[ level.exit_level_func ]]();
5557  }
5558  else
5559  {
5560  if ( GetPlayers().size == 1 )
5561  {
5562  player = GetPlayers()[0];
5564  if ( !isdefined( level.move_away_points ) )
5565  {
5566  level.move_away_points = PositionQuery_Source_Navigation( player.last_valid_position, ‪ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MIN, ‪ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MAX, ‪ZM_POSITION_QUERY_MOVE_DIST_MAX, ‪ZM_POSITION_QUERY_RADIUS );
5567  }
5568  }
5569  }
5570 
5571  solo_revive_time = 10.0;
5572 
5573  ‪name = level.player_name_directive[self GetEntityNumber()];
5574  self.revive_hud setText( &"ZOMBIE_REVIVING_SOLO", ‪name );
5575  self ‪laststand::revive_hud_show_n_fade( solo_revive_time );
5576 
5577  level ‪flag::wait_till_timeout( solo_revive_time, "instant_revive" );
5578 
5579  if ( level ‪flag::get( "instant_revive" ) )
5580  {
5582  }
5583 
5584  level ‪flag::clear( "wait_and_revive" );
5585  level.wait_and_revive = false;
5586 
5587  self ‪zm_laststand::auto_revive( self );
5588  self.waiting_to_revive = false;
5589 
5590  // Give player his perks back if he has the "perk_lose" persistent ability
5591  if( ‪IS_TRUE(self.pers_upgrades_awarded["perk_lose"]) )
5592  {
5594  }
5595 }
5596 
5598 {
5599  if( !IsDefined( level.vehicle_damage_callbacks ) )
5600  {
5601  level.vehicle_damage_callbacks = [];
5602  }
5603 
5604  level.vehicle_damage_callbacks[level.vehicle_damage_callbacks.size] = func;
5605 }
5606 
5607 function ‪vehicle_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
5608 {
5609  //apply damage modifiers on the vehicle
5610  if( IsDefined( level.vehicle_damage_callbacks ) )
5611  {
5612  for( i = 0; i < level.vehicle_damage_callbacks.size; i++ )
5613  {
5614  iDamage = self [[ level.vehicle_damage_callbacks[i] ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal );
5615  }
5616  }
5617 
5618  //TODO Sabarish: Move code from globallogic to here to be more consistent with other zombie damage functions
5619  self ‪globallogic_vehicle::Callback_VehicleDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal );
5620 }
5621 
5622 //
5623 // MUST return the value of the damage override
5624 //
5625 function ‪actor_damage_override( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType )
5626 {
5627  // skip conditions
5628  if ( !isdefined( self ) || !isdefined( attacker ) )
5629  return ‪damage;
5630 
5631  ‪damage = ‪bgb::actor_damage_override( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType );
5632 
5633  ‪damage = self ‪check_actor_damage_callbacks( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType );
5634 
5635  self.knuckles_extinguish_flames = (weapon.name == "tazer_knuckles");
5636 
5637  if ( isdefined( attacker.animname ) && attacker.animname == "quad_zombie" )
5638  {
5639  if ( isdefined( self.animname ) && self.animname == "quad_zombie" )
5640  {
5641  return 0;
5642  }
5643  }
5644 
5645  if ( isdefined( self.killby_interdimensional_gun_hole ) )
5646  {
5647  return ‪damage;
5648  }
5649  else if ( isdefined( self.interdimensional_gun_kill ) )
5650  {
5651  if ( isdefined( self.idgun_damage_cb ) )
5652  {
5653  self [[ self.idgun_damage_cb ]]( inflictor, attacker );
5654  return 0;
5655  }
5656  }
5657 
5658 
5659  if ( isdefined( weapon ) )
5660  {
5661  if( ‪is_idgun_damage( weapon ) && ( !IsDefined( meansofdeath ) || meansofdeath != "MOD_EXPLOSIVE" ) )
5662  {
5663  if( !‪IS_EQUAL( self.archetype, ‪ARCHETYPE_MARGWA ) && !‪IS_EQUAL( self.archetype, ‪ARCHETYPE_MECHZ ))
5664  {
5665  self.damageOrigin = vpoint;
5666  self.allowdeath = false;
5667  self.magic_bullet_shield = true;
5668  self.interdimensional_gun_kill = true;
5669  self.interdimensional_gun_weapon = weapon;
5670  self.interdimensional_gun_attacker = attacker;
5671 
5672  if ( isdefined( inflictor ) )
5673  {
5674  self.interdimensional_gun_inflictor = inflictor;
5675  }
5676  else
5677  {
5678  self.interdimensional_gun_inflictor = attacker;
5679  }
5680  }
5681 
5682  if ( isdefined( self.idgun_damage_cb ) )
5683  {
5684  self [[ self.idgun_damage_cb ]]( inflictor, attacker );
5685  }
5686 
5687  return 0;
5688  }
5689  }
5690 
5691  attacker thread ‪zm_audio::sndPlayerHitAlert( self, meansofdeath, inflictor, weapon );
5692 
5693  if ( !isplayer( attacker ) && isdefined( self.non_attacker_func ) )
5694  {
5695  if(‪IS_TRUE(self.non_attack_func_takes_attacker))
5696  {
5697  return self [[ self.non_attacker_func ]]( ‪damage, weapon, attacker );
5698  }
5699  else
5700  {
5701  return self [[ self.non_attacker_func ]]( ‪damage, weapon );
5702  }
5703  }
5704 
5705  if ( IsDefined( attacker ) && IsAI( attacker ) )
5706  {
5707  // AI do not do melee damage to teammates
5708  if( self.team == attacker.team && meansofdeath == "MOD_MELEE" )
5709  {
5710  return 0;
5711  }
5712  }
5713 
5714  if ( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
5715  {
5716  attacker = attacker.owner;
5717  }
5718 
5719  if ( !isdefined( ‪damage ) || !isdefined( meansofdeath ) )
5720  {
5721  return ‪damage;
5722  }
5723 
5724  if ( meansofdeath == "" )
5725  {
5726  return ‪damage;
5727  }
5728 
5729  // This is the AI system's override damage callback, it must come last!
5730  if ( IsDefined( self.aiOverrideDamage ) )
5731  {
5732  for ( index = 0; index < self.aiOverrideDamage.size; index++ )
5733  {
5734  damageCallback = self.aiOverrideDamage[index];
5735  ‪damage = self [[damageCallback]]( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, undefined );
5736  }
5737  if ( ‪damage < 1 )
5738  return 0;
5739 
5740  ‪damage = int( ‪damage + 0.5 );
5741  }
5742 
5743  old_damage = ‪damage;
5744  final_damage = ‪damage;
5745 
5746  if ( IsDefined( self.actor_damage_func ) )
5747  {
5748  final_damage = [[ self.actor_damage_func ]]( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex );
5749  }
5750 
5751  // debug
5752 /#
5753  if ( GetDvarInt( "scr_perkdebug") )
5754  println( "Perk/> Damage Factor: " + final_damage/old_damage + " - Pre Damage: " + old_damage + " - Post Damage: " + final_damage );
5755 #/
5756 
5757  if ( ‪IS_TRUE( self.in_water ) )
5758  {
5759  if ( int( final_damage ) >= self.health )
5760  {
5761  self.water_damage = true;
5762  }
5763  }
5764 
5765  //modifier for the sword in ZOD colliding with zombies
5766  if ( IsDefined( inflictor ) && IsDefined( inflictor.archetype ) && inflictor.archetype == ‪ARCHETYPE_GLAIVE )
5767  {
5768  if( meansofdeath == "MOD_CRUSH" )
5769  {
5770  if ( ( IsDefined( inflictor.enemy ) && inflictor.enemy != self ) || ‪IS_TRUE( inflictor._glaive_must_return_to_owner ) )
5771  {
5772  if ( IsDefined( self.archetype ) && self.archetype != ‪ARCHETYPE_MARGWA )
5773  {
5774  final_damage += self.health;
5775  if ( IsActor( self ) )
5776  {
5778  }
5779  }
5780  }
5781  else
5782  {
5783  return 0;
5784  }
5785  }
5786  }
5787 
5788  if ( isdefined( inflictor ) && isPlayer( attacker ) && attacker == inflictor )
5789  {
5790  if ( meansofdeath == "MOD_HEAD_SHOT" || meansofdeath == "MOD_PISTOL_BULLET" || meansofdeath == "MOD_RIFLE_BULLET" )
5791  {
5792  attacker.hits++;
5793  }
5794  }
5795 
5796  if ( ‪IS_TRUE( level.headshots_only ) && isDefined( attacker ) && isplayer( attacker ) )
5797  {
5798  if ( meansofdeath == "MOD_MELEE" && ( sHitLoc == "head" || sHitLoc == "helmet" ) )
5799  {
5800  return int( final_damage );
5801  }
5802  if ( ‪zm_utility::is_explosive_damage( meansofdeath ) )
5803  {
5804  return int( final_damage );
5805  }
5806  else if ( !‪zm_utility::is_headshot( weapon, sHitLoc, meansofdeath ) )
5807  {
5808  return 0;
5809  }
5810  }
5811 
5812  return int( final_damage );
5813 }
5814 
5815 function ‪check_actor_damage_callbacks( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType )
5816 {
5817  if ( !isdefined( level.actor_damage_callbacks ) )
5818  {
5819  return ‪damage;
5820  }
5821 
5822  for ( i = 0; i < level.actor_damage_callbacks.size; i++ )
5823  {
5824  newDamage = self [[ level.actor_damage_callbacks[i] ]]( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType );
5825  if ( -1 != newDamage )
5826  {
5827  return newDamage;
5828  }
5829  }
5830 
5831  return ‪damage;
5832 }
5833 
5834 
5836 {
5837  if ( !isdefined( level.actor_damage_callbacks ) )
5838  {
5839  level.actor_damage_callbacks = [];
5840  }
5841 
5842  level.actor_damage_callbacks[level.actor_damage_callbacks.size] = func;
5843 }
5844 
5845 
5846 
5847 function ‪actor_damage_override_wrapper( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, modelIndex, surfaceType, vSurfaceNormal )
5848 {
5849  damage_override = self ‪actor_damage_override( inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType );
5850  willBeKilled = ( self.health - damage_override ) <= 0;
5851  if( isdefined( level.zombie_damage_override_callbacks ) )
5852  {
5853  foreach( func_override in level.zombie_damage_override_callbacks )
5854  {
5855  self thread [[ func_override ]]( willBeKilled, inflictor, attacker, ‪damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType );
5856  }
5857  }
5858 
5859  if ( !willBeKilled || !‪IS_TRUE( self.dont_die_on_me ) )
5860  {
5861  self finishActorDamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, surfaceType, vSurfaceNormal );
5862  }
5863 }
5864 
5866 {
5867  ‪DEFAULT( level.zombie_damage_override_callbacks, [] );
5868 
5869  ‪ARRAY_ADD( level.zombie_damage_override_callbacks, func );
5870 }
5871 
5872 function ‪actor_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime)
5873 {
5874  if ( game["state"] == "postgame" )
5875  {
5876  return;
5877  }
5878 
5879  if( isai(attacker) && isDefined( attacker.script_owner ) )
5880  {
5881  // if the person who called the dogs in switched teams make sure they don't
5882  // get penalized for the kill
5883  if ( attacker.script_owner.team != self.team )
5884  attacker = attacker.script_owner;
5885  }
5886 
5887  if( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
5888  {
5889  attacker = attacker.owner;
5890  }
5891 
5892  if ( isdefined( attacker ) && isplayer( attacker ) )
5893  {
5894  multiplier = 1;
5895  if( ‪zm_utility::is_headshot( weapon, sHitLoc, sMeansOfDeath ) )
5896  {
5897  multiplier = 1.5;
5898  }
5899 
5900  type = undefined;
5901 
5902  //MM (3/18/10) no animname check
5903  if ( IsDefined(self.animname) )
5904  {
5905  switch( self.animname )
5906  {
5907  case "quad_zombie":
5908  type = "quadkill";
5909  break;
5910  case "ape_zombie":
5911  type = "apekill";
5912  break;
5913  case "zombie":
5914  type = "zombiekill";
5915  break;
5916  case "zombie_dog":
5917  type = "dogkill";
5918  break;
5919  }
5920  }
5921  }
5922 
5923  if(‪IS_TRUE(self.is_ziplining))
5924  {
5925  self.deathanim = undefined;
5926  }
5927 
5928  if ( IsDefined( self.‪actor_killed_override ) )
5929  {
5930  self [[ self.actor_killed_override ]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime );
5931  }
5932 
5933  if ( IsDefined( self.deathFunction ) )
5934  {
5935  self [[ self.deathFunction ]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime );
5936  }
5937 }
5938 
5939 
5941 {
5942  while(1)
5943  {
5944  level waittill( "end_of_round" );
5945 
5946  ‪demo::bookmark( "zm_round_end", gettime(), undefined, undefined, 1 );
5947  BBPostDemoStreamStatsForRound( level.round_number );
5949 
5951  }
5952 }
5953 
5954 
5955 //*****************************************************************************
5956 //*****************************************************************************
5957 
5959 {
5960  ‪zm_utility::increment_zm_dash_counter( "end_per_game", 1 );
5961  ‪zm_utility::increment_zm_dash_counter( "end_per_player", level.players.size );
5962 
5963  if( !‪IS_TRUE( level.dash_counter_round_reached_5 ) )
5964  {
5965  ‪zm_utility::increment_zm_dash_counter( "end_less_5", 1 );
5966  }
5967  else
5968  {
5969  if( !‪IS_TRUE( level.dash_counter_round_reached_10 ) )
5970  {
5971  ‪zm_utility::increment_zm_dash_counter( "end_reached_5_less_10", 1 );
5972  }
5973  else
5974  {
5975  ‪zm_utility::increment_zm_dash_counter( "end_reached_10", 1 );
5976  }
5977  }
5978 
5980  {
5981  if( level.dash_counter_start_player_count != level.players.size )
5982  {
5983  ‪zm_utility::increment_zm_dash_counter( "end_player_count_diff", 1 );
5984  }
5985  }
5986 }
5987 
5988 function ‪end_game()
5989 {
5990  level waittill ( "end_game" );
5991 
5993 
5994 /# println( "end_game TRIGGERED " ); #/
5995 
5996  setmatchflag( "game_ended", 1 );
5997 
5998  level ‪clientfield::set("gameplay_started", 0);
5999  level ‪clientfield::set("game_end_time", int( ( GetTime() - level.n_gameplay_start_time + 500 ) / 1000 ) );
6000 
6001  util::clientnotify( "zesn" );
6002 
6003  level thread ‪zm_audio::sndMusicSystem_PlayState( "game_over" );
6004 
6005  //AYERS: Turn off ANY last stand audio at the end of the game
6006  players = GetPlayers();
6007  for ( i = 0; i < players.size; i++ )
6008  {
6009  players[i] ‪clientfield::set( "zmbLastStand", 0 );
6010  }
6011 
6012  for ( i = 0; i < players.size; i++ )
6013  {
6014  if ( players[i] ‪laststand::player_is_in_laststand() )
6015  {
6016  players[i] RecordPlayerDeathZombies();
6017  players[i] ‪zm_stats::increment_player_stat( "deaths" );
6018  players[i] ‪zm_stats::increment_client_stat( "deaths" );
6020  }
6021 
6022  //clean up the revive text hud if it's active
6023  if( isdefined( players[i].reviveTextHud ) )
6024  {
6025  players[i].reviveTextHud ‪destroy();
6026  }
6027  }
6028 
6029  StopAllRumbles();
6030 
6031  level.intermission = true;
6032  level.zombie_vars["zombie_powerup_insta_kill_time"] = 0;
6033  level.zombie_vars["zombie_powerup_fire_sale_time"] = 0;
6034  level.zombie_vars["zombie_powerup_double_points_time"] = 0;
6035  wait 0.1;
6036 
6037  game_over = [];
6038  survived = [];
6039 
6040  players = GetPlayers();
6041 
6042  //disabled the ingame pause menu from opening after a game ends
6043  setMatchFlag( "disableIngameMenu", 1 );
6044  foreach( player in players )
6045  {
6046  player closeInGameMenu();
6047  player CloseMenu( "StartMenu_Main" );
6048  }
6049 
6050 
6051  //AAR - set stat for each player (this will show the menu)
6052  foreach( player in players )
6053  {
6054  player setDStat( "AfterActionReportStats", "lobbyPopup", "summary" );
6055  }
6056 
6057  if(!isDefined(level._supress_survived_screen))
6058  {
6059 
6060  for( i = 0; i < players.size; i++ )
6061  {
6062  game_over[i] = NewClientHudElem( players[i] );
6063  survived[i] = NewClientHudElem( players[i] );
6064  if ( IsDefined( level.custom_game_over_hud_elem ) )
6065  {
6066  [[ level.custom_game_over_hud_elem ]]( players[i], game_over[i], survived[i] );
6067  }
6068  else
6069  {
6070  game_over[i].alignX = "center";
6071  game_over[i].alignY = "middle";
6072  game_over[i].horzAlign = "center";
6073  game_over[i].vertAlign = "middle";
6074  game_over[i].y -= 130;
6075  game_over[i].foreground = true;
6076  game_over[i].fontScale = 3;
6077  game_over[i].alpha = 0;
6078  game_over[i].color = ( 1.0, 1.0, 1.0 );
6079  game_over[i].hidewheninmenu = true;
6080  game_over[i] SetText( &"ZOMBIE_GAME_OVER" );
6081 
6082  game_over[i] FadeOverTime( 1 );
6083  game_over[i].alpha = 1;
6084  if ( players[i] isSplitScreen() )
6085  {
6086  game_over[i].fontScale = 2;
6087  game_over[i].y += 40;
6088  }
6089 
6090  survived[i].alignX = "center";
6091  survived[i].alignY = "middle";
6092  survived[i].horzAlign = "center";
6093  survived[i].vertAlign = "middle";
6094  survived[i].y -= 100;
6095  survived[i].foreground = true;
6096  survived[i].fontScale = 2;
6097  survived[i].alpha = 0;
6098  survived[i].color = ( 1.0, 1.0, 1.0 );
6099  survived[i].hidewheninmenu = true;
6100  if ( players[i] isSplitScreen() )
6101  {
6102  survived[i].fontScale = 1.5;
6103  survived[i].y += 40;
6104  }
6105  }
6106 
6107 
6108  //OLD COUNT METHOD
6109  if( level.round_number < 2 )
6110  {
6111  if( level.script == "zm_moon" )
6112  {
6113  if( !isdefined(level.left_nomans_land) )
6114  {
6115  nomanslandtime = level.nml_best_time;
6116  player_survival_time = int( nomanslandtime/1000 );
6117  player_survival_time_in_mins = ‪zm::to_mins( player_survival_time );
6118  survived[i] SetText( &"ZOMBIE_SURVIVED_NOMANS", player_survival_time_in_mins );
6119  }
6120  else if( level.left_nomans_land == 2 )
6121  {
6122  survived[i] SetText( &"ZOMBIE_SURVIVED_ROUND" );
6123  }
6124  }
6125  else
6126  {
6127  survived[i] SetText( &"ZOMBIE_SURVIVED_ROUND" );
6128  }
6129  }
6130  else
6131  {
6132  survived[i] SetText( &"ZOMBIE_SURVIVED_ROUNDS", level.round_number );
6133  }
6134 
6135  survived[i] FadeOverTime( 1 );
6136  survived[i].alpha = 1;
6137  }
6138  }
6139 
6140 
6141  //check to see if we are in a game module that wants to do something with PvP damage
6142  if(isDefined(level.custom_end_screen))
6143  {
6144  level [[level.custom_end_screen]]();
6145  }
6146 
6147  for (i = 0; i < players.size; i++)
6148  {
6149  players[i] SetClientUIVisibilityFlag( "weapon_hud_visible", 0 );
6150  players[i] SetClientMiniScoreboardHide( true );
6151  //players[i] setDStat( "AfterActionReportStats", "lobbyPopup", "summary" );
6152 
6153  players[i] notify( "report_bgb_consumption" );
6154 
6156  }
6157 
6158  //LUINotifyEvent( &"force_scoreboard", 0 );
6159 
6160  UploadStats();
6163 
6165 
6166  recordGameResult( "draw" );
6170 
6171  //update dash and promo counters
6172  if( SessionModeIsOnlineGame() )
6173  {
6175  }
6176 
6177  // Finalize Match Record
6178  finalizeMatchRecord();
6179 
6180  //zm_utility::play_sound_at_pos( "end_of_game", ( 0, 0, 0 ) );
6181 
6182  players = GetPlayers();
6183  foreach( player in players )
6184  {
6185  if( IsDefined( player.sessionstate ) && player.sessionstate == "spectator" )
6186  {
6187  player.sessionstate = "playing";
6188  player thread ‪end_game_player_was_spectator();
6189  }
6190  }
6192 
6193  /#
6194  if ( !‪IS_TRUE(level.host_ended_game) && GetDvarInt( "scr_restart_on_wipe" ) > 1 )
6195  {
6196  LUINotifyEvent( &"force_scoreboard", 0 );
6197  map_restart( true );
6198  wait( 666 );
6199  }
6200  #/
6201 
6202  players = GetPlayers();
6203 
6204  LUINotifyEvent( &"force_scoreboard", 1, 1 );
6205 
6206  ‪intermission();
6207 
6208  wait( level.zombie_vars["zombie_intermission_time"] );
6209 
6210  // hide the gameover message
6211  if ( !isDefined( level._supress_survived_screen ) )
6212  {
6213  for ( i = 0; i < players.size; i++ )
6214  {
6215  survived[i] Destroy();
6216  game_over[i] Destroy();
6217  }
6218  }
6219  else
6220  {
6221  for ( i = 0; i < players.size; i++ )
6222  {
6223  if(isDefined(players[i].survived_hud ) )
6224  players[i].survived_hud Destroy();
6225  if (isDefined( players[i].game_over_hud ) )
6226  players[i].game_over_hud Destroy();
6227  }
6228  }
6229 
6230  level notify( "stop_intermission" );
6231  array::thread_all( GetPlayers(), &‪player_exit_level );
6232 
6233  wait( 1.5 );
6234 
6235  players = GetPlayers();
6236  for ( i = 0; i < players.size; i++ )
6237  {
6238  players[i] CameraActivate( false );
6239  }
6240 
6241  /#
6242  if ( !‪IS_TRUE(level.host_ended_game) && GetDvarInt( "scr_restart_on_wipe" ) )
6243  {
6244  LUINotifyEvent( &"force_scoreboard", 1, 0 );
6245  map_restart( true );
6246  wait( 666 );
6247  }
6248  #/
6249 
6250  ExitLevel( false );
6251 
6252  // Let's not exit the function
6253  wait( 666 );
6254 }
6255 
6256 //*****************************************************************************
6257 //*****************************************************************************
6258 
6260 {
6262 
6263  self Ghost();
6264  self FreezeControls( true );
6265 }
6266 
6267 //*****************************************************************************
6268 //*****************************************************************************
6269 
6271 {
6272  level.disable_intermission = true;
6273  wait( ‪delay );
6274  level.disable_intermission = undefined;
6275 }
6276 
6277 
6278 //*****************************************************************************
6279 //*****************************************************************************
6280 
6282 {
6283  if( IsDefined(level.disable_intermission) )
6284  {
6285  while( 1 )
6286  {
6287  if( !IsDefined(level.disable_intermission) )
6288  {
6289  break;
6290  }
6291  wait( 0.01 );
6292  }
6293  }
6294 }
6295 
6296 
6297 //*****************************************************************************
6298 // This will save the leaderboard data per round, for use in single player
6299 //*****************************************************************************
6300 
6302 {
6303  // place restrictions on whether leaderboards are uploaded to in the precache leaderboards function
6304  players = GetPlayers();
6305  for( i = 0; i < players.size; i++ )
6306  {
6307  players[i] uploadleaderboards();
6308  }
6309 }
6310 
6311 
6313 {
6314  level.global_zombies_killed = 0;
6315  level.zombies_timeout_spawn = 0;
6316  level.zombies_timeout_playspace = 0;
6317  level.zombies_timeout_undamaged = 0;
6318  level.zombie_player_killed_count = 0;
6319  level.zombie_trap_killed_count = 0;
6320  level.zombie_pathing_failed = 0;
6321  level.zombie_breadcrumb_failed = 0;
6322 
6323 }
6324 
6326 {
6327  incrementCounter( "global_zombies_killed", level.global_zombies_killed );
6328  incrementCounter( "global_zombies_killed_by_players", level.zombie_player_killed_count );
6329  incrementCounter( "global_zombies_killed_by_traps", level.zombie_trap_killed_count );
6330 }
6331 
6333 {
6334  level notify ("fake_death");
6335  self notify ("fake_death");
6336 
6337  self TakeAllWeapons();
6338  self AllowStand( false );
6339  self AllowCrouch( false );
6340  self AllowProne( true );
6341 
6342  self.ignoreme = true;
6343  self EnableInvulnerability();
6344 
6345  wait( 1 );
6346  self FreezeControls( true );
6347 }
6348 
6350 {
6351  self AllowStand( true );
6352  self AllowCrouch( false );
6353  self AllowProne( false );
6354 
6355  //self thread lui::screen_fade_out( 1 );
6356 }
6357 
6358 
6359 function ‪player_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
6360 {
6361  // BLANK
6362  level waittill( "forever" );
6363 }
6364 
6366 {
6367  self notify("stop_player_zombie_breadcrumb");
6368  self endon("stop_player_zombie_breadcrumb");
6369  self endon( "disconnect" );
6370  self endon( "spawned_spectator" );
6371  level endon( "intermission" );
6372 
6373  self.zombie_breadcrumbs = [];
6374  self.zombie_breadcrumb_distance = 24 * 24; // min dist (squared) the player must move to drop a crumb
6375  self.zombie_breadcrumb_area_num = 3; // the number of "rings" the area breadcrumbs use
6376  self.zombie_breadcrumb_area_distance = 16; // the distance between each "ring" of the area breadcrumbs
6377 
6378  self ‪store_crumb( self.origin );
6379  last_crumb = self.origin;
6380 
6381  self thread ‪zm_utility::debug_breadcrumbs();
6382 
6383  while( 1 )
6384  {
6385  wait_time = 0.1;
6386 
6387 
6388  if( self.ignoreme )
6389  {
6390  wait( wait_time );
6391  continue;
6392  }
6393 
6394  //For cloaking ability
6395  //if( self.ignoreme )
6396  //{
6397  // wait( wait_time );
6398  // continue;
6399  //}
6400 
6401 
6402  ‪store_crumb = true;
6403  airborne = false;
6404  crumb = self.origin;
6405 
6406 //TODO TEMP SCRIPT for vehicle testing Delete/comment when done
6407  if ( !self IsOnGround() && self isinvehicle() )
6408  {
6409  ‪trace = bullettrace( self.origin + (0,0,10), self.origin, false, undefined );
6410  crumb = ‪trace["position"];
6411  }
6412 
6413 //TODO TEMP DISABLE for vehicle testing. Uncomment when reverting
6414 // if ( !self IsOnGround() )
6415 // {
6416 // airborne = true;
6417 // store_crumb = false;
6418 // wait_time = 0.05;
6419 // }
6420 //
6421  if( !airborne && DistanceSquared( crumb, last_crumb ) < self.zombie_breadcrumb_distance )
6422  {
6423  ‪store_crumb = false;
6424  }
6425 
6426  if ( airborne && self IsOnGround() )
6427  {
6428  // player was airborne, store crumb now that he's on the ground
6429  ‪store_crumb = true;
6430  airborne = false;
6431  }
6432 
6433  if( isDefined( level.custom_breadcrumb_store_func ) )
6434  {
6435  ‪store_crumb = self [[ level.custom_breadcrumb_store_func ]]( ‪store_crumb );
6436  }
6437 
6438  if( isDefined( level.custom_airborne_func ) )
6439  {
6440  airborne = self [[ level.custom_airborne_func ]]( airborne );
6441  }
6442 
6443  if( ‪store_crumb )
6444  {
6445  ‪zm_utility::debug_print( "Player is storing breadcrumb " + crumb );
6446 
6447  if( IsDefined(self.node) )
6448  {
6449  ‪zm_utility::debug_print( "has closest node " );
6450  }
6451 
6452  last_crumb = crumb;
6453  self ‪store_crumb( crumb );
6454  }
6455 
6456  wait( wait_time );
6457  }
6458 }
6459 
6460 
6461 function ‪store_crumb( origin )
6462 {
6463  offsets = [];
6464  height_offset = 32;
6465 
6466  index = 0;
6467  for( j = 1; j <= self.zombie_breadcrumb_area_num; j++ )
6468  {
6469  offset = ( j * self.zombie_breadcrumb_area_distance );
6470 
6471  offsets[0] = ( origin[0] - offset, origin[1], origin[2] );
6472  offsets[1] = ( origin[0] + offset, origin[1], origin[2] );
6473  offsets[2] = ( origin[0], origin[1] - offset, origin[2] );
6474  offsets[3] = ( origin[0], origin[1] + offset, origin[2] );
6475 
6476  offsets[4] = ( origin[0] - offset, origin[1], origin[2] + height_offset );
6477  offsets[5] = ( origin[0] + offset, origin[1], origin[2] + height_offset );
6478  offsets[6] = ( origin[0], origin[1] - offset, origin[2] + height_offset );
6479  offsets[7] = ( origin[0], origin[1] + offset, origin[2] + height_offset );
6480 
6481  for ( i = 0; i < offsets.size; i++ )
6482  {
6483  self.zombie_breadcrumbs[index] = offsets[i];
6484  index++;
6485  }
6486  }
6487 }
6488 
6489 
6493 function ‪to_mins( seconds )
6494 {
6495  hours = 0;
6496  minutes = 0;
6497 
6498  if( seconds > 59 )
6499  {
6500  minutes = int( seconds / 60 );
6501 
6502  seconds = int( seconds * 1000 ) % ( 60 * 1000 );
6503  seconds = seconds * 0.001;
6504 
6505  if( minutes > 59 )
6506  {
6507  hours = int( minutes / 60 );
6508  minutes = int( minutes * 1000 ) % ( 60 * 1000 );
6509  minutes = minutes * 0.001;
6510  }
6511  }
6512 
6513  if( hours < 10 )
6514  {
6515  hours = "0" + hours;
6516  }
6517 
6518  if( minutes < 10 )
6519  {
6520  minutes = "0" + minutes;
6521  }
6522 
6523  seconds = Int( seconds );
6524  if( seconds < 10 )
6525  {
6526  seconds = "0" + seconds;
6527  }
6528 
6529  combined = "" + hours + ":" + minutes + ":" + seconds;
6530 
6531  return combined;
6532 }
6533 
6537 
6538 //
6539 // INTERMISSION =========================================================== //
6540 //
6541 
6543 {
6544  level.intermission = true;
6545  level notify( "intermission" );
6546 
6547  players = GetPlayers();
6548  for( i = 0; i < players.size; i++ )
6549  {
6550  players[i] SetClientThirdPerson( 0 );
6551  players[i] resetFov();
6552 
6553  players[i].health = 100; // This is needed so the player view doesn't get stuck
6554  players[i] thread [[level.custom_intermission]]();
6555 
6556  players[i] StopSounds();
6557  }
6558 
6559  wait( 5.25 );
6560 
6561  players = GetPlayers();
6562  for( i = 0; i < players.size; i++ )
6563  {
6564  players[i] ‪clientfield::set( "zmbLastStand", 0 );
6565  }
6566 
6567  level thread ‪zombie_game_over_death();
6568 }
6569 
6571 {
6572  // Kill remaining zombies, in style!
6573  zombies = GetAiTeamArray( level.zombie_team );
6574  for( i = 0; i < zombies.size; i++ )
6575  {
6576  if( !IsAlive( zombies[i] ) )
6577  {
6578  continue;
6579  }
6580 
6581  zombies[i] SetGoal( zombies[i].origin );
6582  }
6583 
6584  for( i = 0; i < zombies.size; i++ )
6585  {
6586  if( !IsAlive( zombies[i] ) )
6587  {
6588  continue;
6589  }
6590 
6591  if ( ‪IS_TRUE( zombies[i].ignore_game_over_death ) )
6592  {
6593  continue;
6594  }
6595 
6596  wait( 0.5 + RandomFloat( 2 ) );
6597 
6598  if ( isdefined( zombies[i] ) )
6599  {
6600  if( !IsVehicle( zombies[i] ) )
6601  {
6603  }
6604 
6605  zombies[i] Kill();
6606  }
6607  }
6608 }
6609 
6610 
6611 #define INTERMISSION_STREAMER_HINT_PRIORITY 0.9
6612 
6613 function ‪screen_fade_in( n_time, v_color, str_menu_id )
6614 {
6615  ‪lui::screen_fade( n_time, 0, 1, v_color, false, str_menu_id );
6616  wait n_time;
6617 }
6618 
6619 
6621 {
6622  self closeInGameMenu();
6623  self CloseMenu( "StartMenu_Main" );
6624 
6625  self notify("player_intermission");
6626  self endon("player_intermission");
6627  level endon( "stop_intermission" );
6628  self endon("disconnect");
6629  self endon("death");
6630  self notify( "_zombie_game_over" ); // ww: notify so hud elements know when to leave
6631 
6632  //Show total gained point for end scoreboard and lobby
6633  self.score = self.score_total;
6634 
6635  points =‪struct::get_array( "intermission", "targetname" );
6636 
6637  if( !IsDefined( points ) || points.size == 0 )
6638  {
6639  points = getentarray( "info_intermission", "classname" );
6640  if( points.size < 1 )
6641  {
6642  /# println( "NO info_intermission POINTS IN MAP" ); #/
6643  return;
6644  }
6645  }
6646 
6647  if ( ‪IS_TRUE( level.b_show_single_intermission ) )
6648  {
6649  a_s_temp_points = array::randomize( points );
6650  points = [];
6651  points[0] = array::random( a_s_temp_points );
6652  }
6653  else
6654  {
6655  points = array::randomize( points );
6656  }
6657 
6658  self ‪zm_utility::create_streamer_hint( points[0].origin, points[0].angles, ‪INTERMISSION_STREAMER_HINT_PRIORITY );
6659 
6660  wait( 5 );
6661 
6662  self ‪lui::screen_fade_out( 1 );
6663 
6664  // don't do this unti we're ready to "spawn" the players in the exit scenes
6665  // the player camera will clip into the ground if this is done too early
6666  self.sessionstate = "intermission";
6667  self.spectatorclient = -1;
6668  self.killcamentity = -1;
6669  self.archivetime = 0;
6670  self.psoffsettime = 0;
6671  self.friendlydamage = undefined;
6672  if ( isdefined( level.player_intemission_spawn_callback ) )
6673  {
6674  self thread [[ level.player_intemission_spawn_callback ]] ( points[0].origin, points[0].angles );
6675  }
6676 
6677  while( 1 )
6678  {
6679  for( i = 0; i < points.size; i++ )
6680  {
6681  point = points[i];
6682  nextpoint = points[i+1];
6683 
6684  self SetOrigin( point.origin );
6685  self SetPlayerAngles( point.angles );
6686  wait 0.15;
6687 
6688  self notify("player_intermission_spawned");
6689 
6690  if ( IsDefined(nextpoint) )
6691  {
6692  self ‪zm_utility::create_streamer_hint( nextpoint.origin, nextpoint.angles, ‪INTERMISSION_STREAMER_HINT_PRIORITY );
6693  self ‪screen_fade_in( 2 );
6694 
6695  wait( 3 );
6696 
6697  self ‪lui::screen_fade_out( 2 );
6698  }
6699  else
6700  {
6701  self ‪screen_fade_in( 2 );
6702 
6703  if ( points.size == 1 )
6704  {
6705  return;
6706  }
6707  }
6708  }
6709  }
6710 }
6711 
6713 {
6714  self FadeOverTime( t );
6715  self.alpha = 1;
6716 }
6717 
6719 {
6720  zombies = GetAiTeamArray( level.zombie_team );
6721  for ( i = 0; i < zombies.size; i++ )
6722  {
6723  if ( ‪IS_TRUE( zombies[i].ignore_solo_last_stand ) )
6724  {
6725  continue;
6726  }
6727 
6728  if ( isDefined( zombies[i].find_exit_point ) )
6729  {
6730  zombies[i] thread [[ zombies[i].find_exit_point ]]();
6731  continue;
6732  }
6733 
6734  if ( zombies[i].ignoreme )
6735  {
6736  zombies[i] thread ‪default_delayed_exit();
6737  }
6738  else
6739  {
6740  zombies[i] thread ‪default_find_exit_point();
6741  }
6742  }
6743 }
6744 
6746 {
6747  self endon( "death" );
6748 
6749  while ( 1 )
6750  {
6751  if ( !level ‪flag::get( "wait_and_revive" ) )
6752  {
6753  return;
6754  }
6755 
6756  // broke through the barricade, find an exit point
6757  if ( !self.ignoreme )
6758  {
6759  break;
6760  }
6761  wait( 0.1 );
6762  }
6763 
6764  self thread ‪default_find_exit_point();
6765 }
6766 
6768 {
6769  self endon( "death" );
6770 
6771  player = GetPlayers()[0];
6772 
6773  dist_zombie = 0;
6774  dist_player = 0;
6775  dest = 0;
6776 
6777  away = VectorNormalize( self.origin - player.origin );
6778  endPos = self.origin + VectorScale( away, 600 );
6779 
6780  if ( isdefined( level.zm_loc_types[ "wait_location" ] ) && level.zm_loc_types[ "wait_location" ].size > 0 )
6781  {
6782  locs = array::randomize( level.zm_loc_types[ "wait_location" ] );
6783  }
6784  //TODO Add wait_locations to Der Reise and we can remove this line
6785  else // Legacy catch
6786  {
6787  locs = array::randomize( level.zm_loc_types[ "dog_location" ] );
6788  }
6789 
6790  for ( i = 0; i < locs.size; i++ )
6791  {
6792  dist_zombie = DistanceSquared( locs[i].origin, endPos );
6793  dist_player = DistanceSquared( locs[i].origin, player.origin );
6794 
6795  if ( dist_zombie < dist_player )
6796  {
6797  dest = i;
6798  break;
6799  }
6800  }
6801 
6802  self notify( "stop_find_flesh" );
6803  self notify( "zombie_acquire_enemy" );
6804 
6805  if( isdefined( locs[dest] ) )
6806  {
6807  self SetGoal( locs[dest].origin );
6808  }
6809 
6810  while ( 1 )
6811  {
6812  // in the event this function isn't run through a solo revive, use level override to dictate behavior; don't change existing behavior if this doesn't exist
6813  b_passed_override = true;
6814 
6815  // Returning 'false' from the level override will put zombies back into find_flesh
6816  if ( IsDefined( level.default_find_exit_position_override ) )
6817  {
6818  b_passed_override = [[ level.default_find_exit_position_override ]]();
6819  }
6820 
6821  if ( !level ‪flag::get( "wait_and_revive" ) && b_passed_override )
6822  {
6823  break;
6824  }
6825  wait( 0.1 );
6826  }
6827 
6828 }
6829 
6831 {
6832  wait(3);
6833  players = GetPlayers();
6834  num = RandomIntRange( 0, players.size );
6835  players[num] ‪zm_audio::create_and_play_dialog( "general", "intro" );
6836 }
6837 
6838 
6839 function ‪register_sidequest( id, sidequest_stat )
6840 {
6841  if ( !IsDefined( level.zombie_sidequest_stat ) )
6842  {
6843  level.zombie_sidequest_previously_completed = [];
6844  level.zombie_sidequest_stat = [];
6845  }
6846 
6847  level.zombie_sidequest_stat[id] = sidequest_stat;
6848 
6849  //level flag::wait_till( "all_players_spawned" );
6850  level ‪flag::wait_till( "start_zombie_round_logic" );
6851 
6852  level.zombie_sidequest_previously_completed[id] = false;
6853 
6854  // don't do stats stuff if it's not an online game
6855  if ( !level.onlineGame )
6856  {
6857  return;
6858  }
6859 
6860  //don't do stats stuff if stats are disabled
6861  if ( ‪IS_TRUE( level.zm_disable_recording_stats ) )
6862  {
6863  return;
6864  }
6865 
6866  players = GetPlayers();
6867  for ( i = 0; i < players.size; i++ )
6868  {
6869  if ( players[i] ‪zm_stats::get_global_stat( level.zombie_sidequest_stat[id] ) )
6870  {
6871  level.zombie_sidequest_previously_completed[id] = true;
6872  return;
6873  }
6874  }
6875 }
6876 
6877 
6879 {
6880  return ‪IS_TRUE( level.zombie_sidequest_previously_completed[id] );
6881 }
6882 
6883 
6885 {
6886  level notify( "zombie_sidequest_completed", id );
6887  level.zombie_sidequest_previously_completed[id] = true;
6888 
6889  // don't do stats stuff if it's not an online game
6890  if ( !level.onlineGame )
6891  {
6892  return;
6893  }
6894 
6895  //don't do stats stuff if stats are disabled
6896  if ( ‪IS_TRUE( level.zm_disable_recording_stats ) )
6897  {
6898  return;
6899  }
6900 
6901  players = GetPlayers();
6902  for ( i = 0; i < players.size; i++ )
6903  {
6904  if ( isdefined( level.zombie_sidequest_stat[id] ) )
6905  {
6906  players[i] ‪zm_stats::add_global_stat( level.zombie_sidequest_stat[id], 1 );
6907  }
6908  }
6909 }
6910 
6911 function ‪playSwipeSound( mod, attacker )
6912 {
6913  if( ‪IS_TRUE(attacker.is_zombie) || (isdefined( attacker.archetype ) && attacker.archetype == "margwa" ) )
6914  {
6915  self playsoundtoplayer( "evt_player_swiped", self );
6916  return;
6917  }
6918 }
6919 
6921 {
6922  // don't save leaderboards for systemlink or custom games
6923  if( SessionModeIsSystemlink() )
6924  {
6925  return;
6926  }
6927 
6928  // GLOBAL LEADERBOARDS
6929  globalLeaderboards = "LB_ZM_GB_BULLETS_FIRED_AT ";
6930  globalLeaderboards += "LB_ZM_GB_BULLETS_HIT_AT ";
6931  globalLeaderboards += "LB_ZM_GB_DISTANCE_TRAVELED_AT ";
6932  globalLeaderboards += "LB_ZM_GB_DOORS_PURCHASED_AT ";
6933  globalLeaderboards += "LB_ZM_GB_GRENADE_KILLS_AT ";
6934  globalLeaderboards += "LB_ZM_GB_HEADSHOTS_AT ";
6935  globalLeaderboards += "LB_ZM_GB_KILLS_AT ";
6936  globalLeaderboards += "LB_ZM_GB_PERKS_DRANK_AT ";
6937  globalLeaderboards += "LB_ZM_GB_REVIVES_AT ";
6938 
6939  //Multirank
6940  globalLeaderboards += "LB_ZM_GB_KILLSTATS_MR ";
6941  globalLeaderboards += "LB_ZM_GB_GAMESTATS_MR ";
6942 
6943  if ( !level.rankedMatch && (GetDvarInt( "zm_private_rankedmatch", 0 ) == 0) )
6944  {
6945  precacheLeaderboards( globalLeaderboards );
6946  return;
6947  }
6948 
6949  // MAP LEADERBOARD
6950  mapname = GetDvarString( "mapname" );
6951  expectedPlayerNum = GetNumExpectedPlayers();
6952 
6953  mapLeaderboard = "LB_ZM_MAP_"+ getsubstr( mapname, 3, mapname.size ) + "_" + expectedPlayerNum + "PLAYER";
6954 
6955  precacheLeaderboards( globalLeaderboards + mapLeaderboard );
6956 }
6957 
6959 {
6960  if( level.passed_introscreen)
6961  {
6962  self setClientUIVisibilityFlag( "hud_visible", 1 );
6963  self setClientUIVisibilityFlag( "weapon_hud_visible", 1 );
6964 
6965  ‪zm_utility::increment_zm_dash_counter( "hotjoined", 1 );
6967  }
6968 
6969  self ‪flag::init( "used_consumable" );
6972 
6974  self thread ‪watchDisconnect();
6975 
6976  self.hud_damagefeedback = newdamageindicatorhudelem(self);
6977  self.hud_damagefeedback.horzAlign = "center";
6978  self.hud_damagefeedback.vertAlign = "middle";
6979  self.hud_damagefeedback.x = -12;
6980  self.hud_damagefeedback.y = -12;
6981  self.hud_damagefeedback.alpha = 0;
6982  self.hud_damagefeedback.archived = true;
6983  self.hud_damagefeedback setShader( "damage_feedback", 24, 48 );
6984  self.hitSoundTracker = true;
6985 
6986 }
6987 
6989 {
6991 
6992  ‪zm_utility::increment_zm_dash_counter( "left_midgame", 1 );
6994 }
6995 
6997 {
6998  self notify("watchDisconnect");
6999  self endon("watchDisconnect");
7000  self waittill("disconnect");
7002 }
7003 
7004 
7005 
7007 {
7008  players = GetPlayers();
7009  foreach(player in players)
7010  {
7011  player ‪zm_stats::increment_client_stat( "zdog_rounds_" + stat );
7012  }
7013 }
7014 
7016 {
7017  level ‪flag::wait_till( "start_zombie_round_logic" );
7019 }
7020 
7021 
7023 {
7024  if (!IsDefined(level.navcards))
7025  return;
7026  players = GetPlayers();
7027  foreach( player in players )
7028  {
7029  navcard_bits = 0;
7030  for(i = 0;i < level.navcards.size; i++)
7031  {
7032  hasit = player ‪zm_stats::get_global_stat( level.navcards[i] );
7033  if (isdefined(player.navcard_grabbed) && player.navcard_grabbed == level.navcards[i] )
7034  hasit = 1;
7035  if( hasit )
7036  {
7037  navcard_bits +=( 1 << i );
7038  }
7039  }
7041  player ‪clientfield::set( "navcard_held", 0 );
7042  if ( navcard_bits > 0 )
7043  {
7045  player ‪clientfield::set( "navcard_held", navcard_bits );
7046  }
7047  }
7048 
7049 }
7050 
7052 {
7053 
7054  if (!solo_mode )
7055  {
7056  level.laststandpistol = level.default_laststandpistol;
7057  }
7058  else
7059  {
7060  level.laststandpistol = level.default_solo_laststandpistol;
7061  }
7062 
7063 }
7064 
7065 //109171 Zombies - ZM_Global - Add check for player count at beginning of the game
7066 //monitors during the match for exploits extra players being able to join the match
7068 {
7069  max_players = 4;
7070  if ( level.scr_zm_ui_gametype == "zgrief" || level.scr_zm_ui_gametype == "zmeat" )
7071  {
7072  max_players = 8;
7073  }
7074 
7075  if ( GetPlayers().size > max_players )
7076  {
7078  level notify("end_game");
7079  }
7080 
7081 }
7082 
7083 //vehicle response to idgun damage
7084 function ‪is_idgun_damage( weapon )
7085 {
7086  if( isdefined( level.idgun_weapons ) )
7087  {
7088  if ( IsInArray( level.idgun_weapons, weapon ) )
7089  return true;
7090  }
7091  return false;
7092 }
7093 
7095 {
7096  thread ‪update_zone_name();
7097  thread ‪update_is_player_valid();
7098 }
7099 
7101 {
7102  self endon( "death" );
7103  self endon( "disconnnect" );
7104 
7105  self.am_i_valid = true;
7106  while ( isDefined( self ) )
7107  {
7108  self.am_i_valid = ‪zm_utility::is_player_valid( self, true );
7110  }
7111 }
7112 
7114 {
7115  self endon( "death" );
7116  self endon( "disconnnect" );
7117 
7118  self.zone_name = ‪zm_utility::get_current_zone();
7119  if ( isDefined( self.zone_name ) )
7120  {
7121  self.previous_zone_name = self.zone_name;
7122  }
7123 
7124  while ( isDefined( self ) )
7125  {
7126  if( isDefined( self.zone_name ) )
7127  {
7128  self.previous_zone_name = self.zone_name;
7129  }
7130  self.zone_name = ‪zm_utility::get_current_zone();
7131 
7132  wait RandomFloatRange( 0.5, 1.0 );
7133  }
7134 }
7135 
7136 /#
7138 {
7139  outputString = "\n------------------- BEGIN HASH ID DUMP -----------------------------\n";
7140 
7141 
7142  //Print Craftables
7143  outputString += "** CRAFTABLES **\n";
7144  foreach( s_craftable in level.zombie_include_craftables )
7145  {
7146  outputString += "+" + s_craftable.name + "," + s_craftable.hash_id + "\n";
7147  if (!isDefined(s_craftable.a_piecestubs))
7148  {
7149  continue;
7150  }
7151 
7152  foreach( s_piece in s_craftable.a_piecestubs )
7153  {
7154  outputString += s_piece.pieceName + "," + s_piece.hash_id + "\n";
7155  }
7156  }
7157 
7158  //Print Powerups
7159  outputString += "** POWERUPS **\n";
7160  foreach ( powerup in level.zombie_powerups)
7161  {
7162  outputString += powerup.powerup_name + "," + powerup.hash_id + "\n";
7163  }
7164 
7165  //Print AATs
7166  outputString += "** AAT **\n";
7167  if( ‪IS_TRUE( level.aat_in_use ) )
7168  {
7169  foreach (aat in level.aat)
7170  {
7171  if (!isDefined(aat) || !isDefined(aat.name) || aat.name == "none")
7172  {
7173  continue;
7174  }
7175  outputString += aat.name + "," + aat.hash_id + "\n";
7176  }
7177  }
7178 
7179  //Print AATs
7180  outputString += "** PERKS **\n";
7181  foreach (perk in level._custom_perks)
7182  {
7183  if (!isDefined(perk) || !isDefined(perk.alias))
7184  {
7185  continue;
7186  }
7187  outputString += perk.alias + "," + perk.hash_id + "\n";
7188  }
7189 
7190  outputString += "------------------- END HASH ID DUMP -----------------------------\n";
7191  PrintLn(outputString);
7192 }
7193 
7194 #/
‪is_zombie
‪function is_zombie()
Definition: zombie_utility.gsc:1320
‪processScoreEvent
‪function processScoreEvent(event, player, victim, weapon)
Definition: scoreevents_shared.gsc:19
‪end_game_player_was_spectator
‪function end_game_player_was_spectator()
Definition: _zm.gsc:6259
‪player_out_of_playable_area_monitor
‪function player_out_of_playable_area_monitor()
Definition: _zm.gsc:2035
‪spectator_toggle_3rd_person
‪function spectator_toggle_3rd_person()
Definition: _zm.gsc:2745
‪player_damage_override_cheat
‪function player_damage_override_cheat(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime)
Definition: _zm.gsc:5094
‪reset_actor_bookmark_kill_times
‪function reset_actor_bookmark_kill_times()
Definition: demo_shared.gsc:99
‪drive_client_connected_notifies
‪function drive_client_connected_notifies()
Definition: _zm.gsc:459
‪init_shellshocks
‪function init_shellshocks()
Definition: _zm.gsc:1071
‪check_for_valid_spawn_within_range
‪function check_for_valid_spawn_within_range(revivee, v_position, return_struct, min_distance, max_distance)
Definition: _zm.gsc:3578
‪init_levelvars
‪function init_levelvars()
Definition: _zm.gsc:1147
‪callback
‪function callback(event, localclientnum, params)
Definition: callbacks_shared.csc:13
‪clear_all_corpses
‪function clear_all_corpses()
Definition: zombie_utility.gsc:2252
‪ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MIN
‪#define ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MIN
Definition: skeleton.gsh:17
‪spawnSpectator
‪function spawnSpectator()
Definition: _zm.gsc:2640
‪destroy_hud
‪function destroy_hud()
Definition: _zm_utility.gsc:384
‪update_is_player_valid
‪function update_is_player_valid()
Definition: _zm.gsc:7100
‪print_zombie_counts
‪function print_zombie_counts()
Definition: _zm.gsc:4662
‪startTime
‪class AnimationAdjustmentInfoZ startTime
‪activate
‪function activate()
Definition: traps_shared.gsc:655
‪recordActivePlayersEndGameMatchRecordStats
‪function recordActivePlayersEndGameMatchRecordStats()
Definition: _globallogic_player.gsc:2601
‪get_players_on_team
‪function get_players_on_team(exclude)
Definition: _zm.gsc:3622
‪get_current_zone
‪function get_current_zone(return_zone)
Definition: _zm_utility.gsc:3614
‪ARCHETYPE_MECHZ
‪#define ARCHETYPE_MECHZ
Definition: archetype_shared.gsh:17
‪last_stand_grenade_save_and_return
‪function last_stand_grenade_save_and_return()
Definition: _zm.gsc:3165
‪register_vehicle_damage_callback
‪function register_vehicle_damage_callback(func)
Definition: _zm.gsc:5597
‪default_delayed_exit
‪function default_delayed_exit()
Definition: _zm.gsc:6745
‪updateEndOfMatchCounters
‪function updateEndOfMatchCounters()
Definition: _zm.gsc:5958
‪init_player_offhand_weapons
‪function init_player_offhand_weapons()
Definition: _zm_utility.gsc:4496
‪set_sidequest_completed
‪function set_sidequest_completed(id)
Definition: _zm.gsc:6884
‪increment_client_stat
‪function increment_client_stat(stat_name, include_gametype)
Definition: _zm_stats.gsc:389
‪round_up_to_ten
‪function round_up_to_ten(score)
Definition: _zm_utility.csc:48
‪playerzombie_player_damage
‪function playerzombie_player_damage()
Definition: _zm.gsc:4808
‪zm_on_player_disconnect
‪function zm_on_player_disconnect()
Definition: _zm.gsc:6988
‪register_custom_ai_spawn_check
‪function register_custom_ai_spawn_check(str_id, func_check, func_get_spawners, func_get_locations)
Definition: _zm.gsc:3945
‪timer
‪function timer(n_time, str_endon, x, y, height)
Definition: lui_shared.gsc:163
‪register_zombie_damage_override_callback
‪function register_zombie_damage_override_callback(func)
Definition: _zm.gsc:5865
‪remote_revive_watch
‪function remote_revive_watch()
Definition: _zm.gsc:2484
‪ZM_POSITION_QUERY_MOVE_DIST_MAX
‪#define ZM_POSITION_QUERY_MOVE_DIST_MAX
Definition: skeleton.gsh:15
‪get_player_spawns_for_gametype
‪function get_player_spawns_for_gametype()
Definition: _zm_gametype.gsc:589
‪ignore_systems
‪function autoexec ignore_systems()
Definition: _zm.gsc:162
‪laststand_giveback_player_perks
‪function laststand_giveback_player_perks()
Definition: _zm.gsc:2456
‪play_door_dialog
‪function play_door_dialog()
Definition: _zm.gsc:4146
‪play_sound_on_ent
‪function play_sound_on_ent(ref)
Definition: _zm_utility.gsc:3070
‪update_global_counters_on_match_end
‪function update_global_counters_on_match_end()
Definition: _zm_stats.gsc:529
‪get_player_weapon_limit
‪function get_player_weapon_limit(player)
Definition: _zm_utility.gsc:5865
‪remove_ignore_attacker
‪function remove_ignore_attacker()
Definition: _zm.gsc:5078
‪init_fx
‪function init_fx()
Definition: _zm.gsc:1670
‪uploadGlobalStatCounters
‪function uploadGlobalStatCounters()
Definition: _zm.gsc:6325
‪store_crumb
‪function store_crumb(origin)
Definition: _zm.gsc:6461
‪intermission
‪function intermission()
Definition: _zm.gsc:6542
‪increment_player_stat
‪function increment_player_stat(stat_name)
Definition: _zm_stats.gsc:369
‪player_add_points
‪function player_add_points(event, mod, hit_location, is_dog, zombie_team, damage_weapon)
Definition: _zm_score.gsc:129
‪last_stand_restore_pistol_ammo
‪function last_stand_restore_pistol_ammo()
Definition: _zm.gsc:3072
‪playerzombie_play_sound
‪function playerzombie_play_sound(alias)
Definition: _zm.gsc:5030
‪ignore
‪function ignore(str_system)
Definition: system_shared.csc:165
‪last_stand_best_pistol
‪function last_stand_best_pistol()
Definition: _zm.gsc:2924
‪pers_upgrade_perk_lose_restore
‪function pers_upgrade_perk_lose_restore()
Definition: _zm_pers_upgrades_functions.gsc:10
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪Callback_VehicleRadiusDamage
‪function Callback_VehicleRadiusDamage(eInflictor, eAttacker, iDamage, fInnerDamage, fOuterDamage, iDFlags, sMeansOfDeath, weapon, vPoint, fRadius, fConeAngleCos, vConeDir, psOffsetTime)
Definition: _globallogic_vehicle.gsc:266
‪player_getup_setup
‪function player_getup_setup()
Definition: laststand_shared.gsc:213
‪ShowHudAndPlayPromo
‪function ShowHudAndPlayPromo()
Definition: _zm.gsc:534
‪revive_hud_create
‪function revive_hud_create()
Definition: laststand_shared.gsc:135
‪increment_dog_round_stat
‪function increment_dog_round_stat(stat)
Definition: _zm.gsc:7006
‪actor_killed_override
‪function actor_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime)
Definition: _zm.gsc:5872
‪playerzombie_waitfor_buttonrelease
‪function playerzombie_waitfor_buttonrelease(inputType)
Definition: _zm.gsc:5035
‪getFreeSpawnpoint
‪function getFreeSpawnpoint(spawnpoints, player)
Definition: _zm.gsc:690
‪Callback_VehicleDamage
‪function Callback_VehicleDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal)
Definition: _globallogic_vehicle.gsc:45
‪player_grenade_multiattack_bookmark_watcher
‪function player_grenade_multiattack_bookmark_watcher(grenade)
Definition: _zm.gsc:2275
‪wait_till_any
‪function wait_till_any(a_flags)
Definition: flag_shared.csc:227
‪disable_end_game_intermission
‪function disable_end_game_intermission(delay)
Definition: _zm.gsc:6270
‪zombie_head_gib
‪function zombie_head_gib(attacker, means_of_death)
Definition: zombie_utility.gsc:2952
‪init_flags
‪function init_flags()
Definition: _zm.gsc:1597
‪recordPlayerRoundWeapon
‪function recordPlayerRoundWeapon(weapon, statname)
Definition: _zm.gsc:4287
‪player_downed_penalty
‪function player_downed_penalty()
Definition: _zm_score.gsc:646
‪breakAfter
‪function breakAfter(time, damage, piece)
Definition: _zm.gsc:1404
‪zombie_damage
‪function zombie_damage(mod, hit_location, hit_origin, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel)
Definition: _zm_spawner.gsc:1902
‪get_current_actor_count
‪function get_current_actor_count()
Definition: zombie_utility.gsc:2265
‪player_zombie_breadcrumb
‪function player_zombie_breadcrumb()
Definition: _zm.gsc:6365
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪give_start_weapon
‪function give_start_weapon(b_switch_weapon)
Definition: _zm_utility.gsc:4530
‪set_third_person
‪function set_third_person(value)
Definition: _zm.gsc:2755
‪pers_upgrade_perk_lose_save
‪function pers_upgrade_perk_lose_save()
Definition: _zm_pers_upgrades_functions.gsc:9
‪actor_damage_override
‪function actor_damage_override(inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType)
Definition: _zm.gsc:5625
‪cointoss
‪function cointoss()
Definition: math_shared.csc:171
‪player_exit_level
‪function player_exit_level()
Definition: _zm.gsc:6349
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪set_zombie_var
‪function set_zombie_var(zvar, value, is_float=false, column=1, is_team_based=false)
Definition: zombie_utility.gsc:1434
‪player_damage_override
‪function player_damage_override(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime)
Definition: _zm.gsc:5108
‪zm_on_player_connect
‪function zm_on_player_connect()
Definition: _zm.gsc:6958
‪playerzombie_infinite_health
‪function playerzombie_infinite_health()
Definition: _zm.gsc:4907
‪default_find_exit_point
‪function default_find_exit_point()
Definition: _zm.gsc:6767
‪upload_leaderboards
‪function upload_leaderboards()
Definition: _zm.gsc:6301
‪debug_print
‪function debug_print(str_line)
Definition: _zm_daily_challenges.gsc:402
‪screen_fade
‪function screen_fade(n_time, n_target_alpha=1, n_start_alpha=0, str_color="black", b_force_close_menu=false)
Definition: lui_shared.csc:372
‪in_enabled_playable_area
‪function in_enabled_playable_area()
Definition: _zm.gsc:1999
‪wait_and_revive
‪function wait_and_revive()
Definition: _zm.gsc:5533
‪shock_onpain
‪function shock_onpain()
Definition: load_shared.gsc:855
‪printHashIDs
‪function printHashIDs()
Definition: _zm.gsc:7137
‪playerzombie_downed_hud
‪function playerzombie_downed_hud()
Definition: _zm.gsc:4875
‪get_player_too_many_weapons_monitor_wait_time
‪function get_player_too_many_weapons_monitor_wait_time()
Definition: _zm.gsc:2111
‪add_client_stat
‪function add_client_stat(stat_name, stat_value, include_gametype)
Definition: _zm_stats.gsc:353
‪add_global_stat
‪function add_global_stat(stat_name, value)
Definition: _zm_stats.gsc:322
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪playerExert
‪function playerExert(localClientNum, exert)
Definition: _zm_audio.csc:157
‪round_pause
‪function round_pause(delay)
Definition: _zm.gsc:4028
‪destroyElem
‪function destroyElem()
Definition: hud_util_shared.gsc:755
‪Callback_VehicleKilled
‪function Callback_VehicleKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime)
Definition: _globallogic_vehicle.gsc:341
‪last_stand_compare_pistols
‪function last_stand_compare_pistols(struct_array)
Definition: _zm.gsc:2974
‪default_exit_level
‪function default_exit_level()
Definition: _zm.gsc:6718
‪run_custom_ai_spawn_checks
‪function run_custom_ai_spawn_checks()
Definition: _zm.gsc:3878
‪register_player_damage_callback
‪function register_player_damage_callback(func)
Definition: _zm.gsc:5522
‪round_end
‪function round_end()
Definition: _zm_pers_upgrades_system.gsc:6
‪self_delete
‪function self_delete()
Definition: _util.gsc:739
‪getAllOtherPlayers
‪function getAllOtherPlayers()
Definition: _zm.gsc:654
‪register_player_friendly_fire_callback
‪function register_player_friendly_fire_callback(callback)
Definition: _zm.gsc:1579
‪ZM_MAP_EVENT_ROUND_END
‪#define ZM_MAP_EVENT_ROUND_END
Definition: _zm_utility.gsh:49
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪is_weapon_upgraded
‪function is_weapon_upgraded(weapon)
Definition: _zm_weapons.csc:155
‪actor_damage_override_wrapper
‪function actor_damage_override_wrapper(inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, modelIndex, surfaceType, vSurfaceNormal)
Definition: _zm.gsc:5847
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪check_point_in_enabled_zone
‪function check_point_in_enabled_zone(origin, zone_is_active, player_zones)
Definition: _zm_utility.gsc:512
‪get_player_index
‪function get_player_index(player)
Definition: _zm_utility.gsc:5949
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪is_weapon_included
‪function is_weapon_included(weapon)
Definition: _zm_weapons.csc:51
‪add_sound
‪function add_sound(ref, alias)
Definition: _zm_utility.gsc:3030
‪zombiemode_melee_miss
‪function zombiemode_melee_miss()
Definition: _zm.gsc:967
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪upload_zm_dash_counters
‪function upload_zm_dash_counters(force_upload=false)
Definition: _zm_utility.gsc:6258
‪player_died_penalty
‪function player_died_penalty()
Definition: _zm_score.gsc:629
‪onPlayerSpawned
‪function onPlayerSpawned()
Definition: _zm.gsc:1800
‪set_game_var
‪function set_game_var(gvar, val)
Definition: _zm_utility.gsc:5185
‪set_demo_intermission_point
‪function set_demo_intermission_point()
Definition: _zm_utility.gsc:5384
‪init_function_overrides
‪function init_function_overrides()
Definition: _zm.gsc:1338
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: skeleton.gsc:256
‪RED
‪#define RED
Definition: shared.gsh:175
‪last_stand_take_thrown_grenade
‪function last_stand_take_thrown_grenade()
Definition: _zm.gsc:3145
‪startUnitriggers
‪function startUnitriggers()
Definition: _zm.gsc:453
‪round_spawning
‪function round_spawning()
Definition: _zm.gsc:3678
‪zm_on_player_spawned
‪function zm_on_player_spawned()
Definition: _zm.gsc:7094
‪create_counter_hud
‪function create_counter_hud(x)
Definition: _zm_utility.gsc:3587
‪zombie_game_over_death
‪function zombie_game_over_death()
Definition: _zm.gsc:6570
‪update_players_stats_at_match_end
‪function update_players_stats_at_match_end(players)
Definition: _zm_stats.gsc:186
‪get_safe_breadcrumb_pos
‪function get_safe_breadcrumb_pos(player)
Definition: _zm.gsc:3641
‪main_end
‪function main_end()
Definition: _zm_ffotd.csc:6
‪add_zombie_hint
‪function add_zombie_hint(ref, text)
Definition: _zm_utility.gsc:2923
‪check_actor_damage_callbacks
‪function check_actor_damage_callbacks(inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType)
Definition: _zm.gsc:5815
‪spawn_kill_brush
‪function spawn_kill_brush(origin, radius, height)
Definition: _zm.gsc:1965
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪increment_is_drinking
‪function increment_is_drinking()
Definition: _zm_utility.gsc:3859
‪precache_models
‪function precache_models()
Definition: _zm.gsc:1063
‪round_spawning_test
‪function round_spawning_test()
Definition: _zm.gsc:3958
‪clear_path_timers
‪function clear_path_timers()
Definition: _zm.gsc:5489
‪get_player_out_of_playable_area_monitor_wait_time
‪function get_player_out_of_playable_area_monitor_wait_time()
Definition: _zm.gsc:2022
‪has_behavior_attribute
‪function has_behavior_attribute(attribute)
Definition: ai_shared.gsc:198
‪increment_challenge_stat
‪function increment_challenge_stat(stat_name, amount=1)
Definition: _zm_stats.gsc:478
‪last_stand_pistol_swap
‪function last_stand_pistol_swap()
Definition: _zm.gsc:2825
‪player_killed_override
‪function player_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
Definition: _zm.gsc:6359
‪failsafe_revive_give_back_weapons
‪function failsafe_revive_give_back_weapons(excluded_player)
Definition: _zm.gsc:2590
‪round_spawn_failsafe
‪function round_spawn_failsafe()
Definition: zombie_utility.gsc:1806
‪start_zombie_logic_in_x_sec
‪function start_zombie_logic_in_x_sec(time_to_wait)
Definition: _zm.gsc:647
‪zombie_intro_screen
‪function zombie_intro_screen(string1, string2, string3, string4, string5)
Definition: _zm.gsc:1733
‪powerup_round_start
‪function powerup_round_start()
Definition: _zm_powerups.gsc:581
‪round_over
‪function round_over()
Definition: _zm.gsc:4253
‪last_stand_revive
‪function last_stand_revive()
Definition: _zm.gsc:2774
‪spectator_thread
‪function spectator_thread()
Definition: _zm.gsc:2717
‪INTERMISSION_STREAMER_HINT_PRIORITY
‪#define INTERMISSION_STREAMER_HINT_PRIORITY
Definition: _zm.gsc:6611
‪init_player_levelvars
‪function init_player_levelvars()
Definition: _zm.gsc:1283
‪PERK_ELECTRIC_CHERRY
‪#define PERK_ELECTRIC_CHERRY
Definition: _zm_perks.gsh:31
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪track_players_intersection_tracker
‪function track_players_intersection_tracker()
Definition: _zm_utility.gsc:4923
‪round_one_up
‪function round_one_up()
Definition: _zm.gsc:4192
‪check_end_game_intermission_delay
‪function check_end_game_intermission_delay()
Definition: _zm.gsc:6281
‪on_spawned
‪function on_spawned(func, obj)
Definition: callbacks_shared.csc:245
‪spawn_vo
‪function spawn_vo()
Definition: _zm.gsc:1039
‪register_sidequest
‪function register_sidequest(id, sidequest_stat)
Definition: _zm.gsc:6839
‪recordRoundEndStats
‪function recordRoundEndStats()
Definition: _zm.gsc:4323
‪increment_map_cheat_stat
‪function increment_map_cheat_stat(stat_name)
Definition: _zm_stats.gsc:467
‪clear_is_drinking
‪function clear_is_drinking()
Definition: _zm_utility.gsc:3920
‪check_for_valid_spawn_near_position
‪function check_for_valid_spawn_near_position(revivee, v_position, return_struct)
Definition: _zm.gsc:3508
‪get_game_var
‪function get_game_var(gvar)
Definition: _zm_utility.gsc:5198
‪create_streamer_hint
‪function create_streamer_hint(origin, angles, value, lifetime)
Definition: _zm_utility.gsc:6064
‪get_zombie_count_for_round
‪function get_zombie_count_for_round(n_round, n_player_count)
Definition: _zm.gsc:3842
‪waittill_any_ex
‪function waittill_any_ex(...)
Definition: util_shared.csc:270
‪player_too_many_weapons_monitor_takeaway_simultaneous
‪function player_too_many_weapons_monitor_takeaway_simultaneous(primary_weapons_to_take)
Definition: _zm.gsc:2117
‪pers_upgrade_jugg_player_death_stat
‪function pers_upgrade_jugg_player_death_stat()
Definition: _zm_pers_upgrades_functions.gsc:11
‪player_monitor_time_played
‪function player_monitor_time_played()
Definition: _zm.gsc:2260
‪player_laststand
‪function player_laststand(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
Definition: _zm.gsc:2502
‪init_sounds
‪function init_sounds()
Definition: _zm.gsc:1096
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪set_default_laststand_pistol
‪function set_default_laststand_pistol(solo_mode)
Definition: _zm.gsc:7051
‪VERSION_TU15_FFOTD_090816_0
‪#define VERSION_TU15_FFOTD_090816_0
Definition: version.gsh:71
‪player_track_ammo_count
‪function player_track_ammo_count()
Definition: _zm.gsc:978
‪PERK_QUICK_REVIVE
‪#define PERK_QUICK_REVIVE
Definition: _zm_perks.gsh:24
‪has_powerup_weapon
‪function has_powerup_weapon()
Definition: _zm_utility.gsc:4519
‪sndMusicSystem_PlayState
‪function sndMusicSystem_PlayState(state)
Definition: _zm_audio.gsc:1042
‪round_start
‪function round_start()
Definition: _zm.gsc:4071
‪zm_dash_stats_wait_for_consumable_use
‪function zm_dash_stats_wait_for_consumable_use()
Definition: _zm_utility.gsc:6268
‪init_utility
‪function init_utility()
Definition: util_shared.csc:1259
‪set_intermission_point
‪function set_intermission_point()
Definition: _zm.gsc:2624
‪end_game
‪function end_game()
Definition: _zm.gsc:5988
‪is_sidequest_previously_completed
‪function is_sidequest_previously_completed(id)
Definition: _zm.gsc:6878
‪spectator_respawn_player
‪function spectator_respawn_player()
Definition: _zm.gsc:3253
‪set_player_tactical_grenade
‪function set_player_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4250
‪to_mins
‪function to_mins(seconds)
Definition: _zm.gsc:6493
‪set_player_placeable_mine
‪function set_player_placeable_mine(weapon)
Definition: _zm_utility.gsc:4304
‪spectator_respawn_all
‪function spectator_respawn_all()
Definition: _zm_melee_weapon.gsc:247
‪ARCHETYPE_GLAIVE
‪#define ARCHETYPE_GLAIVE
Definition: archetype_shared.gsh:39
‪last_stand_pistol_rank_init
‪function last_stand_pistol_rank_init()
Definition: _zm.gsc:2804
‪zone_is_enabled
‪function zone_is_enabled(zone_name)
Definition: _zm_zonemgr.gsc:65
‪remote_revive
‪function remote_revive(reviver)
Definition: _zm_laststand.gsc:1404
‪set_round_number
‪function set_round_number(new_round)
Definition: _zm.gsc:440
‪delete_in_createfx
‪function delete_in_createfx()
Definition: _zm.gsc:799
‪refresh_player_navcard_hud
‪function refresh_player_navcard_hud()
Definition: _zm.gsc:7022
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪freeze_players
‪function freeze_players(freeze)
Definition: _zm_game_module.gsc:122
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪process_friendly_fire_callbacks
‪function process_friendly_fire_callbacks(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, boneIndex)
Definition: _zm.gsc:1586
‪zombie_eye_glow_stop
‪function zombie_eye_glow_stop()
Definition: zombie_utility.gsc:1733
‪ai_calculate_health
‪function ai_calculate_health(round_number)
Definition: zombie_utility.gsc:1907
‪decrement_is_drinking
‪function decrement_is_drinking()
Definition: _zm_utility.gsc:3898
‪get_player_placeable_mine
‪function get_player_placeable_mine()
Definition: _zm_utility.gsc:4291
‪setSpectatePermissions
‪function setSpectatePermissions(isOn)
Definition: _zm.gsc:2709
‪revive_give_back_weapons
‪function revive_give_back_weapons(w_reviver, w_revive_tool)
Definition: _zm_laststand.gsc:1009
‪spectators_respawn
‪function spectators_respawn()
Definition: _zm.gsc:3231
‪precache_zombie_leaderboards
‪function precache_zombie_leaderboards()
Definition: _zm.gsc:6920
‪init_client_field_callback_funcs
‪function init_client_field_callback_funcs()
Definition: _zm.gsc:1627
‪player_intermission
‪function player_intermission()
Definition: _zm.gsc:6620
‪is_enabled
‪function is_enabled(name)
Definition: _zm_bgb.gsc:4
‪dot_product
‪function dot_product(origin)
Definition: _bot_combat.gsc:198
‪playSwipeSound
‪function playSwipeSound(mod, attacker)
Definition: _zm.gsc:6911
‪watchDisconnect
‪function watchDisconnect()
Definition: _zm.gsc:6996
‪player_reduce_points
‪function player_reduce_points(event, n_amount)
Definition: _zm_score.gsc:460
‪init_custom_ai_type
‪function init_custom_ai_type()
Definition: _zm.gsc:953
‪main_start
‪function main_start()
Definition: _zm_ffotd.csc:4
‪upload_zm_dash_counters_end_game
‪function upload_zm_dash_counters_end_game()
Definition: _zm_utility.gsc:6260
‪player_fake_death
‪function player_fake_death()
Definition: _zm.gsc:6332
‪is_headshot
‪function is_headshot(weapon, sHitLoc, sMeansOfDeath)
Definition: _zm_utility.gsc:5265
‪zm_dash_stats_game_end
‪function zm_dash_stats_game_end()
Definition: _zm_utility.gsc:6266
‪register_offhand_weapons_for_level_defaults
‪function register_offhand_weapons_for_level_defaults()
Definition: _zm_utility.gsc:4471
‪ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MAX
‪#define ZM_POSITION_QUERY_LAST_STAND_MOVE_DIST_MAX
Definition: skeleton.gsh:18
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪player_revive_monitor
‪function player_revive_monitor()
Definition: _zm.gsc:2395
‪players_reached_rounds_counter_watcher
‪function players_reached_rounds_counter_watcher()
Definition: _zm.gsc:932
‪debug_breadcrumbs
‪function debug_breadcrumbs()
Definition: _zm_utility.gsc:3370
‪give_start_weapons
‪function give_start_weapons(takeAllWeapons, alreadySpawned)
Definition: _zm_weapons.gsc:264
‪in_life_brush
‪function in_life_brush()
Definition: _zm.gsc:1943
‪VERSION_SHIP_OBSOLETE
‪#define VERSION_SHIP_OBSOLETE
Definition: version.gsh:111
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪screen_fade_in
‪function screen_fade_in(n_time, v_color, str_menu_id)
Definition: _zm.gsc:6613
‪bookmark
‪function bookmark(type, time, mainClientEnt, otherClientEnt, eventPriority, inflictorEnt, overrideEntityCamera, actorEnt)
Definition: demo_shared.gsc:25
‪check_player_damage_callbacks
‪function check_player_damage_callbacks(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime)
Definition: _zm.gsc:5502
‪recordPrimaryWeaponsStats
‪function recordPrimaryWeaponsStats(base_stat_name, max_weapons)
Definition: _zm.gsc:4299
‪array
‪function filter array
Definition: array_shared.csc:16
‪initializeStatTracking
‪function initializeStatTracking()
Definition: _zm.gsc:6312
‪initActorBookmarkParams
‪function initActorBookmarkParams(killTimesCount, killTimeMsec, killTimeDelay)
Definition: demo_shared.gsc:16
‪spawn_zombie
‪function spawn_zombie(spawner, target_name, spawn_point, round_number)
Definition: zombie_utility.gsc:1454
‪zombie_damage_ads
‪function zombie_damage_ads(mod, hit_location, hit_origin, player, amount, team, weapon, direction_vec, tagName, modelName, partName, dFlags, inflictor, chargeLevel)
Definition: _zm_spawner.gsc:2035
‪last_stand_save_pistol_ammo
‪function last_stand_save_pistol_ammo()
Definition: _zm.gsc:3037
‪get_global_stat
‪function get_global_stat(stat_name)
Definition: _zm_stats.gsc:307
‪get_player_tactical_grenade
‪function get_player_tactical_grenade()
Definition: _zm_utility.gsc:4237
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪player_too_many_players_check
‪function player_too_many_players_check()
Definition: _zm.gsc:7067
‪spawn_vo_player
‪function spawn_vo_player(index, num)
Definition: _zm.gsc:1056
‪get_delay_between_rounds
‪function get_delay_between_rounds()
Definition: _zm.gsc:4282
‪fade_up_over_time
‪function fade_up_over_time(t)
Definition: _zm.gsc:6712
‪spawn_life_brush
‪function spawn_life_brush(origin, radius, height)
Definition: _zm.gsc:1934
‪register_actor_damage_callback
‪function register_actor_damage_callback(func)
Definition: _zm.gsc:5835
‪sndMusicOnKillRound
‪function sndMusicOnKillRound()
Definition: _zm.gsc:4749
‪initialBlackEnd
‪function initialBlackEnd()
Definition: _zm.gsc:639
‪playerzombie_soundboard
‪function playerzombie_soundboard()
Definition: _zm.gsc:4925
‪Callback_PlayerDamage
‪function Callback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal)
Definition: _zm.gsc:1415
‪give_perk
‪function give_perk(perk, bought)
Definition: _zm_perks.gsc:738
‪vehicle_damage_override
‪function vehicle_damage_override(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal)
Definition: _zm.gsc:5607
‪get_valid_spawn_location
‪function get_valid_spawn_location(revivee, spawn_points, closest_group, return_struct)
Definition: _zm.gsc:3451
‪finishPlayerDamageWrapper
‪function finishPlayerDamageWrapper(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, boneIndex, vSurfaceNormal)
Definition: _zm.gsc:1568
‪return_retained_perks
‪function return_retained_perks()
Definition: _zm_perks.gsc:698
‪PERK_WHOSWHO
‪#define PERK_WHOSWHO
Definition: _zm_perks.gsh:33
‪round_spawn_failsafe_debug
‪function round_spawn_failsafe_debug()
Definition: _zm.gsc:4640
‪update_zone_name
‪function update_zone_name()
Definition: _zm.gsc:7113
‪init
‪function init()
Definition: _zm.gsc:215
‪initialBlack
‪function initialBlack()
Definition: _zm.gsc:633
‪registerClientSys
‪function registerClientSys(sSysName)
Definition: util_shared.gsc:1344
‪__init__
‪function __init__()
Definition: _zm.gsc:210
‪post_all_players_connected
‪function post_all_players_connected()
Definition: _zm.gsc:885
‪increment_zm_dash_counter
‪function increment_zm_dash_counter(counter_name, amount)
Definition: _zm_utility.gsc:6262
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪IS_EQUAL
‪#define IS_EQUAL(__a, __b)
Definition: shared.gsh:250
‪recordZMEndGameComScoreEvent
‪function recordZMEndGameComScoreEvent(winner)
Definition: _globallogic.gsc:1173
‪PlayerLastStand
‪function PlayerLastStand(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride)
Definition: _laststand.gsc:63
‪update_playing_utc_time
‪function update_playing_utc_time(matchEndUTCTime)
Definition: _zm_stats.gsc:289
‪first_consumables_used_watcher
‪function first_consumables_used_watcher()
Definition: _zm.gsc:922
‪get_player_lethal_grenade
‪function get_player_lethal_grenade()
Definition: _zm_utility.gsc:4167
‪set_behavior_attribute
‪function set_behavior_attribute(attribute, value)
Definition: ai_shared.gsc:159
‪gib_random_parts
‪function gib_random_parts()
Definition: zombie_utility.gsc:2979
‪take
‪function take(killstreak)
Definition: _killstreaks.gsc:568
‪is_explosive_damage
‪function is_explosive_damage(mod)
Definition: _zm_utility.gsc:5294
‪screen_fade_out
‪function screen_fade_out(n_time, str_color)
Definition: lui_shared.csc:396
‪main
‪function main()
Definition: _global_fx.csc:17
‪player_is_in_laststand
‪function player_is_in_laststand()
Definition: laststand_shared.gsc:18
‪exists
‪function exists(str_flag)
Definition: flag_shared.csc:43
‪auto_revive
‪function auto_revive(reviver, dont_enable_weapons)
Definition: _zm_laststand.gsc:1327
‪round_think
‪function round_think(restart=false)
Definition: _zm.gsc:4335
‪setup_player_navcard_hud
‪function setup_player_navcard_hud()
Definition: _zm.gsc:7015
‪wait_till_timeout
‪function wait_till_timeout(n_timeout, str_flag)
Definition: flag_shared.csc:199
‪get_active_zones_entities
‪function get_active_zones_entities()
Definition: _zm_zonemgr.gsc:1230
‪is_solo_ranked_game
‪function is_solo_ranked_game()
Definition: _zm_utility.gsc:6253
‪can_do_input
‪function can_do_input(inputType)
Definition: _zm.gsc:4990
‪player_spawn_protection
‪function player_spawn_protection()
Definition: _zm.gsc:1921
‪Callback_PlayerLastStand
‪function Callback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
Definition: _zm.gsc:1373
‪init_strings
‪function init_strings()
Definition: _zm.gsc:1076
‪destroy
‪function destroy(watcher, owner)
Definition: _decoy.gsc:108
‪get_current_zombie_count
‪function get_current_zombie_count()
Definition: zombie_utility.gsc:2018
‪set_ignoreme
‪function set_ignoreme(val)
Definition: ai_shared.gsc:33
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪checkForAllDead
‪function checkForAllDead(excluded_player)
Definition: _zm.gsc:1773
‪zombie_speed_up
‪function zombie_speed_up()
Definition: zombie_utility.gsc:1969
‪players_playing
‪function players_playing()
Definition: _zm.gsc:1738
‪zombie_eye_glow
‪function zombie_eye_glow()
Definition: zombie_utility.gsc:1720
‪updatePlayerNum
‪function updatePlayerNum(player)
Definition: _zm.gsc:673
‪revive_hud_show_n_fade
‪function revive_hud_show_n_fade(time)
Definition: laststand_shared.gsc:162
‪in_kill_brush
‪function in_kill_brush()
Definition: _zm.gsc:1974
‪create_and_play_dialog
‪function create_and_play_dialog(category, subcategory, force_variant)
Definition: _zm_audio.gsc:603
‪player_too_many_weapons_monitor
‪function player_too_many_weapons_monitor()
Definition: _zm.gsc:2172
‪default_validate_enemy_path_length
‪function default_validate_enemy_path_length(player)
Definition: _zm_utility.gsc:1380
‪cheat_enabled
‪function cheat_enabled(val)
Definition: _zm.gsc:427
‪post_main
‪function post_main()
Definition: _zm.gsc:422
‪set_player_lethal_grenade
‪function set_player_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4180
‪pers_insta_kill_melee_swipe
‪function pers_insta_kill_melee_swipe(sMeansOfDeath, eAttacker)
Definition: _zm_pers_upgrades_functions.gsc:8
‪init_dvars
‪function init_dvars()
Definition: _zm.gsc:1303
‪ZM_MAP_EVENT_ROUND_START
‪#define ZM_MAP_EVENT_ROUND_START
Definition: _zm_utility.gsh:48
‪player_prevent_damage
‪function player_prevent_damage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime)
Definition: _zm.gsc:2369
‪last_stand_minimum_pistol_override
‪function last_stand_minimum_pistol_override()
Definition: _zm.gsc:2896
‪on_connect
‪function on_connect()
Definition: _arena.gsc:20
‪sndPlayerHitAlert
‪function sndPlayerHitAlert(e_victim, str_meansofdeath, e_inflictor, weapon)
Definition: _zm_audio.gsc:1927
‪award_grenades_for_survivors
‪function award_grenades_for_survivors()
Definition: _zm.gsc:4564
‪is_idgun_damage
‪function is_idgun_damage(weapon)
Definition: _zm.gsc:7084
‪play_level_start_vox_delayed
‪function play_level_start_vox_delayed()
Definition: _zm.gsc:6830
‪wait_till_clear
‪function wait_till_clear(str_flag)
Definition: flag_shared.csc:248
‪zombify_player
‪function zombify_player()
Definition: _zm.gsc:4759
‪ARCHETYPE_ZOMBIE_QUAD
‪#define ARCHETYPE_ZOMBIE_QUAD
Definition: archetype_shared.gsh:21
‪round_wait
‪function round_wait()
Definition: _zm.gsc:4698
‪get_zombie_spawn_delay
‪function get_zombie_spawn_delay(n_round)
Definition: _zm.gsc:4598
‪get_round_number
‪function get_round_number()
Definition: _zm.gsc:447
‪decrement_ignoreme
‪function decrement_ignoreme()
Definition: _zm_utility.gsc:3840
‪wait_zone_flags_updating
‪function wait_zone_flags_updating()
Definition: _zm_zonemgr.gsc:652
‪zm_dash_stats_game_start
‪function zm_dash_stats_game_start()
Definition: _zm_utility.gsc:6264
‪name
‪class GroundFx name
‪is_placeable_mine
‪function is_placeable_mine(weapon)
Definition: _zm_utility.gsc:4267
‪ARCHETYPE_MARGWA
‪#define ARCHETYPE_MARGWA
Definition: archetype_shared.gsh:16
‪player_grenade_watcher
‪function player_grenade_watcher()
Definition: _zm.gsc:2341
‪onPlayerConnect_clientDvars
‪function onPlayerConnect_clientDvars()
Definition: _zm.gsc:1755
‪take_fallback_weapon
‪function take_fallback_weapon()
Definition: _zm_melee_weapon.gsc:223
‪round_end_monitor
‪function round_end_monitor()
Definition: _zm.gsc:5940
‪ZM_POSITION_QUERY_RADIUS
‪#define ZM_POSITION_QUERY_RADIUS
Definition: skeleton.gsh:13
‪onFindValidSpawnPoint
‪function onFindValidSpawnPoint()
Definition: _zm_gametype.gsc:434
‪check_for_valid_spawn_near_team
‪function check_for_valid_spawn_near_team(revivee, return_struct)
Definition: _zm.gsc:3361
‪move_zombie_spawn_location
‪function move_zombie_spawn_location(spot)
Definition: _zm_utility.gsc:188
‪ZM_LASTSTAND_VISIONSET
‪#define ZM_LASTSTAND_VISIONSET
Definition: _zm_laststand.gsh:1
‪spectator_respawn
‪function spectator_respawn()
Definition: _zm.gsc:3277
‪start_zm_dash_counter_watchers
‪function start_zm_dash_counter_watchers()
Definition: _zm.gsc:916
‪player_monitor_travel_dist
‪function player_monitor_travel_dist()
Definition: _zm.gsc:2244
‪CodeCallback_DestructibleEvent
‪function CodeCallback_DestructibleEvent(event, param1, param2, param3)
Definition: _zm.gsc:1380
‪default_max_zombie_func
‪function default_max_zombie_func(max_num, n_round)
Definition: zombie_utility.gsc:1933
‪fade_out_intro_screen_zm
‪function fade_out_intro_screen_zm(hold_black_time, fade_out_time, destroyed_afterwards)
Definition: _zm.gsc:469
‪wait_until_first_player
‪function wait_until_first_player()
Definition: _zm.gsc:4181
‪rebuild_barrier_reward_reset
‪function rebuild_barrier_reward_reset()
Definition: _zm_blockers.gsc:2361
‪set_global_stat
‪function set_global_stat(stat_name, value)
Definition: _zm_stats.gsc:312
‪increment_ignoreme
‪function increment_ignoreme()
Definition: _zm_utility.gsc:3833
‪recordRoundStartStats
‪function recordRoundStartStats()
Definition: _zm.gsc:4308
‪zbot_spawn
‪function zbot_spawn()
Definition: _zm.gsc:861
‪playerzombie_downed_state
‪function playerzombie_downed_state()
Definition: _zm.gsc:4841
‪add_bots
‪function add_bots()
Definition: _zm.gsc:824
‪onAllPlayersReady
‪function onAllPlayersReady()
Definition: _zm.gsc:546
‪perk_set_max_health_if_jugg
‪function perk_set_max_health_if_jugg(str_perk, set_preMaxHealth, clamp_health_to_max_health)
Definition: _zm_perks.gsc:791
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪magic_bullet_shield
‪function magic_bullet_shield(ent)
Definition: util_shared.gsc:1997
‪player_too_many_weapons_monitor_takeaway_sequence
‪function player_too_many_weapons_monitor_takeaway_sequence(primary_weapons_to_take)
Definition: _zm.gsc:2143
‪is_reviving_any
‪function is_reviving_any()
Definition: _zm_laststand.gsc:1144