‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm_utility.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\array_shared;
4 #using scripts\shared\clientfield_shared;
5 #using scripts\shared\flag_shared;
6 #using scripts\shared\hud_message_shared;
7 #using scripts\shared\laststand_shared;
8 #using scripts\shared\util_shared;
9 
10 #insert scripts\shared\shared.gsh;
11 #insert scripts\shared\statstable_shared.gsh;
12 
13 #using scripts\shared\ai\zombie_utility;
14 
15 #using scripts\zm\_util;
16 #using scripts\zm\_zm;
17 #using scripts\zm\_zm_ai_faller;
18 #using scripts\zm\_zm_audio;
19 #using scripts\zm\_zm_bgb;
20 #using scripts\zm\_zm_equipment;
21 #using scripts\zm\_zm_laststand;
22 #using scripts\zm\_zm_perks;
23 #using scripts\zm\_zm_power;
24 #using scripts\zm\_zm_powerups;
25 #using scripts\zm\_zm_server_throttle;
26 #using scripts\zm\_zm_stats;
27 #using scripts\zm\_zm_spawner;
28 #using scripts\zm\_zm_weapons;
29 
30 #insert scripts\zm\_zm_perks.gsh;
31 #insert scripts\zm\_zm_utility.gsh;
32 
33 #namespace zm_utility;
34 
35 function ‪init_utility()
36 {
37 // level thread edge_fog_start();
38 
39 // level thread hudelem_count();
40 }
41 
42 function ‪is_Classic()
43 {
44  return true;
45 }
46 
47 function ‪is_Standard()
48 {
49  dvar = GetDvarString( "ui_gametype" );
50 
51  if ( dvar == "zstandard" )
52  {
53  return true;
54  }
55 
56  return false;
57 }
58 
59 
61 {
62  return ( seconds * 1000 );
63 }
64 
65 function ‪is_player()
66 {
67  return ( IsPlayer( self ) || ( IsDefined( self.pers ) && ‪IS_TRUE( self.pers[ "isBot" ] ) ) );
68 }
69 
70 // self is Ai and chunk is selected piece
71 function ‪lerp( chunk )
72 {
73  // anim_reach_aligned
74  link = ‪Spawn( "script_origin", self GetOrigin() ); // link is a new origin of the ai
75  link.angles = self.first_node.angles ; // link now has the angles of itself, perhaps these angles aren't coming over..
76  self LinkTo(link); // link ai + origin to chunk + origin
77 
78  // link RotateTo(chunk.origin GetTagAngles("Tag_bottom"), level._CONTEXTUAL_GRAB_LERP_TIME); // this should angle him to spot
79  // link MoveTo(chunk.origin GetTagOrigin("Tag_bottom"), level._CONTEXTUAL_GRAB_LERP_TIME); // this should move him over to spot
80 
81  // I need to have the offest for the bar
82  link RotateTo(self.first_node.angles , level._CONTEXTUAL_GRAB_LERP_TIME); // this should angle him to spot
83 
84  link MoveTo(self.attacking_spot , level._CONTEXTUAL_GRAB_LERP_TIME); // this should move him over to spot
85  //link RotateTo(self GetTagAngles ("Tag_player"), level._CONTEXTUAL_GRAB_LERP_TIME); // this should angle him to spot
86  //link MoveTo(self GetTagOrigin ("Tag_player"), level._CONTEXTUAL_GRAB_LERP_TIME); // this should move him over to spot
87 
88  link ‪util::waittill_multiple("rotatedone", "movedone");
89 
90  self Unlink();
91  link Delete();
92 
93  return;
94 }
95 
97 {
98 /*
99  enemies = [];
100  level.current_zombie_array = [];
101  enemies = GetAiSpeciesArray( level.zombie_team, "all" );
102 
103  for( i = 0; i < enemies.size; i++ )
104  {
105  if ( IS_TRUE( enemies[i].ignore_enemy_count ) )
106  {
107  continue;
108  }
109  ARRAY_ADD( level.current_zombie_array, enemies[i] );
110  }
111 
112  level.current_zombie_count = level.current_zombie_array.size;
113 */
114 }
115 
117 {
118  if ( isdefined( level.speed_change_round ) )
119  {
120  if ( level.round_number >= level.speed_change_round )
121  {
122  speed_percent = 0.2 + ( ( level.round_number - level.speed_change_round ) * 0.2 );
123  speed_percent = min( speed_percent, 1 );
124 
125  change_round_max = Int( level.speed_change_max * speed_percent );
126  change_left = change_round_max - level.speed_change_num;
127 
128  if ( change_left == 0 )
129  {
131  return;
132  }
133 
134  change_speed = RandomInt( 100 );
135  if ( change_speed > 80 )
136  {
138  return;
139  }
140 
142  zombie_left = level.zombie_ai_limit - zombie_count;
143 
144  if ( zombie_left == change_left ) // need to force the speed change at this point
145  {
147  return;
148  }
149  }
150  }
151 
153 }
154 
156 {
157  level.speed_change_num++;
158  if ( level.gamedifficulty == 0 )
159  {
161  }
162  else
163  {
164  /*
165  iprintln( "walker round " + level.round_number + " change " + level.speed_change_num );
166  */
168  }
169 
170  self thread ‪speed_change_watcher();
171 }
172 
174 {
175  self ‪zombie_utility::set_zombie_run_cycle( "super_sprint" );
176 }
177 
179 {
180  self waittill( "death" );
181 
182  if ( level.speed_change_num > 0 )
183  {
184  level.speed_change_num--;
185  }
186 }
187 
189 {
190  self endon( "death" );
191 
192  if(IsDefined(self.spawn_pos))
193  {
194  self notify("risen", self.spawn_pos.script_string );
195  return;
196  }
197  self.spawn_pos = spot;
198 
199  // give target from spawn location to spawner to path
200  if(IsDefined(spot.target))
201  {
202  self.target = spot.target;
203  }
204 
205  if(IsDefined(spot.zone_name))
206  {
207  self.zone_name = spot.zone_name;
208  self.previous_zone_name = spot.zone_name;
209  }
210 
211  if(IsDefined(spot.script_parameters))
212  {
213  self.script_parameters = spot.script_parameters;
214  }
215 
216  if(!IsDefined(spot.script_noteworthy))
217  {
218  spot.script_noteworthy = "spawn_location";
219  }
220 
221  tokens = StrTok( spot.script_noteworthy, " " );
222  foreach ( index, token in tokens )
223  {
224  // time bomb needs to spawn zombies away from their original spawn point; this should point to a struct
225  if ( IsDefined( self.spawn_point_override ) )
226  {
227  spot = self.spawn_point_override;
228  token = spot.script_noteworthy;
229  }
230 
231  if ( token == "custom_spawner_entry" )
232  {
233  next_token = index + 1;
234 
235  if ( IsDefined( tokens[ next_token ] ) )
236  {
237  str_spawn_entry = tokens[ next_token ];
238 
239  if ( IsDefined( level.custom_spawner_entry ) && IsDefined( level.custom_spawner_entry[ str_spawn_entry ] ) )
240  {
241  self thread [[ level.custom_spawner_entry[ str_spawn_entry ] ]]( spot );
242  continue;
243  }
244  }
245  }
246 
247  if(token == "riser_location")
248  {
249  self thread ‪zm_spawner::do_zombie_rise(spot);
250  }
251  else if (token == "faller_location")
252  {
253  self thread ‪zm_ai_faller::do_zombie_fall(spot);
254  }
255  else if (token == "spawn_location" )
256  {
257  // anchor defined by some other custom spawner behavior, so bypass standard behavior
258  if ( IsDefined( self.anchor ) )
259  {
260  return;
261  }
262 
263  self.anchor = ‪spawn("script_origin", self.origin);
264  self.anchor.angles = self.angles;
265  self linkto(self.anchor);
266  self.anchor thread ‪anchor_delete_failsafe( self );
267 
268  if( !isDefined( spot.angles ) )
269  {
270  spot.angles = (0, 0, 0);
271  }
272 
273  self Ghost();
274  self.anchor moveto(spot.origin, .05);
275  self.anchor waittill("movedone");
276 
277  // face goal
279  if (IsDefined(target_org))
280  {
281  anim_ang = VectorToAngles(target_org - self.origin);
282  self.anchor RotateTo((0, anim_ang[1], 0), .05);
283  self.anchor waittill("rotatedone");
284  }
285  if(isDefined(level.zombie_spawn_fx))
286  {
287  playfx(level.zombie_spawn_fx,spot.origin);
288  }
289  self unlink();
290 
291  if(isDefined(self.anchor))
292  {
293  self.anchor delete();
294  }
295  if(!‪IS_TRUE(self.dontShow))
296  {
297  self Show();
298  }
299  self notify("risen", spot.script_string );
300  }
301  }
302 }
303 
304 
305 // self is an anchor script_origin
306 // There is a very small window where a zombie could be killed and the anchor would be left hanging around.
307 function ‪anchor_delete_failsafe( ai_zombie )
308 {
309  ai_zombie endon( "risen" );
310 
311  ai_zombie waittill( "death" );
312 
313  if( isdefined( self ) )
314  {
315  self Delete();
316  }
317 }
318 
320 {
321  self endon( "death" );
322 
323  waittillframeend; // spawn functions should override default settings, so they need to be last
324 
325  for (i = 0; i < level.spawn_funcs[ self.team ].size; i++)
326  {
327  func = level.spawn_funcs[ self.team ][ i ];
328  ‪util::single_thread(self, func[ "function" ], func[ "param1" ], func[ "param2" ], func[ "param3" ], func[ "param4" ], func[ "param5" ] );
329  }
330 
331  if ( IsDefined( self.spawn_funcs ))
332  {
333  for (i = 0; i < self.spawn_funcs.size; i++)
334  {
335  func = self.spawn_funcs[ i ];
336  ‪util::single_thread(self, func[ "function" ], func[ "param1" ], func[ "param2" ], func[ "param3" ], func[ "param4" ] );
337  }
338 
339  /#
340  self.saved_spawn_functions = self.spawn_funcs;
341  #/
342 
343  self.spawn_funcs = undefined;
344 
345  /#
346  // keep them around in developer mode, for debugging
347  self.spawn_funcs = self.saved_spawn_functions;
348  self.saved_spawn_functions = undefined;
349  #/
350 
351  self.spawn_funcs = undefined;
352  }
353 }
354 
355 
356 function ‪create_simple_hud( client, team )
357 {
358  if ( IsDefined( team ) )
359  {
360  hud = NewTeamHudElem( team );
361  hud.team = team;
362  }
363  else
364  {
365  if( IsDefined( client ) )
366  {
367  hud = NewClientHudElem( client );
368  }
369  else
370  {
371  hud = NewHudElem();
372  }
373  }
374 
375  level.hudelem_count++;
376 
377  hud.foreground = true;
378  hud.sort = 1;
379  hud.hidewheninmenu = false;
380 
381  return hud;
382 }
383 
384 function ‪destroy_hud()
385 {
386  level.hudelem_count--;
387  self Destroy();
388 }
389 
390 
391 // self = exterior_goal which is barrier_chunks
392 function ‪all_chunks_intact( barrier, barrier_chunks )
393 {
394  if(isdefined(barrier.zbarrier))
395  {
396  pieces = barrier.zbarrier GetZBarrierPieceIndicesInState("closed");
397 
398  if(pieces.size != barrier.zbarrier GetNumZBarrierPieces())
399  {
400  return false;
401  }
402  }
403  else
404  {
405  for( i = 0; i < barrier_chunks.size; i++ ) // Count up barrier_chunks total size
406  {
407  if( barrier_chunks[i] ‪get_chunk_state() != "repaired" ) // if any piece has the state of not repaired then return false
408  {
409  return false;
410  }
411  }
412  }
413 
414  return true; // if the board has been repaired then return true
415 }
416 
417 
418 // self = exterior_goal which is barrier_chunks
419 function ‪no_valid_repairable_boards( barrier, barrier_chunks )
420 {
421 
422  if(isdefined(barrier.zbarrier))
423  {
424  pieces = barrier.zbarrier GetZBarrierPieceIndicesInState("open");
425 
426  if(pieces.size)
427  {
428  return false;
429  }
430  }
431  else
432  {
433  for( i = 0; i < barrier_chunks.size; i++ ) // Count up barrier_chunks total size
434  {
435  if( barrier_chunks[i] ‪get_chunk_state() == "destroyed" ) // if any piece has been destroyed return false
436  {
437  return false;
438  }
439  }
440  }
441 
442  return true; // if any piece is not destroyed then return true
443 }
444 
445 function ‪is_Survival()
446 {
447  return false;
448 }
449 
450 function ‪is_Encounter()
451 {
452  return false;
453 }
454 
455 function ‪all_chunks_destroyed( barrier, barrier_chunks )
456 {
457  if(isdefined(barrier.zbarrier))
458  {
459  pieces = ArrayCombine(barrier.zbarrier GetZBarrierPieceIndicesInState("open"), barrier.zbarrier GetZBarrierPieceIndicesInState("opening"), true, false);
460 
461  if(pieces.size != barrier.zbarrier GetNumZBarrierPieces())
462  {
463  return false;
464  }
465  }
466  else if( IsDefined( barrier_chunks ) )
467  {
468  ASSERT( IsDefined(barrier_chunks), "zombie_utility::all_chunks_destroyed - Barrier chunks undefined" );
469  for( i = 0; i < barrier_chunks.size; i++ )
470  {
471  if( barrier_chunks[i] ‪get_chunk_state() != "destroyed" )
472  {
473  return false;
474  }
475  }
476  }
477  return true;
478 }
479 
481 {
482  playable_area = getentarray("player_volume","script_noteworthy");
483 
484  if ( !IsDefined( level.check_model ) )
485  {
486  level.check_model = ‪spawn ("script_model", origin + (0,0,40));
487  }
488  else
489  {
490  level.check_model.origin = origin + ( 0, 0, 40 );
491  }
492 
493  valid_point = false;
494  for (i = 0; i < playable_area.size; i++)
495  {
496  if (level.check_model istouching(playable_area[i]))
497  {
498  valid_point = true;
499  }
500  }
501 
502  return valid_point;
503 }
504 
505 //*****************************************************************************
506 // origin -
507 // zone_is_active - (optional) if set the zone must also be active as well
508 // player_zones - (optional) optimization
509 //*****************************************************************************
510 
511 //aka check_point_in_active_zone( origin )
512 function ‪check_point_in_enabled_zone( origin, zone_is_active, player_zones )
513 {
514  if( !IsDefined(player_zones) )
515  {
516  player_zones = getentarray("player_volume","script_noteworthy");
517  }
518 
519  if( !isDefined( level.zones ) || !isDefined( player_zones ) )
520  {
521  return true;
522  }
523 
524  if ( !isdefined( level.e_check_point ) )
525  {
526  // Just spawn the checker entity once and move it around as needed instead of creating and deleting all the time
527  level.e_check_point = ‪spawn( "script_origin", origin+(0, 0, 40) );
528  }
529  else
530  {
531  level.e_check_point.origin = origin+(0,0,40);
532  }
533 
534  one_valid_zone = false;
535  for( i = 0; i < player_zones.size; i++ )
536  {
537  if( level.e_check_point IsTouching( player_zones[i] ) )
538  {
539  zone = level.zones[player_zones[i].targetname];
540 
541  if( IsDefined(zone) && ‪IS_TRUE(zone.is_enabled) )
542  {
543  if( IsDefined(zone_is_active) && (zone_is_active == true) && !‪IS_TRUE(zone.is_active) )
544  {
545  continue;
546  }
547 
548  one_valid_zone = true;
549  break;
550  }
551  }
552  }
553 
554  return one_valid_zone;
555 }
556 
557 function ‪round_up_to_ten( score )
558 {
559  new_score = score - score % 10;
560  if( new_score < score )
561  {
562  new_score += 10;
563  }
564  return new_score;
565 }
566 
567 function ‪round_up_score( score, value )
568 {
569  score = int(score); // Make sure it's an int or modulus will die
570 
571  new_score = score - score % value;
572  if( new_score < score )
573  {
574  new_score += value;
575  }
576  return new_score;
577 }
578 
579 function ‪halve_score( n_score )
580 {
581  n_score = n_score / 2;
582  n_score = ‪zm_utility::round_up_score( n_score, 10 );
583 
584  return n_score;
585 }
586 
587 function ‪random_tan()
588 {
589  rand = randomint( 100 );
590 
591  if(isDefined(level.char_percent_override) )
592  {
593  percentNotCharred = level.char_percent_override;
594  }
595  else
596  {
597  percentNotCharred = 65;
598  }
599 
600 // if( rand > percentNotCharred )
601 // {
602 // self StartTanning();
603 // }
604  // PI_CHANGE_END
605 }
606 
607 // Returns the amount of places before the decimal, ie 1000 = 4, 100 = 3...
609 {
610  abs_num = abs( num );
611  count = 0;
612  while( 1 )
613  {
614  abs_num *= 0.1; // Really doing num / 10
615  count += 1;
616 
617  if( abs_num < 1 )
618  {
619  return count;
620  }
621  }
622 }
623 
624 function ‪create_zombie_point_of_interest( attract_dist, num_attractors, added_poi_value, start_turned_on, initial_attract_func, arrival_attract_func,poi_team )
625 {
626  if( !isDefined( added_poi_value ) )
627  {
628  self.added_poi_value = 0;
629  }
630  else
631  {
632  self.added_poi_value = added_poi_value;
633  }
634 
635  if( !isDefined( start_turned_on ) )
636  {
637  start_turned_on = true;
638  }
639 
640  if ( !isdefined( attract_dist ) )
641  {
642  attract_dist = 1536; // Covers all available zombies within a given district
643  }
644 
645  self.script_noteworthy = "zombie_poi";
646  self.poi_active = start_turned_on;
647 
648  if( isDefined( attract_dist ) )
649  {
650  self.max_attractor_dist = attract_dist;
651  self.poi_radius = attract_dist * attract_dist;
652  }
653  else // This poi has no maximum attract distance, it will attract all zombies
654  {
655  self.poi_radius = undefined;
656  }
657  self.num_poi_attracts = num_attractors;
658  self.attract_to_origin = true;
659  self.attractor_array = [];
660  self.initial_attract_func = undefined;
661  self.arrival_attract_func = undefined;
662  if(isDefined(poi_team))
663  {
664  self._team = poi_team;
665  }
666 
667  // any special functions for initial reaction or arrival at the poi are stored here for get_zombie_point_of_intrest
668  if( IsDefined( initial_attract_func ) )
669  {
670  self.initial_attract_func = initial_attract_func;
671  }
672 
673  if( IsDefined( arrival_attract_func ) )
674  {
675  self.arrival_attract_func = arrival_attract_func;
676  }
677 
678  ‪ARRAY_ADD( level.zombie_poi_array, self );
680 
681 }
682 
684 {
685  self waittill( "death" );
686 
687  //Remove from list
688  if ( IsInArray( level.zombie_poi_array, self ) )
689  {
690  ArrayRemoveValue( level.zombie_poi_array, self );
691  }
692 }
693 
695 {
696  self endon( "death" );
697 
698  while ( 1 )
699  {
700  foreach( attract in self.attractor_positions )
701  {
702  passed = BulletTracePassed( attract[0] + (0, 0, 24), self.origin + (0, 0, 24), false, self );
703  if ( passed )
704  {
705  /# debugstar( attract[0], 6, (1,1,1) ); #/
706  }
707  else
708  {
709  /# debugstar( attract[0], 6, (1,0,0) ); #/
710  }
711  }
712 
714  }
715 }
716 
717 function ‪create_zombie_point_of_interest_attractor_positions( num_attract_dists, attract_dist )
718 {
719  self endon( "death" );
720 
721  if( !isdefined( self.num_poi_attracts ) || (isDefined(self.script_noteworthy) && self.script_noteworthy != "zombie_poi" ))
722  {
723  return;
724  }
725 
726  if( !isdefined( num_attract_dists ) ) // TODO Holdover from previous logic. Should be reevaluated
727  {
728  num_attract_dists = 4;
729  }
730 
731  // Creates matrix of attraction points and assigns them to grenade
732  queryResult = PositionQuery_Source_Navigation( self.origin, (attract_dist / 2), self.max_attractor_dist, (attract_dist / 2), (attract_dist / 2), true, (attract_dist / 2) );
733 
734  if( queryResult.data.size < self.num_poi_attracts )
735  {
736  self.num_poi_attracts = queryResult.data.size;
737  }
738  for ( i = 0; i < self.num_poi_attracts; i++ )
739  {
740  if ( ‪IS_TRUE( level.validate_poi_attractors ) )
741  {
742  passed = BulletTracePassed( queryResult.data[i].origin + (0, 0, 24), self.origin + (0, 0, 24), false, self );
743  if ( passed )
744  {
745  self.attractor_positions[i][0] = queryResult.data[i].origin;
746  self.attractor_positions[i][1] = self;
747  }
748  }
749  else
750  {
751  self.attractor_positions[i][0] = queryResult.data[i].origin;
752  self.attractor_positions[i][1] = self;
753  }
754  }
755 
756  if( !IsDefined( self.attractor_positions ) )
757  {
758  self.attractor_positions = [];
759  }
760 
761  self.num_attract_dists = num_attract_dists;
762 
763  // The last index in the attractor_position arrays for each of the possible distances. The array is a holdover from previous logic.
764  self.last_index = [];
765  for( i = 0; i < num_attract_dists; i++ )
766  {
767  self.last_index[i] = -1;
768  }
769 
770  // Represents origin point TODO Holdover from previous logic. Should be reevaluated
771  self.last_index[0] = 1;
772 
773  // Represents total number of attraction points TODO Holdover from previous logic. Should be reevaluated
774  self.last_index[1] = self.attractor_positions.size;
775 
776  self.attract_to_origin = false;
777 
778  self notify( "attractor_positions_generated" );
779  level notify( "attractor_positions_generated" );
780 
781 // self thread debug_draw_new_attractor_positions();
782 }
783 
784 function ‪generated_radius_attract_positions( forward, offset, num_positions, attract_radius )
785 {
786  self endon( "death" );
787 
788  epsilon = 1;
789  failed = 0;
790  degs_per_pos = 360 / num_positions;
791  for( i = offset; i < 360+offset; i += degs_per_pos )
792  {
793  altforward = forward * attract_radius;
794  rotated_forward = ( (cos(i)*altforward[0] - sin(i)*altforward[1]), (sin(i)*altforward[0] + cos(i)*altforward[1]), altforward[2] );
795 
796  if(isDefined(level.poi_positioning_func))
797  {
798  pos = [[level.poi_positioning_func]](self.origin, rotated_forward);
799  }
800  else if(‪IS_TRUE(level.use_alternate_poi_positioning))
801  {
802  pos = ‪zm_server_throttle::server_safe_ground_trace( "poi_trace", 10, self.origin + rotated_forward + ( 0, 0, 10 ) ); //only trace from 10 units above instead of 100 units
803  }
804  else
805  {
806  pos = ‪zm_server_throttle::server_safe_ground_trace( "poi_trace", 10, self.origin + rotated_forward + ( 0, 0, 100 ) );
807  }
808 
809  if(!isDefined(pos))
810  {
811  failed++;
812  continue;
813  }
814 
815  if(‪IS_TRUE(level.use_alternate_poi_positioning)) // Attractors are defined and sent to the array here
816  {
817  if ( isDefined( self ) && isDefined( self.origin ) )
818  {
819  if( self.origin[2] >= (pos[2]-epsilon) && self.origin[2] - pos[2] <= 150 )
820  {
821  pos_array = [];
822  pos_array[0] = pos;
823  pos_array[1] = self;
824  ‪ARRAY_ADD( self.attractor_positions , pos_array );
825  }
826  }
827  else
828  {
829  failed++;
830  }
831  }
832  else if(abs( pos[2] - self.origin[2] ) < 60 )
833  {
834  pos_array = [];
835  pos_array[0] = pos;
836  pos_array[1] = self;
837  ‪ARRAY_ADD( self.attractor_positions , pos_array );
838  }
839  else
840  {
841  failed++;
842  }
843  }
844  return failed;
845 }
846 
848 {
849  /#
850  while( true )
851  {
852  while( !isDefined( self.attractor_positions ) )
853  {
855  continue;
856  }
857  for( i = 0; i < self.attractor_positions.size; i++ )
858  {
859  Line( self.origin, self.attractor_positions[i][0], (1, 0, 0), true, 1 );
860  }
862  if( !IsDefined( self ) )
863  {
864  return;
865  }
866  }
867  #/
868 }
869 
871 {
872  /#
873  while( true )
874  {
875  while( !isDefined( self.claimed_attractor_positions ) )
876  {
878  continue;
879  }
880  for( i = 0; i < self.claimed_attractor_positions.size; i++ )
881  {
882  Line( self.origin, self.claimed_attractor_positions[i][0], (0, 1, 0), true, 1 );
883  }
885  if( !IsDefined( self ) )
886  {
887  return;
888  }
889  }
890  #/
891 }
892 
893 function ‪get_zombie_point_of_interest( origin, poi_array )
894 {
895  AIProfile_BeginEntry( "get_zombie_point_of_interest" );
896 
897  if ( ‪IS_TRUE( self.ignore_all_poi ) )
898  {
899  AIProfile_EndEntry();
900  return undefined;
901  }
902 
903  curr_radius = undefined;
904 
905  if ( isdefined( poi_array ) )
906  {
907  ent_array = poi_array;
908  }
909  else
910  {
911  ent_array = level.zombie_poi_array;//getEntArray( "zombie_poi", "script_noteworthy" );
912  }
913 
914  best_poi = undefined;
915  position = undefined;
916  best_dist = 10000 * 10000;
917 
918  for( i = 0; i < ent_array.size; i++ )
919  {
920  if( !isDefined( ent_array[i] ) || !isDefined( ent_array[i].poi_active ) || !ent_array[i].poi_active )
921  {
922  continue;
923  }
924 
925  if ( isDefined( self.ignore_poi_targetname ) && self.ignore_poi_targetname.size > 0 )
926  {
927  if ( isDefined( ent_array[i].targetname ) )
928  {
929  ‪ignore = false;
930  for ( j = 0; j < self.ignore_poi_targetname.size; j++ )
931  {
932  if ( ent_array[i].targetname == self.ignore_poi_targetname[j] )
933  {
934  ‪ignore = true;
935  break;
936  }
937  }
938  if ( ‪ignore )
939  {
940  continue;
941  }
942  }
943  }
944 
945  if ( isDefined( self.ignore_poi ) && self.ignore_poi.size > 0 )
946  {
947  ‪ignore = false;
948  for ( j = 0; j < self.ignore_poi.size; j++ )
949  {
950  if ( self.ignore_poi[j] == ent_array[i] )
951  {
952  ‪ignore = true;
953  break;
954  }
955  }
956  if ( ‪ignore )
957  {
958  continue;
959  }
960  }
961 
962  dist = distanceSquared( origin, ent_array[i].origin );
963 
964  dist -= ent_array[i].added_poi_value;
965 
966  if( isDefined( ent_array[i].poi_radius ) )
967  {
968  curr_radius = ent_array[i].poi_radius;
969  }
970 
971  if( (!isDefined( curr_radius ) || dist < curr_radius) && dist < best_dist && ent_array[i] ‪can_attract(self) )
972  {
973  best_poi = ent_array[i];
974  best_dist = dist;
975  }
976  }
977 
978  if( isDefined( best_poi ) )
979  {
980  if(isDefined(best_poi._team))
981  {
982  if(isDefined(self._race_team) && self._race_team != best_poi._team)
983  {
984  AIProfile_EndEntry();
985  return undefined;
986  }
987  }
988  if( ‪IS_TRUE( best_poi._new_ground_trace ) ) // needed for the bhb so it won't trace through metal clip
989  {
990  position = [];
991  position[0] = ‪groundpos_ignore_water_new( best_poi.origin + (0, 0, 100) );
992  position[1] = self;
993  }
994  else if( isDefined( best_poi.attract_to_origin ) && best_poi.attract_to_origin ) // Override, currently only used for monkeys in the air.
995  {
996  position = [];
997  position[0] = ‪groundpos( best_poi.origin + (0, 0, 100) );
998  position[1] = self;
999  }
1000  else
1001  {
1002  position = self ‪add_poi_attractor( best_poi );
1003  }
1004 
1005  if( IsDefined( best_poi.initial_attract_func ) )
1006  {
1007  self thread [[ best_poi.initial_attract_func ]]( best_poi );
1008  }
1009 
1010  if( IsDefined( best_poi.arrival_attract_func ) )
1011  {
1012  self thread [[ best_poi.arrival_attract_func ]]( best_poi );
1013  }
1014  }
1015 
1016  AIProfile_EndEntry();
1017  return position;
1018 }
1019 
1021 {
1022  if( self.script_noteworthy != "zombie_poi" )
1023  {
1024  return;
1025  }
1026 
1027  self.poi_active = true;
1028 }
1029 
1031 {
1032  if( self.script_noteworthy != "zombie_poi" )
1033  {
1034  return;
1035  }
1036 
1037  self.attractor_array = ‪array::remove_undefined( self.attractor_array );
1038  for( i = 0; i < self.attractor_array.size; i++ )
1039  {
1040  self.attractor_array[i] notify( "kill_poi" );
1041  }
1042 
1043  self.attractor_array = [];
1044  self.claimed_attractor_positions = [];
1045 
1046  self.poi_active = false;
1047 
1048  if ( ‪IS_TRUE( dont_remove ) )
1049  {
1050  return;
1051  }
1052 
1053  //Remove from list
1054  if ( isdefined( self ) )
1055  {
1056  if ( IsInArray( level.zombie_poi_array, self ) )
1057  {
1058  ArrayRemoveValue( level.zombie_poi_array, self );
1059  }
1060  }
1061 }
1062 
1063 //PI_CHANGE_BEGIN - 6/18/09 JV This works to help set "wait" points near the stage if all players are in the process teleportation.
1064 //It is unlike the previous function in that you dictate the poi.
1066 {
1067  position = undefined;
1068  doremovalthread = false;
1069 
1070  if (IsDefined(poi) && poi ‪can_attract(self))
1071  {
1072  //don't want to touch add poi attractor, but yeah, this is kind of weird
1073  if (!IsDefined(poi.attractor_array) || ( IsDefined(poi.attractor_array) && !IsInArray( poi.attractor_array, self ) ))
1074  doremovalthread = true;
1075 
1076  position = self ‪add_poi_attractor( poi );
1077 
1078  //now that I know this is the first time they've been added, set up the thread to remove them from the array
1079  if (IsDefined(position) && doremovalthread && IsInArray( poi.attractor_array, self ))
1080  self thread ‪update_on_poi_removal( poi );
1081  }
1082 
1083  return position;
1084 }
1085 //PI_CHANGE_END
1086 
1087 function ‪remove_poi_attractor( zombie_poi )
1088 {
1089  if( !isDefined( zombie_poi ) || !isDefined( zombie_poi.attractor_array ) )
1090  {
1091  return;
1092  }
1093 
1094  for( i = 0; i < zombie_poi.attractor_array.size; i++ )
1095  {
1096  if( zombie_poi.attractor_array[i] == self )
1097  {
1098  ArrayRemoveValue( zombie_poi.attractor_array, zombie_poi.attractor_array[i] );
1099  ArrayRemoveValue( zombie_poi.claimed_attractor_positions, zombie_poi.claimed_attractor_positions[i] );
1100 
1101  if ( isdefined( self ) )
1102  {
1103  self notify( "kill_poi" );
1104  }
1105  }
1106  }
1107 }
1108 
1109 function ‪array_check_for_dupes_using_compare( ‪array, single, is_equal_fn )
1110 {
1111  for( i = 0; i < ‪array.size; i++ )
1112  {
1113  if( [[is_equal_fn]]( ‪array[i], single ) )
1114  {
1115  return false;
1116  }
1117  }
1118 
1119  return true;
1120 }
1121 
1122 function ‪poi_locations_equal( loc1, loc2 )
1123 {
1124  return loc1[0]==loc2[0];
1125 }
1126 
1127 
1128 function ‪add_poi_attractor( zombie_poi )
1129 {
1130  if( !isDefined( zombie_poi ) )
1131  {
1132  return;
1133  }
1134  if( !isDefined( zombie_poi.attractor_array ) )
1135  {
1136  zombie_poi.attractor_array = [];
1137  }
1138 
1139  // If we are not yet an attractor to this poi, claim an attractor position and start attracting to it
1140  if( !IsInArray( zombie_poi.attractor_array, self ) )
1141  {
1142  if( !isDefined( zombie_poi.claimed_attractor_positions ) )
1143  {
1144  zombie_poi.claimed_attractor_positions = [];
1145  }
1146 
1147  if( !isDefined( zombie_poi.attractor_positions ) || zombie_poi.attractor_positions.size <= 0 )
1148  {
1149  return undefined;
1150  }
1151 
1152  start = -1;
1153  ‪end = -1;
1154  last_index = -1;
1155  for( i = 0; i < 4; i++ )
1156  {
1157  if( zombie_poi.claimed_attractor_positions.size < zombie_poi.last_index[i] )
1158  {
1159  start = last_index+1;
1160  ‪end = zombie_poi.last_index[i];
1161  break;
1162  }
1163  last_index = zombie_poi.last_index[i];
1164  }
1165 
1166 
1167  best_dist = 10000*10000;
1168  best_pos = undefined;
1169  if( start < 0 )
1170  {
1171  start = 0;
1172  }
1173  if( ‪end < 0 )
1174  {
1175  return undefined;
1176  }
1177  for( i = int(start); i <= int(‪end); i++ )
1178  {
1179  if(!isDefined(zombie_poi.attractor_positions[i]))
1180  {
1181  continue;
1182  }
1183  //if( !IsInArray( zombie_poi.claimed_attractor_positions, zombie_poi.attractor_positions[i] ) )
1184  if( ‪array_check_for_dupes_using_compare( zombie_poi.claimed_attractor_positions, zombie_poi.attractor_positions[i], &‪poi_locations_equal ) )
1185  {
1186 
1187  if ( isDefined( zombie_poi.attractor_positions[i][0] ) && isDefined( self.origin ) )
1188  {
1189  dist = distancesquared( zombie_poi.attractor_positions[i][0], zombie_poi.origin );
1190  if( dist < best_dist || !isDefined( best_pos ) )
1191  {
1192  best_dist = dist;
1193  best_pos = zombie_poi.attractor_positions[i];
1194  }
1195  }
1196  }
1197  }
1198 
1199  if( !isDefined( best_pos ) )
1200  {
1201  if ( ‪IS_TRUE( level.validate_poi_attractors ) )
1202  {
1203  valid_pos = [];
1204  valid_pos[0] = zombie_poi.origin;
1205  valid_pos[1] = zombie_poi;
1206  return valid_pos;
1207  }
1208 
1209  return undefined;
1210  }
1211 
1212  ‪ARRAY_ADD( zombie_poi.attractor_array, self );
1213  self thread ‪update_poi_on_death( zombie_poi );
1214 
1215  ‪ARRAY_ADD( zombie_poi.claimed_attractor_positions, best_pos );
1216 
1217  return best_pos;
1218  }
1219  else
1220  {
1221  for( i = 0; i < zombie_poi.attractor_array.size; i++ )
1222  {
1223  if( zombie_poi.attractor_array[i] == self )
1224  {
1225  if( isDefined( zombie_poi.claimed_attractor_positions ) && isDefined( zombie_poi.claimed_attractor_positions[i] ) )
1226  {
1227  return zombie_poi.claimed_attractor_positions[i];
1228  }
1229  }
1230  }
1231  }
1232 
1233  return undefined;
1234 }
1235 
1236 function ‪can_attract( attractor )
1237 {
1238  if( !isDefined( self.attractor_array ) )
1239  {
1240  self.attractor_array = [];
1241  }
1242  //Raven Begin - Allow only selected zombies to be attracted
1243  if( isDefined(self.attracted_array) && !IsInArray(self.attracted_array, attractor) )
1244  {
1245  return false;
1246  }
1247  //Raven End
1248  if( IsInArray( self.attractor_array, attractor ) )
1249  {
1250  return true;
1251  }
1252  if( isDefined(self.num_poi_attracts) && self.attractor_array.size >= self.num_poi_attracts )
1253  {
1254  return false;
1255  }
1256 
1257  return true;
1258 }
1259 
1260 function ‪update_poi_on_death( zombie_poi )
1261 {
1262  self endon( "kill_poi" );
1263 
1264  self waittill( "death" );
1265  self ‪remove_poi_attractor( zombie_poi );
1266 }
1267 
1268 //PI_CHANGE_BEGIN - 6/18/09 JV This was set up to work with assign_zombie_point_of_interest (which works with the teleportation in theater).
1269 //The poi attractor array needs to be emptied when a player is teleported out of projection room (if they were all in there).
1270 //As a result, we wait for the poi's death (I'm sending that notify via the level script)
1271 function ‪update_on_poi_removal (zombie_poi )
1272 {
1273  zombie_poi waittill( "death" );
1274 
1275  if( !isDefined( zombie_poi.attractor_array ) )
1276  return;
1277 
1278  for( i = 0; i < zombie_poi.attractor_array.size; i++ )
1279  {
1280  if( zombie_poi.attractor_array[i] == self )
1281  {
1282  ArrayRemoveIndex( zombie_poi.attractor_array, i );
1283  ArrayRemoveIndex( zombie_poi.claimed_attractor_positions, i );
1284  }
1285  }
1286 
1287 }
1288 //PI_CHANGE_END
1289 
1290 function ‪invalidate_attractor_pos( attractor_pos, zombie )
1291 {
1292  if( !isDefined( self ) || !isDefined( attractor_pos ) )
1293  {
1294  wait( 0.1 );
1295  return undefined;
1296  }
1297 
1298  if( isDefined( self.attractor_positions) && !‪array_check_for_dupes_using_compare( self.attractor_positions, attractor_pos, &‪poi_locations_equal ) )
1299  {
1300  index = 0;
1301  for( i = 0; i < self.attractor_positions.size; i++ )
1302  {
1303  if( ‪poi_locations_equal( self.attractor_positions[i], attractor_pos) )
1304  {
1305  index = i;
1306  }
1307  }
1308 
1309  for( i = 0; i < self.last_index.size; i++ )
1310  {
1311  if( index <= self.last_index[i] )
1312  {
1313  self.last_index[i]--;
1314  }
1315  }
1316 
1317  ArrayRemoveValue( self.attractor_array, zombie );
1318  ArrayRemoveValue( self.attractor_positions, attractor_pos );
1319  for( i = 0; i < self.claimed_attractor_positions.size; i++ )
1320  {
1321  if( self.claimed_attractor_positions[i][0] == attractor_pos[0] )
1322  {
1323  ArrayRemoveValue( self.claimed_attractor_positions, self.claimed_attractor_positions[i] );
1324  }
1325  }
1326  }
1327  else
1328  {
1329  wait( 0.1 );
1330  }
1331 
1332  return ‪get_zombie_point_of_interest( zombie.origin );
1333 }
1334 
1336 {
1337  if ( isDefined( self.ignore_poi ) && self.ignore_poi.size > 0 )
1338  {
1339  for ( i = 0; i < self.ignore_poi.size; i++ )
1340  {
1341  if ( self.ignore_poi[i] == poi )
1342  {
1343  ArrayRemoveValue( self.ignore_poi, self.ignore_poi[i] );
1344  return;
1345  }
1346  }
1347  }
1348 }
1349 
1351 {
1352  if ( !isDefined( self.ignore_poi ) )
1353  {
1354  self.ignore_poi = [];
1355  }
1356 
1357  add_poi = true;
1358  if ( self.ignore_poi.size > 0 )
1359  {
1360  for ( i = 0; i < self.ignore_poi.size; i++ )
1361  {
1362  if ( self.ignore_poi[i] == poi )
1363  {
1364  add_poi = false;
1365  break;
1366  }
1367  }
1368  }
1369 
1370  if ( add_poi )
1371  {
1372  self.ignore_poi[self.ignore_poi.size] = poi;
1373  }
1374 }
1375 
1376 
1377 //-------------------------------------------------------------------------------
1378 // player should be within a couple feet of enemy
1379 //-------------------------------------------------------------------------------
1381 {
1382  max_dist = 1296;
1383 
1384  d = DistanceSquared( self.origin, player.origin );
1385  if ( d <= max_dist )
1386  {
1387  return true;
1388  }
1389 
1390  return false;
1391 }
1392 
1393 function ‪get_closest_valid_player( origin, ignore_player )
1394 {
1395  AIProfile_BeginEntry( "get_closest_valid_player" );
1396 
1397  valid_player_found = false;
1398  players = GetPlayers();
1399 
1400  if( isdefined( level.get_closest_valid_player_override ) )
1401  {
1402  players = [[ level.get_closest_valid_player_override ]]();
1403  }
1404 
1405  b_designated_target_exists = false;
1406  for(i = 0; i < players.size; i++ )
1407  {
1408  player = players[i];
1409 
1410  //if( !is_player_valid( players[i], true ) )
1411  if( !player.am_i_valid )
1412  {
1413  continue;
1414  }
1415 
1416  if( isDefined( level.evaluate_zone_path_override ) )
1417  {
1418  if( ![[ level.evaluate_zone_path_override ]]( player ) )
1419  {
1420  ‪array::add( ignore_player, player );
1421  }
1422  }
1423 
1424  // is any player a designated target?
1425  if( ‪IS_TRUE( player.b_is_designated_target ) )
1426  {
1427  b_designated_target_exists = true;
1428  }
1429  }
1430 
1431  if( IsDefined( ignore_player ) )
1432  {
1433  for(i = 0; i < ignore_player.size; i++ )
1434  {
1435  ArrayRemoveValue( players, ignore_player[i] );
1436  }
1437  }
1438 
1439  // pre-cull any players that are in last stand or not designated target when a designated target is present
1440  done = false;
1441  while ( players.size && !done )
1442  {
1443  done = true;
1444  for(i = 0; i < players.size; i++ )
1445  {
1446  player = players[i];
1447  //if( !is_player_valid( player, true ) )
1448  if( !player.am_i_valid )
1449  {
1450  ArrayRemoveValue( players, player );
1451  done = false;
1452  break;
1453  }
1454  if( b_designated_target_exists && !‪IS_TRUE( player.b_is_designated_target ) )
1455  {
1456  ArrayRemoveValue( players, player );
1457  done = false;
1458  break;
1459  }
1460  }
1461  }
1462 
1463  if( players.size == 0 )
1464  {
1465  AIProfile_EndEntry();
1466  return undefined;
1467  }
1468 
1469  while( !valid_player_found )
1470  {
1471  // find the closest player
1472  if( IsDefined( self.closest_player_override ) )
1473  {
1474  player = [[ self.closest_player_override ]]( origin, players );
1475  }
1476  else if( isdefined( level.closest_player_override ) )
1477  {
1478  player = [[ level.closest_player_override ]]( origin, players );
1479  }
1480  else
1481  {
1482  player = ArrayGetClosest( origin, players );
1483  }
1484 
1485  if( !isdefined( player ) || players.size == 0 )
1486  {
1487  AIProfile_EndEntry();
1488  return undefined;
1489  }
1490 
1491  if( ‪IS_TRUE(level.allow_zombie_to_target_ai) || ‪IS_TRUE(player.allow_zombie_to_target_ai) )
1492  {
1493  AIProfile_EndEntry();
1494  return player;
1495  }
1496 
1497  // make sure they're not a zombie or in last stand
1498  //if( !is_player_valid( player, true ) )
1499  if( !player.am_i_valid )
1500  {
1501  // unlikely to get here unless there is a wait in one of the closest player overrides
1502  ArrayRemoveValue( players, player );
1503  if( players.size == 0 )
1504  {
1505  AIProfile_EndEntry();
1506  return undefined;
1507  }
1508 
1509  continue;
1510  }
1511 
1512  AIProfile_EndEntry();
1513  return player;
1514  }
1515 }
1516 
1517 //modified version of get_closest_valid_player that gives perfect info and sets up ignoreEnts to respect the ignore_player array.
1518 
1519 function ‪update_valid_players( origin, ignore_player )
1520 {
1521  AIProfile_BeginEntry( "update_valid_players" );
1522 
1523  valid_player_found = false;
1524  players = ArrayCopy( level.players ); // Have to use ArrayCopy otherwise the ArrayRemove calls below will remove the players from level.players
1525 
1526  //new zombie enemy selection
1527  foreach( player in players )
1528  {
1529  self SetIgnoreEnt( player, true );
1530  }
1531 
1532  b_designated_target_exists = false;
1533  for(i = 0; i < players.size; i++ )
1534  {
1535  player = players[i];
1536 
1537  //if( !is_player_valid( players[i], true ) )
1538  if( !player.am_i_valid )
1539  {
1540  continue;
1541  }
1542 
1543  if( isDefined( level.evaluate_zone_path_override ) )
1544  {
1545  if( ![[ level.evaluate_zone_path_override ]]( player ) )
1546  {
1547  ‪array::add( ignore_player, player );
1548  }
1549  }
1550 
1551  // is any player a designated target?
1552  if( ‪IS_TRUE( player.b_is_designated_target ) )
1553  {
1554  b_designated_target_exists = true;
1555  }
1556  }
1557 
1558  if( IsDefined( ignore_player ) )
1559  {
1560  for(i = 0; i < ignore_player.size; i++ )
1561  {
1562  ArrayRemoveValue( players, ignore_player[i] );
1563  }
1564  }
1565 
1566  // pre-cull any players that are in last stand or not designated target when a designated target is present
1567  done = false;
1568  while ( players.size && !done )
1569  {
1570  done = true;
1571  for(i = 0; i < players.size; i++ )
1572  {
1573  player = players[i];
1574  //if( !is_player_valid( player, true ) )
1575  if( !player.am_i_valid )
1576  {
1577  ArrayRemoveValue( players, player );
1578  done = false;
1579  break;
1580  }
1581  if( b_designated_target_exists && !‪IS_TRUE( player.b_is_designated_target ) )
1582  {
1583  ArrayRemoveValue( players, player );
1584  done = false;
1585  break;
1586  }
1587  }
1588  }
1589 
1590  //new zombie enemy selection
1591  foreach( player in players )
1592  {
1593  self SetIgnoreEnt( player, false );
1594  self GetPerfectInfo( player );
1595  }
1596 
1597  AIProfile_EndEntry();
1598 }
1599 
1600 function ‪is_player_valid( player, checkIgnoreMeFlag,ignore_laststand_players )
1601 {
1602  if( !IsDefined( player ) )
1603  {
1604  return false;
1605  }
1606 
1607  if( !IsAlive( player ) )
1608  {
1609  return false;
1610  }
1611 
1612  if( !IsPlayer( player ) )
1613  {
1614  return false;
1615  }
1616 
1617  if( IsDefined(player.is_zombie) && player.is_zombie == true )
1618  {
1619  return false;
1620  }
1621 
1622  if( player.sessionstate == "spectator" )
1623  {
1624  return false;
1625  }
1626 
1627  if( player.sessionstate == "intermission" )
1628  {
1629  return false;
1630  }
1631 
1632  if( ‪IS_TRUE( level.intermission ) )
1633  {
1634  return false;
1635  }
1636 
1637  if( !‪IS_TRUE( ignore_laststand_players ) )
1638  {
1640  {
1641  return false;
1642  }
1643  }
1644 
1645 //T6.5todo if ( player isnotarget() )
1646 //T6.5todo {
1647 //T6.5todo return false;
1648 //T6.5todo }
1649 
1650  //We only want to check this from the zombie attack script
1651  if( ‪IS_TRUE(checkIgnoreMeFlag) && player.ignoreme )
1652  {
1653  //IPrintLnBold(" ignore me ");
1654  return false;
1655  }
1656 
1657  //for additional level specific checks
1658  if( IsDefined( level.is_player_valid_override ) )
1659  {
1660  return [[ level.is_player_valid_override ]]( player );
1661  }
1662 
1663  return true;
1664 }
1665 
1667 {
1668 
1669  players = GetPlayers();
1670  num_player_valid = 0;
1671  for( i = 0 ; i < players.size; i++ )
1672  {
1673  if( ‪is_player_valid( players[i] ) )
1674  num_player_valid += 1;
1675  }
1676 
1677 
1678  return num_player_valid;
1679 
1680 
1681 
1682 }
1683 
1685 {
1686  if (isdefined(self.rt_time) && self.rt_time + 100 >= GetTime())
1687  return self.in_rt_cached;
1688  self.rt_time = GetTime();
1689 
1690  players = level.players; //GetPlayers();
1691  for( i = 0; i < players.size; i++ )
1692  {
1693  current_player = players[i];
1694 
1695  //if( !IsDefined( current_player )) || !IsAlive( current_player ) )
1696  //{
1697  // continue;
1698  //}
1699 
1700  if( IsDefined( current_player ) && IsDefined( current_player.revivetrigger ) && IsAlive( current_player ) )
1701  {
1702  if( self IsTouching( current_player.revivetrigger ) )
1703  {
1704  self.in_rt_cached = true;
1705  return true;
1706  }
1707  }
1708  }
1709 
1710  self.in_rt_cached = false;
1711  return false;
1712 }
1713 
1714 function ‪get_closest_node( org, nodes )
1715 {
1716  return ArrayGetClosest( org, nodes );
1717 }
1718 
1719 // bars are not damaged pull them off now.
1720 function ‪non_destroyed_bar_board_order( origin, chunks )
1721 {
1722  //bars = getentarray("bar","script_parameters");
1723  first_bars = []; // first set of 2 bars to be removed
1724  first_bars1 = []; // Added single check when combined with wood
1725  first_bars2 = []; // Added single check when combined with wood
1726 
1727  //-------------------------BOARDS----------------------------------------------------------
1728  // If all boards do the old system
1729  for( i=0;i<chunks.size;i++ ) // Go through the array
1730  {
1731  if (IsDefined ( chunks[i].script_team ) && ( chunks[i].script_team == "classic_boards" ) )
1732  {
1733  if (IsDefined (chunks[i].script_parameters) && (chunks[i].script_parameters == "board") )
1734  {
1735  return ‪get_closest_2d( origin, chunks );
1736  }
1737  // I need to add a script name team regular boards
1738  else if (IsDefined ( chunks[i].script_team ) && chunks[i].script_team == "bar_board_variant1" || chunks[i].script_team == "bar_board_variant2" ||
1739  chunks[i].script_team == "bar_board_variant4" || chunks[i].script_team == "bar_board_variant5" )
1740  {
1741  return undefined;
1742  }
1743  }
1744  // DCS: adding new variable to start with like new condition repaired with boards.
1745  else if(IsDefined(chunks[i].script_team ) && chunks[i].script_team == "new_barricade")
1746  {
1747  if(IsDefined(chunks[i].script_parameters) && (chunks[i].script_parameters == "repair_board" || chunks[i].script_parameters == "barricade_vents"))
1748  {
1749  return ‪get_closest_2d( origin, chunks );
1750  }
1751  }
1752  }
1753  //-------------------------BOARDS----------------------------------------------------------
1754 
1755  //-------------------------BARS------------------------------------------------------------
1756  for(i=0;i<chunks.size;i++) // Go through the array
1757  {
1758  if ( IsDefined (chunks[i].script_team ) && ( chunks[i].script_team == "6_bars_bent" ) || ( chunks[i].script_team == "6_bars_prestine" ) )
1759  {
1760  if (IsDefined (chunks[i].script_parameters) && (chunks[i].script_parameters == "bar") )
1761  {
1762  if(isDefined(chunks[i].script_noteworthy))
1763  {
1764  if(chunks[i].script_noteworthy == "4" || chunks[i].script_noteworthy == "6" ) // this two are defined create a new array that just keeps track of them
1765  {
1766  first_bars[first_bars.size] = chunks[i]; // In total this should be a size of two
1767  }
1768  }
1769  }
1770  }
1771  }
1772 
1773  for(i=0;i<first_bars.size;i++) // Jl added second check if there is only peace
1774  {
1775  if ( IsDefined (chunks[i].script_team ) && ( chunks[i].script_team == "6_bars_bent" ) || ( chunks[i].script_team == "6_bars_prestine" ) )
1776  {
1777  if (IsDefined (chunks[i].script_parameters) && (chunks[i].script_parameters == "bar") )
1778  {
1779  //send back the first bars that are NOT destroyed
1780  if( !first_bars[i].destroyed )
1781  {
1782  return first_bars[i];
1783  }
1784  }
1785  }
1786  }
1787 
1788  // Grab the remaining bars that are the closest to the ai
1789  for(i=0;i<chunks.size;i++)
1790  {
1791  if ( IsDefined (chunks[i].script_team ) && ( chunks[i].script_team == "6_bars_bent" ) || ( chunks[i].script_team == "6_bars_prestine" ) )
1792  {
1793 
1794  if (IsDefined (chunks[i].script_parameters) && (chunks[i].script_parameters == "bar") )
1795  {
1796  if( !chunks[i].destroyed )
1797  {
1798  return ‪get_closest_2d( origin, chunks );
1799  //return chunks[i];
1800  }
1801  }
1802  }
1803  }
1804  //-------------------------BARS------------------------------------------------------------
1805 }
1806 
1807 
1808 function ‪non_destroyed_grate_order( origin, chunks_grate )
1809 {
1810  //-------------------------GRATES----------------------------------------------------------
1811  grate_order = [];
1812  grate_order1 =[]; // this sets up the order for the grates
1813  grate_order2 =[]; // this sets up the order for the grates
1814  grate_order3 =[]; // this sets up the order for the grates
1815  grate_order4 =[]; // this sets up the order for the grates
1816  grate_order5 =[]; // this sets up the order for the grates
1817  grate_order6 =[]; // this sets up the order for the grates
1818 
1819 
1820  if ( IsDefined ( chunks_grate ) )
1821  {
1822  for(i=0;i<chunks_grate.size;i++) // Go through the array
1823  {
1824  if (IsDefined (chunks_grate[i].script_parameters) && (chunks_grate[i].script_parameters == "grate") )
1825  {
1826  //return grate_order[i];
1827 
1828  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "1" ) )
1829  {
1830  grate_order1[grate_order1.size] = chunks_grate[i];
1831  // send back order here
1832  }
1833  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "2" ) )
1834  {
1835  grate_order2[grate_order2.size] = chunks_grate[i];
1836  // send back order here
1837  }
1838  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "3" ) )
1839  {
1840  grate_order3[grate_order3.size] = chunks_grate[i];
1841  // send back order here
1842  }
1843  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "4" ) )
1844  {
1845  grate_order4[grate_order4.size] = chunks_grate[i];
1846  // send back order here
1847  }
1848  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "5" ) )
1849  {
1850  grate_order5[grate_order5.size] = chunks_grate[i];
1851  // send back order here
1852  }
1853  if ( IsDefined ( chunks_grate[i].script_noteworthy ) && ( chunks_grate[i].script_noteworthy == "6" ) )
1854  {
1855  grate_order6[grate_order6.size] = chunks_grate[i];
1856  // send back order here
1857  }
1858  }
1859  }
1860 
1861 
1862  // I need to make this function also tell which piece to move again.
1863  for(i=0;i<chunks_grate.size;i++) // Go through the array
1864  {
1865  if (IsDefined ( chunks_grate[i].script_parameters ) && ( chunks_grate[i].script_parameters == "grate") )
1866  {
1867  if ( IsDefined ( grate_order1[i] ) )
1868  {
1869  if( ( grate_order1[i].state == "repaired" ) )
1870  {
1871  grate_order2[i] thread ‪show_grate_pull();
1872  return grate_order1[i];
1873  }
1874  if( ( grate_order2[i].state == "repaired" ) )
1875  {
1876  /#
1877  IPrintLnBold(" pull bar2 ");
1878  #/
1879  grate_order3[i] thread ‪show_grate_pull();
1880  return grate_order2[i];
1881 
1882  }
1883  else if( ( grate_order3[i].state == "repaired" ) )
1884  {
1885  /#
1886  IPrintLnBold(" pull bar3 ");
1887  #/
1888  grate_order4[i] thread ‪show_grate_pull();
1889  return grate_order3[i];
1890 
1891  }
1892  else if( ( grate_order4[i].state == "repaired" ) )
1893  {
1894  /#
1895  IPrintLnBold(" pull bar4 ");
1896  #/
1897  grate_order5[i] thread ‪show_grate_pull();
1898  return grate_order4[i];
1899  }
1900  else if( ( grate_order5[i].state == "repaired" ) )
1901  {
1902  /#
1903  IPrintLnBold(" pull bar5 ");
1904  #/
1905  grate_order6[i] thread ‪show_grate_pull();
1906  return grate_order5[i];
1907  }
1908  else if( ( grate_order6[i].state == "repaired" ) )
1909  {
1910  // I need to return nothing here.
1911  //return undefined();
1912  return grate_order6[i];
1913  }
1914  }
1915  }
1916  }
1917  }
1918  //-------------------------GRATES----------------------------------------------------------
1919 }
1920 
1922 //
1923 // A seperate function is needed for each variant because there are different pull down and repair orders for each
1924 // Also I had to add extra strings to idetify combined pieces that used the same script_noteworthy
1925 //
1927 // variant1
1928 function ‪non_destroyed_variant1_order( origin, chunks_variant1 )
1929 {
1930  //-------------------------VARIANT1----------------------------------------------------------
1931  variant1_order = [];
1932  variant1_order1 =[]; // this sets up the order for the grates
1933  variant1_order2 =[]; // this sets up the order for the grates
1934  variant1_order3 =[]; // this sets up the order for the grates
1935  variant1_order4 =[]; // this sets up the order for the grates
1936  variant1_order5 =[]; // this sets up the order for the grates
1937  variant1_order6 =[]; // this sets up the order for the grates
1938 
1939 
1940  if ( IsDefined ( chunks_variant1 ) )
1941  {
1942  for(i=0;i<chunks_variant1.size;i++) // Go through the array
1943  {
1944  if (IsDefined (chunks_variant1[i].script_team) && (chunks_variant1[i].script_team == "bar_board_variant1") )
1945  {
1946  //return grate_order[i];
1947 
1948  if ( IsDefined ( chunks_variant1[i].script_noteworthy ) )
1949  {
1950  if ( chunks_variant1[i].script_noteworthy == "1" )
1951  {
1952  variant1_order1[variant1_order1.size] = chunks_variant1[i];
1953  }
1954  if ( chunks_variant1[i].script_noteworthy == "2" )
1955  {
1956  variant1_order2[variant1_order2.size] = chunks_variant1[i];
1957  }
1958  if ( chunks_variant1[i].script_noteworthy == "3" )
1959  {
1960  variant1_order3[variant1_order3.size] = chunks_variant1[i];
1961  }
1962  if ( chunks_variant1[i].script_noteworthy == "4" )
1963  {
1964  variant1_order4[variant1_order4.size] = chunks_variant1[i];
1965  }
1966  if ( chunks_variant1[i].script_noteworthy == "5" )
1967  {
1968  variant1_order5[variant1_order5.size] = chunks_variant1[i];
1969  }
1970  if ( chunks_variant1[i].script_noteworthy == "6" )
1971  {
1972  variant1_order6[variant1_order6.size] = chunks_variant1[i];
1973  }
1974  }
1975  }
1976  }
1977 
1978 
1979  // This needs a different order
1980  for(i=0;i<chunks_variant1.size;i++) // Go through the array
1981  {
1982  if (IsDefined ( chunks_variant1[i].script_team ) && ( chunks_variant1[i].script_team == "bar_board_variant1") )
1983  {
1984  if( IsDefined ( variant1_order2[i] ) )
1985  {
1986  if( ( variant1_order2[i].state == "repaired" ) )
1987  {
1988  return variant1_order2[i];
1989  }
1990  else if( ( variant1_order3[i].state == "repaired" ) )
1991  {
1992  return variant1_order3[i];
1993  }
1994  else if( ( variant1_order4[i].state == "repaired" ) )
1995  {
1996  return variant1_order4[i];
1997  }
1998  else if( ( variant1_order6[i].state == "repaired" ) )
1999  {
2000  return variant1_order6[i];
2001  }
2002  else if( ( variant1_order5[i].state == "repaired" ) )
2003  {
2004  return variant1_order5[i];
2005  }
2006  else if( ( variant1_order1[i].state == "repaired" ) )
2007  {
2008  return variant1_order1[i];
2009  }
2010  }
2011  }
2012  }
2013  }
2014 
2015  //if( chunks_variant1.size == 0 )
2016  //{
2017  // return undefined; // If there are no more pieces left then don't allow it to continue
2018  //}
2019  //-------------------------VARIANT1----------------------------------------------------------
2020 }
2021 
2022 // variant2
2023 function ‪non_destroyed_variant2_order( origin, chunks_variant2 )
2024 {
2025  //-------------------------VARIENT2----------------------------------------------------------
2026  variant2_order = [];
2027  variant2_order1 =[]; // this sets up the order for the grates
2028  variant2_order2 =[]; // this sets up the order for the grates
2029  variant2_order3 =[]; // this sets up the order for the grates
2030  variant2_order4 =[]; // this sets up the order for the grates
2031  variant2_order5 =[]; // this sets up the order for the grates
2032  variant2_order6 =[]; // this sets up the order for the grates
2033 
2034 
2035  if ( IsDefined ( chunks_variant2 ) )
2036  {
2037  for(i=0;i<chunks_variant2.size;i++) // Go through the array
2038  {
2039  if (IsDefined (chunks_variant2[i].script_team) && (chunks_variant2[i].script_team == "bar_board_variant2") )
2040  {
2041  //return grate_order[i];
2042 
2043  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "1" ) )
2044  {
2045  variant2_order1[variant2_order1.size] = chunks_variant2[i];
2046  // send back order here
2047  }
2048  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "2" ) )
2049  {
2050  variant2_order2[variant2_order2.size] = chunks_variant2[i];
2051  // send back order here
2052  }
2053  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "3" ) )
2054  {
2055  variant2_order3[variant2_order3.size] = chunks_variant2[i];
2056  // send back order here
2057  }
2058  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "4" ) )
2059  {
2060  variant2_order4[variant2_order4.size] = chunks_variant2[i];
2061  // send back order here
2062  }
2063  // I had to add another string to check against out of order noteworthy when combining board and wood
2064  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "5" ) && IsDefined( chunks_variant2[i].script_location ) && (chunks_variant2[i].script_location == "5") )
2065  {
2066  variant2_order5[variant2_order5.size] = chunks_variant2[i];
2067  // send back order here
2068  }
2069  if ( IsDefined ( chunks_variant2[i].script_noteworthy ) && ( chunks_variant2[i].script_noteworthy == "5" ) && IsDefined( chunks_variant2[i].script_location ) && (chunks_variant2[i].script_location == "6") )
2070  {
2071  variant2_order6[variant2_order6.size] = chunks_variant2[i];
2072  // send back order here
2073  }
2074  }
2075  }
2076 
2077  // There is a different pull order for every variant
2078  for(i=0;i<chunks_variant2.size;i++) // Go through the array
2079  {
2080  if (IsDefined ( chunks_variant2[i].script_team ) && ( chunks_variant2[i].script_team == "bar_board_variant2") )
2081  {
2082  if( IsDefined ( variant2_order1[i] ) )
2083  {
2084  if( ( variant2_order1[i].state == "repaired" ) )
2085  {
2086  return variant2_order1[i];
2087  }
2088  else if( ( variant2_order2[i].state == "repaired" ) )
2089  {
2090  return variant2_order2[i];
2091  }
2092  else if( ( variant2_order3[i].state == "repaired" ) )
2093  {
2094  return variant2_order3[i];
2095  }
2096  else if( ( variant2_order5[i].state == "repaired" ) )
2097  {
2098  return variant2_order5[i];
2099  }
2100  else if( ( variant2_order4[i].state == "repaired" ) )
2101  {
2102  return variant2_order4[i];
2103  }
2104  else if( ( variant2_order6[i].state == "repaired" ) )
2105  {
2106  return variant2_order6[i];
2107  }
2108  }
2109  }
2110  }
2111  }
2112  //-------------------------VARIENT2----------------------------------------------------------
2113 }
2114 
2115 // variant4
2116 function ‪non_destroyed_variant4_order( origin, chunks_variant4 )
2117 {
2118  //-------------------------VARIENT4----------------------------------------------------------
2119  variant4_order = [];
2120  variant4_order1 =[]; // this sets up the order for the grates
2121  variant4_order2 =[]; // this sets up the order for the grates
2122  variant4_order3 =[]; // this sets up the order for the grates
2123  variant4_order4 =[]; // this sets up the order for the grates
2124  variant4_order5 =[]; // this sets up the order for the grates
2125  variant4_order6 =[]; // this sets up the order for the grates
2126 
2127 
2128  if ( IsDefined ( chunks_variant4 ) )
2129  {
2130  for(i=0;i<chunks_variant4.size;i++) // Go through the array
2131  {
2132  if (IsDefined (chunks_variant4[i].script_team) && (chunks_variant4[i].script_team == "bar_board_variant4") )
2133  {
2134  //return grate_order[i];
2135 
2136  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "1" ) && !IsDefined( chunks_variant4[i].script_location ) )
2137  {
2138  variant4_order1[variant4_order1.size] = chunks_variant4[i];
2139  // send back order here
2140  }
2141  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "2" ) )
2142  {
2143  variant4_order2[variant4_order2.size] = chunks_variant4[i];
2144  // send back order here
2145  }
2146  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "3" ) )
2147  {
2148  variant4_order3[variant4_order3.size] = chunks_variant4[i];
2149  // send back order here
2150  }
2151  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "1" ) && IsDefined( chunks_variant4[i].script_location ) && (chunks_variant4[i].script_location == "3") )
2152  {
2153  variant4_order4[variant4_order4.size] = chunks_variant4[i];
2154  // send back order here
2155  }
2156  // There isn't a noteworthy 4
2157  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "5" ) )
2158  {
2159  variant4_order5[variant4_order5.size] = chunks_variant4[i];
2160  // send back order here
2161  }
2162  if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "6" ) )
2163  {
2164  variant4_order6[variant4_order6.size] = chunks_variant4[i];
2165  // send back order here
2166  }
2167  }
2168  }
2169 
2170  // There is a different pull order for every variant
2171  for(i=0;i<chunks_variant4.size;i++) // Go through the array
2172  {
2173  if (IsDefined ( chunks_variant4[i].script_team ) && ( chunks_variant4[i].script_team == "bar_board_variant4") )
2174  {
2175  if( IsDefined ( variant4_order1[i] ) ) // last one here
2176  {
2177  if( ( variant4_order1[i].state == "repaired" ) )
2178  {
2179  return variant4_order1[i];
2180  }
2181  else if( ( variant4_order6[i].state == "repaired" ) )
2182  {
2183  return variant4_order6[i];
2184  }
2185  else if( ( variant4_order3[i].state == "repaired" ) )
2186  {
2187  return variant4_order3[i];
2188  }
2189  else if( ( variant4_order4[i].state == "repaired" ) ) // second one
2190  {
2191  return variant4_order4[i];
2192  }
2193  else if( ( variant4_order2[i].state == "repaired" ) )
2194  {
2195  return variant4_order2[i];
2196  }
2197  else if( ( variant4_order5[i].state == "repaired" ) )
2198  {
2199  return variant4_order5[i];
2200  }
2201  }
2202  }
2203  }
2204  }
2205  //-------------------------Variant2----------------------------------------------------------
2206 }
2207 
2208 // variant5
2209 function ‪non_destroyed_variant5_order( origin, chunks_variant5 )
2210 {
2211  //-------------------------VARIANT5----------------------------------------------------------
2212  variant5_order = [];
2213  variant5_order1 =[]; // this sets up the order for the grates
2214  variant5_order2 =[]; // this sets up the order for the grates
2215  variant5_order3 =[]; // this sets up the order for the grates
2216  variant5_order4 =[]; // this sets up the order for the grates
2217  variant5_order5 =[]; // this sets up the order for the grates
2218  variant5_order6 =[]; // this sets up the order for the grates
2219 
2220 
2221  if ( IsDefined ( chunks_variant5 ) )
2222  {
2223  for(i=0;i<chunks_variant5.size;i++) // Go through the array
2224  {
2225  if (IsDefined (chunks_variant5[i].script_team) && (chunks_variant5[i].script_team == "bar_board_variant5") )
2226  {
2227  //return grate_order[i];
2228  if ( IsDefined ( chunks_variant5[i].script_noteworthy ) )
2229  {
2230  // if ( IsDefined ( chunks_variant4[i].script_noteworthy ) && ( chunks_variant4[i].script_noteworthy == "1" ) && !IsDefined( chunks_variant4[i].script_location ) )
2231  if ( ( chunks_variant5[i].script_noteworthy == "1" ) && !IsDefined( chunks_variant5[i].script_location ) )
2232  {
2233  variant5_order1[variant5_order1.size] = chunks_variant5[i];
2234  }
2235  if ( chunks_variant5[i].script_noteworthy == "2" )
2236  {
2237  variant5_order2[variant5_order2.size] = chunks_variant5[i];
2238  }
2239  if ( IsDefined ( chunks_variant5[i].script_noteworthy ) && ( chunks_variant5[i].script_noteworthy == "1" ) && IsDefined( chunks_variant5[i].script_location ) && (chunks_variant5[i].script_location == "3") )
2240  {
2241  variant5_order3[variant5_order3.size] = chunks_variant5[i];
2242  }
2243  if ( chunks_variant5[i].script_noteworthy == "4" )
2244  {
2245  variant5_order4[variant5_order4.size] = chunks_variant5[i];
2246  }
2247  if ( chunks_variant5[i].script_noteworthy == "5" )
2248  {
2249  variant5_order5[variant5_order5.size] = chunks_variant5[i];
2250  }
2251  if ( chunks_variant5[i].script_noteworthy == "6" )
2252  {
2253  variant5_order6[variant5_order6.size] = chunks_variant5[i];
2254  }
2255  }
2256  }
2257  }
2258  for(i=0;i<chunks_variant5.size;i++) // Go through the array
2259  {
2260  if (IsDefined ( chunks_variant5[i].script_team ) && ( chunks_variant5[i].script_team == "bar_board_variant5") )
2261  {
2262  if( IsDefined ( variant5_order1[i] ) )
2263  {
2264  if( ( variant5_order1[i].state == "repaired" ) )
2265  {
2266  return variant5_order1[i];
2267  }
2268  else if( ( variant5_order6[i].state == "repaired" ) )
2269  {
2270  return variant5_order6[i];
2271  }
2272  else if( ( variant5_order3[i].state == "repaired" ) )
2273  {
2274  return variant5_order3[i];
2275  }
2276  else if( ( variant5_order2[i].state == "repaired" ) )
2277  {
2278  return variant5_order2[i];
2279  }
2280  else if( ( variant5_order5[i].state == "repaired" ) )
2281  {
2282  return variant5_order5[i];
2283  }
2284  else if( ( variant5_order4[i].state == "repaired" ) )
2285  {
2286  return variant5_order4[i];
2287  }
2288  }
2289  }
2290  }
2291  }
2292  //-------------------------VARIANT5----------------------------------------------------------
2293 }
2294 
2296 {
2297  wait(0.53);
2298  self Show();
2299  self vibrate(( 0, 270, 0 ), 0.2, 0.4, 0.4);
2300  // I could fx and sound from here as well.
2301 }
2302 
2303 
2304 function ‪get_closest_2d( origin, ents )
2305 {
2306  if( !IsDefined( ents ) )
2307  {
2308  return undefined;
2309  }
2310 
2311  dist = Distance2d( origin, ents[0].origin );
2312  index = 0;
2313  temp_array = [];
2314 
2315  for( i = 1; i < ents.size; i++ )
2316  {
2317  if(IsDefined(ents[i].unbroken) && ents[i].unbroken == true)
2318  {
2319  ents[i].index = i;
2320  ‪ARRAY_ADD(temp_array, ents[i]);
2321  }
2322  }
2323 
2324  if(temp_array.size > 0)
2325  {
2326  index = temp_array[RandomIntRange(0, temp_array.size)].index; // must pick unbroken piece first!
2327  return ents[index];
2328  }
2329  else
2330  {
2331  for( i = 1; i < ents.size; i++ )
2332  {
2333  temp_dist = Distance2d( origin, ents[i].origin );
2334  if( temp_dist < dist )
2335  {
2336  dist = temp_dist;
2337  index = i;
2338  }
2339  }
2340  return ents[index];
2341  }
2342 }
2343 
2344 //edge_fog_start()
2345 //{
2346 // playpoint = struct::get( "edge_fog_start", "targetname" );
2347 //
2348 // if( !IsDefined( playpoint ) )
2349 // {
2350 //
2351 // }
2352 //
2353 // while( isdefined( playpoint ) )
2354 // {
2355 // playfx( level._effect["edge_fog"], playpoint.origin );
2356 //
2357 // if( !isdefined( playpoint.target ) )
2358 // {
2359 // return;
2360 // }
2361 //
2362 // playpoint = struct::get( playpoint.target, "targetname" );
2363 // }
2364 //}
2365 
2366 
2367 //chris_p - fix bug with this not being an ent array!
2369 {
2370  playable_area = getentarray("player_volume","script_noteworthy");
2371 
2372  if( !IsDefined( playable_area ) )
2373  {
2374  /# println( "No playable area playable_area found! Assume EVERYWHERE is PLAYABLE" ); #/
2375  return true;
2376  }
2377 
2378  for(i=0;i<playable_area.size;i++)
2379  {
2380 
2381  if( self IsTouching( playable_area[i] ) )
2382  {
2383  return true;
2384  }
2385  }
2386 
2387  return false;
2388 }
2389 
2390 // I beleive this is where I can do the check to see what
2391 // barrier_chunks is the total amount of bars or boards that the exterior_goal was connected to.
2392 function ‪get_closest_non_destroyed_chunk( origin, barrier, barrier_chunks )
2393 {
2394  chunks = undefined;
2395  chunks_grate = undefined;
2396 
2397  // This returns only if grate is defined
2398  chunks_grate = ‪get_non_destroyed_chunks_grate( barrier, barrier_chunks );
2399 
2400  // This grabs classic boards, 6 bar prestine set and 6 bar bent set
2401  chunks = ‪get_non_destroyed_chunks( barrier, barrier_chunks ); // Grab all the chunks that are repaired
2402 
2403  if(isdefined(barrier.zbarrier))
2404  {
2405  if(isdefined(chunks))
2406  {
2407  return array::randomize(chunks)[0];
2408  }
2409 
2410  if(isdefined(chunks_grate))
2411  {
2412  return array::randomize(chunks_grate)[0];
2413  }
2414  }
2415  else
2416  {
2417  // This returns an array of what chunks can be pulled
2418 
2419  if( IsDefined( chunks ) ) // && IsDefined ( chunks.script_parameters ) && chunks.script_parameters == "board" )
2420  {
2421  // Jl This was the original call
2422  // return get_closest_2d( origin, chunks );
2423  return ‪non_destroyed_bar_board_order ( origin, chunks ); // Go through all the repaired chunk pieces
2424  }
2425 
2426  else if ( IsDefined ( chunks_grate ) )
2427  {
2428  return ‪non_destroyed_grate_order ( origin, chunks_grate ); // Go through all the repaired chunk pices
2429  }
2430  }
2431 
2432  return undefined;
2433 }
2434 
2435 
2436 // Jluyties barrier_chunks is the total amount of bars or boards that the exterior_goal was connected to
2437 // The grates do not return random
2438 function ‪get_random_destroyed_chunk( barrier, barrier_chunks )
2439 {
2440  if(isdefined(barrier.zbarrier))
2441  {
2442  ret = undefined;
2443 
2444  pieces = barrier.zbarrier GetZBarrierPieceIndicesInState("open");
2445 
2446  if(pieces.size)
2447  {
2448  ret = array::randomize(pieces)[0];
2449  }
2450 
2451  return ret;
2452  }
2453  else
2454  {
2455  chunk = undefined;
2456  chunks_repair_grate = undefined;
2457 
2458 
2459  chunks = ‪get_destroyed_chunks( barrier_chunks );
2460 
2461  chunks_repair_grate = ‪get_destroyed_repair_grates ( barrier_chunks );
2462 
2463  // for(i = 0; i < chunks.size; i++ )
2464 
2465  if ( IsDefined( chunks ) )
2466  {
2467  return chunks[RandomInt( chunks.size )];
2468  //return get_destroyed_chunks_without_grate ( chunks );
2469  }
2470 
2471  else if( IsDefined( chunks_repair_grate ) )
2472  {
2473  return ‪grate_order_destroyed ( chunks_repair_grate );
2474  }
2475 
2476  return undefined;
2477  }
2478 }
2479 
2480 function ‪get_destroyed_repair_grates( barrier_chunks )
2481 {
2482  // I may have to do my check here
2483  ‪array = []; // Setup array
2484  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2485  {
2486  if( IsDefined ( barrier_chunks[i] ) )
2487  {
2488  if( IsDefined ( barrier_chunks[i].script_parameters ) && ( barrier_chunks[i].script_parameters == "grate" ) )
2489  {
2490  ‪array[‪array.size] = barrier_chunks[i];
2491  }
2492  }
2493  }
2494 
2495  if( ‪array.size == 0 )
2496  {
2497  return undefined; // If there are no more pieces left then don't allow it to continue
2498  }
2499 
2500  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2501 }
2502 
2503 
2504 // this is the layer I want to do the check
2505 // I need to define each part of
2506 function ‪get_non_destroyed_chunks( barrier, barrier_chunks )
2507 {
2508  if(isdefined(barrier.zbarrier))
2509  {
2510  return barrier.zbarrier GetZBarrierPieceIndicesInState("closed");
2511  }
2512  else
2513  {
2514  ‪array = []; // Setup array
2515  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2516  {
2517  if(IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "classic_boards") )
2518  {
2519  if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "board") )
2520  {
2521  if( barrier_chunks[i] ‪get_chunk_state() == "repaired" ) // If the state of the chunk is repaired then continue
2522  {
2523  if( barrier_chunks[i].origin == barrier_chunks[i].og_origin ) // If this chunk has its original origin then continue
2524  {
2525  ‪array[‪array.size] = barrier_chunks[i]; //
2526  }
2527  }
2528  }
2529  }
2530  //DCS: new barricade added for pentagon.
2531  if(IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "new_barricade") )
2532  {
2533  if(IsDefined(barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "repair_board" || barrier_chunks[i].script_parameters == "barricade_vents"))
2534  {
2535  if( barrier_chunks[i] ‪get_chunk_state() == "repaired" ) // If the state of the chunk is repaired then continue
2536  {
2537  if( barrier_chunks[i].origin == barrier_chunks[i].og_origin ) // If this chunk has its original origin then continue
2538  {
2539  ‪array[‪array.size] = barrier_chunks[i]; //
2540  }
2541  }
2542  }
2543  }
2544 
2545  else if ( IsDefined (barrier_chunks[i].script_team ) && ( barrier_chunks[i].script_team == "6_bars_bent" ) )
2546  {
2547  if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "bar") )
2548  {
2549  if( barrier_chunks[i] ‪get_chunk_state() == "repaired" ) // If the state of the chunk is repaired then continue
2550  {
2551 
2552  if( barrier_chunks[i].origin == barrier_chunks[i].og_origin ) // If this chunk has its original origin then continue
2553  {
2554  ‪array[‪array.size] = barrier_chunks[i]; //
2555  }
2556  }
2557  }
2558  }
2559 
2560  else if ( IsDefined (barrier_chunks[i].script_team ) && ( barrier_chunks[i].script_team == "6_bars_prestine" ) )
2561  {
2562  if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "bar") )
2563  {
2564  if( barrier_chunks[i] ‪get_chunk_state() == "repaired" ) // If the state of the chunk is repaired then continue
2565  {
2566 
2567  if( barrier_chunks[i].origin == barrier_chunks[i].og_origin ) // If this chunk has its original origin then continue
2568  {
2569  ‪array[‪array.size] = barrier_chunks[i]; //
2570  }
2571  }
2572  }
2573  }
2574  }
2575 
2576  if( ‪array.size == 0 )
2577  {
2578  return undefined; // If there are no more pieces left then don't allow it to continue
2579  }
2580 
2581  return ‪array; // send back state of array
2582  }
2583 }
2584 
2585 function ‪get_non_destroyed_chunks_grate( barrier, barrier_chunks )
2586 {
2587  if(isdefined(barrier.zbarrier))
2588  {
2589  return barrier.zbarrier GetZBarrierPieceIndicesInState("closed");
2590  }
2591  else
2592  {
2593  ‪array = []; // Setup array
2594  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2595  {
2596  if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "grate") )
2597  {
2598  if( IsDefined ( barrier_chunks[i] ) )
2599  {
2600  ‪array[‪array.size] = barrier_chunks[i]; //
2601  }
2602  }
2603  }
2604 
2605  if( ‪array.size == 0 )
2606  {
2607  return undefined; // If there are no more pieces left then don't allow it to continue
2608  }
2609 
2610  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2611  }
2612 }
2613 
2614 function ‪get_non_destroyed_variant1( barrier_chunks )
2615 {
2616  ‪array = []; // Setup array
2617  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2618  {
2619  if (IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "bar_board_variant1") )
2620  {
2621  if( IsDefined ( barrier_chunks[i] ) )
2622  {
2623  ‪array[‪array.size] = barrier_chunks[i];
2624  }
2625  }
2626  }
2627 
2628  if( ‪array.size == 0 )
2629  {
2630  return undefined; // If there are no more pieces left then don't allow it to continue
2631  }
2632 
2633  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2634 }
2635 
2636 function ‪get_non_destroyed_variant2( barrier_chunks )
2637 {
2638  ‪array = []; // Setup array
2639  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2640  {
2641  if (IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "bar_board_variant2") )
2642  {
2643  if( IsDefined ( barrier_chunks[i] ) )
2644  {
2645  ‪array[‪array.size] = barrier_chunks[i];
2646  }
2647  }
2648  }
2649 
2650  if( ‪array.size == 0 )
2651  {
2652  return undefined; // If there are no more pieces left then don't allow it to continue
2653  }
2654 
2655  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2656 }
2657 
2658 function ‪get_non_destroyed_variant4( barrier_chunks )
2659 {
2660  ‪array = []; // Setup array
2661  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2662  {
2663  if (IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "bar_board_variant4") )
2664  {
2665  if( IsDefined ( barrier_chunks[i] ) )
2666  {
2667  ‪array[‪array.size] = barrier_chunks[i]; //
2668  }
2669  }
2670  }
2671 
2672  if( ‪array.size == 0 )
2673  {
2674  return undefined; // If there are no more pieces left then don't allow it to continue
2675  }
2676 
2677  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2678 }
2679 
2680 function ‪get_non_destroyed_variant5( barrier_chunks )
2681 {
2682  ‪array = []; // Setup array
2683  for( i = 0; i < barrier_chunks.size; i++ ) // Cycle through and grab all chunks
2684  {
2685  if (IsDefined (barrier_chunks[i].script_team) && (barrier_chunks[i].script_team == "bar_board_variant5") )
2686  {
2687  if( IsDefined ( barrier_chunks[i] ) )
2688  {
2689  ‪array[‪array.size] = barrier_chunks[i]; //
2690  }
2691  }
2692  }
2693 
2694  if( ‪array.size == 0 )
2695  {
2696  return undefined; // If there are no more pieces left then don't allow it to continue
2697  }
2698 
2699  return ‪array; // send back state of array so it knows if boards are full or note and which board it is.
2700 }
2701 
2702 function ‪get_destroyed_chunks( barrier_chunks )
2703 {
2704  ‪array = [];
2705  for( i = 0; i < barrier_chunks.size; i++ )
2706  {
2707  if( barrier_chunks[i] ‪get_chunk_state() == "destroyed" ) // if the chunks state says it is destroyed then continue
2708  {
2709  if (IsDefined (barrier_chunks[i].script_parameters) && barrier_chunks[i].script_parameters == "board")
2710  {
2711  ‪array[‪array.size] = barrier_chunks[i]; // create a new array from barrier chunks
2712  }
2713  else if (IsDefined (barrier_chunks[i].script_parameters) && barrier_chunks[i].script_parameters == "repair_board" || barrier_chunks[i].script_parameters == "barricade_vents")
2714  {
2715  ‪array[‪array.size] = barrier_chunks[i]; // create a new array from barrier chunks
2716  }
2717  else if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "bar") )
2718  {
2719  ‪array[‪array.size] = barrier_chunks[i]; // create a new array from barrier chunks
2720  }
2721 
2722  else if (IsDefined (barrier_chunks[i].script_parameters) && (barrier_chunks[i].script_parameters == "grate") )
2723  {
2724  // This makes sure that it isn't returned
2725  return undefined;
2726  //array[array.size] = barrier_chunks[i]; // create a new array from barrier chunks
2727  }
2728  }
2729  }
2730 
2731  if( ‪array.size == 0 )
2732  {
2733  return undefined;
2734  }
2735 
2736  return ‪array;
2737 
2738  //if( IsDefined( barrier_chunks ) )
2739  //{
2740  // return barrier_chunks;
2741  //}
2742 }
2743 
2744 
2745 function ‪grate_order_destroyed( chunks_repair_grate )
2746 {
2747  grate_repair_order = [];
2748  grate_repair_order1 =[]; // this sets up the order for the grates
2749  grate_repair_order2 =[]; // this sets up the order for the grates
2750  grate_repair_order3 =[]; // this sets up the order for the grates
2751  grate_repair_order4 =[]; // this sets up the order for the grates
2752  grate_repair_order5 =[]; // this sets up the order for the grates
2753  grate_repair_order6 =[]; // this sets up the order for the grates
2754 
2755 
2756  // DEBUG
2757  /*
2758  for(i=0;i<chunks_repair_grate.size;i++) // Go through the array
2759  {
2760  if (IsDefined (chunks_repair_grate[i].script_parameters) && (chunks_repair_grate[i].script_parameters == "grate") )
2761  {
2762  grate_repair_order[grate_repair_order.size] = chunks_repair_grate[i]; // now chunks is the total amount of grates connecte
2763  }
2764  }
2765  */
2766 
2767  for(i=0;i<chunks_repair_grate.size;i++)
2768  {
2769  if (IsDefined (chunks_repair_grate[i].script_parameters) && (chunks_repair_grate[i].script_parameters == "grate") )
2770  {
2771  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "1" ) )
2772  {
2773  grate_repair_order1[grate_repair_order1.size] = chunks_repair_grate[i];
2774  // send back order here
2775  }
2776  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "2" ) )
2777  {
2778  grate_repair_order2[grate_repair_order2.size] = chunks_repair_grate[i];
2779  // send back order here
2780  }
2781  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "3" ) )
2782  {
2783  grate_repair_order3[grate_repair_order3.size] = chunks_repair_grate[i];
2784  // send back order here
2785  }
2786  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "4" ) )
2787  {
2788  grate_repair_order4[grate_repair_order4.size] = chunks_repair_grate[i];
2789  // send back order here
2790  }
2791  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "5" ) )
2792  {
2793  grate_repair_order5[grate_repair_order5.size] = chunks_repair_grate[i];
2794  // send back order here
2795  }
2796  if ( IsDefined ( chunks_repair_grate[i].script_noteworthy ) && ( chunks_repair_grate[i].script_noteworthy == "6" ) )
2797  {
2798  grate_repair_order6[grate_repair_order6.size] = chunks_repair_grate[i];
2799  // send back order here
2800  }
2801  }
2802  }
2803 
2804  for(i=0;i<chunks_repair_grate.size;i++) // Go through the array
2805  {
2806  if (IsDefined (chunks_repair_grate[i].script_parameters) && (chunks_repair_grate[i].script_parameters == "grate") )
2807  {
2808  if( IsDefined ( grate_repair_order1[i] ) ) // last one here
2809  {
2810 
2811  if( ( grate_repair_order6[i].state == "destroyed" ) )
2812  {
2813  /#
2814  IPrintLnBold(" Fix grate6 ");
2815  #/
2816  // Here I will tell the other board to replace
2817  return grate_repair_order6[i];
2818  }
2819  if( ( grate_repair_order5[i].state == "destroyed" ) )
2820  {
2821  /#
2822  IPrintLnBold(" Fix grate5 ");
2823  #/
2824  grate_repair_order6[i] thread ‪show_grate_repair();
2825  return grate_repair_order5[i];
2826  }
2827  else if( ( grate_repair_order4[i].state == "destroyed" ) )
2828  {
2829  /#
2830  IPrintLnBold(" Fix grate4 ");
2831  #/
2832  grate_repair_order5[i] thread ‪show_grate_repair();
2833  return grate_repair_order4[i];
2834  }
2835  else if( ( grate_repair_order3[i].state == "destroyed" ) )
2836  {
2837  /#
2838  IPrintLnBold(" Fix grate3 ");
2839  #/
2840  grate_repair_order4[i] thread ‪show_grate_repair();
2841  return grate_repair_order3[i];
2842  }
2843  else if( ( grate_repair_order2[i].state == "destroyed" ) )
2844  {
2845  /#
2846  IPrintLnBold(" Fix grate2 ");
2847  #/
2848  grate_repair_order3[i] thread ‪show_grate_repair();
2849  return grate_repair_order2[i];
2850  }
2851  else if( ( grate_repair_order1[i].state == "destroyed" ) )
2852  {
2853  /#
2854  IPrintLnBold(" Fix grate1 ");
2855  #/
2856  grate_repair_order2[i] thread ‪show_grate_repair();
2857  // I need to return nothing here.
2858  //return undefined();
2859  return grate_repair_order1[i];
2860  }
2861  }
2862  }
2863  }
2864 }
2865 
2866 // Self is grate
2868 {
2869  wait( 0.34 );
2870  self Hide();
2871 }
2872 
2874 {
2875  assert( isdefined( self.state ) );
2876 
2877  return self.state;
2878 }
2879 
2880 function ‪array_limiter( ‪array, total )
2881 {
2882  new_array = [];
2883 
2884  for( i = 0; i < ‪array.size; i++ )
2885  {
2886  if( i < total )
2887  {
2888  new_array[new_array.size] = ‪array[i];
2889  }
2890  }
2891 
2892  return new_array;
2893 }
2894 
2895 
2896 function ‪fake_physicslaunch( target_pos, power )
2897 {
2898  start_pos = self.origin;
2899 
2901  // Reverse the gravity so it's negative, you could change the gravity
2902  // by just putting a number in there, but if you keep the dvar, then the
2903  // user will see it change.
2904  gravity = GetDvarInt( "bg_gravity" ) * -1;
2905 
2906  dist = Distance( start_pos, target_pos );
2907 
2908  time = dist / power;
2909  delta = target_pos - start_pos;
2910  drop = 0.5 * gravity *( time * time );
2911 
2912  velocity = ( ( delta[0] / time ), ( delta[1] / time ), ( delta[2] - drop ) / time );
2914 
2915  level thread ‪draw_line_ent_to_pos( self, target_pos );
2916  self MoveGravity( velocity, time );
2917  return time;
2918 }
2919 
2920 //
2921 // STRINGS =======================================================================
2922 //
2923 function ‪add_zombie_hint( ref, text )
2924 {
2925  if( !IsDefined( level.zombie_hints ) )
2926  {
2927  level.zombie_hints = [];
2928  }
2929 
2930  level.zombie_hints[ref] = text;
2931 }
2932 
2933 function ‪get_zombie_hint( ref )
2934 {
2935  if( IsDefined( level.zombie_hints[ref] ) )
2936  {
2937  return level.zombie_hints[ref];
2938  }
2939 
2940 /#
2941  println( "UNABLE TO FIND HINT STRING " + ref );
2942 #/
2943  return level.zombie_hints["undefined"];
2944 }
2945 
2946 // self is the trigger( usually spawned in on the fly )
2947 // ent is the entity that has the script_hint info
2948 function ‪set_hint_string( ent, default_ref, cost )
2949 {
2950  ref = default_ref;
2951  if( IsDefined( ent.script_hint ) )
2952  {
2953  ref = ent.script_hint;
2954  }
2955  if ( ‪IS_TRUE( level.legacy_hint_system ) ) // T7TODO - this can be deleted
2956  {
2957  ref = ref + "_" + cost;
2958  self SetHintString( ‪get_zombie_hint( ref ) );
2959  }
2960  else
2961  {
2962  hint = ‪get_zombie_hint( ref );
2963  if (IsDefined(cost))
2964  {
2965  self SetHintString( hint, cost );
2966  }
2967  else
2968  {
2969  self SetHintString( hint );
2970  }
2971  }
2972 }
2973 
2974 function ‪get_hint_string(ent, default_ref, cost )
2975 {
2976  ref = default_ref;
2977  if( IsDefined( ent.script_hint ) )
2978  {
2979  ref = ent.script_hint;
2980  }
2981  if ( ‪IS_TRUE( level.legacy_hint_system ) && IsDefined(cost) ) // T7TODO - this can be deleted
2982  {
2983  ref = ref + "_" + cost;
2984  }
2985  return ‪get_zombie_hint( ref );
2986 }
2987 
2988 function ‪unitrigger_set_hint_string( ent, default_ref, cost )
2989 {
2990  triggers=[];
2991  if(self.trigger_per_player)
2992  {
2993  triggers = self.playertrigger;
2994  }
2995  else
2996  {
2997  triggers[0] = self.trigger;
2998  }
2999  foreach(trigger in triggers)
3000  {
3001  ref = default_ref;
3002  if( IsDefined( ent.script_hint ) )
3003  {
3004  ref = ent.script_hint;
3005  }
3006  if ( ‪IS_TRUE( level.legacy_hint_system ) ) // T7TODO - this can be deleted
3007  {
3008  ref = ref + "_" + cost;
3009  trigger SetHintString( ‪get_zombie_hint( ref ) );
3010  }
3011  else
3012  {
3013  hint = ‪get_zombie_hint( ref );
3014  if (IsDefined(cost))
3015  {
3016  trigger SetHintString( hint, cost );
3017  }
3018  else
3019  {
3020  trigger SetHintString( hint );
3021  }
3022  }
3023  }
3024 }
3025 
3026 //
3027 // SOUNDS ===========================================================
3028 //
3029 
3030 function ‪add_sound( ref, alias )
3031 {
3032  if( !IsDefined( level.zombie_sounds ) )
3033  {
3034  level.zombie_sounds = [];
3035  }
3036 
3037  level.zombie_sounds[ref] = alias;
3038 }
3039 
3040 function ‪play_sound_at_pos( ref, pos, ent )
3041 {
3042  if( IsDefined( ent ) )
3043  {
3044  if( IsDefined( ent.script_soundalias ) )
3045  {
3046  PlaySoundAtPosition( ent.script_soundalias, pos );
3047  return;
3048  }
3049 
3050  if( IsDefined( self.script_sound ) )
3051  {
3052  ref = self.script_sound;
3053  }
3054  }
3055 
3056  if( ref == "none" )
3057  {
3058  return;
3059  }
3060 
3061  if( !IsDefined( level.zombie_sounds[ref] ) )
3062  {
3063  AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
3064  return;
3065  }
3066 
3067  PlaySoundAtPosition( level.zombie_sounds[ref], pos );
3068 }
3069 
3070 function ‪play_sound_on_ent( ref )
3071 {
3072  if( IsDefined( self.script_soundalias ) )
3073  {
3074  self PlaySound( self.script_soundalias );
3075  return;
3076  }
3077 
3078  if( IsDefined( self.script_sound ) )
3079  {
3080  ref = self.script_sound;
3081  }
3082 
3083  if( ref == "none" )
3084  {
3085  return;
3086  }
3087 
3088  if( !IsDefined( level.zombie_sounds[ref] ) )
3089  {
3090  AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
3091  return;
3092  }
3093 
3094  self PlaySound( level.zombie_sounds[ref] );
3095 }
3096 
3098 {
3099  if( IsDefined( self.script_firefxsound ) )
3100  {
3101  ref = self.script_firefxsound;
3102  }
3103 
3104  if( ref == "none" )
3105  {
3106  return;
3107  }
3108 
3109  if( !IsDefined( level.zombie_sounds[ref] ) )
3110  {
3111  AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
3112  return;
3113  }
3114 
3115  self PlaySound( level.zombie_sounds[ref] );
3116 }
3117 
3118 
3119 function ‪string_to_float( string )
3120 {
3121  floatParts = strTok( string, "." );
3122  if ( floatParts.size == 1 )
3123  return int(floatParts[0]);
3124 
3125  whole = int(floatParts[0]);
3126  // Convert the decimal part into a floating point value
3127  decimal = 0;
3128  for ( i=floatParts[1].size-1; i>=0; i-- )
3129  {
3130  decimal = decimal/10 + int(floatParts[1][i])/10;
3131  }
3132 
3133  if ( whole >= 0 )
3134  return (whole + decimal);
3135  else
3136  return (whole - decimal);
3137 }
3138 
3139 //
3140 // TABLE LOOK SECTION ============================================================
3141 //
3142 
3143 // Read a value from a table and set the related level.zombie_var
3144 //
3145 function ‪set_zombie_var( zvar, value, is_float, column, is_team_based )
3146 {
3147  if ( !IsDefined( is_float ) )
3148  {
3149  is_float = false;
3150  }
3151  if ( !IsDefined(column) )
3152  {
3153  column = 1;
3154  }
3155 
3156  if ( ‪IS_TRUE( is_team_based ) )
3157  {
3158  foreach( team in level.teams )
3159  {
3160  level.zombie_vars[ team ][ zvar ] = value;
3161  }
3162  }
3163  else
3164  {
3165  level.zombie_vars[zvar] = value;
3166  }
3167 
3168  return value;
3169 }
3170 
3171 
3172 // Read a value from a table and return the result
3173 //
3174 function ‪get_table_var( table, var_name, value, is_float, column )
3175 {
3176  if ( !IsDefined(table) )
3177  {
3178  table = "mp/zombiemode.csv";
3179  }
3180  if ( !IsDefined(is_float) )
3181  {
3182  is_float = false;
3183  }
3184  if ( !IsDefined(column) )
3185  {
3186  column = 1;
3187  }
3188 
3189  // First look it up in the table
3190  table_value = TableLookUp( table, 0, var_name, column );
3191  if ( IsDefined( table_value ) && table_value != "" )
3192  {
3193  if( is_float )
3194  {
3195  value = ‪string_to_float( table_value );
3196  }
3197  else
3198  {
3199  value = int( table_value );
3200  }
3201  }
3202 
3203  return value;
3204 }
3205 
3206 
3208 {
3209 /#
3210  max = 0;
3211  curr_total = 0;
3212  while( 1 )
3213  {
3214  if( level.hudelem_count > max )
3215  {
3216  max = level.hudelem_count;
3217  }
3218 
3219  println( "HudElems: " + level.hudelem_count + "[Peak: " + max + "]" );
3221  }
3222 #/
3223 }
3224 
3226 {
3227 /#
3228  while( 1 )
3229  {
3231 
3232  for( i = 0; i < zombs.size; i++ )
3233  {
3234  zombs[i] dodamage( zombs[i].health + 666, ( 0, 0, 0 ) );
3235  wait 0.5;
3236  }
3237  }
3238 #/
3239 }
3240 
3241 function ‪print_run_speed( speed )
3242 {
3243 /#
3244  self endon( "death" );
3245  while( 1 )
3246  {
3247  print3d( self.origin +( 0, 0, 64 ), speed, ( 1, 1, 1 ) );
3249  }
3250 #/
3251 }
3252 
3253 function ‪draw_line_ent_to_ent( ent1, ent2 )
3254 {
3255 /#
3256  if( GetDvarInt( "zombie_debug" ) != 1 )
3257  {
3258  return;
3259  }
3260 
3261  ent1 endon( "death" );
3262  ent2 endon( "death" );
3263 
3264  while( 1 )
3265  {
3266  line( ent1.origin, ent2.origin );
3268  }
3269 #/
3270 }
3271 
3272 function ‪draw_line_ent_to_pos( ent, pos, end_on )
3273 {
3274 /#
3275  if( GetDvarInt( "zombie_debug" ) != 1 )
3276  {
3277  return;
3278  }
3279 
3280  ent endon( "death" );
3281 
3282  ent notify( "stop_draw_line_ent_to_pos" );
3283  ent endon( "stop_draw_line_ent_to_pos" );
3284 
3285  if( IsDefined( end_on ) )
3286  {
3287  ent endon( end_on );
3288  }
3289 
3290  while( 1 )
3291  {
3292  line( ent.origin, pos );
3294  }
3295 #/
3296 }
3297 
3298 function ‪debug_print( msg )
3299 {
3300 /#
3301  if( GetDvarInt( "zombie_debug" ) > 0 )
3302  {
3303  println( "######### ZOMBIE: " + msg );
3304  }
3305 #/
3306 }
3307 
3308 function ‪debug_blocker( pos, rad, height )
3309 {
3310 /#
3311  self notify( "stop_debug_blocker" );
3312  self endon( "stop_debug_blocker" );
3313 
3314  for( ;; )
3315  {
3316  if( GetDvarInt( "zombie_debug" ) != 1 )
3317  {
3318  return;
3319  }
3320 
3322  ‪drawcylinder( pos, rad, height );
3323 
3324  }
3325 #/
3326 }
3327 
3328 function ‪drawcylinder( pos, rad, height )
3329 {
3330 /#
3331  currad = rad;
3332  curheight = height;
3333 
3334  for( r = 0; r < 20; r++ )
3335  {
3336  theta = r / 20 * 360;
3337  theta2 = ( r + 1 ) / 20 * 360;
3338 
3339  line( pos +( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos +( cos( theta2 ) * currad, sin( theta2 ) * currad, 0 ) );
3340  line( pos +( cos( theta ) * currad, sin( theta ) * currad, curheight ), pos +( cos( theta2 ) * currad, sin( theta2 ) * currad, curheight ) );
3341  line( pos +( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos +( cos( theta ) * currad, sin( theta ) * currad, curheight ) );
3342  }
3343 #/
3344 }
3345 
3346 function ‪print3d_at_pos( msg, pos, thread_endon, offset )
3347 {
3348 /#
3349  self endon( "death" );
3350 
3351  if( IsDefined( thread_endon ) )
3352  {
3353  self notify( thread_endon );
3354  self endon( thread_endon );
3355  }
3356 
3357  if( !IsDefined( offset ) )
3358  {
3359  offset = ( 0, 0, 0 );
3360  }
3361 
3362  while( 1 )
3363  {
3364  print3d( self.origin + offset, msg );
3366  }
3367 #/
3368 }
3369 
3371 {
3372 /#
3373  self endon( "disconnect" );
3374  self notify("stop_debug_breadcrumbs");
3375  self endon("stop_debug_breadcrumbs");
3376 
3377 
3378  while( 1 )
3379  {
3380  if( GetDvarInt( "zombie_debug" ) != 1 )
3381  {
3382  wait( 1 );
3383  continue;
3384  }
3385 
3386  for( i = 0; i < self.zombie_breadcrumbs.size; i++ )
3387  {
3388  ‪drawcylinder( self.zombie_breadcrumbs[i], 5, 5 );
3389  }
3390 
3392  }
3393 #/
3394 }
3395 
3396 /#
3398 {
3399 // this section was totally commented out.
3400  self notify("stop_debug_breadcrumbs");
3401  self endon("stop_debug_breadcrumbs");
3402 
3403  while( 1 )
3404  {
3405  if( GetDvarInt( "zombie_debug" ) != 2 )
3406  {
3407  wait( 1 );
3408  continue;
3409  }
3410 
3412  count = 0;
3413  for( i = 0; i < self.attack_spots_taken.size; i++ )
3414  {
3415  if( self.attack_spots_taken[i] )
3416  {
3417  count++;
3418  circle(self.attack_spots[i], 12, (1,0,0), false, true, 1);
3419  }
3420  else
3421  {
3422  circle(self.attack_spots[i], 12, (0,1,0), false, true, 1);
3423  }
3424  }
3425 
3426  msg = "" + count + " / " + self.attack_spots_taken.size;
3427  print3d( self.origin, msg );
3428  }
3429 
3430 }
3431 #/
3432 
3433 function ‪float_print3d( msg, time )
3434 {
3435 /#
3436  self endon( "death" );
3437 
3438  time = GetTime() + ( time * 1000 );
3439  offset = ( 0, 0, 72 );
3440  while( GetTime() < time )
3441  {
3442  offset = offset + ( 0, 0, 2 );
3443  print3d( self.origin + offset, msg, ( 1, 1, 1 ) );
3445  }
3446 #/
3447 }
3448 function ‪do_player_vo(snd, variation_count)
3449 {
3450  index = ‪get_player_index(self);
3451 
3452  // updated to new alias format - Steve G
3453  sound = "zmb_vox_plr_" + index + "_" + snd;
3454  if(IsDefined (variation_count))
3455  {
3456  sound = sound + "_" + randomintrange(0, variation_count);
3457  }
3458  if(!isDefined(level.player_is_speaking))
3459  {
3460  level.player_is_speaking = 0;
3461  }
3462 
3463  if (level.player_is_speaking == 0)
3464  {
3465  level.player_is_speaking = 1;
3466  self PlaySoundWithNotify(sound, "sound_done");
3467  self waittill("sound_done");
3468  //This ensures that there is at least 3 seconds waittime before playing another VO.
3469  wait(2);
3470  level.player_is_speaking = 0;
3471  }
3472 }
3473 
3475 {
3476  if( !IsDefined( ent ) )
3477  return false;
3478 
3479  //return ( IsDefined( ent.magic_bullet_shield ) && ent.magic_bullet_shield == true );
3480  return !‪IS_TRUE( ent.allowDeath );
3481 }
3482 
3484 {
3485  temp_ent = ‪spawn("script_origin", (0,0,0));
3486  temp_ent PlaySoundWithNotify (sound, sound + "wait");
3487  temp_ent waittill (sound + "wait");
3489  temp_ent delete();
3490 }
3491 
3492 
3493 function ‪play_sound_2D(sound)
3494 {
3495  level thread ‪really_play_2D_sound(sound);
3496 
3497  /*
3498  if(!isdefined(level.playsound2dent))
3499  {
3500  level.playsound2dent = spawn("script_origin",(0,0,0));
3501  }
3502 
3503  //players=GetPlayers();
3504  level.playsound2dent playsound ( sound );
3505  */
3506  /*
3507  temp_ent = spawn("script_origin", (0,0,0));
3508  temp_ent PlaySoundWithNotify (sound, sound + "wait");
3509  temp_ent waittill (sound + "wait");
3510  WAIT_SERVER_FRAME;
3511  temp_ent delete();
3512  */
3513 }
3514 
3515 function ‪include_weapon( weapon_name, in_box )
3516 {
3517 /# println( "ZM >> include_weapon = " + weapon_name ); #/
3518  if( !isDefined( in_box ) )
3519  {
3520  in_box = true;
3521  }
3522 
3523  ‪zm_weapons::include_zombie_weapon( weapon_name, in_box );
3524 }
3525 
3526 // Allows triggers to be un/seen by players
3528 {
3529  players = GetPlayers();
3530  for ( i = 0; i < players.size; i++ )
3531  {
3532  if ( isdefined( players[i] ) )
3533  {
3534  self SetInvisibleToPlayer( players[i], ‪enable );
3535  }
3536  }
3537 }
3538 
3539 
3540 // Print3d
3541 function ‪print3d_ent( text, color, scale, offset, end_msg, overwrite )
3542 {
3543  self endon("death");
3544 
3545  if ( IsDefined(overwrite) && overwrite && IsDefined( self._debug_print3d_msg ) )
3546  {
3547  // Kill the previous thread
3548  self notify( "end_print3d" );
3550  }
3551 
3552  self endon("end_print3d");
3553 
3554  if ( !IsDefined(color) )
3555  {
3556  color = (1,1,1);
3557  }
3558 
3559  if ( !IsDefined(scale) )
3560  {
3561  scale = 1.0;
3562  }
3563 
3564  if ( !IsDefined(offset) )
3565  {
3566  offset = (0,0,0);
3567  }
3568 
3569  if ( IsDefined(end_msg) )
3570  {
3571  self endon(end_msg);
3572  }
3573 
3574  // This way you can change the message dynamically by changing the var
3575  self._debug_print3d_msg = text;
3576  /#
3577  while ( !‪IS_TRUE( level.disable_print3d_ent ) )
3578  {
3579  print3d( self.origin+offset, self._debug_print3d_msg, color, scale );
3581  }
3582  #/
3583 }
3584 
3585 //
3586 //
3588 {
3589  if( !IsDefined( x ) )
3590  {
3591  x = 0;
3592  }
3593 
3594  hud = ‪create_simple_hud();
3595  hud.alignX = "left";
3596  hud.alignY = "top";
3597  hud.horzAlign = "user_left";
3598  hud.vertAlign = "user_top";
3599  hud.color = ( 1, 1, 1 );
3600 // hud.color = ( 0.21, 0, 0 );
3601  hud.fontscale = 32;
3602  hud.x = x;
3603  hud.alpha = 0;
3604 
3605  hud SetShader( "hud_chalk_1", 64, 64 );
3606 
3607  return hud;
3608 }
3609 
3610 
3611 //
3612 // Get the name of the zone that the entity is currently in
3613 // self is the entity to check on
3614 function ‪get_current_zone( return_zone )
3615 {
3616  level ‪flag::wait_till( "zones_initialized" );
3617 
3618  if ( IsDefined(self.cached_zone) )
3619  {
3620  zone = self.cached_zone;
3621  zone_name = self.cached_zone_name;
3622  vol = self.cached_zone_volume;
3623  // check most recent zone and volume
3624  if ( self IsTouching(zone.volumes[vol]) )
3625  {
3626  if ( ‪IS_TRUE( return_zone ) )
3627  {
3628  return zone;
3629  }
3630  return zone_name;
3631  }
3632  // check other volumes in the most recent zone
3633  for (i = 0; i < zone.volumes.size; i++)
3634  {
3635  if ( i == vol )
3636  continue;
3637  if ( self IsTouching(zone.volumes[i]) )
3638  {
3639  self.cached_zone = zone;
3640  self.cached_zone_volume = i;
3641  if ( ‪IS_TRUE( return_zone ) )
3642  {
3643  return zone;
3644  }
3645  return zone_name;
3646  }
3647  }
3648  }
3649 
3650  // clear out active zone flags
3651  for( z=0; z<level.zone_keys.size; z++ )
3652  {
3653  zone_name = level.zone_keys[z];
3654  zone = level.zones[ zone_name ];
3655 
3656  if ( ‪IS_EQUAL( zone, self.cached_zone ) )
3657  continue;
3658 
3659  // Okay check to see if the entity is in one of the zone volumes
3660  for (i = 0; i < zone.volumes.size; i++)
3661  {
3662  if ( self IsTouching(zone.volumes[i]) )
3663  {
3664  self.cached_zone = zone;
3665  self.cached_zone_name = zone_name;
3666  self.cached_zone_volume = i;
3667  if ( ‪IS_TRUE( return_zone ) )
3668  {
3669  return zone;
3670  }
3671  return zone_name;
3672  }
3673  }
3674  }
3675 
3676  self.cached_zone = undefined;
3677  self.cached_zone_name = undefined;
3678  self.cached_zone_volume = undefined;
3679 
3680  return undefined;
3681 }
3682 
3684 {
3685  /*modStrings = strtok( mod, "mod_" );
3686  modName = "";
3687  for ( i = 1; i < modStrings.size; i++ )//skip the MOD_
3688  {
3689  modName += modStrings[i];
3690  }*/
3691 
3692  return mod;
3693 }
3694 
3696 {
3697  players = GetPlayers();
3698 
3699  for( i = 0; i < players.size; i++ )
3700  {
3701  players[i] notify( "stop_fog" );
3702  }
3703 }
3704 
3705 function ‪display_message( titleText, notifyText, duration )
3706 {
3707  notifyData = spawnStruct();
3708  notifyData.titleText = notifyText;//titleText;
3709  notifyData.notifyText = titleText;//notifyText;
3710  //notifyData.titleText = &"ZM_MEAT_GRAB";
3711  //notifyData.notifyText = "MEAT GRAB";
3712  notifyData.sound = "mus_level_up";
3713  notifyData.duration = duration;
3714  notifyData.glowColor = (1.0, 0.0, 0.0);
3715  notifyData.color = (0.0, 0.0, 0.0);
3716  notifyData.iconName = "hud_zombies_meat";
3717  self thread ‪hud_message::notifyMessage( notifyData );
3718 }
3719 
3720 function ‪is_quad()
3721 {
3722  return self.animname == "quad_zombie";
3723 }
3724 
3725 function ‪is_leaper()
3726 {
3727  return self.animname == "leaper_zombie";
3728 }
3729 
3731 {
3732  self endon( "death" );
3733  self endon( "disconnect" );
3734 
3735  self notify("stop_shock_onpain");
3736  self endon("stop_shock_onpain");
3737 
3738  if( GetDvarString( "blurpain" ) == "" )
3739  {
3740  SetDvar( "blurpain", "on" );
3741  }
3742 
3743  while( 1 )
3744  {
3745  oldhealth = self.health;
3746  self waittill( "damage", ‪damage, attacker, direction_vec, point, mod );
3747 
3748  if( IsDefined( level.shock_onpain ) && !level.shock_onpain )
3749  {
3750  continue;
3751  }
3752 
3753  if( IsDefined( self.‪shock_onpain ) && !self.‪shock_onpain )
3754  {
3755  continue;
3756  }
3757 
3758  if( self.health < 1 )
3759  {
3760  continue;
3761  }
3762 
3763  if ( IsDefined(attacker) && IsDefined(attacker.custom_player_shellshock) )
3764  {
3765  self [[ attacker.custom_player_shellshock ]] ( ‪damage, attacker, direction_vec, point, mod );
3766  }
3767  else if( mod == "MOD_PROJECTILE" || mod == "MOD_PROJECTILE_SPLASH" )
3768  {
3769  continue;
3770  }
3771  else if( mod == "MOD_GRENADE_SPLASH" || mod == "MOD_GRENADE" || mod == "MOD_EXPLOSIVE" )
3772  {
3773  shockType = undefined;
3774  shockLight = undefined;
3775 
3776  if ( ‪IS_TRUE( self.is_burning ) )
3777  {
3778  shockType = "lava";
3779  shockLight = "lava_small";
3780  }
3781 
3782  self ‪shock_onexplosion( ‪damage, shockType, shockLight );
3783  }
3784  else
3785  {
3786  if( GetDvarString( "blurpain" ) == "on" )
3787  {
3788  self ShellShock( "pain_zm", 0.5 );
3789  }
3790  }
3791  }
3792 }
3793 
3794 function ‪shock_onexplosion( ‪damage, shockType, shockLight )
3795 {
3796  time = 0;
3797 
3798  scaled_damage = 100 * ‪damage / self.maxhealth;
3799 
3800  if( scaled_damage >= 90 )
3801  {
3802  time = 4;
3803  }
3804  else if( scaled_damage >= 50 )
3805  {
3806  time = 3;
3807  }
3808  else if( scaled_damage >= 25 )
3809  {
3810  time = 2;
3811  }
3812  else if( scaled_damage > 10 )
3813  {
3814  time = 1;
3815  }
3816 
3817  if( time )
3818  {
3819  if ( !IsDefined( shockType ) )
3820  {
3821  shockType = "explosion";
3822  }
3823 
3824  self ShellShock( shockType, time );
3825  }
3826  else if (IsDefined(shockLight))
3827  {
3828  self ShellShock( shockLight, time );
3829  }
3830 }
3831 
3832 
3834 {
3835  ‪DEFAULT( self.ignorme_count, 0 );
3836  self.ignorme_count++;
3837  self.ignoreme = ( self.ignorme_count > 0 );
3838 }
3839 
3841 {
3842  ‪DEFAULT( self.ignorme_count, 0 );
3843  if( self.ignorme_count > 0 )
3844  {
3845  self.ignorme_count--;
3846  }
3847  else
3848  {
3849  AssertMsg( "making ignorme_count less than 0" );
3850  }
3851 
3852  self.ignoreme = ( self.ignorme_count > 0 );
3853 }
3854 
3855 
3856 
3857 
3858 // ww: increment the is_drinking variable on a player
3860 {
3861  //self endon( "death" );
3862  /#
3863  if( ‪IS_TRUE(level.devgui_dpad_watch) )
3864  {
3865  self.is_drinking++;
3866  return;
3867  }
3868  #/
3869 
3870  if( !isdefined(self.is_drinking) )
3871  self.is_drinking = 0;
3872 
3873  if( self.is_drinking == 0 )
3874  {
3875 
3876  self DisableOffhandWeapons();
3877  self DisableWeaponCycling();
3878  }
3879 
3880  self.is_drinking++;
3881 }
3882 
3883 // ww: checks is_drinking
3884 //is_drinking()
3885 //{
3886 // //self endon( "death" );
3887 // return ( self.is_drinking > 0 );
3888 //}
3889 
3890 // to check if more than one is active at once
3892 {
3893  //self endon( "death" );
3894  return ( self.is_drinking > 1 );
3895 }
3896 
3897 // ww: decrement drinking
3899 {
3900  //self endon( "death" );
3901 
3902  if( self.is_drinking > 0 )
3903  {
3904  self.is_drinking--;
3905  }
3906  else
3907  {
3908  AssertMsg( "making is_drinking less than 0" );
3909  }
3910 
3911 
3912  if( self.is_drinking == 0 )
3913  {
3914  self EnableOffhandWeapons();
3915  self EnableWeaponCycling();
3916  }
3917 }
3918 
3919 // ww: clear the variable, used for players going in to last stand
3921 {
3922  //self endon( "death" );
3923 
3924  self.is_drinking = 0;
3925 
3926  self EnableOffhandWeapons();
3927  self EnableWeaponCycling();
3928 }
3929 
3930 // PORTIZ 7/27/16: At this point there are multiple mechanics prolonging solo games when player doesn't have Quick Revive, so we need a
3931 // better way of supporting them in conjunction
3933 {
3934  ‪DEFAULT( level.n_no_end_game_check_count, 0 );
3935  level.n_no_end_game_check_count++;
3936  level.no_end_game_check = ( level.n_no_end_game_check_count > 0 );
3937 }
3938 
3940 {
3941  ‪DEFAULT( level.n_no_end_game_check_count, 0 );
3942  if( level.n_no_end_game_check_count > 0 )
3943  {
3944  level.n_no_end_game_check_count--;
3945  }
3946  else
3947  {
3948  AssertMsg( "making no_end_game_check_count less than 0" );
3949  }
3950 
3951  level.no_end_game_check = ( level.n_no_end_game_check_count > 0 );
3952 
3953  if ( !level.no_end_game_check )
3954  {
3955  level ‪zm::checkForAllDead(); // run this manually any time this is decremented back to a false state
3956  }
3957 }
3958 
3960 /*
3961 function fade_out(time)
3962 {
3963  if (!isDefined(time))
3964  {
3965  time = 1;
3966  }
3967  if( !IsDefined(level.introblack) )
3968  {
3969  level.introblack = NewHudElem();
3970  level.introblack.x = 0;
3971  level.introblack.y = 0;
3972  level.introblack.horzAlign = "fullscreen";
3973  level.introblack.vertAlign = "fullscreen";
3974  level.introblack.foreground = true;
3975  level.introblack SetShader( "black", 640, 480 );
3976  level.introblack.alpha = 0;
3977  wait .05;
3978  }
3979 
3980  if( time > 0 )
3981  {
3982  level.introblack FadeOverTime( time );
3983  }
3984  level.introblack.alpha = 1;
3985 
3986  players = GetPlayers();
3987  for(i = 0; i < players.size; i++)
3988  {
3989  players[i] freezecontrols(true);
3990  }
3991 
3992  wait time;
3993 }
3994 
3995 function fade_in( hold_black_time )
3996 {
3997  if( !IsDefined(level.introblack) )
3998  {
3999  level.introblack = NewHudElem();
4000  level.introblack.x = 0;
4001  level.introblack.y = 0;
4002  level.introblack.horzAlign = "fullscreen";
4003  level.introblack.vertAlign = "fullscreen";
4004  level.introblack.foreground = true;
4005  level.introblack SetShader( "black", 640, 480 );
4006  level.introblack.alpha = 1;
4007  wait .05;
4008  }
4009 
4010  level.introblack.alpha = 1;
4011 
4012  if( IsDefined( hold_black_time ) )
4013  wait hold_black_time;
4014  else
4015  wait .2;
4016 
4017  level.introblack FadeOverTime( 1.5 );
4018  level.introblack.alpha = 0;
4019 
4020  level notify("fade_introblack");
4021 
4022  wait 1.5;
4023 
4024  players = GetPlayers();
4025  for(i = 0; i < players.size; i++)
4026  {
4027  players[i] freezecontrols(false);
4028  }
4029  level notify("fade_in_complete");
4030 }
4031 */
4033 // WEAPONS
4035 
4036 function ‪getWeaponClassZM( weapon )
4037 {
4038  assert( isdefined( weapon ) );
4039  if ( !isdefined( weapon ) )
4040  {
4041  return undefined;
4042  }
4043 
4044  if ( !isdefined ( level.weaponClassArray ) )
4045  {
4046  level.weaponClassArray = [];
4047  }
4048 
4049  if ( isdefined( level.weaponClassArray[weapon] ) )
4050  {
4051  return level.weaponClassArray[weapon];
4052  }
4053 
4054  baseWeaponIndex = GetBaseWeaponItemIndex( weapon );
4055  statsTableName = ‪util::getStatsTableName();
4056  weaponClass = tableLookup( statsTableName, 0, baseWeaponIndex, ‪STATS_TABLE_COL_GROUP);
4057  level.weaponClassArray[weapon] = weaponClass;
4058  return weaponClass;
4059 }
4060 
4061 function ‪spawn_weapon_model( weapon, model, origin, angles, options )
4062 {
4063  if ( !isdefined( model ) )
4064  {
4065  model = weapon.worldModel;
4066  }
4067 
4068  weapon_model = ‪spawn( "script_model", origin );
4069  if ( isdefined( angles ) )
4070  {
4071  weapon_model.angles = angles;
4072  }
4073 
4074  if ( isdefined( options ) )
4075  {
4076  weapon_model useweaponmodel( weapon, model, options );
4077  }
4078  else
4079  {
4080  weapon_model useweaponmodel( weapon, model );
4081  }
4082 
4083  return weapon_model;
4084 }
4085 
4086 
4087 function ‪spawn_buildkit_weapon_model( player, weapon, camo, origin, angles )
4088 {
4089  weapon_model = ‪spawn( "script_model", origin );
4090  if ( isdefined( angles ) )
4091  {
4092  weapon_model.angles = angles;
4093  }
4094 
4095  upgraded = ‪zm_weapons::is_weapon_upgraded( weapon );
4096  if ( upgraded && (!IsDefined( camo ) || 0 > camo) )
4097  {
4098  camo = ‪zm_weapons::get_pack_a_punch_camo_index( undefined );
4099  }
4100 
4101  weapon_model UseBuildKitWeaponModel( player, weapon, camo, upgraded );
4102 
4103  return weapon_model;
4104 }
4105 
4106 
4107 function ‪is_player_revive_tool( weapon )
4108 {
4109  if ( weapon == level.weaponReviveTool || ‪IS_EQUAL(weapon,self.weaponReviveTool) )
4110  {
4111  return true;
4112  }
4113 
4114  return false;
4115 }
4116 
4117 function ‪is_limited_weapon( weapon )
4118 {
4119  if ( IsDefined( level.limited_weapons ) && IsDefined( level.limited_weapons[weapon] ) )
4120  {
4121  return true;
4122  }
4123 
4124  return false;
4125 }
4126 
4127 
4129 {
4130  weapon = GetWeapon( weaponname );
4131  if ( ‪is_lethal_grenade( weapon ) )
4132  {
4133  return;
4134  }
4135 
4136  if ( !isdefined( level.zombie_lethal_grenade_list ) )
4137  {
4138  level.zombie_lethal_grenade_list = [];
4139  }
4140 
4141  level.zombie_lethal_grenade_list[weapon] = weapon;
4142 }
4143 
4144 
4145 function ‪is_lethal_grenade( weapon )
4146 {
4147  if ( !isdefined( weapon ) || !isdefined( level.zombie_lethal_grenade_list ) )
4148  {
4149  return false;
4150  }
4151 
4152  return isdefined(level.zombie_lethal_grenade_list[weapon]);
4153 }
4154 
4155 
4157 {
4158  if ( !isdefined( weapon ) || !isdefined( self.current_lethal_grenade ) )
4159  {
4160  return false;
4161  }
4162 
4163  return self.current_lethal_grenade == weapon;
4164 }
4165 
4166 
4168 {
4169  grenade = level.weaponNone;
4170 
4171  if(IsDefined(self.current_lethal_grenade))
4172  {
4173  grenade = self.current_lethal_grenade;
4174  }
4175 
4176  return grenade;
4177 }
4178 
4179 
4181 {
4182  if ( !IsDefined( weapon ) )
4183  {
4184  weapon = level.weaponNone;
4185  }
4186 
4187  self notify( "new_lethal_grenade", weapon );
4188  self.current_lethal_grenade = weapon;
4189 }
4190 
4191 
4193 {
4194  self ‪set_player_lethal_grenade( level.zombie_lethal_grenade_player_init );
4195 }
4196 
4197 
4199 {
4200  weapon = GetWeapon( weaponname );
4201  if ( ‪is_tactical_grenade( weapon ) )
4202  {
4203  return;
4204  }
4205 
4206  if ( !isdefined( level.zombie_tactical_grenade_list ) )
4207  {
4208  level.zombie_tactical_grenade_list = [];
4209  }
4210 
4211  level.zombie_tactical_grenade_list[weapon] = weapon;
4212 }
4213 
4214 
4215 function ‪is_tactical_grenade( weapon )
4216 {
4217  if ( !isdefined( weapon ) || !isdefined( level.zombie_tactical_grenade_list ) )
4218  {
4219  return false;
4220  }
4221 
4222  return isdefined(level.zombie_tactical_grenade_list[weapon]);
4223 }
4224 
4225 
4227 {
4228  if ( !isdefined( weapon ) || !isdefined( self.current_tactical_grenade ) )
4229  {
4230  return false;
4231  }
4232 
4233  return self.current_tactical_grenade == weapon;
4234 }
4235 
4236 
4238 {
4239  tactical = level.weaponNone;
4240 
4241  if(IsDefined(self.current_tactical_grenade))
4242  {
4243  tactical = self.current_tactical_grenade;
4244  }
4245 
4246  return tactical;
4247 }
4248 
4249 
4251 {
4252  if ( !IsDefined( weapon ) )
4253  {
4254  weapon = level.weaponNone;
4255  }
4256 
4257  self notify( "new_tactical_grenade", weapon );
4258  self.current_tactical_grenade = weapon;
4259 }
4260 
4261 
4263 {
4264  self ‪set_player_tactical_grenade( level.zombie_tactical_grenade_player_init );
4265 }
4266 
4267 function ‪is_placeable_mine( weapon )
4268 {
4269  ‪DEFAULT(level.placeable_mines,[]);
4270 
4271  if ( !isdefined( weapon ) || weapon == level.weaponNone )
4272  {
4273  return false;
4274  }
4275 
4276  return isdefined( level.placeable_mines[weapon.name] );
4277 }
4278 
4279 
4281 {
4282  if ( !isdefined( weapon ) || !isdefined( self.current_placeable_mine ) )
4283  {
4284  return false;
4285  }
4286 
4287  return self.current_placeable_mine == weapon;
4288 }
4289 
4290 
4292 {
4293  placeable_mine = level.weaponNone;
4294 
4295  if(IsDefined(self.current_placeable_mine))
4296  {
4297  placeable_mine = self.current_placeable_mine;
4298  }
4299 
4300  return placeable_mine;
4301 }
4302 
4303 
4305 {
4306  if ( !IsDefined( weapon ) )
4307  {
4308  weapon = level.weaponNone;
4309  }
4310 
4311  self notify( "new_placeable_mine", weapon );
4312  self.current_placeable_mine = weapon;
4313 }
4314 
4315 
4317 {
4318  self ‪set_player_placeable_mine( level.zombie_placeable_mine_player_init );
4319 }
4320 
4321 
4323 {
4324  weapon = GetWeapon( weaponname );
4325  if ( ‪is_melee_weapon( weapon ) )
4326  {
4327  return;
4328  }
4329 
4330  if ( !isdefined( level.zombie_melee_weapon_list ) )
4331  {
4332  level.zombie_melee_weapon_list = [];
4333  }
4334 
4335  level.zombie_melee_weapon_list[weapon] = weapon;
4336 }
4337 
4338 
4339 function ‪is_melee_weapon( weapon )
4340 {
4341  if ( !isdefined( weapon ) || !isdefined( level.zombie_melee_weapon_list ) || ( weapon == GetWeapon( "none" ) ) )
4342  {
4343  return false;
4344  }
4345 
4346  return isdefined(level.zombie_melee_weapon_list[weapon]);
4347 }
4348 
4349 
4350 function ‪is_player_melee_weapon( weapon )
4351 {
4352  if ( !isdefined( weapon ) || !isdefined( self.current_melee_weapon ) )
4353  {
4354  return false;
4355  }
4356 
4357  return self.current_melee_weapon == weapon;
4358 }
4359 
4360 
4362 {
4363  melee_weapon = level.weaponNone;
4364 
4365  if(IsDefined(self.current_melee_weapon))
4366  {
4367  melee_weapon = self.current_melee_weapon;
4368  }
4369 
4370  return melee_weapon;
4371 }
4372 
4373 
4374 function ‪set_player_melee_weapon( weapon )
4375 {
4376  if ( !IsDefined( weapon ) )
4377  {
4378  weapon = level.weaponNone;
4379  }
4380 
4381  self notify( "new_melee_weapon", weapon );
4382  self.current_melee_weapon = weapon;
4383 }
4384 
4385 
4387 {
4388  self ‪set_player_melee_weapon( level.zombie_melee_weapon_player_init );
4389 }
4390 
4391 
4393 {
4394  weapon = GetWeapon( weaponname );
4395  if ( ‪is_hero_weapon( weapon ) )
4396  {
4397  return;
4398  }
4399 
4400  if ( !isdefined( level.zombie_hero_weapon_list ) )
4401  {
4402  level.zombie_hero_weapon_list = [];
4403  }
4404 
4405  level.zombie_hero_weapon_list[weapon] = weapon;
4406 }
4407 
4408 function ‪is_hero_weapon( weapon )
4409 {
4410  if ( !isdefined( weapon ) || !isdefined( level.zombie_hero_weapon_list ) )
4411  {
4412  return false;
4413  }
4414 
4415  return isdefined(level.zombie_hero_weapon_list[weapon]);
4416 }
4417 
4418 
4419 function ‪is_player_hero_weapon( weapon )
4420 {
4421  if ( !isdefined( weapon ) || !isdefined( self.current_hero_weapon ) )
4422  {
4423  return false;
4424  }
4425 
4426  return self.current_hero_weapon == weapon;
4427 }
4428 
4429 
4431 {
4432  hero_weapon = level.weaponNone;
4433 
4434  if(IsDefined(self.current_hero_weapon))
4435  {
4436  hero_weapon = self.current_hero_weapon;
4437  }
4438 
4439  return hero_weapon;
4440 }
4441 
4442 
4443 function ‪set_player_hero_weapon( weapon )
4444 {
4445  if ( !IsDefined( weapon ) )
4446  {
4447  weapon = level.weaponNone;
4448  }
4449 
4450  self notify( "new_hero_weapon", weapon );
4451  self.current_hero_weapon = weapon;
4452 }
4453 
4455 {
4456  self ‪set_player_hero_weapon( level.zombie_hero_weapon_player_init );
4457 }
4458 
4460 {
4461  return (IsDefined(self.current_hero_weapon) && self.current_hero_weapon != level.weaponNone);
4462 }
4463 
4464 
4465 
4467 {
4468  return ‪IS_TRUE( level.should_watch_for_emp );
4469 }
4470 
4472 {
4473  if ( isdefined( level.register_offhand_weapons_for_level_defaults_override ) )
4474  {
4475  [[ level.register_offhand_weapons_for_level_defaults_override ]]();
4476  return;
4477  }
4478 
4479  ‪register_lethal_grenade_for_level( "frag_grenade" );
4480  level.zombie_lethal_grenade_player_init = GetWeapon( "frag_grenade" );
4481 
4482  ‪register_tactical_grenade_for_level( "cymbal_monkey" );
4483  level.zombie_tactical_grenade_player_init = undefined;
4484 
4485 
4486  level.zombie_placeable_mine_player_init = undefined;
4487 
4489  ‪register_melee_weapon_for_level( "bowie_knife" );
4490  level.zombie_melee_weapon_player_init = GetWeapon( "knife" );
4491 
4492  level.zombie_equipment_player_init = undefined;
4493 }
4494 
4495 
4497 {
4504 }
4505 
4506 
4507 function ‪is_offhand_weapon( weapon )
4508 {
4509  return (‪is_lethal_grenade( weapon ) || ‪is_tactical_grenade( weapon ) || ‪is_placeable_mine( weapon ) || ‪is_melee_weapon( weapon ) || ‪is_hero_weapon( weapon ) || ‪zm_equipment::is_equipment( weapon ) );
4510 }
4511 
4512 
4514 {
4515  return (self ‪is_player_lethal_grenade( weapon ) || self ‪is_player_tactical_grenade( weapon ) || self ‪is_player_placeable_mine( weapon ) || self ‪is_player_melee_weapon( weapon ) || self ‪is_player_hero_weapon( weapon ) || self ‪zm_equipment::is_player_equipment( weapon ) );
4516 }
4517 
4518 
4520 {
4521  return ‪IS_TRUE( self.‪has_powerup_weapon );
4522 }
4523 
4525 {
4526  weapon = self GetCurrentWeapon();
4527  return ‪IS_TRUE( weapon.isheroweapon );
4528 }
4529 
4530 function ‪give_start_weapon( b_switch_weapon )
4531 {
4532  ‪DEFAULT( self.hasCompletedSuperEE, self ‪zm_stats::get_global_stat( "DARKOPS_GENESIS_SUPER_EE" ) > 0 );
4533 
4534  if( self.hasCompletedSuperEE )
4535  {
4536  self ‪zm_weapons::weapon_give( level.start_weapon, false, false, true, false );
4537  self GiveMaxAmmo( level.start_weapon );
4538  self ‪zm_weapons::weapon_give( level.super_ee_weapon, false, false, true, b_switch_weapon );
4539  }
4540  else
4541  {
4542  self ‪zm_weapons::weapon_give( level.start_weapon, false, false, true, b_switch_weapon );
4543  }
4544 }
4545 
4547 
4548 
4549 function ‪array_flag_wait_any( flag_array )
4550 {
4551  if( !IsDefined ( level._array_flag_wait_any_calls ) )
4552  {
4553  level._n_array_flag_wait_any_calls = 0;
4554  }
4555  else
4556  {
4557  level._n_array_flag_wait_any_calls ++; // Used to ensure that we can have multiple calls to this concurrently, that don't interfere with each other.
4558  }
4559 
4560  str_condition = "array_flag_wait_call_" + level._n_array_flag_wait_any_calls;
4561 
4562  for(index = 0; index < flag_array.size; index ++)
4563  {
4564  level thread ‪array_flag_wait_any_thread ( flag_array[ index ], str_condition );
4565  }
4566 
4567  level waittill( str_condition );
4568 
4569 }
4570 
4571 function ‪array_flag_wait_any_thread( flag_name, condition )
4572 {
4573  level endon( condition );
4574 
4575  level ‪flag::wait_till( flag_name );
4576 
4577  level notify( condition );
4578 }
4579 
4580 function ‪groundpos( origin )
4581 {
4582  return bullettrace( origin, ( origin + ( 0, 0, -100000 ) ), 0, self )[ "position" ];
4583 }
4584 
4585 function ‪groundpos_ignore_water( origin )
4586 {
4587  return bullettrace( origin, ( origin + ( 0, 0, -100000 ) ), 0, self, true )[ "position" ];
4588 }
4589 
4591 {
4592  return groundtrace( origin, ( origin + ( 0, 0, -100000 ) ), 0, self, true )[ "position" ];
4593 }
4594 
4604 function ‪self_delete()
4605 {
4606  if (IsDefined(self))
4607  {
4608  self delete();
4609  }
4610 }
4611 
4622 {
4623  // ignore triggers for awhile so others can trigger the trigger we're in.
4624  self endon( "death" );
4625  self.ignoreTriggers = true;
4626  if( IsDefined( ‪timer ) )
4627  {
4628  wait( ‪timer );
4629  }
4630  else
4631  {
4632  wait( 0.5 );
4633  }
4634  self.ignoreTriggers = false;
4635 }
4636 
4637 
4638 
4649 function ‪giveachievement_wrapper( achievement, all_players )
4650 {
4651  if ( achievement == "" )
4652  {
4653  return;
4654  }
4655 
4656  //don't do stats stuff if stats are disabled
4657  if ( ‪IS_TRUE( level.zm_disable_recording_stats ) )
4658  {
4659  return;
4660  }
4661 
4662  achievement_lower = tolower(achievement);
4663  global_counter = 0;
4664 
4665  if ( IsDefined( all_players ) && all_players )
4666  {
4667  players = GetPlayers();
4668  for ( i = 0; i < players.size; i++ )
4669  {
4670  players[i] GiveAchievement( achievement );
4671 
4672  has_achievement = false; // T7 DLC5 TODO: players[i] zm_stats::get_global_stat( achievement_lower );
4673  if(!‪IS_TRUE(has_achievement))
4674  {
4675  global_counter++;
4676  }
4677 
4678  // T7 DLC5 TODO: players[i] zm_stats::increment_client_stat( achievement_lower,false );
4679 
4680  if( issplitscreen() && i == 0 || !issplitscreen() )
4681  {
4682  if(isDefined(level.achievement_sound_func))
4683  {
4684  players[i] thread [[level.achievement_sound_func]](achievement_lower);
4685  }
4686  }
4687  }
4688  }
4689  else
4690  {
4691  if ( !IsPlayer( self ) )
4692  {
4693  /# println( "^1self needs to be a player for util::giveachievement_wrapper()" ); #/
4694  return;
4695  }
4696 
4697  self GiveAchievement( achievement );
4698 
4699  //test the stat before updating it from 0 to 1
4700  has_achievement = false; // T7 DLC5 TODO: self zm_stats::get_global_stat( achievement_lower );
4701  if(!‪IS_TRUE(has_achievement))
4702  {
4703  global_counter++;
4704  }
4705  // T7 DLC5 TODO: self zm_stats::increment_client_stat( achievement_lower,false );
4706 
4707  if(isDefined(level.achievement_sound_func))
4708  {
4709  self thread [[level.achievement_sound_func]](achievement_lower);
4710  }
4711 
4712  }
4713  if(global_counter)
4714  {
4715  incrementCounter( "global_" + achievement_lower,global_counter);
4716  }
4717 
4718 }
4719 
4720 function ‪GetYaw(org)
4721 {
4722  angles = VectorToAngles(org-self.origin);
4723  return angles[1];
4724 }
4725 
4726 
4727 function ‪GetYawToSpot(spot)
4728 {
4729  pos = spot;
4730  yaw = self.angles[1] - ‪GetYaw(pos);
4731  yaw = AngleClamp180( yaw );
4732  return yaw;
4733 }
4734 
4735 /*
4736 =============
4738 "Function Name: disable_react()"
4739 <br/>"Summary: Disables reaction behavior of given AI"
4740 "Module: Utility"
4741 "CallOn: An ai"
4742 <br/>"Example:level.zakhaev disable_react();"
4743 <br/>"Single Player / Multi Player: singleplayer"
4745 =============
4746 */
4748 {
4749  assert( isalive( self ), "Tried to disable react on a non ai" );
4750  self.a.disableReact = true;
4751  self.allowReact = false;
4752 }
4753 
4754 
4755 /*
4756 =============
4758 "Function Name: enable_react()"
4759 <br/>"Summary: Enables reaction behavior of given AI"
4760 "Module: Utility"
4761 "CallOn: An ai"
4762 <br/>"Example:level.zakhaev enable_react();"
4763 <br/>"Single Player / Multi Player: singleplayer"
4765 =============
4766 */
4768 {
4769  assert( isalive( self ), "Tried to enable react on a non ai" );
4770  self.a.disableReact = false;
4771  self.allowReact = true;
4772 }
4773 
4774 // MikeD (12/15/2007): IW abandoned the auto-adjust feature, however, we can use it for stats?
4775 // SCRIPTER_MOD: JesseS (4/14/2008): Added back in for Arcade mode
4776 function ‪bullet_attack( type )
4777 {
4778  if ( type == "MOD_PISTOL_BULLET" )
4779  {
4780  return true;
4781  }
4782  return type == "MOD_RIFLE_BULLET";
4783 }
4784 
4785 
4786 
4787 function ‪pick_up()
4788 {
4789  player = self.owner;
4790  self ‪destroy_ent();
4791 
4792  clip_ammo = player GetWeaponAmmoClip( self.weapon );
4793  clip_max_ammo = self.weapon.clipSize;
4794  if( clip_ammo < clip_max_ammo )
4795  {
4796  clip_ammo++;
4797  }
4798  player SetWeaponAmmoClip( self.weapon, clip_ammo );
4799 }
4800 
4801 function ‪destroy_ent()
4802 {
4803  self delete();
4804 }
4805 
4806 
4817 {
4818  self endon("death");
4819  self endon( "disconnect" );
4820  self endon( "detonated" );
4821  level endon( "game_ended" );
4822 
4823  if ( self.classname == "grenade" )
4824  {
4825  self waittill("stationary");
4826  }
4827  else
4828  {
4829  prevorigin = self.origin;
4830  while(1)
4831  {
4832  wait .15;
4833  if ( self.origin == prevorigin )
4834  break;
4835  prevorigin = self.origin;
4836  }
4837  }
4838 }
4839 
4840 
4850 function ‪get_closest_player( org )
4851 {
4852  players = [];
4853  players = GetPlayers();
4854  return ArrayGetClosest( org, players );
4855 }
4856 
4857 
4859 {
4860  message_array = [];
4861 
4862  message_array[ message_array.size ] = "goal";
4863  message_array[ message_array.size ] = "damage";
4864 
4865  for( i = 0; i < message_array.size; i++)
4866  {
4867  self ‪flag::init( message_array[ i ] );
4868  self thread ‪ent_flag_wait_ai_standards( message_array[ i ] );
4869  }
4870 }
4871 
4873 {
4874  /*
4875  only runs the first time on the message, so for
4876  example if it's waiting on goal, it will only set
4877  the goal to true the first time. It also doesn't
4878  call ent_set_flag() because that would notify the
4879  message possibly twice in the same frame, or worse
4880  in the next frame.
4881  */
4882  self endon("death");
4883  self waittill( message );
4884  self.ent_flag[ message ] = true;
4885 }
4886 
4887 
4898 function ‪flat_angle( angle )
4899 {
4900  rangle = ( 0, angle[ 1 ], 0 );
4901  return rangle;
4902 }
4903 
4914 {
4915  self.alwaysRunForward = undefined;
4916  self.a.combatrunanim = undefined;
4917  self.run_noncombatanim = undefined;
4918  self.walk_combatanim = undefined;
4919  self.walk_noncombatanim = undefined;
4920  self.preCombatRunEnabled = true;
4921 }
4922 
4924 {
4925  self endon( "disconnect" );
4926  self endon( "death" );
4927  level endon( "end_game" );
4928 
4929  wait( 5 );
4930 
4931  while ( 1 )
4932  {
4933  killed_players = false;
4934  players = GetPlayers();
4935  for ( i = 0; i < players.size; i++ )
4936  {
4937  if ( players[i] ‪laststand::player_is_in_laststand() || "playing" != players[i].sessionstate )
4938  {
4939  continue;
4940  }
4941 
4942  for ( j = 0; j < players.size; j++ )
4943  {
4944  if ( i == j || players[j] ‪laststand::player_is_in_laststand() || "playing" != players[j].sessionstate )
4945  {
4946  continue;
4947  }
4948 
4949  if ( isDefined( level.player_intersection_tracker_override ) )
4950  {
4951  if ( players[i] [[level.player_intersection_tracker_override]]( players[j] ) )
4952  {
4953  continue;
4954  }
4955  }
4956 
4957  playerI_origin = players[i].origin;
4958  playerJ_origin = players[j].origin;
4959 
4960  //Check height first
4961  if ( abs(playerI_origin[2] - playerJ_origin[2] ) > 60 )
4962  continue;
4963 
4964  //Check 2d distance
4965  distance_apart = distance2d( playerI_origin, playerJ_origin );
4966  //IPrintLnBold( "player=", i, ",", j, "distance_apart=", distance_apart );
4967 
4968  if ( abs(distance_apart) > 18 )
4969  continue;
4970 
4971 /#
4972  IPrintLnBold( "PLAYERS ARE TOO FRIENDLY!!!!!" );
4973 #/
4974  players[i] dodamage( 1000, (0, 0, 0) );
4975  players[j] dodamage( 1000, (0, 0, 0) );
4976 
4977  if ( !killed_players )
4978  {
4979  players[i] playlocalsound( level.zmb_laugh_alias );
4980  }
4981  players[i] ‪zm_stats::increment_map_cheat_stat( "cheat_too_friendly" );
4982  players[i] ‪zm_stats::increment_client_stat( "cheat_too_friendly",false );
4983  players[i] ‪zm_stats::increment_client_stat( "cheat_total",false );
4984 
4985  players[j] ‪zm_stats::increment_map_cheat_stat( "cheat_too_friendly" );
4986  players[j] ‪zm_stats::increment_client_stat( "cheat_too_friendly",false );
4987  players[j] ‪zm_stats::increment_client_stat( "cheat_total",false );
4988 
4989  killed_players = true;
4990  }
4991  }
4992  wait( .5 );
4993  }
4994 }
4995 
5009 function ‪is_player_looking_at(origin, dot, do_trace, ignore_ent)
5010 {
5011  assert(IsPlayer(self), "player_looking_at must be called on a player.");
5012 
5013  if (!IsDefined(dot))
5014  {
5015  dot = .7;
5016  }
5017 
5018  if (!IsDefined(do_trace))
5019  {
5020  do_trace = true;
5021  }
5022 
5023  eye = self ‪util::get_eye();
5024 
5025  delta_vec = AnglesToForward(VectorToAngles(origin - eye));
5026  view_vec = AnglesToForward(self GetPlayerAngles());
5027 
5028  new_dot = VectorDot( delta_vec, view_vec );
5029  if ( new_dot >= dot )
5030  {
5031  if (do_trace)
5032  {
5033  return BulletTracePassed( origin, eye, false, ignore_ent );
5034  }
5035  else
5036  {
5037  return true;
5038  }
5039  }
5040 
5041  return false;
5042 }
5043 
5044 
5045 
5053 function ‪add_gametype( gt, dummy1, ‪name, dummy2 )
5054 {
5055 }
5056 
5064 function ‪add_gameloc( gl, dummy1, ‪name, dummy2 )
5065 {
5066 }
5067 
5080 function ‪get_closest_index( org, ‪array, dist )
5081 {
5082  if( !IsDefined( dist ) )
5083  {
5084  dist = 9999999;
5085  }
5086  distsq = dist*dist;
5087  if( ‪array.size < 1 )
5088  {
5089  return;
5090  }
5091  index = undefined;
5092  for( i = 0;i < ‪array.size;i++ )
5093  {
5094  newdistsq = distancesquared( ‪array[ i ].origin, org );
5095  if( newdistsq >= distsq )
5096  {
5097  continue;
5098  }
5099  distsq = newdistsq;
5100  index = i;
5101  }
5102  return index;
5103 }
5104 
5106 {
5107  liftedorigin = point.origin + (0,0,5);
5108  size = 48;
5109  height = 64;
5110  mins = (-1 * size,-1 * size,0 );
5111  maxs = ( size,size,height );
5112  absmins = liftedorigin + mins;
5113  absmaxs = liftedorigin + maxs;
5114  // check to see if we would telefrag any players
5115  if ( BoundsWouldTelefrag( absmins, absmaxs ) )
5116  {
5117  return false;
5118  }
5119  return true;
5120 }
5121 
5134 function ‪get_closest_index_to_entity( entity, ‪array, dist, extra_check )
5135 {
5136  org = entity.origin;
5137  if( !IsDefined( dist ) )
5138  {
5139  dist = 9999999;
5140  }
5141  distsq = dist*dist;
5142  if( ‪array.size < 1 )
5143  {
5144  return;
5145  }
5146  index = undefined;
5147  for( i = 0;i < ‪array.size;i++ )
5148  {
5149  if (isdefined(extra_check) && ![[extra_check]](entity,‪array[ i ]) )
5150  continue;
5151  newdistsq = distancesquared( ‪array[ i ].origin, org );
5152  if( newdistsq >= distsq )
5153  {
5154  continue;
5155  }
5156  distsq = newdistsq;
5157  index = i;
5158  }
5159  return index;
5160 }
5161 
5162 function ‪set_gamemode_var(gvar, val)
5163 {
5164  if(!isdefined(game["gamemode_match"]))
5165  {
5166  game["gamemode_match"] = [];
5167  }
5168 
5169  game["gamemode_match"][gvar] = val;
5170 }
5171 
5172 function ‪set_gamemode_var_once(gvar, val)
5173 {
5174  if(!isdefined(game["gamemode_match"]))
5175  {
5176  game["gamemode_match"] = [];
5177  }
5178 
5179  if(!isdefined(game["gamemode_match"][gvar]))
5180  {
5181  game["gamemode_match"][gvar] = val;
5182  }
5183 }
5184 
5185 function ‪set_game_var(gvar, val)
5186 {
5187  game[gvar] = val;
5188 }
5189 
5190 function ‪set_game_var_once(gvar, val)
5191 {
5192  if(!isdefined(game[gvar]))
5193  {
5194  game[gvar] = val;
5195  }
5196 }
5197 
5198 function ‪get_game_var( gvar )
5199 {
5200  if(isdefined(game[gvar]))
5201  {
5202  return game[gvar];
5203  }
5204 
5205  return undefined;
5206 }
5207 
5208 function ‪get_gamemode_var( gvar )
5209 {
5210  if(isdefined(game["gamemode_match"]) && isdefined(game["gamemode_match"][gvar]))
5211  {
5212  return game["gamemode_match"][gvar];
5213  }
5214 
5215  return undefined;
5216 }
5217 
5218 function ‪waittill_subset(min_num, string1, string2, string3, string4, string5 )
5219 {
5220  self endon ("death");
5221  ent = SpawnStruct();
5222  ent.threads = 0;
5223  returned_threads = 0;
5224 
5225  if (IsDefined (string1))
5226  {
5227  self thread ‪util::waittill_string(string1, ent);
5228  ent.threads++;
5229  }
5230  if (IsDefined (string2))
5231  {
5232  self thread ‪util::waittill_string(string2, ent);
5233  ent.threads++;
5234  }
5235  if (IsDefined (string3))
5236  {
5237  self thread ‪util::waittill_string(string3, ent);
5238  ent.threads++;
5239  }
5240  if (IsDefined (string4))
5241  {
5242  self thread ‪util::waittill_string(string4, ent);
5243  ent.threads++;
5244  }
5245  if (IsDefined (string5))
5246  {
5247  self thread ‪util::waittill_string(string5, ent);
5248  ent.threads++;
5249  }
5250 
5251  while (ent.threads)
5252  {
5253  ent waittill ("returned");
5254  ent.threads--;
5255  returned_threads++;
5256  if(returned_threads >= min_num ) //if we've got the minimum number of waittills returned, then that is good enough!
5257  {
5258  break;
5259  }
5260  }
5261 
5262  ent notify ("die");
5263 }
5264 
5265 function ‪is_headshot( weapon, sHitLoc, sMeansOfDeath )
5266 {
5267  if( !isdefined( sHitLoc ) )
5268  {
5269  return false;
5270  }
5271 
5272  if( (sHitLoc != "head" && sHitLoc != "helmet") )
5273  {
5274  return false;
5275  }
5276 
5277  //ballsitic knives
5278  if( sMeansofDeath == "MOD_IMPACT" && weapon.isBallisticKnife )
5279  {
5280  return true;
5281  }
5282 
5283  return sMeansOfDeath != "MOD_MELEE" && sMeansOfDeath != "MOD_IMPACT" && sMeansofDeath != "MOD_UNKNOWN";
5284 }
5285 
5286 function ‪is_jumping()
5287 {
5288  // this probably doesn't work correctly on the bus
5289  // checking PMF_JUMPING in code would give more accurate results
5290  ground_ent = self GetGroundEnt();
5291  return (!isdefined(ground_ent));
5292 }
5293 
5294 function ‪is_explosive_damage( mod )
5295 {
5296  if( !IsDefined( mod ) )
5297  return false;
5298 
5299  if( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" || mod == "MOD_PROJECTILE" || mod == "MOD_PROJECTILE_SPLASH" || mod == "MOD_EXPLOSIVE" )
5300  return true;
5301 
5302  return false;
5303 }
5304 
5306 {
5307  switch( who )
5308  {
5309  case "sam":
5310  game["zmbdialog"]["prefix"] = "vox_zmba_sam";
5311  level.zmb_laugh_alias = "zmb_laugh_sam";
5312  level.sndAnnouncerIsRich = false;
5313  break;
5314  }
5315 }
5316 
5317 function ‪do_player_general_vox(category,type,‪timer,chance)
5318 {
5319 
5320  if( isDefined(‪timer) && isDefined(level.votimer[type]) && level.votimer[type] > 0)
5321  {
5322  return;
5323  }
5324 
5325  self thread ‪zm_audio::create_and_play_dialog( category, type);
5326 
5327  if(isDefined(‪timer))
5328  {
5329  level.votimer[type] = ‪timer;
5330  level thread ‪general_vox_timer( level.votimer[type],type );
5331  }
5332 }
5333 
5335 {
5336  level endon("end_game");
5337 
5338  /# println( "ZM >> VOX TIMER STARTED FOR " + type + " ( " + ‪timer + ")" ); #/
5339 
5340  while(‪timer > 0 )
5341  {
5342  wait(1);
5343  ‪timer--;
5344  }
5345  level.votimer[type] = ‪timer;
5346  /# println( "ZM >> VOX TIMER ENDED FOR " + type + " ( " + ‪timer + ")" ); #/
5347 
5348 
5349 }
5350 
5351 function ‪create_vox_timer(type)
5352 {
5353  level.votimer[type] = 0;
5354 }
5355 
5356 function ‪play_vox_to_player(category,type,force_variant )
5357 {
5358  //self thread zm_audio::playVoxToPlayer( category, type, force_variant );
5359 }
5360 
5361 function ‪is_favorite_weapon(weapon_to_check)
5362 {
5363  if(!isDefined(self.favorite_wall_weapons_list))
5364  {
5365  return false;
5366  }
5367 
5368  foreach(weapon in self.favorite_wall_weapons_list)
5369  {
5370  if (weapon_to_check == weapon )
5371  {
5372  return true;
5373  }
5374  }
5375 
5376  return false;
5377 }
5378 
5379 function ‪add_vox_response_chance(event,chance)
5380 {
5381  level.response_chances[event] = chance;
5382 }
5383 
5385 {
5386  spawnpoints = getentarray("mp_global_intermission", "classname");
5387  if ( !spawnpoints.size )
5388  {
5389  return;
5390  }
5391 
5392  spawnpoint = spawnpoints[0];
5393  match_string = "";
5394 
5395  location = level.scr_zm_map_start_location;
5396  if ( (location == "default" || location == "") && IsDefined( level.default_start_location ) )
5397  {
5398  location = level.default_start_location;
5399  }
5400 
5401  match_string = level.scr_zm_ui_gametype + "_" + location;
5402 
5403  for ( i = 0; i < spawnpoints.size; i++ )
5404  {
5405  if ( IsDefined( spawnpoints[i].script_string ) )
5406  {
5407  tokens = strtok( spawnpoints[i].script_string," " );
5408  foreach ( token in tokens )
5409  {
5410  if ( token == match_string )
5411  {
5412  spawnpoint = spawnpoints[i];
5413  i = spawnpoints.size; // to get out of the outer for loop
5414  break;
5415  }
5416  }
5417  }
5418  }
5419 
5420  setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
5421 }
5422 
5423 function ‪register_map_navcard(navcard_on_map,navcard_needed_for_computer)
5424 {
5425  level.navcard_needed = navcard_needed_for_computer;
5426  level.map_navcard = navcard_on_map;
5427 }
5428 
5430 {
5431  return player ‪zm_stats::get_global_stat( level.map_navcard );
5432 }
5433 
5435 {
5436  if(!isDefined(level.navcard_needed ))
5437  {
5438  return false;
5439  }
5440  return player ‪zm_stats::get_global_stat( level.navcard_needed );
5441 }
5442 
5443 function ‪place_navcard( str_model, str_stat, org, angles )
5444 {
5445  navcard = ‪spawn("script_model",org);
5446  navcard setmodel( str_model );
5447  navcard.angles = angles;
5448 
5449  wait 1; // delay between spawning card and picking it up
5450 
5451  navcard_pickup_trig = ‪Spawn( "trigger_radius_use", org, 0, 84, 72 );
5452  navcard_pickup_trig SetCursorHint( "HINT_NOICON" );
5453  navcard_pickup_trig SetHintString( &"ZOMBIE_NAVCARD_PICKUP" );
5454  navcard_pickup_trig TriggerIgnoreTeam();
5455 
5456  a_navcard_stats = ‪array( "navcard_held_zm_transit", "navcard_held_zm_highrise", "navcard_held_zm_buried" );
5457 
5458  is_holding_card = false;
5459  str_placing_stat = undefined;
5460 
5461  while(1)
5462  {
5463  navcard_pickup_trig waittill("trigger",who );
5464 
5465  if( ‪is_player_valid(who) )
5466  {
5467  // check for any currently held card. If found, clear that stat and save which it was
5468  foreach ( str_cur_stat in a_navcard_stats )
5469  {
5470  if ( who ‪zm_stats::get_global_stat( str_cur_stat ) )
5471  {
5472  str_placing_stat = str_cur_stat;
5473  is_holding_card = true;
5474  who ‪zm_stats::set_global_stat( str_cur_stat, 0 );
5475  }
5476  }
5477 
5478  who playsound( "zmb_buildable_piece_add" );
5479  who ‪zm_stats::set_global_stat( str_stat, 1 );
5480  who.navcard_grabbed = str_stat;
5482 
5483  is_stat = who ‪zm_stats::get_global_stat( str_stat );
5484 
5486  break;
5487  }
5488  }
5489 
5490  navcard delete();
5491  navcard_pickup_trig delete();
5492 
5493  // if a card was held, place a new card with the stat of the one that was held (set down the old card)
5494  if ( is_holding_card )
5495  {
5496  level thread ‪place_navcard( str_model, str_placing_stat, org, angles );
5497  }
5498 }
5499 
5501 {
5502  if (!IsDefined(level.navcards))
5503  return;
5504  players = GetPlayers();
5505  foreach( player in players )
5506  {
5508  }
5509 }
5510 
5512 {
5513  self endon("disconnect");
5514 
5515  navcard_bits = 0;
5516  for(i = 0;i < level.navcards.size; i++)
5517  {
5518  hasit = self ‪zm_stats::get_global_stat( level.navcards[i] );
5519  if (isdefined(self.navcard_grabbed) && self.navcard_grabbed == level.navcards[i] )
5520  hasit = 1;
5521  if( hasit )
5522  {
5523  navcard_bits +=( 1 << i );
5524  }
5525  }
5527  self ‪clientfield::set( "navcard_held", 0 );
5528  if ( navcard_bits > 0 )
5529  {
5531  self ‪clientfield::set( "navcard_held", navcard_bits );
5532  }
5533 }
5534 
5535 
5536 function ‪disable_player_move_states(forceStanceChange)
5537 {
5538  self AllowCrouch( true );
5539  self AllowLean( false );
5540  self AllowAds( false );
5541  self AllowSprint( false );
5542  self AllowProne( false );
5543  self AllowMelee( false );
5544 
5545  if((isdefined(forceStanceChange)) && (forceStanceChange == true))
5546  {
5547  if ( self GetStance() == "prone" )
5548  {
5549  self SetStance( "crouch" );
5550  }
5551  }
5552 }
5553 
5555 {
5556  if((!isdefined(self._allow_lean)) || (self._allow_lean == true))
5557  {
5558  self AllowLean( true );
5559  }
5560 
5561  if((!isdefined(self._allow_ads)) || (self._allow_ads == true))
5562  {
5563  self AllowAds( true );
5564  }
5565 
5566  if((!isdefined(self._allow_sprint)) || (self._allow_sprint == true))
5567  {
5568  self AllowSprint( true );
5569  }
5570 
5571  if((!isdefined(self._allow_prone)) || (self._allow_prone == true))
5572  {
5573  self AllowProne( true );
5574  }
5575 
5576  if((!isdefined(self._allow_melee)) || (self._allow_melee == true))
5577  {
5578  self AllowMelee( true );
5579  }
5580 
5581 }
5582 
5584 {
5585  if(!isdefined(level._link_node_list))
5586  {
5587  level._link_node_list = [];
5588  }
5589 
5590  if(!isdefined(level._unlink_node_list))
5591  {
5592  level._unlink_node_list = [];
5593  }
5594 }
5595 
5596 function ‪link_nodes(‪a, b, bDontUnlinkOnMigrate = false)
5597 {
5598  if(NodesAreLinked(‪a,b))
5599  {
5600  return;
5601  }
5602 
5604 
5605  a_index_string = "" + ‪a.origin;
5606  b_index_string = "" + b.origin;
5607 
5608  if(!isdefined(level._link_node_list[a_index_string]))
5609  {
5610  level._link_node_list[a_index_string] = spawnstruct();
5611  level._link_node_list[a_index_string].node = ‪a;
5612  level._link_node_list[a_index_string].links = [];
5613  level._link_node_list[a_index_string].ignore_on_migrate = [];
5614  }
5615 
5616  if(!isdefined(level._link_node_list[a_index_string].links[b_index_string]))
5617  {
5618  level._link_node_list[a_index_string].links[b_index_string] = b; // Add a record of the link.
5619  level._link_node_list[a_index_string].ignore_on_migrate[b_index_string] = bDontUnlinkOnMigrate;
5620  }
5621 
5622  if(isdefined(level._unlink_node_list[a_index_string]))
5623  {
5624  if(isdefined(level._unlink_node_list[a_index_string].links[b_index_string]))
5625  {
5626  level._unlink_node_list[a_index_string].links[b_index_string] = undefined; // Remove record of earlier unlink
5627  level._unlink_node_list[a_index_string].ignore_on_migrate[b_index_string] = undefined;
5628  }
5629  }
5630 
5631 // /# println("Linking node at " + a.origin + " to node at " + b.origin); #/
5632 
5633  LinkNodes(‪a,b);
5634 }
5635 
5636 function ‪unlink_nodes(‪a,b, bDontLinkOnMigrate = false)
5637 {
5638  if(!NodesAreLinked(‪a,b))
5639  {
5640  return;
5641  }
5642 
5644 
5645  a_index_string = "" + ‪a.origin;
5646  b_index_string = "" + b.origin;
5647 
5648  if(!isdefined(level._unlink_node_list[a_index_string]))
5649  {
5650  level._unlink_node_list[a_index_string] = spawnstruct();
5651  level._unlink_node_list[a_index_string].node = ‪a;
5652  level._unlink_node_list[a_index_string].links = [];
5653  level._unlink_node_list[a_index_string].ignore_on_migrate = [];
5654  }
5655 
5656  if(!isdefined(level._unlink_node_list[a_index_string].links[b_index_string]))
5657  {
5658  level._unlink_node_list[a_index_string].links[b_index_string] = b; // Add a record of the unlink.
5659  level._unlink_node_list[a_index_string].ignore_on_migrate[b_index_string] = bDontLinkOnMigrate;
5660  }
5661 
5662 
5663  if(isdefined(level._link_node_list[a_index_string]))
5664  {
5665  if(isdefined(level._link_node_list[a_index_string].links[b_index_string]))
5666  {
5667  level._link_node_list[a_index_string].links[b_index_string] = undefined; // Remove record of earlier link.
5668  level._link_node_list[a_index_string].ignore_on_migrate[b_index_string] = undefined;
5669  }
5670  }
5671 
5672 // /# println("Unlinking node at " + a.origin + " from node at " + b.origin); #/
5673 
5674  UnlinkNodes(‪a,b);
5675 }
5676 
5677 //spawn_path_node( (-6392, 4329, 0), (0,0,0), "targetname", "blah" );
5678 
5679 function ‪spawn_path_node(origin, angles, k1, v1, k2, v2)
5680 {
5681  if(!isdefined(level._spawned_path_nodes))
5682  {
5683  level._spawned_path_nodes = [];
5684  }
5685 
5686  node = spawnstruct();
5687 
5688  node.origin = origin;
5689  node.angles = angles;
5690  node.k1 = k1;
5691  node.v1 = v1;
5692  node.k2 = k2;
5693  node.v2 = v2;
5694 
5695  node.node = ‪spawn_path_node_internal(origin, angles, k1, v1, k2, v2);
5696 
5697  level._spawned_path_nodes[level._spawned_path_nodes.size] = node;
5698 
5699  return node.node;
5700 }
5701 
5702 function ‪spawn_path_node_internal(origin, angles, k1, v1, k2, v2)
5703 {
5704  if(isdefined(k2))
5705  {
5706  return SpawnPathNode("node_pathnode", origin, angles, k1, v1, k2, v2);
5707  }
5708  else if(isdefined(k1))
5709  {
5710  return SpawnPathNode("node_pathnode", origin, angles, k1, v1);
5711  }
5712  else
5713  {
5714  return SpawnPathNode("node_pathnode", origin, angles);
5715  }
5716 
5717  return undefined;
5718 }
5719 
5721 {
5722 /* if(!isdefined(level._spawned_path_nodes))
5723  {
5724  return;
5725  }
5726 
5727  //for(i = 0; i < level._spawned_path_nodes.size; i ++)
5728  for(i = level._spawned_path_nodes.size - 1; i > -1; i --)
5729  {
5730  /# println("Deleting spawned path node @ " + level._spawned_path_nodes[i].origin); #/
5731  DeletePathNode(level._spawned_path_nodes[i].node);
5732  level._spawned_path_nodes[i].node = undefined;
5733  }*/
5734 }
5735 
5737 {
5738  if(!isdefined(level._spawned_path_nodes))
5739  {
5740  return;
5741  }
5742 
5743  for(i = 0; i < level._spawned_path_nodes.size; i ++)
5744  {
5745  node_struct = level._spawned_path_nodes[i];
5746 
5747  /# println("Re-spawning spawned path node @ " + node_struct.origin); #/
5748  node_struct.node = ‪spawn_path_node_internal(node_struct.origin, node_struct.angles, node_struct.k1, node_struct.v1, node_struct.k2, node_struct.v2);
5749  }
5750 }
5751 
5753 {
5754  keys = GetArrayKeys(list);
5755 
5756  for(i = 0; i < keys.size; i ++)
5757  {
5758  node = list[keys[i]].node;
5759 
5760  node_keys = GetArrayKeys(list[keys[i]].links);
5761 
5762  for(j = 0; j < node_keys.size; j ++)
5763  {
5764  if(isdefined(list[keys[i]].links[node_keys[j]]))
5765  {
5766 
5767  if(‪IS_TRUE(list[keys[i]].ignore_on_migrate[node_keys[j]]))
5768  {
5769  /# println("Node at " + keys[i] + " to node at " + node_keys[j] + " - IGNORED"); #/
5770  }
5771  else
5772  {
5773  /# println("Node at " + keys[i] + " to node at " + node_keys[j]); #/
5774  [[func]](node, list[keys[i]].links[node_keys[j]]);
5775  }
5776  }
5777  }
5778  }
5779 }
5780 
5781 function ‪link_changes_internal(func_for_link_list, func_for_unlink_list)
5782 {
5783  if(isdefined(level._link_node_list))
5784  {
5785  /# println("Link List"); #/
5786  ‪link_changes_internal_internal(level._link_node_list, func_for_link_list);
5787  }
5788 
5789  if(isdefined(level._unlink_node_list))
5790  {
5791  /# println("UnLink List"); #/
5792  ‪link_changes_internal_internal(level._unlink_node_list, func_for_unlink_list);
5793  }
5794 }
5795 
5797 {
5798  if(!NodesAreLinked(‪a,b))
5799  {
5800  LinkNodes(‪a,b);
5801  }
5802 }
5803 
5805 {
5806  if(NodesAreLinked(‪a,b))
5807  {
5808  UnlinkNodes(‪a,b);
5809  }
5810 }
5811 
5813 {
5814  /# println("***");
5815  println("***");
5816  println("*** Undoing link changes"); #/
5817 
5819 
5821 
5822 }
5823 
5825 {
5826  /# println("***");
5827  println("***");
5828  println("*** Redoing link changes"); #/
5829 
5831 
5833 }
5834 
5835 function ‪is_gametype_active( a_gametypes )
5836 {
5837  b_is_gametype_active = false;
5838 
5839  if ( !IsArray( a_gametypes ) )
5840  {
5841  a_gametypes = Array( a_gametypes );
5842  }
5843 
5844  for ( i = 0; i < a_gametypes.size; i++ )
5845  {
5846  if ( GetDvarString( "g_gametype" ) == a_gametypes[ i ] )
5847  {
5848  b_is_gametype_active = true;
5849  }
5850  }
5851 
5852  return b_is_gametype_active;
5853 }
5854 
5855 function ‪register_custom_spawner_entry( spot_noteworthy, func )
5856 {
5857  if ( !IsDefined( level.custom_spawner_entry ) )
5858  {
5859  level.custom_spawner_entry = [];
5860  }
5861 
5862  level.custom_spawner_entry[ spot_noteworthy ] = func;
5863 }
5864 
5865 function ‪get_player_weapon_limit( player )
5866 {
5867  if ( IsDefined( self.‪get_player_weapon_limit ) )
5868  {
5869  return [[self.get_player_weapon_limit]]( player );
5870  }
5871 
5872  if ( IsDefined( level.get_player_weapon_limit ) )
5873  {
5874  return [[level.get_player_weapon_limit]]( player );
5875  }
5876 
5877  weapon_limit = 2;
5878  if ( player HasPerk( ‪PERK_ADDITIONAL_PRIMARY_WEAPON ) )
5879  {
5880  weapon_limit = level.additionalprimaryweapon_limit;
5881  }
5882 
5883  return weapon_limit;
5884 }
5885 
5887 {
5888  n_perk_purchase_limit_override = level.perk_purchase_limit; // start with the default value
5889 
5890  // level-specific override
5891  if ( IsDefined( level.get_player_perk_purchase_limit ) )
5892  {
5893  n_perk_purchase_limit_override = self [[level.get_player_perk_purchase_limit]]();
5894  }
5895 
5896  return n_perk_purchase_limit_override;
5897 }
5898 
5900 {
5901  if ( self.num_perks < self ‪zm_utility::get_player_perk_purchase_limit() )
5902  {
5903  return true;
5904  }
5905 
5906  // you can always buy one more if you currently have unquenchable
5907  if ( self ‪bgb::is_enabled( "zm_bgb_unquenchable" ) || self ‪bgb::is_enabled( "zm_bgb_soda_fountain" ) )
5908  {
5909  return true;
5910  }
5911 
5912  return false;
5913 }
5914 
5915 // Give player all perks
5916 // b_exclude_quick_revive - if you need to prevent a solo player from getting quick revive
5917 function ‪give_player_all_perks( b_exclude_quick_revive = false ) // self == player
5918 {
5919  // give the player all the perks in the map
5920  a_str_perks = GetArrayKeys( level._custom_perks );
5921 
5922  foreach( str_perk in a_str_perks )
5923  {
5924  if ( str_perk == ‪PERK_QUICK_REVIVE && b_exclude_quick_revive )
5925  {
5926  continue;
5927  }
5928 
5929  if( !self HasPerk( str_perk ) )
5930  {
5931  self ‪zm_perks::give_perk( str_perk, false );
5932 
5933  if ( isdefined( level.perk_bought_func ) )
5934  {
5935  self [[ level.perk_bought_func ]]( str_perk );
5936  }
5937  }
5938  }
5939 }
5940 
5942 {
5943  self waittill( "attractor_positions_generated" );
5944 
5945  self.attract_to_origin = false;
5946 }
5947 
5948 // Migrated from _zm_weapons.
5949 function ‪get_player_index( player )
5950 {
5951  assert( IsPlayer( player ) );
5952  assert( IsDefined( player.characterIndex ) );
5953 
5954 /#
5955  // used for testing to switch player's VO in-game from devgui
5956  if ( player.entity_num == 0 && GetDvarString( "zombie_player_vo_overwrite" ) != "" )
5957  {
5958  new_vo_index = GetDvarInt( "zombie_player_vo_overwrite" );
5959  return new_vo_index;
5960  }
5961 #/
5962  return player.characterIndex;
5963 }
5964 
5965 // ****************************************
5966 // get_specific_character() returns the player character associated with the index given.
5967 // For zm_zod, the indices are defined as follows:
5968 // #define FLOYD 0
5969 // #define JACK 1
5970 // #define ROSE 2
5971 // #define NERO 3
5972 // For other levels, indices will differ.
5973 // Copied from zm_factory.gsc
5974 function ‪get_specific_character( n_character_index )
5975 {
5976  foreach( character in level.players )
5977  {
5978  if( character.characterIndex == n_character_index )
5979  return character;
5980  }
5981  return undefined;
5982 }
5983 
5984 function ‪zombie_goto_round( n_target_round )
5985 {
5986  level notify( "restart_round" );
5987 
5988  if ( n_target_round < 1 )
5989  {
5990  n_target_round = 1;
5991  }
5992 
5993  level.zombie_total = 0;
5994  ‪zombie_utility::ai_calculate_health( n_target_round );
5995  ‪zm::set_round_number( n_target_round - 1 );
5996 
5997  // kill all active zombies
5999  if ( isdefined( zombies ) )
6000  {
6001  array::run_all( zombies, &Kill );
6002  }
6003 
6004  level.sndGotoRoundOccurred = true;
6005 
6006  level waittill( "between_round_over" );
6007 }
6008 
6009 // spawn ent at v_point and test if it's touching any enabled zone volume; return true/false
6010 // this is a workaround for not having a good way of testing whether a point or struct is inside a volume for now
6011 // ignore_zone - zone that we don't want to return true from
6012 function ‪is_point_inside_enabled_zone( v_origin, ignore_zone )
6013 {
6014  temp_ent = ‪Spawn( "script_origin", v_origin );
6015 
6016  foreach( zone in level.zones )
6017  {
6018  // If the zone hasn't been enabled, don't even bother checking
6019  if ( !zone.is_enabled )
6020  {
6021  continue;
6022  }
6023 
6024  if( isdefined( ignore_zone ) && ( zone == ignore_zone ) )
6025  {
6026  continue;
6027  }
6028 
6029  // Okay check to see if an entity is in one of the zone volumes
6030  foreach( e_volume in zone.volumes )
6031  {
6032  if ( temp_ent IsTouching( e_volume ) )
6033  {
6034  temp_ent Delete();
6035  return true;
6036  }
6037  }
6038  }
6039 
6040  temp_ent Delete();
6041  return false;
6042 }
6043 
6044 
6046 {
6047  if ( IsDefined(self.streamer_hint) )
6048  {
6049  self.streamer_hint Delete();
6050  self.streamer_hint = undefined;
6051  }
6052  self notify("wait_clear_streamer_hint");
6053 }
6054 
6055 function ‪wait_clear_streamer_hint( lifetime )
6056 {
6057  self endon("wait_clear_streamer_hint");
6058  wait lifetime;
6059  if ( IsDefined(self) )
6060  self ‪clear_streamer_hint();
6061 }
6062 
6063 
6064 function ‪create_streamer_hint( origin, angles, value, lifetime )
6065 {
6066  if ( self == level )
6067  {
6068  foreach( player in GetPlayers() )
6069  {
6070  player ‪clear_streamer_hint();
6071  }
6072  }
6073  self ‪clear_streamer_hint();
6074  self.streamer_hint = CreateStreamerHint( origin, value );
6075  if ( IsDefined(angles) )
6076  self.streamer_hint.angles = angles;
6077  if ( self != level )
6078  {
6079  self.streamer_hint SetInvisibleToAll();
6080  self.streamer_hint SetVisibleToPlayer( self );
6081  }
6082 
6083  self.streamer_hint SetIncludeMeshes( true );
6084 
6085  self notify("wait_clear_streamer_hint");
6086  if ( IsDefined(lifetime) && lifetime > 0 )
6087  {
6088  self thread ‪wait_clear_streamer_hint(lifetime);
6089  }
6090 }
6091 
6092 function ‪approximate_path_dist( player )
6093 {
6094  AIProfile_BeginEntry( "approximate_path_dist" );
6095 
6096  goal_pos = player.origin;
6097  if ( isdefined( player.last_valid_position ) )
6098  {
6099  goal_pos = player.last_valid_position;
6100  }
6101 
6102  if ( ‪IS_TRUE( player.b_teleporting ) )
6103  {
6104  if ( isdefined( player.teleport_location ) )
6105  {
6106  goal_pos = player.teleport_location;
6107  if ( !IsPointOnNavmesh( goal_pos, self ) )
6108  {
6109  position = GetClosestPointOnNavMesh( goal_pos, 100, 15 );
6110  if ( IsDefined( position ) )
6111  {
6112  goal_pos = position;
6113  }
6114  }
6115  }
6116  }
6117 
6118  assert( IsDefined( level.pathdist_type ), "level.pathdist_type must be set before calling PathDistance" );
6119 
6120  //PathDistance( <start>, <end>, <generatePathForAccurateDist>, <pathEnt>, <pathDistanceType>, <maxCornerPredictions> )
6121  approx_dist = PathDistance( self.origin, goal_pos, true, self, level.pathdist_type );
6122 
6123  AIProfile_EndEntry();
6124 
6125  return approx_dist;
6126 }
6127 
6128 
6129 
6130 // Helper function for slowdowns
6131 function ‪register_slowdown( str_type, n_rate, n_duration )
6132 {
6133  if ( !isdefined( level.a_n_slowdown_rates ) )
6134  {
6135  level.a_n_slowdown_rates = [];
6136  }
6137 
6138  level.a_s_slowdowns[ str_type ] = SpawnStruct();
6139  level.a_s_slowdowns[ str_type ].n_rate = n_rate;
6140  level.a_s_slowdowns[ str_type ].n_duration = n_duration;
6141 }
6142 
6143 
6144 // All-purpose function to slow a zombie. Can handle slowdowns from multiple sources.
6145 // The slowest rate will always be applied first, until it wears out, then the next highest one will be applied.
6146 // str_type is the reason for the slow
6147 // n_rate is the new animation rate
6148 function ‪slowdown_ai( str_type )
6149 {
6150  self notify( "starting_slowdown_ai" );
6151  self endon( "starting_slowdown_ai" );
6152  self endon( "death" );
6153 
6154  Assert( isdefined( level.a_s_slowdowns[ str_type ] ), "Slowdown \"" + str_type + "\" must be registered through register_slowdown first" );
6155 
6156  if ( !isdefined( self.a_n_slowdown_timeouts ) )
6157  {
6158  self.a_n_slowdown_timeouts = [];
6159  }
6160 
6161  n_time = GetTime();
6162  n_timeout = n_time + level.a_s_slowdowns[ str_type ].n_duration;
6163 
6164  // See if the slowdown is already being applied
6165  if ( !isdefined( self.a_n_slowdown_timeouts[ str_type ] ) ||
6166  self.a_n_slowdown_timeouts[ str_type ] < n_timeout )
6167  {
6168  self.a_n_slowdown_timeouts[ str_type ] = n_timeout;
6169  }
6170 
6171  // search for the lowest rate and apply that
6172  while ( self.a_n_slowdown_timeouts.size )
6173  {
6174  str_lowest_type = undefined;
6175  n_lowest_rate = 10.0;
6176  foreach( str_index, n_slowdown_timeout in self.a_n_slowdown_timeouts )
6177  {
6178  //TODO Make sure clearing an entry doesn't mess up the foreach
6179  // remove old expired times
6180  if ( n_slowdown_timeout <= n_time )
6181  {
6182  self.a_n_slowdown_timeouts[ str_index ] = undefined;
6183  continue;
6184  }
6185 
6186  if ( level.a_s_slowdowns[ str_index ].n_rate < n_lowest_rate )
6187  {
6188  str_lowest_type = str_index;
6189  n_lowest_rate = level.a_s_slowdowns[ str_index ].n_rate;
6190  }
6191  }
6192 
6193  if ( isdefined ( str_lowest_type ) )
6194  {
6195  // Apply the slowest rate
6196  self ASMSetAnimationRate( n_lowest_rate );
6197 
6198  n_duration = self.a_n_slowdown_timeouts[ str_lowest_type ] - n_time;
6199  wait( n_duration );
6200 
6201  // Remove slowdown
6202  self.a_n_slowdown_timeouts[ str_lowest_type ] = undefined;
6203  }
6204  }
6205 
6206  // No more slowdowns, return to normal
6207  self ASMSetAnimationRate( 1.0 );
6208 }
6209 
6210 //*****************************************************************************
6211 //*****************************************************************************
6212 
6214 {
6215  a_players= ArrayCopy( level.activeplayers );
6216 
6217  // If the target is also a player, remove it from the copied array of players.
6218  ArrayRemoveValue( a_players, ‪e_target );
6219 
6220  e_closest_player = ArrayGetClosest( ‪e_target.origin, a_players );
6221 
6222  return e_closest_player;
6223 }
6224 
6225 //*****************************************************************************
6226 //*****************************************************************************
6227 
6228 function ‪is_facing( facee, requiredDot = 0.5, b_2d = true )
6229 {
6230  orientation = self getPlayerAngles();
6231  v_forward = anglesToForward( orientation );
6232  v_to_facee = facee.origin - self.origin;
6233 
6234  if( b_2d )
6235  {
6236  v_forward_computed = ( v_forward[0], v_forward[1], 0 );
6237  v_to_facee_computed = ( v_to_facee[0], v_to_facee[1], 0 );
6238  }
6239  else
6240  {
6241  v_forward_computed = v_forward;
6242  v_to_facee_computed = v_to_facee;
6243  }
6244 
6245  v_unit_forward_computed = VectorNormalize( v_forward_computed );
6246  v_unit_to_facee_computed = VectorNormalize( v_to_facee_computed );
6247 
6248  dotProduct = VectorDot( v_unit_forward_computed, v_unit_to_facee_computed );
6249  return ( dotProduct > requiredDot ); // reviver is facing player within given dot tolerance.
6250 }
6251 
6252 //Returns true if the player is in a solo game that cannot be hotjoined
6254 {
6255  return ( level.players.size == 1 && GetDvarInt( "zm_private_rankedmatch", 0 ) );
6256 }
6257 
6258 function ‪upload_zm_dash_counters( force_upload = false ) {}
6259 
6261 
6262 function ‪increment_zm_dash_counter( counter_name, amount ) {}
6263 
6265 
6267 
‪add_gameloc
‪function add_gameloc(gl, dummy1, name, dummy2)
Definition: _zm_utility.gsc:5064
‪slowdown_ai
‪function slowdown_ai(str_type)
Definition: _zm_utility.gsc:6148
‪play_vox_to_player
‪function play_vox_to_player(category, type, force_variant)
Definition: _zm_utility.gsc:5356
‪array_flag_wait_any
‪function array_flag_wait_any(flag_array)
Definition: _zm_utility.gsc:4549
‪disable_react
‪function disable_react()
Definition: _zm_utility.gsc:4747
‪is_equipment
‪function is_equipment(weapon)
Definition: _zm_equipment.gsc:691
‪is_leaper
‪function is_leaper()
Definition: _zm_utility.gsc:3725
‪notifyMessage
‪function notifyMessage(notifyData)
Definition: hud_message_shared.gsc:214
‪groundpos_ignore_water_new
‪function groundpos_ignore_water_new(origin)
Definition: _zm_utility.gsc:4590
‪enable
‪function enable(handler)
Definition: _perplayer.gsc:54
‪destroy_hud
‪function destroy_hud()
Definition: _zm_utility.gsc:384
‪get_closest_player
‪function get_closest_player(org)
Definition: _zm_utility.gsc:4850
‪print3d_at_pos
‪function print3d_at_pos(msg, pos, thread_endon, offset)
Definition: _zm_utility.gsc:3346
‪update_valid_players
‪function update_valid_players(origin, ignore_player)
Definition: _zm_utility.gsc:1519
‪get_current_zone
‪function get_current_zone(return_zone)
Definition: _zm_utility.gsc:3614
‪get_non_destroyed_variant2
‪function get_non_destroyed_variant2(barrier_chunks)
Definition: _zm_utility.gsc:2636
‪shock_onexplosion
‪function shock_onexplosion(damage, shockType, shockLight)
Definition: _zm_utility.gsc:3794
‪anchor_delete_failsafe
‪function anchor_delete_failsafe(ai_zombie)
Definition: _zm_utility.gsc:307
‪get_closest_index_to_entity
‪function get_closest_index_to_entity(entity, array, dist, extra_check)
Definition: _zm_utility.gsc:5134
‪register_lethal_grenade_for_level
‪function register_lethal_grenade_for_level(weaponname)
Definition: _zm_utility.gsc:4128
‪update_poi_on_death
‪function update_poi_on_death(zombie_poi)
Definition: _zm_utility.gsc:1260
‪register_custom_spawner_entry
‪function register_custom_spawner_entry(spot_noteworthy, func)
Definition: _zm_utility.gsc:5855
‪all_chunks_intact
‪function all_chunks_intact(barrier, barrier_chunks)
Definition: _zm_utility.gsc:392
‪e_target
‪var e_target
Definition: traps_shared.gsc:2029
‪init_player_offhand_weapons
‪function init_player_offhand_weapons()
Definition: _zm_utility.gsc:4496
‪display_message
‪function display_message(titleText, notifyText, duration)
Definition: _zm_utility.gsc:3705
‪increment_client_stat
‪function increment_client_stat(stat_name, include_gametype)
Definition: _zm_stats.gsc:389
‪clear_run_anim
‪function clear_run_anim()
Definition: _zm_utility.gsc:4913
‪non_destroyed_variant4_order
‪function non_destroyed_variant4_order(origin, chunks_variant4)
Definition: _zm_utility.gsc:2116
‪approximate_path_dist
‪function approximate_path_dist(player)
Definition: _zm_utility.gsc:6092
‪timer
‪function timer(n_time, str_endon, x, y, height)
Definition: lui_shared.gsc:163
‪get_player_perk_purchase_limit
‪function get_player_perk_purchase_limit()
Definition: _zm_utility.gsc:5886
‪lerp
‪function lerp(chunk)
Definition: _zm_utility.gsc:71
‪is_lethal_grenade
‪function is_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4145
‪debug_round_advancer
‪function debug_round_advancer()
Definition: _zm_utility.gsc:3225
‪play_sound_at_pos
‪function play_sound_at_pos(ref, pos, ent)
Definition: _zm_utility.gsc:3040
‪non_destroyed_grate_order
‪function non_destroyed_grate_order(origin, chunks_grate)
Definition: _zm_utility.gsc:1808
‪link_nodes
‪function link_nodes(a, b, bDontUnlinkOnMigrate=false)
Definition: _zm_utility.gsc:5596
‪play_sound_on_ent
‪function play_sound_on_ent(ref)
Definition: _zm_utility.gsc:3070
‪get_player_weapon_limit
‪function get_player_weapon_limit(player)
Definition: _zm_utility.gsc:5865
‪do_player_vo
‪function do_player_vo(snd, variation_count)
Definition: _zm_utility.gsc:3448
‪remove_mod_from_methodofdeath
‪function remove_mod_from_methodofdeath(mod)
Definition: _zm_utility.gsc:3683
‪spawn_weapon_model
‪function spawn_weapon_model(weapon, model, origin, angles, options)
Definition: _zm_utility.gsc:4061
‪is_Standard
‪function is_Standard()
Definition: _zm_utility.gsc:47
‪ignore
‪function ignore(str_system)
Definition: system_shared.csc:165
‪pick_up
‪function pick_up()
Definition: _zm_utility.gsc:4787
‪create_zombie_point_of_interest
‪function create_zombie_point_of_interest(attract_dist, num_attractors, added_poi_value, start_turned_on, initial_attract_func, arrival_attract_func, poi_team)
Definition: _zm_utility.gsc:624
‪ent_flag_init_ai_standards
‪function ent_flag_init_ai_standards()
Definition: _zm_utility.gsc:4858
‪draw_line_ent_to_ent
‪function draw_line_ent_to_ent(ent1, ent2)
Definition: _zm_utility.gsc:3253
‪does_player_have_map_navcard
‪function does_player_have_map_navcard(player)
Definition: _zm_utility.gsc:5429
‪groundpos_ignore_water
‪function groundpos_ignore_water(origin)
Definition: _zm_utility.gsc:4585
‪waittill_subset
‪function waittill_subset(min_num, string1, string2, string3, string4, string5)
Definition: _zm_utility.gsc:5218
‪is_player_revive_tool
‪function is_player_revive_tool(weapon)
Definition: _zm_utility.gsc:4107
‪set_zombie_var
‪function set_zombie_var(zvar, value, is_float, column, is_team_based)
Definition: _zm_utility.gsc:3145
‪add_vox_response_chance
‪function add_vox_response_chance(event, chance)
Definition: _zm_utility.gsc:5379
‪get_closest_non_destroyed_chunk
‪function get_closest_non_destroyed_chunk(origin, barrier, barrier_chunks)
Definition: _zm_utility.gsc:2392
‪is_Encounter
‪function is_Encounter()
Definition: _zm_utility.gsc:450
‪init_player_melee_weapon
‪function init_player_melee_weapon()
Definition: _zm_utility.gsc:4386
‪init_player_equipment
‪function init_player_equipment()
Definition: _zm_equipment.gsc:779
‪do_player_general_vox
‪function do_player_general_vox(category, type, timer, chance)
Definition: _zm_utility.gsc:5317
‪give_start_weapon
‪function give_start_weapon(b_switch_weapon)
Definition: _zm_utility.gsc:4530
‪get_non_destroyed_variant4
‪function get_non_destroyed_variant4(barrier_chunks)
Definition: _zm_utility.gsc:2658
‪unitrigger_set_hint_string
‪function unitrigger_set_hint_string(ent, default_ref, cost)
Definition: _zm_utility.gsc:2988
‪disable_player_move_states
‪function disable_player_move_states(forceStanceChange)
Definition: _zm_utility.gsc:5536
‪is_facing
‪function is_facing(facee, requiredDot=0.5, b_2d=true)
Definition: _zm_utility.gsc:6228
‪add_poi_attractor
‪function add_poi_attractor(zombie_poi)
Definition: _zm_utility.gsc:1128
‪clear_fog_threads
‪function clear_fog_threads()
Definition: _zm_utility.gsc:3695
‪is_Classic
‪function is_Classic()
Definition: _zm_utility.gsc:42
‪round_up_score
‪function round_up_score(score, value)
Definition: _zm_utility.gsc:567
‪print3d_ent
‪function print3d_ent(text, color, scale, offset, end_msg, overwrite)
Definition: _zm_utility.gsc:3541
‪sq_refresh_player_navcard_hud
‪function sq_refresh_player_navcard_hud()
Definition: _zm_utility.gsc:5500
‪respawn_path_nodes
‪function respawn_path_nodes()
Definition: _zm_utility.gsc:5736
‪spawn_path_node_internal
‪function spawn_path_node_internal(origin, angles, k1, v1, k2, v2)
Definition: _zm_utility.gsc:5702
‪shock_onpain
‪function shock_onpain()
Definition: _zm_utility.gsc:3730
‪create_vox_timer
‪function create_vox_timer(type)
Definition: _zm_utility.gsc:5351
‪random_tan
‪function random_tan()
Definition: _zm_utility.gsc:587
‪debug_draw_attractor_positions
‪function debug_draw_attractor_positions()
Definition: _zm_utility.gsc:847
‪is_player_offhand_weapon
‪function is_player_offhand_weapon(weapon)
Definition: _zm_utility.gsc:4513
‪get_player_hero_weapon
‪function get_player_hero_weapon()
Definition: _zm_utility.gsc:4430
‪register_map_navcard
‪function register_map_navcard(navcard_on_map, navcard_needed_for_computer)
Definition: _zm_utility.gsc:5423
‪show_grate_repair
‪function show_grate_repair()
Definition: _zm_utility.gsc:2867
‪is_player_tactical_grenade
‪function is_player_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4226
‪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
‪get_desired_origin
‪function get_desired_origin()
Definition: zombie_utility.gsc:1570
‪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_round_enemy_array
‪function get_round_enemy_array()
Definition: zombie_utility.gsc:2024
‪init_player_tactical_grenade
‪function init_player_tactical_grenade()
Definition: _zm_utility.gsc:4262
‪link_changes_internal
‪function link_changes_internal(func_for_link_list, func_for_unlink_list)
Definition: _zm_utility.gsc:5781
‪a
‪function add_remove_list a
Definition: util_shared.csc:906
‪get_player_melee_weapon
‪function get_player_melee_weapon()
Definition: _zm_utility.gsc:4361
‪add_sound
‪function add_sound(ref, alias)
Definition: _zm_utility.gsc:3030
‪waittill_multiple
‪function waittill_multiple(...)
Definition: util_shared.csc:123
‪upload_zm_dash_counters
‪function upload_zm_dash_counters(force_upload=false)
Definition: _zm_utility.gsc:6258
‪generated_radius_attract_positions
‪function generated_radius_attract_positions(forward, offset, num_positions, attract_radius)
Definition: _zm_utility.gsc:784
‪add
‪function add(entity, dyingplayer, team, timeout)
Definition: _deathicons.gsc:43
‪set_game_var
‪function set_game_var(gvar, val)
Definition: _zm_utility.gsc:5185
‪enable_player_move_states
‪function enable_player_move_states()
Definition: _zm_utility.gsc:5554
‪change_zombie_run_cycle
‪function change_zombie_run_cycle()
Definition: _zm_utility.gsc:155
‪init_player_hero_weapon
‪function init_player_hero_weapon()
Definition: _zm_utility.gsc:4454
‪set_demo_intermission_point
‪function set_demo_intermission_point()
Definition: _zm_utility.gsc:5384
‪is_tactical_grenade
‪function is_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4215
‪self_delete
‪function self_delete()
Definition: _zm_utility.gsc:4604
‪spawn_path_node
‪function spawn_path_node(origin, angles, k1, v1, k2, v2)
Definition: _zm_utility.gsc:5679
‪fake_physicslaunch
‪function fake_physicslaunch(target_pos, power)
Definition: _zm_utility.gsc:2896
‪register_hero_weapon_for_level
‪function register_hero_weapon_for_level(weaponname)
Definition: _zm_utility.gsc:4392
‪redo_link_changes
‪function redo_link_changes()
Definition: _zm_utility.gsc:5824
‪create_counter_hud
‪function create_counter_hud(x)
Definition: _zm_utility.gsc:3587
‪array_flag_wait_any_thread
‪function array_flag_wait_any_thread(flag_name, condition)
Definition: _zm_utility.gsc:4571
‪get_table_var
‪function get_table_var(table, var_name, value, is_float, column)
Definition: _zm_utility.gsc:3174
‪check_point_in_playable_area
‪function check_point_in_playable_area(origin)
Definition: _zm_utility.gsc:480
‪add_zombie_hint
‪function add_zombie_hint(ref, text)
Definition: _zm_utility.gsc:2923
‪STATS_TABLE_COL_GROUP
‪#define STATS_TABLE_COL_GROUP
Definition: _statstable.gsh:4
‪create_simple_hud
‪function create_simple_hud(client, team)
Definition: _zm_utility.gsc:356
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪no_valid_repairable_boards
‪function no_valid_repairable_boards(barrier, barrier_chunks)
Definition: _zm_utility.gsc:419
‪non_destroyed_bar_board_order
‪function non_destroyed_bar_board_order(origin, chunks)
Definition: _zm_utility.gsc:1720
‪increment_is_drinking
‪function increment_is_drinking()
Definition: _zm_utility.gsc:3859
‪really_play_2D_sound
‪function really_play_2D_sound(sound)
Definition: _zm_utility.gsc:3483
‪set_gamemode_var_once
‪function set_gamemode_var_once(gvar, val)
Definition: _zm_utility.gsc:5172
‪make_supersprinter
‪function make_supersprinter()
Definition: _zm_utility.gsc:173
‪decrement_no_end_game_check
‪function decrement_no_end_game_check()
Definition: _zm_utility.gsc:3939
‪undo_link_changes
‪function undo_link_changes()
Definition: _zm_utility.gsc:5812
‪get_closest_2d
‪function get_closest_2d(origin, ents)
Definition: _zm_utility.gsc:2304
‪destroy_ent
‪function destroy_ent()
Definition: _zm_utility.gsc:4801
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪track_players_intersection_tracker
‪function track_players_intersection_tracker()
Definition: _zm_utility.gsc:4923
‪unlink_nodes
‪function unlink_nodes(a, b, bDontLinkOnMigrate=false)
Definition: _zm_utility.gsc:5636
‪giveachievement_wrapper
‪function giveachievement_wrapper(achievement, all_players)
Definition: _zm_utility.gsc:4649
‪ConvertSecondsToMilliseconds
‪function ConvertSecondsToMilliseconds(seconds)
Definition: _zm_utility.gsc:60
‪wait_for_attractor_positions_complete
‪function wait_for_attractor_positions_complete()
Definition: _zm_utility.gsc:5941
‪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
‪does_player_have_correct_navcard
‪function does_player_have_correct_navcard(player)
Definition: _zm_utility.gsc:5434
‪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
‪register_slowdown
‪function register_slowdown(str_type, n_rate, n_duration)
Definition: _zm_utility.gsc:6131
‪sq_refresh_player_navcard_hud_internal
‪function sq_refresh_player_navcard_hud_internal()
Definition: _zm_utility.gsc:5511
‪places_before_decimal
‪function places_before_decimal(num)
Definition: _zm_utility.gsc:608
‪get_chunk_state
‪function get_chunk_state()
Definition: _zm_utility.gsc:2873
‪include_zombie_weapon
‪function include_zombie_weapon(weapon_name, in_box)
Definition: _zm_weapons.gsc:658
‪get_player_closest_to
‪function get_player_closest_to(e_target)
Definition: _zm_utility.gsc:6213
‪update_on_poi_removal
‪function update_on_poi_removal(zombie_poi)
Definition: _zm_utility.gsc:1271
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪PERK_QUICK_REVIVE
‪#define PERK_QUICK_REVIVE
Definition: _zm_perks.gsh:24
‪has_powerup_weapon
‪function has_powerup_weapon()
Definition: _zm_utility.gsc:4519
‪is_point_inside_enabled_zone
‪function is_point_inside_enabled_zone(v_origin, ignore_zone)
Definition: _zm_utility.gsc:6012
‪unlink_nodes_wrapper
‪function unlink_nodes_wrapper(a, b)
Definition: _zm_utility.gsc:5804
‪clear_streamer_hint
‪function clear_streamer_hint()
Definition: _zm_utility.gsc:6045
‪zm_dash_stats_wait_for_consumable_use
‪function zm_dash_stats_wait_for_consumable_use()
Definition: _zm_utility.gsc:6268
‪play_loopsound_on_ent
‪function play_loopsound_on_ent(ref)
Definition: _zm_utility.gsc:3097
‪is_limited_weapon
‪function is_limited_weapon(weapon)
Definition: _zm_utility.gsc:4117
‪set_player_tactical_grenade
‪function set_player_tactical_grenade(weapon)
Definition: _zm_utility.gsc:4250
‪end
‪function end(final)
Definition: _killcam.gsc:511
‪set_player_placeable_mine
‪function set_player_placeable_mine(weapon)
Definition: _zm_utility.gsc:4304
‪get_zombie_hint
‪function get_zombie_hint(ref)
Definition: _zm_utility.gsc:2933
‪get_destroyed_repair_grates
‪function get_destroyed_repair_grates(barrier_chunks)
Definition: _zm_utility.gsc:2480
‪is_valid_zombie_spawn_point
‪function is_valid_zombie_spawn_point(point)
Definition: _zm_utility.gsc:5105
‪show_grate_pull
‪function show_grate_pull()
Definition: _zm_utility.gsc:2295
‪set_round_number
‪function set_round_number(new_round)
Definition: _zm.gsc:440
‪hudelem_count
‪function hudelem_count()
Definition: _zm_utility.gsc:3207
‪is_player_melee_weapon
‪function is_player_melee_weapon(weapon)
Definition: _zm_utility.gsc:4350
‪get_non_destroyed_variant1
‪function get_non_destroyed_variant1(barrier_chunks)
Definition: _zm_utility.gsc:2614
‪is_gametype_active
‪function is_gametype_active(a_gametypes)
Definition: _zm_utility.gsc:5835
‪register_tactical_grenade_for_level
‪function register_tactical_grenade_for_level(weaponname)
Definition: _zm_utility.gsc:4198
‪wait_clear_streamer_hint
‪function wait_clear_streamer_hint(lifetime)
Definition: _zm_utility.gsc:6055
‪non_destroyed_variant5_order
‪function non_destroyed_variant5_order(origin, chunks_variant5)
Definition: _zm_utility.gsc:2209
‪set_gamemode_var
‪function set_gamemode_var(gvar, val)
Definition: _zm_utility.gsc:5162
‪is_favorite_weapon
‪function is_favorite_weapon(weapon_to_check)
Definition: _zm_utility.gsc:5361
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪GetYawToSpot
‪function GetYawToSpot(spot)
Definition: _zm_utility.gsc:4727
‪add_gametype
‪function add_gametype(gt, dummy1, name, dummy2)
Definition: _zm_utility.gsc:5053
‪ai_calculate_health
‪function ai_calculate_health(round_number)
Definition: zombie_utility.gsc:1907
‪get_closest_node
‪function get_closest_node(org, nodes)
Definition: _zm_utility.gsc:1714
‪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
‪sndSwitchAnnouncerVox
‪function sndSwitchAnnouncerVox(who)
Definition: _zm_utility.gsc:5305
‪get_specific_character
‪function get_specific_character(n_character_index)
Definition: _zm_utility.gsc:5974
‪create_zombie_point_of_interest_attractor_positions
‪function create_zombie_point_of_interest_attractor_positions(num_attract_dists, attract_dist)
Definition: _zm_utility.gsc:717
‪is_enabled
‪function is_enabled(name)
Definition: _zm_bgb.gsc:4
‪drawcylinder
‪function drawcylinder(pos, rad, height)
Definition: _zm_utility.gsc:3328
‪waittill_string
‪function waittill_string(msg, ent)
Definition: util_shared.csc:104
‪include_weapon
‪function include_weapon(weapon_name, in_box)
Definition: _zm_utility.gsc:3515
‪is_player_equipment
‪function is_player_equipment(weapon)
Definition: _zm_equipment.gsc:706
‪debug_blocker
‪function debug_blocker(pos, rad, height)
Definition: _zm_utility.gsc:3308
‪waittill_not_moving
‪function waittill_not_moving()
Definition: _zm_utility.gsc:4816
‪upload_zm_dash_counters_end_game
‪function upload_zm_dash_counters_end_game()
Definition: _zm_utility.gsc:6260
‪ent_flag_wait_ai_standards
‪function ent_flag_wait_ai_standards(message)
Definition: _zm_utility.gsc:4872
‪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
‪is_player_looking_at
‪function is_player_looking_at(origin, dot, do_trace, ignore_ent)
Definition: _zm_utility.gsc:5009
‪remove_undefined
‪function remove_undefined(array, b_keep_keys)
Definition: array_shared.csc:56
‪register_offhand_weapons_for_level_defaults
‪function register_offhand_weapons_for_level_defaults()
Definition: _zm_utility.gsc:4471
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪is_offhand_weapon
‪function is_offhand_weapon(weapon)
Definition: _zm_utility.gsc:4507
‪can_player_purchase_perk
‪function can_player_purchase_perk()
Definition: _zm_utility.gsc:5899
‪bullet_attack
‪function bullet_attack(type)
Definition: _zm_utility.gsc:4776
‪debug_breadcrumbs
‪function debug_breadcrumbs()
Definition: _zm_utility.gsc:3370
‪init_zombie_run_cycle
‪function init_zombie_run_cycle()
Definition: _zm_utility.gsc:116
‪get_non_destroyed_variant5
‪function get_non_destroyed_variant5(barrier_chunks)
Definition: _zm_utility.gsc:2680
‪array
‪function filter array
Definition: array_shared.csc:16
‪is_player_lethal_grenade
‪function is_player_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4156
‪should_watch_for_emp
‪function should_watch_for_emp()
Definition: _zm_utility.gsc:4466
‪get_number_of_valid_players
‪function get_number_of_valid_players()
Definition: _zm_utility.gsc:1666
‪halve_score
‪function halve_score(n_score)
Definition: _zm_utility.gsc:579
‪init_player_placeable_mine
‪function init_player_placeable_mine()
Definition: _zm_utility.gsc:4316
‪grate_order_destroyed
‪function grate_order_destroyed(chunks_repair_grate)
Definition: _zm_utility.gsc:2745
‪is_hero_weapon
‪function is_hero_weapon(weapon)
Definition: _zm_utility.gsc:4408
‪check_and_create_node_lists
‪function check_and_create_node_lists()
Definition: _zm_utility.gsc:5583
‪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
‪round_up_to_ten
‪function round_up_to_ten(score)
Definition: _zm_utility.gsc:557
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪increment_no_end_game_check
‪function increment_no_end_game_check()
Definition: _zm_utility.gsc:3932
‪is_player_placeable_mine
‪function is_player_placeable_mine(weapon)
Definition: _zm_utility.gsc:4280
‪array_limiter
‪function array_limiter(array, total)
Definition: _zm_utility.gsc:2880
‪init_utility
‪function init_utility()
Definition: _zm_utility.gsc:35
‪is_multiple_drinking
‪function is_multiple_drinking()
Definition: _zm_utility.gsc:3891
‪get_zombie_point_of_interest
‪function get_zombie_point_of_interest(origin, poi_array)
Definition: _zm_utility.gsc:893
‪is_player_hero_weapon
‪function is_player_hero_weapon(weapon)
Definition: _zm_utility.gsc:4419
‪draw_line_ent_to_pos
‪function draw_line_ent_to_pos(ent, pos, end_on)
Definition: _zm_utility.gsc:3272
‪assign_zombie_point_of_interest
‪function assign_zombie_point_of_interest(origin, poi)
Definition: _zm_utility.gsc:1065
‪recalc_zombie_array
‪function recalc_zombie_array()
Definition: _zm_utility.gsc:96
‪set_zombie_run_cycle
‪function set_zombie_run_cycle(new_move_speed)
Definition: zombie_utility.gsc:2076
‪give_perk
‪function give_perk(perk, bought)
Definition: _zm_perks.gsc:738
‪do_zombie_fall
‪function do_zombie_fall(spot)
Definition: _zm_ai_faller.gsc:188
‪set_player_hero_weapon
‪function set_player_hero_weapon(weapon)
Definition: _zm_utility.gsc:4443
‪init
‪function init()
Definition: struct.csc:1
‪set_game_var_once
‪function set_game_var_once(gvar, val)
Definition: _zm_utility.gsc:5190
‪remove_poi_from_ignore_list
‪function remove_poi_from_ignore_list(poi)
Definition: _zm_utility.gsc:1335
‪poi_locations_equal
‪function poi_locations_equal(loc1, loc2)
Definition: _zm_utility.gsc:1122
‪invalidate_attractor_pos
‪function invalidate_attractor_pos(attractor_pos, zombie)
Definition: _zm_utility.gsc:1290
‪PERK_ADDITIONAL_PRIMARY_WEAPON
‪#define PERK_ADDITIONAL_PRIMARY_WEAPON
Definition: _zm_perks.gsh:30
‪init_player_lethal_grenade
‪function init_player_lethal_grenade()
Definition: _zm_utility.gsc:4192
‪debug_print
‪function debug_print(msg)
Definition: _zm_utility.gsc:3298
‪place_navcard
‪function place_navcard(str_model, str_stat, org, angles)
Definition: _zm_utility.gsc:5443
‪link_changes_internal_internal
‪function link_changes_internal_internal(list, func)
Definition: _zm_utility.gsc:5752
‪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
‪can_attract
‪function can_attract(attractor)
Definition: _zm_utility.gsc:1236
‪do_zombie_rise
‪function do_zombie_rise(spot)
Definition: _zm_spawner.gsc:2969
‪run_spawn_functions
‪function run_spawn_functions()
Definition: _zm_utility.gsc:319
‪register_melee_weapon_for_level
‪function register_melee_weapon_for_level(weaponname)
Definition: _zm_utility.gsc:4322
‪remove_poi_attractor
‪function remove_poi_attractor(zombie_poi)
Definition: _zm_utility.gsc:1087
‪get_player_lethal_grenade
‪function get_player_lethal_grenade()
Definition: _zm_utility.gsc:4167
‪groundpos
‪function groundpos(origin)
Definition: _zm_utility.gsc:4580
‪is_explosive_damage
‪function is_explosive_damage(mod)
Definition: _zm_utility.gsc:5294
‪print_run_speed
‪function print_run_speed(speed)
Definition: _zm_utility.gsc:3241
‪get_non_destroyed_chunks_grate
‪function get_non_destroyed_chunks_grate(barrier, barrier_chunks)
Definition: _zm_utility.gsc:2585
‪player_is_in_laststand
‪function player_is_in_laststand()
Definition: laststand_shared.gsc:18
‪non_destroyed_variant2_order
‪function non_destroyed_variant2_order(origin, chunks_variant2)
Definition: _zm_utility.gsc:2023
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: _zm_utility.gsc:1600
‪get_closest_index
‪function get_closest_index(org, array, dist)
Definition: _zm_utility.gsc:5080
‪get_pack_a_punch_camo_index
‪function get_pack_a_punch_camo_index(prev_pap_index)
Definition: _zm_weapons.gsc:2457
‪is_solo_ranked_game
‪function is_solo_ranked_game()
Definition: _zm_utility.gsc:6253
‪trigger_invisible
‪function trigger_invisible(enable)
Definition: _zm_utility.gsc:3527
‪array_check_for_dupes_using_compare
‪function array_check_for_dupes_using_compare(array, single, is_equal_fn)
Definition: _zm_utility.gsc:1109
‪get_destroyed_chunks
‪function get_destroyed_chunks(barrier_chunks)
Definition: _zm_utility.gsc:2702
‪get_closest_valid_player
‪function get_closest_valid_player(origin, ignore_player)
Definition: _zm_utility.gsc:1393
‪is_melee_weapon
‪function is_melee_weapon(weapon)
Definition: _zm_utility.gsc:4339
‪server_safe_ground_trace
‪function server_safe_ground_trace(id, max, origin)
Definition: _zm_server_throttle.gsc:96
‪general_vox_timer
‪function general_vox_timer(timer, type)
Definition: _zm_utility.gsc:5334
‪set_hint_string
‪function set_hint_string(ent, default_ref, cost)
Definition: _zm_utility.gsc:2948
‪is_jumping
‪function is_jumping()
Definition: _zm_utility.gsc:5286
‪getWeaponClassZM
‪function getWeaponClassZM(weapon)
Definition: _zm_utility.gsc:4036
‪non_destroyed_variant1_order
‪function non_destroyed_variant1_order(origin, chunks_variant1)
Definition: _zm_utility.gsc:1928
‪weapon_give
‪function weapon_give(weapon, is_upgrade=false, magic_box=false, nosound=false, b_switch_weapon=true)
Definition: _zm_weapons.gsc:2603
‪activate_zombie_point_of_interest
‪function activate_zombie_point_of_interest()
Definition: _zm_utility.gsc:1020
‪single_thread
‪function single_thread(entity, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:699
‪is_player
‪function is_player()
Definition: _zm_utility.gsc:65
‪all_chunks_destroyed
‪function all_chunks_destroyed(barrier, barrier_chunks)
Definition: _zm_utility.gsc:455
‪get_current_zombie_count
‪function get_current_zombie_count()
Definition: zombie_utility.gsc:2018
‪checkForAllDead
‪function checkForAllDead(excluded_player)
Definition: _zm.gsc:1773
‪float_print3d
‪function float_print3d(msg, time)
Definition: _zm_utility.gsc:3433
‪string_to_float
‪function string_to_float(string)
Definition: _zm_utility.gsc:3119
‪create_and_play_dialog
‪function create_and_play_dialog(category, subcategory, force_variant)
Definition: _zm_audio.gsc:603
‪ignore_triggers
‪function ignore_triggers(timer)
Definition: _zm_utility.gsc:4621
‪default_validate_enemy_path_length
‪function default_validate_enemy_path_length(player)
Definition: _zm_utility.gsc:1380
‪is_quad
‪function is_quad()
Definition: _zm_utility.gsc:3720
‪in_revive_trigger
‪function in_revive_trigger()
Definition: _zm_utility.gsc:1684
‪get_non_destroyed_chunks
‪function get_non_destroyed_chunks(barrier, barrier_chunks)
Definition: _zm_utility.gsc:2506
‪set_player_lethal_grenade
‪function set_player_lethal_grenade(weapon)
Definition: _zm_utility.gsc:4180
‪GetYaw
‪function GetYaw(org)
Definition: _zm_utility.gsc:4720
‪add_poi_to_ignore_list
‪function add_poi_to_ignore_list(poi)
Definition: _zm_utility.gsc:1350
‪in_playable_area
‪function in_playable_area()
Definition: _zm_utility.gsc:2368
‪flat_angle
‪function flat_angle(angle)
Definition: _zm_utility.gsc:4898
‪zombie_goto_round
‪function zombie_goto_round(n_target_round)
Definition: _zm_utility.gsc:5984
‪debug_draw_claimed_attractor_positions
‪function debug_draw_claimed_attractor_positions()
Definition: _zm_utility.gsc:870
‪speed_change_watcher
‪function speed_change_watcher()
Definition: _zm_utility.gsc:178
‪debug_attack_spots_taken
‪function debug_attack_spots_taken()
Definition: _zm_utility.gsc:3397
‪delete_spawned_path_nodes
‪function delete_spawned_path_nodes()
Definition: _zm_utility.gsc:5720
‪watch_for_poi_death
‪function watch_for_poi_death()
Definition: _zm_utility.gsc:683
‪has_hero_weapon
‪function has_hero_weapon()
Definition: _zm_utility.gsc:4524
‪decrement_ignoreme
‪function decrement_ignoreme()
Definition: _zm_utility.gsc:3840
‪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
‪get_hint_string
‪function get_hint_string(ent, default_ref, cost)
Definition: _zm_utility.gsc:2974
‪give_player_all_perks
‪function give_player_all_perks(b_exclude_quick_revive=false)
Definition: _zm_utility.gsc:5917
‪enable_react
‪function enable_react()
Definition: _zm_utility.gsc:4767
‪getStatsTableName
‪function getStatsTableName()
Definition: util_shared.csc:1343
‪set_player_melee_weapon
‪function set_player_melee_weapon(weapon)
Definition: _zm_utility.gsc:4374
‪has_player_hero_weapon
‪function has_player_hero_weapon()
Definition: _zm_utility.gsc:4459
‪move_zombie_spawn_location
‪function move_zombie_spawn_location(spot)
Definition: _zm_utility.gsc:188
‪is_magic_bullet_shield_enabled
‪function is_magic_bullet_shield_enabled(ent)
Definition: _zm_utility.gsc:3474
‪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
‪get_random_destroyed_chunk
‪function get_random_destroyed_chunk(barrier, barrier_chunks)
Definition: _zm_utility.gsc:2438
‪link_nodes_wrapper
‪function link_nodes_wrapper(a, b)
Definition: _zm_utility.gsc:5796
‪play_sound_2D
‪function play_sound_2D(sound)
Definition: _zm_utility.gsc:3493
‪deactivate_zombie_point_of_interest
‪function deactivate_zombie_point_of_interest(dont_remove)
Definition: _zm_utility.gsc:1030
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪spawn_buildkit_weapon_model
‪function spawn_buildkit_weapon_model(player, weapon, camo, origin, angles)
Definition: _zm_utility.gsc:4087
‪is_Survival
‪function is_Survival()
Definition: _zm_utility.gsc:445
‪get_eye
‪function get_eye()
Definition: util_shared.csc:948
‪debug_draw_new_attractor_positions
‪function debug_draw_new_attractor_positions()
Definition: _zm_utility.gsc:694
‪get_gamemode_var
‪function get_gamemode_var(gvar)
Definition: _zm_utility.gsc:5208