‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm_ai_wasp.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\aat_shared;
4 #using scripts\shared\array_shared;
5 #using scripts\shared\callbacks_shared;
6 #using scripts\shared\flag_shared;
7 #using scripts\shared\spawner_shared;
8 #using scripts\shared\system_shared;
9 #using scripts\shared\trigger_shared;
10 #using scripts\shared\util_shared;
11 #using scripts\shared\vehicle_shared;
12 #using scripts\shared\vehicles\_parasite;
13 #using scripts\shared\clientfield_shared;
14 #using scripts\shared\visionset_mgr_shared;
15 #using scripts\shared\ai_shared;
16 #using scripts\shared\vehicles\_parasite;
17 
18 #insert scripts\shared\shared.gsh;
19 #insert scripts\shared\weapons\grapple.gsh;
20 
21 #using scripts\zm\_util;
22 #using scripts\zm\_zm;
23 #using scripts\zm\_zm_audio;
24 #using scripts\zm\_zm_net;
25 #using scripts\zm\_zm_powerups;
26 #using scripts\zm\_zm_score;
27 #using scripts\zm\_zm_spawner;
28 #using scripts\zm\_zm_stats;
29 #using scripts\zm\_zm_utility;
30 #using scripts\zm\zm_zod_idgun_quest;
31 
32 #using scripts\shared\ai\zombie_utility;
33 
34 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
35 #insert scripts\zm\_zm_utility.gsh;
36 #insert scripts\shared\aat_zm.gsh;
37 #insert scripts\shared\version.gsh;
38 #insert scripts\zm\_zm_ai_wasp.gsh;
39 #insert scripts\zm\zm_zod_craftables.gsh;
40 
41 #precache( "fx", "zombie/fx_parasite_spawn_buildup_zod_zmb" );
42 
43 #define N_MAX_WASPS 16 // Max number that can be alive at any one time (mainly limited by networking concerns)
44 #define N_MAX_WASPS_PER_PLAYER 5 // Max alive per player in the game
45 
46 #define N_SWARM_SIZE 1
47 
48 // Number of wasps to spawn = N_NUM_WASPS_PER_ROUND * (a scalar if more than one player)
49 #define N_NUM_WASPS_PER_ROUND 10
50 #define N_WASP_PLAYER_SCALAR 0.75
51 
52 #define N_SPAWN_HEIGHT_MIN 60 // Minimum ground height to spawn at
53 #define N_WASP_HEALTH_INCREASE 50 // Amount to increase Wasp health
54 #define N_WASP_HEALTH_MAX 1600 // Maximum health
55 #define N_WASP_KILL_POINTS 70 // Points per kill
56 
57 
58 #namespace zm_ai_wasp;
59 
60 function ‪init()
61 {
62  level.wasp_enabled = true;
63  level.wasp_rounds_enabled = false;
64  level.wasp_round_count = 1;
65 
66  level.wasp_spawners = [];
67 
68  level.a_wasp_priority_targets = [];
69 
70  level ‪flag::init( "wasp_round" );
71  level ‪flag::init( "wasp_round_in_progress" );
72 
73  level.melee_range_sav = GetDvarString( "ai_meleeRange" );
74  level.melee_width_sav = GetDvarString( "ai_meleeWidth" );
75  level.melee_height_sav = GetDvarString( "ai_meleeHeight" );
76 
77  ‪DEFAULT( level.vsmgr_prio_overlay_zm_wasp_round, ‪ZM_WASP_VISION_OVERLAY_PRIORITY );
78 
79  ‪clientfield::register( "toplayer", "parasite_round_fx", ‪VERSION_SHIP, 1, "counter" );
81  ‪clientfield::register( "world", "toggle_on_parasite_fog", ‪VERSION_SHIP, 2, "int" );
82 
84 
85  level._effect[ "lightning_wasp_spawn" ] = "zombie/fx_parasite_spawn_buildup_zod_zmb";
86 
88 
89  // AAT IMMUNITIES
95 
96  // Init wasp targets - mainly for testing purposes.
97  // If you spawn a wasp without having a wasp round, you'll get SREs on hunted_by.
99 }
100 
101 
102 //
103 // If you want to enable wasp rounds, then call this.
104 // Specify an override func if needed.
106 {
107  level.wasp_rounds_enabled = true;
108 
109  if( !isdefined( level.wasp_round_track_override ) )
110  {
111  level.wasp_round_track_override =&‪wasp_round_tracker;
112  }
113 
114  level thread [[level.wasp_round_track_override]]();
115 }
116 
117 
119 {
120  level.wasp_spawners = getEntArray( "zombie_wasp_spawner", "script_noteworthy" );
121  later_wasp = getentarray("later_round_wasp_spawners", "script_noteworthy" );
122  level.wasp_spawners = ArrayCombine( level.wasp_spawners, later_wasp, true, false );
123 
124  if( level.wasp_spawners.size == 0 )
125  {
126  return;
127  }
128 
129  for( i = 0; i < level.wasp_spawners.size; i++ )
130  {
131  if ( ‪zm_spawner::is_spawner_targeted_by_blocker( level.wasp_spawners[i] ) )
132  {
133  level.wasp_spawners[i].is_enabled = false;
134  }
135  else
136  {
137  level.wasp_spawners[i].is_enabled = true;
138  level.wasp_spawners[i].script_forcespawn = true;
139  }
140  }
141 
142  assert( level.wasp_spawners.size > 0 );
143  level.wasp_health = 100;
144 
145  vehicle::add_main_callback( "spawner_bo3_parasite_enemy_tool", &‪wasp_init );
146 }
147 
149 {
150  wasps = GetEntArray( "zombie_wasp", "targetname" );
151  num_alive_wasps = wasps.size;
152  foreach( wasp in wasps )
153  {
154  if( !IsAlive( wasp ) )
155  {
156  num_alive_wasps--;
157  }
158  }
159  return num_alive_wasps;
160 }
161 
163 {
164  level endon( "intermission" );
165  level endon( "wasp_round" );
166 
167  level.wasp_targets = level.players;
168  for( i = 0 ; i < level.wasp_targets.size; i++ )
169  {
170  level.wasp_targets[i].hunted_by = 0;
171  }
172 
173  level endon( "restart_round" );
174  level endon( "kill_round" );
175 
176 /#
177  if ( GetDvarInt( "zombie_cheat" ) == 2 || GetDvarInt( "zombie_cheat" ) >= 4 )
178  {
179  return;
180  }
181 #/
182 
183  if( level.intermission )
184  {
185  return;
186  }
187 
188  array::thread_all( level.players, &‪play_wasp_round );
189 
190  // spawn one at a time, recalculating position each time
191  n_wave_count = ‪N_NUM_WASPS_PER_ROUND;
192  if ( level.players.size > 1 )
193  {
194  n_wave_count *= level.players.size * ‪N_WASP_PLAYER_SCALAR;
195  }
196 
198 
199  // The wait function uses this to determine whether or not to end the round.
200  level.zombie_total = Int( n_wave_count * ‪N_SWARM_SIZE );
201 
202 /#
203  if( GetDvarString( "force_wasp" ) != "" && GetDvarInt( "force_wasp" ) > 0 )
204  {
205  level.zombie_total = GetDvarInt( "force_wasp" );
206  SetDvar( "force_wasp", 0 );
207  }
208  #/
209 
210  wait 1;
211 
214  level ‪clientfield::set( "toggle_on_parasite_fog", 1 );
215 
216  PlaySoundAtPosition( "vox_zmba_event_waspstart_0", ( 0, 0, 0 ) );
217 
218  wait 6; // wait before spawning parasites
219 
220  n_wasps_alive = 0;
221 
222  // Start spawning loop
223  level ‪flag::set( "wasp_round_in_progress" );
224 
225  level endon( "last_ai_down" );
226 
227  level thread ‪wasp_round_aftermath();
228 
229  while ( true )
230  {
231  while( level.zombie_total > 0 )
232  {
233  if( ‪IS_TRUE( level.bzm_worldPaused ) )
234  {
236  continue;
237  }
238  if( isdefined(level.zm_mixed_wasp_raps_spawning) )
239  {
240  [[level.zm_mixed_wasp_raps_spawning]]();
241  }
242  else
243  {
244  ‪spawn_wasp();
245  }
246 
248  }
249 
250  ‪util::wait_network_frame(); // wait network frame between swarms
251  }
252 }
253 
254 
255 function ‪spawn_wasp()
256 {
257  b_swarm_spawned = false;
258 
259  while ( !b_swarm_spawned )
260  {
261  // Spawn limiter - wait until there's space and a place to spawn a wasp, and the spawning flag is set
262  while( !‪ready_to_spawn_wasp() )
263  {
264  wait( 1.0 );
265  }
266 
267  /* Find the base spawn position for the swarm */
268  spawn_point = undefined;
269 
270  while ( !isdefined( spawn_point ) )
271  {
272  favorite_enemy = ‪get_favorite_enemy();
273  spawn_enemy = favorite_enemy;
274  if( !IsDefined( spawn_enemy ) )
275  {
276  //default to spawn near first player
277  spawn_enemy = GetPlayers()[0];
278  }
279 
280  if ( isdefined( level.wasp_spawn_func ) )
281  {
282  spawn_point = [[ level.wasp_spawn_func ]]( spawn_enemy );
283  }
284  else
285  {
286  // Default method
287  spawn_point = ‪wasp_spawn_logic( spawn_enemy );
288  }
289 
290  if ( !isdefined( spawn_point ) )
291  {
292  ‪WAIT_ABOUT( 1 ); // try again after wait
293  }
294  }
295 
296  /* Query the navvolume for valid spawn points around base spawn point */
297  v_spawn_origin = spawn_point.origin;
298  v_ground = ‪GROUNDPOS( undefined, spawn_point.origin + ( 0, 0, ‪N_SPAWN_HEIGHT_MIN ) );
299  if ( DistanceSquared( v_ground, spawn_point.origin ) < ( ‪N_SPAWN_HEIGHT_MIN * ‪N_SPAWN_HEIGHT_MIN ) )
300  {
301  v_spawn_origin = v_ground + ( 0, 0, ‪N_SPAWN_HEIGHT_MIN );
302  }
303 
304  queryResult = PositionQuery_Source_Navigation( v_spawn_origin, 0, 80, 80, 15, "navvolume_small" );
305  a_points = array::randomize( queryResult.data );
306 
307  /* Extra bullettrace to be sure. Save only points that pass test */
308 
309  a_spawn_origins = [];
310 
311  // Only check the number of points we need.
312  n_points_found = 0;
313  foreach ( point in a_points )
314  {
315  if ( BulletTracePassed( point.origin, spawn_point.origin, false, spawn_enemy ) )
316  {
317  ‪ARRAY_ADD( a_spawn_origins, point.origin );
318  n_points_found++;
319  if ( n_points_found >= ‪N_SWARM_SIZE )
320  {
321  break;
322  }
323  }
324  }
325 
326  /* Spawn the swarm only if we have found enough safe points for the whole swarm */
327  if ( a_spawn_origins.size >= ‪N_SWARM_SIZE )
328  {
329  n_spawn = 0;
330  while ( n_spawn < N_SWARM_SIZE && level.zombie_total > 0 )
331  {
332  for ( i = a_spawn_origins.size - 1; i >= 0; i-- )
333  {
334  v_origin = a_spawn_origins[ i ];
335 
336  level.wasp_spawners[ 0 ].origin = v_origin;
337 
338  ai = ‪zombie_utility::spawn_zombie( level.wasp_spawners[ 0 ] );
339 
340  if ( isdefined( ai ) )
341  {
342  ai ‪parasite::set_parasite_enemy( favorite_enemy );
343  level thread ‪wasp_spawn_init( ai, v_origin );
344  ArrayRemoveIndex( a_spawn_origins, i );
345 
346  if( isdefined(level.zm_wasp_spawn_callback) )
347  {
348  ai thread [[level.zm_wasp_spawn_callback]]();
349  }
350 
351  n_spawn++;
352  level.zombie_total--;
353  ‪WAIT_ABOUT( .1 ); // a little seperation between spawns
354  break;
355  }
356 
357  ‪WAIT_ABOUT( .1 ); // a little wait if spawn failed
358  }
359  }
360 
361  b_swarm_spawned = true;
362  }
363 
364  ‪util::wait_network_frame(); // wait network frame between swarms
365  }
366 }
367 
368 
370 {
371  foreach ( player in level.players )
372  {
373  player ‪clientfield::increment_to_player( "parasite_round_fx" );
375  }
376 }
377 
378 function ‪show_hit_marker() // self = player
379 {
380  if ( IsDefined( self ) && IsDefined( self.hud_damagefeedback ) )
381  {
382  self.hud_damagefeedback SetShader( "damage_feedback", 24, 48 );
383  self.hud_damagefeedback.alpha = 1;
384  self.hud_damagefeedback FadeOverTime(1);
385  self.hud_damagefeedback.alpha = 0;
386  }
387 }
388 
389 function ‪waspDamage( inflictor, attacker, ‪damage, dFlags, mod, weapon, point, dir, hitLoc, offsetTime, boneIndex, modelIndex )
390 {
391  if( isdefined(attacker) )
392  {
393  attacker ‪show_hit_marker();
394  }
395  return ‪damage;
396 }
397 
398 // check if there's space and a place to spawn a wasp, and the spawning flag is set
400 {
401  n_wasps_alive = ‪get_current_wasp_count();
402 
403  b_wasp_count_at_max = n_wasps_alive >= ‪N_MAX_WASPS;
404  b_wasp_count_per_player_at_max = n_wasps_alive >= level.players.size * ‪N_MAX_WASPS_PER_PLAYER;
405 
406  if( b_wasp_count_at_max || b_wasp_count_per_player_at_max || !( level ‪flag::get( "spawn_zombies" ) ) )
407  {
408  return false;
409  }
410  return true;
411 }
412 
413 
415 {
416  level waittill( "last_ai_down", e_wasp );
417 
418  level thread ‪zm_audio::sndMusicSystem_PlayState( "parasite_over" );
419 
420  if( isdefined(level.zm_override_ai_aftermath_powerup_drop) )
421  {
422  [[level.zm_override_ai_aftermath_powerup_drop]]( e_wasp, level.last_ai_origin );
423  }
424  else
425  {
426  if( isdefined( level.last_ai_origin ) )
427  {
428  enemy = e_wasp.favoriteenemy;
429  if (!IsDefined(enemy))
430  enemy = array::random(level.players);
431  enemy ‪parasite_drop_item( level.last_ai_origin );
432  }
433  }
434 
435  wait(2);
436  level ‪clientfield::set( "toggle_on_parasite_fog", 2 );
437  level.sndMusicSpecialRound = false;
438  wait(6);
439 
440  level ‪flag::clear( "wasp_round_in_progress" );
441 
442  //level thread wasp_round_aftermath();
443 }
444 
445 // Calculates spawn position for Max Ammo and moves it if in invalid spawn position
446 function ‪parasite_drop_item( v_parasite_origin )
447 {
448  if ( !( ‪zm_utility::check_point_in_enabled_zone( v_parasite_origin, true, level.active_zones ) ) )
449  {
450  // Checks type of item, then spawns item at the parasite's origin
451  e_parasite_drop = level ‪zm_powerups::specific_powerup_drop( "full_ammo", v_parasite_origin );
452 
453  current_zone = self ‪zm_utility::get_current_zone();
454  if( isdefined( current_zone ) )
455  {
456  const n_ground_offset = 20;
457 
458  v_start = e_parasite_drop.origin;
459 
460  e_closest_player = ArrayGetClosest( v_start, level.activeplayers );
461  if( isdefined( e_closest_player ) )
462  {
463  v_target = e_closest_player.origin + (0, 0, n_ground_offset);
464 
465  // We know the target position is valid
466  // - Project a vector to the target position and drop the item at the first available point along the vector
467  // that is inside playable space
468 
469  n_distance_to_target = Distance( v_start, v_target );
470  v_dir = VectorNormalize( v_target - v_start );
471 
472  n_step = 50;
473  n_distance_moved = 0;
474  v_position = v_start;
475  while( n_distance_moved <= n_distance_to_target )
476  {
477  v_position += (v_dir * n_step);
478 
479  if ( ‪zm_utility::check_point_in_enabled_zone( v_position, true, level.active_zones ) )
480  {
481  // Only accept the position if the dist to the target ground position isn't too large
482  // - This check stops pickups getting stuck on ledges
483  n_height_diff = abs( v_target[2] - v_position[2] );
484  if( n_height_diff < 60 )
485  {
486  break;
487  }
488  }
489 
490  n_distance_moved += n_step;
491  }
492 
493  // Push the drop position to the floor
494  ‪trace = bullettrace( v_position, v_position + (0,0,-256 ), false, undefined );
495  v_ground_position = ‪trace["position"];
496  if( isdefined(v_ground_position) )
497  {
498  v_position = ( v_position[0], v_position[1], v_ground_position[2] + n_ground_offset );
499  }
500 
501  // Move to the drop position
502  n_flight_time = Distance( v_start, v_position ) / 100;
503  if( n_flight_time > 4.0 )
504  {
505  n_flight_time = 4.0;
506  }
507  e_parasite_drop MoveTo( v_position, n_flight_time );
508  }
509  else
510  {
511  // Failsafe
512  v_nav_check = GetClosestPointOnNavMesh( e_parasite_drop.origin, 2000, 32 );
513  }
514  }
515  }
516  else
517  {
518  // If parasite is above navmesh, checks type of item and then spawns item on the ground below the parasite
519  level ‪zm_powerups::specific_powerup_drop( "full_ammo", GetClosestPointOnNavMesh( v_parasite_origin, 1000, 30 ) );
520  }
521 }
522 
523 //
524 // Spawn in fx and initialization
525 // - ai.favoriteenemy = the wasps target
526 function ‪wasp_spawn_init( ai, origin, should_spawn_fx = true )
527 {
528  ai endon( "death" );
529 
530  ai SetInvisibleToAll();
531 
532  if ( isdefined( origin ) )
533  {
534  v_origin = origin;
535  }
536  else
537  {
538  v_origin = ai.origin;
539  }
540 
541  if( should_spawn_fx )
542  {
543  ‪PlayFx( level._effect["lightning_wasp_spawn"], v_origin );
544  }
545 
546 // playsoundatposition( "zmb_hellhound_prespawn", v_origin );
547  wait( 1.5 );
548 // playsoundatposition( "zmb_hellhound_bolt", v_origin );
549 
550  Earthquake( 0.3, 0.5, v_origin, 256);
551  //PlayRumbleOnPosition("explosion_generic", v_origin);
552 // playsoundatposition( "zmb_hellhound_spawn", v_origin );
553 
554  // face the enemy
555  if ( IsDefined(ai.favoriteenemy) )
556  angle = VectorToAngles( ai.favoriteenemy.origin - v_origin );
557  else
558  angle = ai.angles;
559  angles = ( ai.angles[0], angle[1], ai.angles[2] );
560 
561  //DCS 080714: this should work for an ai vehicle but currently doesn't. Support should be added soon.
562  //ai ForceTeleport( v_origin, angles );
563  ai.origin = v_origin;
564  ai.angles = angles;
565 
566  assert( isdefined( ai ), "Ent isn't defined." );
567  assert( IsAlive( ai ), "Ent is dead." );
568 
570 
571  if( isdefined( level._wasp_death_cb ) )
572  {
573  ai ‪callback::add_callback( #"on_vehicle_killed", level._wasp_death_cb );
574  }
575 
576  ai SetVisibleToAll();
577  ai.ignoreme = false; // don't let attack wasp give chase until it is visible
578  ai notify( "visible" );
579 }
580 
581 //
582 // Makes use of the _zm_zone_manager and specially named structs for each zone to
583 // indicate wasp spawn locations instead of constantly using ents.
585 {
586  if( !isdefined(level.enemy_wasp_global_locations) )
587  {
588  level.enemy_wasp_global_locations = [];
589  keys = GetArrayKeys( level.zones );
590  for( i=0; i<keys.size; i++ )
591  {
592  zone = level.zones[keys[i]];
593 
594  // add wasp_spawn locations
595  foreach( loc in zone.a_locs[ "wasp_location" ] )
596  {
597  ‪ARRAY_ADD( level.enemy_wasp_global_locations, loc );
598  }
599  }
600  }
601 }
602 
603 function ‪wasp_find_closest_in_global_pool( favorite_enemy )
604 {
605  index_to_use = 0;
606  closest_distance_squared = DistanceSquared( level.enemy_wasp_global_locations[index_to_use].origin, favorite_enemy.origin );
607  for( i = 0; i < level.enemy_wasp_global_locations.size; i++ )
608  {
609  if( level.enemy_wasp_global_locations[i].is_enabled )
610  {
611  dist_squared = DistanceSquared( level.enemy_wasp_global_locations[i].origin, favorite_enemy.origin );
612  if( dist_squared<closest_distance_squared )
613  {
614  index_to_use = i;
615  closest_distance_squared = dist_squared;
616  }
617  }
618  }
619  return level.enemy_wasp_global_locations[index_to_use];
620 }
621 
622 #define WASP_SPAWN_DIST_MIN 400
623 #define WASP_SPAWN_DIST_MAX 600
624 
625 function ‪wasp_spawn_logic( favorite_enemy )
626 {
627  if ( !GetDvarInt( "zm_wasp_open_spawning", 0 ) )
628  {
629  wasp_locs = level.zm_loc_types[ "wasp_location" ];
630 
631  if ( wasp_locs.size == 0 )
632  {
633  //none - use backup global pool - just find first within range
635  return ‪wasp_find_closest_in_global_pool( favorite_enemy );
636  }
637 
638  // if the old one is in the desired range, return it so we get bigger swarms
639  if ( isdefined( level.old_wasp_spawn ) )
640  {
641  dist_squared = DistanceSquared( level.old_wasp_spawn.origin, favorite_enemy.origin );
642  if ( dist_squared > ( ‪WASP_SPAWN_DIST_MIN * ‪WASP_SPAWN_DIST_MIN ) && dist_squared < ( ‪WASP_SPAWN_DIST_MAX * ‪WASP_SPAWN_DIST_MAX ) )
643  {
644  return level.old_wasp_spawn;
645  }
646  }
647 
648  // Find a spawn point that's in the min/max range and use that
649  foreach ( loc in wasp_locs )
650  {
651  dist_squared = DistanceSquared( loc.origin, favorite_enemy.origin );
652  if ( dist_squared > ( ‪WASP_SPAWN_DIST_MIN * ‪WASP_SPAWN_DIST_MIN ) && dist_squared < ( ‪WASP_SPAWN_DIST_MAX * ‪WASP_SPAWN_DIST_MAX ) )
653  {
654  level.old_wasp_spawn = loc;
655  return loc;
656  }
657  }
658  }
659 
660  /* If we still haven't found a valid spot or we are using open spawing, find something suitable using the navvolume */
661 
662  const spawn_height_min = 40;
663  const spawn_height_max = 100;
664  const spawn_dist_min = 300;
665 
666  switch( level.players.size )
667  {
668  case 4:
669  spawn_dist_max = 600;
670  break;
671 
672  case 3:
673  spawn_dist_max = 700;
674  break;
675 
676  case 2:
677  spawn_dist_max = 900;
678  break;
679 
680  default:
681  case 1:
682  spawn_dist_max = 1200;
683  break;
684  }
685 
686  queryResult = PositionQuery_Source_Navigation(
687  favorite_enemy.origin + ( 0, 0, RandomIntRange( spawn_height_min, spawn_height_max ) ),
688  spawn_dist_min,
689  spawn_dist_max,
690  10,
691  10,
692  "navvolume_small" );
693 
694  a_points = array::randomize( queryResult.data );
695 
696  foreach ( point in a_points )
697  {
698  if ( BulletTracePassed( point.origin, favorite_enemy.origin, false, favorite_enemy ) )
699  {
700  level.old_wasp_spawn = point;
701  return point;
702  }
703  }
704 
705  // Failsafe
706  return a_points[0];
707 }
708 
710 {
711  // First check if we have a priority target
712  if( level.a_wasp_priority_targets.size > 0 )
713  {
714  e_enemy = level.a_wasp_priority_targets[0];
715  if( isdefined(e_enemy) )
716  {
717  ArrayRemoveValue( level.a_wasp_priority_targets, e_enemy );
718  return( e_enemy );
719  }
720  }
721 
722  // Check for custom wasp spawner selection
723  if ( isdefined( level.fn_custom_wasp_favourate_enemy ) )
724  {
725  e_enemy = [[ level.fn_custom_wasp_favourate_enemy ]]();
726  return( e_enemy );
727  }
728 
730 
731  return target;
732 }
733 
734 
736 {
737  players = getplayers();
738 
739  level.wasp_health = level.round_number * ‪N_WASP_HEALTH_INCREASE;
740 
741  if( level.wasp_health > ‪N_WASP_HEALTH_MAX )
742  {
743  level.wasp_health = ‪N_WASP_HEALTH_MAX;
744  }
745 }
746 
747 
749 {
750  level endon( "restart_round" );
751  level endon( "kill_round" );
752 
753  if( level ‪flag::get("wasp_round" ) )
754  {
755  level ‪flag::wait_till( "wasp_round_in_progress" );
756 
757  level ‪flag::wait_till_clear( "wasp_round_in_progress" );
758  }
759 }
760 
762 {
763  level.wasp_round_count = 1;
764 
765  // PI_CHANGE_BEGIN - JMA - making wasp rounds random between round 5 thru 7
766  // NOTE: RandomIntRange returns a random integer r, where min <= r < max
767 
768  // Start Round
769  level.next_wasp_round = level.round_number + RandomIntRange( 4, 6 );
770  // PI_CHANGE_END
771 
772  old_spawn_func = level.round_spawn_func;
773  old_wait_func = level.round_wait_func;
774 
775  while ( 1 )
776  {
777  level waittill ( "between_round_over" );
778 
779  /#
780  if( GetDvarInt( "force_wasp" ) > 0 )
781  {
782  level.next_wasp_round = level.round_number;
783  }
784  #/
785 
786  if ( level.round_number == level.next_wasp_round )
787  {
788  level.sndMusicSpecialRound = true;
789  old_spawn_func = level.round_spawn_func;
790  old_wait_func = level.round_wait_func;
792  level.round_spawn_func =&‪wasp_round_spawning;
793  level.round_wait_func = &‪wasp_round_wait_func;
794 
795  // Get the next wasp round
796  if( isdefined(level.zm_custom_get_next_wasp_round) )
797  {
798  level.next_wasp_round = [[level.zm_custom_get_next_wasp_round]]();
799  }
800  else
801  {
802  // Setup so this alternates with Raps rounds... probably a better way to do this
803  level.next_wasp_round = 5 + (level.wasp_round_count * 10) + RandomIntRange( -1, 1 );
804  }
805 
806  /#
807  GetPlayers()[0] iprintln( "Next wasp round: " + level.next_wasp_round );
808  #/
809  }
810  else if ( level ‪flag::get( "wasp_round" ) )
811  {
813  level.round_spawn_func = old_spawn_func;
814  level.round_wait_func = old_wait_func;
815  level.wasp_round_count += 1;
816  }
817  }
818 }
819 
820 
822 {
823  level ‪flag::set( "wasp_round" );
824  level ‪flag::set( "special_round" );
825 
826  if(!isdefined (level.waspround_nomusic))
827  {
828  level.waspround_nomusic = 0;
829  }
830  level.waspround_nomusic = 1;
831  level notify( "wasp_round_starting" );
832  level thread ‪zm_audio::sndMusicSystem_PlayState( "parasite_start" );
833 
834  if(isdefined(level.wasp_melee_range))
835  {
836  SetDvar( "ai_meleeRange", level.wasp_melee_range );
837  }
838  else
839  {
840  SetDvar( "ai_meleeRange", 100 );
841  }
842 }
843 
844 
846 {
847  level ‪flag::clear( "wasp_round" );
848  level ‪flag::clear( "special_round" );
849 
850  if(!isdefined (level.waspround_nomusic))
851  {
852  level.waspround_nomusic = 0;
853  }
854  level.waspround_nomusic = 0;
855  level notify( "wasp_round_ending" );
856 
857  SetDvar( "ai_meleeRange", level.melee_range_sav );
858  SetDvar( "ai_meleeWidth", level.melee_width_sav );
859  SetDvar( "ai_meleeHeight", level.melee_height_sav );
860 }
861 
862 
864 {
865  self playlocalsound( "zmb_wasp_round_start" );
866  variation_count =5;
867 
868  wait(4.5);
869 
870  players = getplayers();
871  num = RandomIntRange(0,players.size);
872  players[num] ‪zm_audio::create_and_play_dialog( "general", "wasp_spawn" );
873 }
874 
875 function ‪wasp_init()
876 {
877  self.targetname = "zombie_wasp";
878  self.script_noteworthy = undefined;
879  self.animname = "zombie_wasp";
880  self.ignoreall = true;
881  self.ignoreme = true; // don't let attack wasp give chase until the wolf is visible
882  self.allowdeath = true; // allows death during animscripted calls
883  self.allowpain = false;
884  self.no_gib = true; //gibbing disabled for now
885  self.is_zombie = true; // needed for melee.gsc in the animscripts
886  // out both legs and then the only allowed stance should be prone.
887  self.gibbed = false;
888  self.head_gibbed = false;
889  self.default_goalheight = 40;
890  self.ignore_inert = true;
891  self.no_eye_glow = true;
892 
893  self.lightning_chain_immune = true;
894 
895  self.holdfire = false;
896 
897  // self.disableArrivals = true;
898  // self.disableExits = true;
899  self.grenadeawareness = 0;
900  self.badplaceawareness = 0;
901 
902  self.ignoreSuppression = true;
903  self.suppressionThreshold = 1;
904  self.noDodgeMove = true;
905  self.dontShootWhileMoving = true;
906  self.pathenemylookahead = 0;
907 
908  self.badplaceawareness = 0;
909  self.chatInitialized = false;
910  self.missingLegs = false;
911  self.isdog = false;
912  self.teslafxtag = "tag_origin";
913 
914  self.grapple_type = ‪GRAPPLE_TYPE_PULLENTIN;
915  self SetGrapplableType( self.grapple_type );
916 
917  self.team = level.zombie_team;
918 
919  self.sword_kill_power = ‪ZM_WASP_SWORD_KILL_POWER;
920 
922 /*
923  self AllowPitchAngle( 1 );
924  self setPitchOrient();
925  self setAvoidanceMask( "avoid none" );
926 
927  self PushActors( true );
928 */
929  health_multiplier = 1.0;
930  if ( GetDvarString( "scr_wasp_health_walk_multiplier" ) != "" )
931  {
932  health_multiplier = GetDvarFloat( "scr_wasp_health_walk_multiplier" );
933  }
934 
935  self.maxhealth = int( level.wasp_health * health_multiplier );
936  if( IsDefined(level.a_zombie_respawn_health[ self.archetype ] ) && level.a_zombie_respawn_health[ self.archetype ].size > 0 )
937  {
938  self.health = level.a_zombie_respawn_health[ self.archetype ][0];
939  ArrayRemoveValue(level.a_zombie_respawn_health[ self.archetype ], level.a_zombie_respawn_health[ self.archetype ][0]);
940  }
941  else
942  {
943  self.health = int( level.wasp_health * health_multiplier );
944  }
945 
946  self thread ‪wasp_run_think();
947  self thread ‪watch_player_melee();
948 
949  self SetInvisibleToAll();
950 
951  self thread ‪wasp_death();
952  self thread ‪wasp_cleanup_failsafe();
953 
954  level thread ‪zm_spawner::zombie_death_event( self );
956 
957  self.thundergun_knockdown_func =&‪wasp_thundergun_knockdown;
958 
959  self ‪zm_spawner::zombie_history( "zombie_wasp_spawn_init -> Spawned = " + self.origin );
960 
961  if ( isdefined(level.achievement_monitor_func) )
962  {
963  self [[level.achievement_monitor_func]]();
964  }
965 }
966 
967 
969 {
970  self endon( "death" );
971 
972  n_damage = Int( self.maxhealth * 0.5 );
973  self DoDamage( n_damage, self.origin, e_player );
974 }
975 
976 #define N_WASP_NOT_MOVED_TIMEOUT 20
977 #define N_WASP_MAX_LIFE_TIMEOUT 150
978 #define N_WASP_HAS_MOVE_DIST 100
979 #define N_MSEC 1000
980 
981 // Wasp failsafe cleanup conditions
983 {
984  self endon( "death" );
985 
986  n_wasp_created_time = GetTime();
987 
988  n_check_time = n_wasp_created_time;
989  v_check_position = self.origin;
990 
991  while( true )
992  {
993  n_current_time = GetTime();
994 
995  if( ‪IS_TRUE( level.bzm_worldPaused ) )
996  {
997  n_check_time = n_current_time; //reset the stuck time when world is paused
998  wait 1;
999  continue;
1000  }
1001 
1002  // If the wasp has moved he is not stuck, so reset the position to check against
1003  n_dist = Distance( v_check_position, self.origin );
1004  if( n_dist > ‪N_WASP_HAS_MOVE_DIST )
1005  {
1006  n_check_time = n_current_time;
1007  v_check_position = self.origin;
1008  }
1009 
1010  // Failsafe 1: If the wasp hasn't significantly moved for a while, kill him
1011  else
1012  {
1013  n_delta_time = ( n_current_time - n_check_time ) / ‪N_MSEC;
1014  if( n_delta_time >= ‪N_WASP_NOT_MOVED_TIMEOUT )
1015  {
1016  break;
1017  }
1018  }
1019 
1020  // Failsafe 2: If the wasp has been alive for too long, kill him
1021  n_delta_time = ( n_current_time - n_wasp_created_time ) / ‪N_MSEC;
1022  if( n_delta_time >= ‪N_WASP_MAX_LIFE_TIMEOUT )
1023  {
1024  break;
1025  }
1026 
1027  wait 1;
1028  }
1029 
1030  self DoDamage( self.health + 100, self.origin );
1031 }
1032 
1033 function ‪wasp_death()
1034 {
1035  self waittill( "death", attacker );
1036 
1037  if ( ‪get_current_wasp_count() == 0 && level.zombie_total == 0 )
1038  {
1039  // Can be overridded for mixed AI rounds, in this case the last AI may be a wasp or raps etc...
1040  if( ( !isdefined(level.zm_ai_round_over) || [[level.zm_ai_round_over]]() ) )
1041  {
1042  level.last_ai_origin = self.origin;
1043  level notify( "last_ai_down", self );
1044  }
1045  }
1046 
1047  // score
1048  if( IsPlayer( attacker ) )
1049  {
1050  if( ‪IS_TRUE(attacker.on_train) )
1051  {
1052  attacker notify( "wasp_train_kill" );
1053  }
1054 
1055  attacker ‪zm_score::player_add_points( "death_wasp", ‪N_WASP_KILL_POINTS ); // points awarded
1056 
1057  if( isdefined(level.hero_power_update))
1058  {
1059  [[level.hero_power_update]](attacker, self);
1060  }
1061 
1062  if( RandomIntRange(0,100) >= 80 )
1063  {
1064  attacker ‪zm_audio::create_and_play_dialog( "kill", "hellhound" );
1065  }
1066 
1067  //stats
1068  attacker ‪zm_stats::increment_client_stat( "zwasp_killed" );
1069  attacker ‪zm_stats::increment_player_stat( "zwasp_killed" );
1070 
1071  }
1072 
1073  // switch to inflictor when SP DoDamage supports it
1074  if( isdefined( attacker ) && isai( attacker ) )
1075  {
1076  attacker notify( "killed", self );
1077  }
1078 
1079  // sound
1080  self stoploopsound();
1081 }
1082 
1083 
1084 // this is where zombies go into attack mode, and need different attributes set up
1086 {
1087  self ‪zm_spawner::zombie_history( "zombie_setup_attack_properties()" );
1088 
1089  self thread ‪wasp_behind_audio();
1090 
1091  // allows zombie to attack again
1092  self.ignoreall = false;
1093 
1094  //self.pathEnemyFightDist = 64;
1095  self.meleeAttackDist = 64;
1096 
1097  // turn off transition anims
1098  self.disableArrivals = true;
1099  self.disableExits = true;
1100 
1101  if( level.wasp_round_count == 2 )
1102  {
1103  self ‪ai::set_behavior_attribute( "firing_rate", "medium" );
1104  }
1105  else if( level.wasp_round_count > 2 )
1106  {
1107  self ‪ai::set_behavior_attribute( "firing_rate", "fast" );
1108  }
1109 }
1110 
1111 
1112 //COLLIN'S Audio Scripts
1114 {
1115  self waittill("death");
1116  self stopsounds();
1117 }
1118 
1120 {
1121  self thread ‪stop_wasp_sound_on_death();
1122 
1123  self endon("death");
1124  self ‪util::waittill_any( "wasp_running", "wasp_combat" );
1125 
1126 // self PlaySound( "zmb_hellhound_vocals_close" );
1127  wait( 3 );
1128 
1129  while(1)
1130  {
1131  players = GetPlayers();
1132  for(i=0;i<players.size;i++)
1133  {
1134  waspAngle = AngleClamp180( vectorToAngles( self.origin - players[i].origin )[1] - players[i].angles[1] );
1135 
1136  if(isAlive(players[i]) && !isdefined(players[i].revivetrigger))
1137  {
1138  if ((abs(waspAngle) > 90) && distance2d(self.origin,players[i].origin) > 100)
1139  {
1140 // self playsound( "zmb_hellhound_vocals_close" );
1141  wait( 3 );
1142  }
1143  }
1144  }
1145 
1146  wait(.75);
1147  }
1148 }
1149 
1150 
1151 //
1152 // Allows wasp to be spawned independent of the round spawning
1169 function ‪special_wasp_spawn( n_to_spawn = 1, spawn_point, n_radius = 32, n_half_height = 32, b_non_round, spawn_fx = true, b_return_ai = false, spawner_override = undefined )
1170 {
1171  wasp = GetEntArray( "zombie_wasp", "targetname" );
1172 
1173  if ( isdefined( wasp ) && wasp.size >= 9 )
1174  {
1175  return false;
1176  }
1177 
1178  count = 0;
1179  while ( count < n_to_spawn )
1180  {
1181  //update the player array.
1182  players = GetPlayers();
1183  favorite_enemy = ‪get_favorite_enemy();
1184  spawn_enemy = favorite_enemy;
1185  if( !IsDefined( spawn_enemy ) )
1186  {
1187  spawn_enemy = players[0];
1188  }
1189 
1190  // Overrides standard parasite spawning
1191  if ( isdefined( level.wasp_spawn_func ) )
1192  {
1193  spawn_point = [[level.wasp_spawn_func]]( spawn_enemy );
1194  }
1195 
1196  // Rarely spawn_point will be undefined
1197  while ( !isdefined( spawn_point ) )
1198  {
1199  if ( !isdefined( spawn_point ) )
1200  {
1201  spawn_point = ‪wasp_spawn_logic( spawn_enemy );
1202  }
1203 
1204  if ( isdefined( spawn_point ) )
1205  {
1206  break;
1207  }
1208 
1209  wait( 0.05 );
1210  }
1211 
1212  spawner = level.wasp_spawners[0];
1213 
1214  if( isDefined( spawner_override))
1215  {
1216  spawner = spawner_override;
1217  }
1218 
1219  ai = ‪zombie_utility::spawn_zombie( spawner );
1220 
1221  v_spawn_origin = spawn_point.origin;
1222 
1223  if ( isdefined( ai ) )
1224  {
1225  // just try to path strait to a nearby position on the path
1226  queryResult = PositionQuery_Source_Navigation( v_spawn_origin, 0, n_radius, n_half_height, 15, "navvolume_small" );
1227  if( queryResult.data.size )
1228  {
1229  point = queryResult.data[ randomint( queryResult.data.size ) ];
1230  v_spawn_origin = point.origin;
1231  }
1232 
1233  ai ‪parasite::set_parasite_enemy( favorite_enemy );
1234  ai.does_not_count_to_round = b_non_round;
1235  level thread ‪wasp_spawn_init( ai, v_spawn_origin, spawn_fx );
1236  count++;
1237  }
1238 
1239  wait level.zombie_vars[ "zombie_spawn_delay" ];
1240  }
1241 
1242  if ( b_return_ai )
1243  {
1244  return ai;
1245  }
1246 
1247  return true;
1248 }
1249 
1251 {
1252  self endon( "death" );
1253 
1254  // these should go back in when the stalking stuff is put back in, the visible check will do for now
1255  //self util::waittill_any( "wasp_running", "wasp_combat" );
1256  //self playsound( "zwasp_close" );
1257  self waittill( "visible" );
1258 
1259  // decrease health
1260  if ( self.health > level.wasp_health )
1261  {
1262  self.maxhealth = level.wasp_health;
1263  self.health = level.wasp_health;
1264  }
1265 
1266  //Check to see if the enemy is not valid anymore
1267  while( 1 )
1268  {
1269  if( !‪zm_utility::is_player_valid(self.favoriteenemy) )
1270  {
1271  //We are targetting an invalid player - select another one
1272  //self.favoriteenemy = get_favorite_enemy();
1273  }
1274  wait( 0.2 );
1275  }
1276 }
1277 
1278 #define MELEE_RANGE_SQ (72 * 72)
1279 #define MELEE_RANGE_Z (64)
1280 #define MELEE_VIEW_DOT 0.5
1281 
1283 {
1284  self endon( "death" );
1285  self waittill( "visible" );
1286 
1287  while( IsDefined(self) )
1288  {
1289  level waittill( "player_melee", player, weapon );
1290 
1291  peye = player GetEye();
1292  dist2 = Distance2DSquared( peye, self.origin );
1293  if ( dist2 > ‪MELEE_RANGE_SQ )
1294  continue;
1295 
1296  if ( abs( peye[2] - self.origin[2]) > ‪MELEE_RANGE_Z )
1297  continue;
1298 
1299  pfwd = player GetWeaponForwardDir();
1300  tome = self.origin - peye;
1301  tome = VectorNormalize( tome );
1302  dot = VectorDot( pfwd, tome );
1303  if ( dot < ‪MELEE_VIEW_DOT )
1304  continue;
1305 
1306  ‪damage = 150;
1307  if ( IsDefined(weapon) )
1308  ‪damage = weapon.meleedamage;
1309 
1310  self DoDamage( ‪damage, peye, player, player, "none", "MOD_MELEE", 0, weapon );
1311  }
1312 }
1313 
1315 {
1316  self endon( "disconnect" );
1317  for ( ;; )
1318  {
1319  self waittill( "weapon_melee", weapon );
1320  level notify( "player_melee", self, weapon );
1321  }
1322 }
1323 
1325 {
1326  self endon( "death" );
1327  self endon( "wasp_running" );
1328  self endon( "wasp_combat" );
1329 
1330  while(1)
1331  {
1332 // self playsound( "zmb_hellhound_vocals_amb" );
1333  wait randomfloatrange(3,6);
1334  }
1335 }
1336 
1337 function ‪wasp_add_to_spawn_pool( optional_player_target )
1338 {
1339  if( isdefined(optional_player_target) )
1340  {
1341  ‪array::add( level.a_wasp_priority_targets, optional_player_target );
1342  }
1343  level.zombie_total++;
1344 }
1345 
‪wasp_health_increase
‪function wasp_health_increase()
Definition: _zm_ai_wasp.gsc:735
‪N_WASP_HEALTH_INCREASE
‪#define N_WASP_HEALTH_INCREASE
Definition: _zm_ai_wasp.gsc:53
‪get_favorite_enemy
‪function get_favorite_enemy()
Definition: _zm_ai_wasp.gsc:709
‪activate
‪function activate()
Definition: traps_shared.gsc:655
‪wasp_find_closest_in_global_pool
‪function wasp_find_closest_in_global_pool(favorite_enemy)
Definition: _zm_ai_wasp.gsc:603
‪get_current_zone
‪function get_current_zone(return_zone)
Definition: _zm_utility.gsc:3614
‪WASP_SPAWN_DIST_MIN
‪#define WASP_SPAWN_DIST_MIN
Definition: _zm_ai_wasp.gsc:622
‪increment_client_stat
‪function increment_client_stat(stat_name, include_gametype)
Definition: _zm_stats.gsc:389
‪ready_to_spawn_wasp
‪function ready_to_spawn_wasp()
Definition: _zm_ai_wasp.gsc:399
‪ZM_WASP_VISION_LERP_COUNT
‪#define ZM_WASP_VISION_LERP_COUNT
Definition: _zm_ai_wasp.gsh:2
‪wasp_round_start
‪function wasp_round_start()
Definition: _zm_ai_wasp.gsc:821
‪play_wasp_round
‪function play_wasp_round()
Definition: _zm_ai_wasp.gsc:863
‪wasp_round_spawning
‪function wasp_round_spawning()
Definition: _zm_ai_wasp.gsc:162
‪increment_player_stat
‪function increment_player_stat(stat_name)
Definition: _zm_stats.gsc:369
‪player_add_points
‪function player_add_points(event, mod, hit_location, is_dog, zombie_team, damage_weapon)
Definition: _zm_score.gsc:129
‪waspDamage
‪function waspDamage(inflictor, attacker, damage, dFlags, mod, weapon, point, dir, hitLoc, offsetTime, boneIndex, modelIndex)
Definition: _zm_ai_wasp.gsc:389
‪specific_powerup_drop
‪function specific_powerup_drop(powerup_name, drop_spot, powerup_team, powerup_location, pickup_delay, powerup_player, b_stay_forever)
Definition: _zm_powerups.gsc:688
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪wasp_run_think
‪function wasp_run_think()
Definition: _zm_ai_wasp.gsc:1250
‪enable_wasp_rounds
‪function enable_wasp_rounds()
Definition: _zm_ai_wasp.gsc:105
‪wasp_thundergun_knockdown
‪function wasp_thundergun_knockdown(e_player, gib)
Definition: _zm_ai_wasp.gsc:968
‪set_parasite_enemy
‪function set_parasite_enemy(enemy)
Definition: _parasite.gsc:167
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪create_global_wasp_spawn_locations_list
‪function create_global_wasp_spawn_locations_list()
Definition: _zm_ai_wasp.gsc:584
‪MELEE_VIEW_DOT
‪#define MELEE_VIEW_DOT
Definition: _zm_ai_wasp.gsc:1280
‪N_WASP_MAX_LIFE_TIMEOUT
‪#define N_WASP_MAX_LIFE_TIMEOUT
Definition: _zm_ai_wasp.gsc:977
‪ZM_WASP_RING_EXIT_DURATION
‪#define ZM_WASP_RING_EXIT_DURATION
Definition: _zm_ai_wasp.gsh:8
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪N_MSEC
‪#define N_MSEC
Definition: _zm_ai_wasp.gsc:979
‪WASP_SPAWN_DIST_MAX
‪#define WASP_SPAWN_DIST_MAX
Definition: _zm_ai_wasp.gsc:623
‪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
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪zombie_setup_attack_properties_wasp
‪function zombie_setup_attack_properties_wasp()
Definition: _zm_ai_wasp.gsc:1085
‪gib
‪function gib(attacker)
Definition: _amws.gsc:1072
‪add
‪function add(entity, dyingplayer, team, timeout)
Definition: _deathicons.gsc:43
‪register_immunity
‪function register_immunity(name, archetype, immune_trigger, immune_result_direct, immune_result_indirect)
Definition: aat_shared.gsc:305
‪N_NUM_WASPS_PER_ROUND
‪#define N_NUM_WASPS_PER_ROUND
Definition: _zm_ai_wasp.gsc:49
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: skeleton.gsc:256
‪N_WASP_NOT_MOVED_TIMEOUT
‪#define N_WASP_NOT_MOVED_TIMEOUT
Definition: _zm_ai_wasp.gsc:976
‪wasp_round_wait_func
‪function wasp_round_wait_func()
Definition: _zm_ai_wasp.gsc:748
‪ARCHETYPE_PARASITE
‪#define ARCHETYPE_PARASITE
Definition: archetype_shared.gsh:38
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪wasp_add_to_spawn_pool
‪function wasp_add_to_spawn_pool(optional_player_target)
Definition: _zm_ai_wasp.gsc:1337
‪spawn_wasp
‪function spawn_wasp()
Definition: _zm_ai_wasp.gsc:255
‪wasp_death
‪function wasp_death()
Definition: _zm_ai_wasp.gsc:1033
‪parasite_round_fx
‪function parasite_round_fx()
Definition: _zm_ai_wasp.gsc:369
‪ZM_WASP_SWORD_KILL_POWER
‪#define ZM_WASP_SWORD_KILL_POWER
Definition: _zm_ai_wasp.gsh:3
‪DEFAULT
‪#define DEFAULT(__var, __default)
Definition: shared.gsh:270
‪show_hit_marker
‪function show_hit_marker()
Definition: _zm_ai_wasp.gsc:378
‪wasp_spawner_init
‪function wasp_spawner_init()
Definition: _zm_ai_wasp.gsc:118
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪ZM_WASP_RING_ENTER_DURATION
‪#define ZM_WASP_RING_ENTER_DURATION
Definition: _zm_ai_wasp.gsh:6
‪sndMusicSystem_PlayState
‪function sndMusicSystem_PlayState(state)
Definition: _zm_audio.gsc:1042
‪wasp_behind_audio
‪function wasp_behind_audio()
Definition: _zm_ai_wasp.gsc:1119
‪zombie_history
‪function zombie_history(msg)
Definition: _zm_spawner.gsc:2863
‪get_parasite_enemy
‪function get_parasite_enemy()
Definition: _parasite.gsc:129
‪N_WASP_HAS_MOVE_DIST
‪#define N_WASP_HAS_MOVE_DIST
Definition: _zm_ai_wasp.gsc:978
‪increment_to_player
‪function increment_to_player(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:169
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪wasp_round_stop
‪function wasp_round_stop()
Definition: _zm_ai_wasp.gsc:845
‪special_wasp_spawn
‪function special_wasp_spawn(n_to_spawn=1, spawn_point, n_radius=32, n_half_height=32, b_non_round, spawn_fx=true, b_return_ai=false, spawner_override=undefined)
Definition: _zm_ai_wasp.gsc:1169
‪ZM_AAT_DEAD_WIRE_NAME
‪#define ZM_AAT_DEAD_WIRE_NAME
Definition: aat_zm.gsh:5
‪ZM_WASP_RING_LOOP_DURATION
‪#define ZM_WASP_RING_LOOP_DURATION
Definition: _zm_ai_wasp.gsh:7
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪wasp_round_aftermath
‪function wasp_round_aftermath()
Definition: _zm_ai_wasp.gsc:414
‪wasp_cleanup_failsafe
‪function wasp_cleanup_failsafe()
Definition: _zm_ai_wasp.gsc:982
‪wasp_init
‪function wasp_init()
Definition: _zm_ai_wasp.gsc:875
‪ZM_AAT_TURNED_NAME
‪#define ZM_AAT_TURNED_NAME
Definition: aat_zm.gsh:8
‪N_WASP_HEALTH_MAX
‪#define N_WASP_HEALTH_MAX
Definition: _zm_ai_wasp.gsc:54
‪enemy_death_detection
‪function enemy_death_detection()
Definition: _zm_spawner.gsc:134
‪spawn_zombie
‪function spawn_zombie(spawner, target_name, spawn_point, round_number)
Definition: zombie_utility.gsc:1454
‪wasp_round_tracker
‪function wasp_round_tracker()
Definition: _zm_ai_wasp.gsc:761
‪wasp_stalk_audio
‪function wasp_stalk_audio()
Definition: _zm_ai_wasp.gsc:1324
‪N_WASP_KILL_POINTS
‪#define N_WASP_KILL_POINTS
Definition: _zm_ai_wasp.gsc:55
‪watch_player_melee_events
‪function watch_player_melee_events()
Definition: _zm_ai_wasp.gsc:1314
‪register_info
‪function register_info(type, name, version, lerp_step_count)
Definition: visionset_mgr_shared.csc:334
‪zombie_death_event
‪function zombie_death_event(zombie)
Definition: _zm_spawner.gsc:2195
‪N_MAX_WASPS
‪#define N_MAX_WASPS
Definition: _zm_ai_wasp.gsc:43
‪GROUNDPOS
‪#define GROUNDPOS(__e, _origin)
Definition: shared.gsh:368
‪get_current_wasp_count
‪function get_current_wasp_count()
Definition: _zm_ai_wasp.gsc:148
‪WAIT_ABOUT
‪#define WAIT_ABOUT(__time)
Definition: shared.gsh:436
‪add_callback
‪function add_callback(event, func, obj)
Definition: callbacks_shared.csc:93
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪ZM_WASP_VISION_OVERLAY_PRIORITY
‪#define ZM_WASP_VISION_OVERLAY_PRIORITY
Definition: _zm_ai_wasp.gsh:1
‪wasp_spawn_logic
‪function wasp_spawn_logic(favorite_enemy)
Definition: _zm_ai_wasp.gsc:625
‪set_behavior_attribute
‪function set_behavior_attribute(attribute, value)
Definition: ai_shared.gsc:159
‪N_SPAWN_HEIGHT_MIN
‪#define N_SPAWN_HEIGHT_MIN
Definition: _zm_ai_wasp.gsc:52
‪ramp_in_out_thread
‪function ramp_in_out_thread(ramp_in, full_period, ramp_out)
Definition: visionset_mgr_shared.gsc:266
‪watch_player_melee
‪function watch_player_melee()
Definition: _zm_ai_wasp.gsc:1282
‪stop_wasp_sound_on_death
‪function stop_wasp_sound_on_death()
Definition: _zm_ai_wasp.gsc:1113
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪create_and_play_dialog
‪function create_and_play_dialog(category, subcategory, force_variant)
Definition: _zm_audio.gsc:603
‪is_spawner_targeted_by_blocker
‪function is_spawner_targeted_by_blocker(ent)
Definition: _zm_spawner.gsc:164
‪ZM_AAT_BLAST_FURNACE_NAME
‪#define ZM_AAT_BLAST_FURNACE_NAME
Definition: aat_zm.gsh:4
‪GRAPPLE_TYPE_PULLENTIN
‪#define GRAPPLE_TYPE_PULLENTIN
Definition: grapple.gsh:6
‪wasp_spawn_init
‪function wasp_spawn_init(ai, origin, should_spawn_fx=true)
Definition: _zm_ai_wasp.gsc:526
‪on_connect
‪function on_connect()
Definition: _arena.gsc:20
‪parasite_initialize
‪function parasite_initialize()
Definition: _parasite.gsc:234
‪wait_till_clear
‪function wait_till_clear(str_flag)
Definition: flag_shared.csc:248
‪MELEE_RANGE_Z
‪#define MELEE_RANGE_Z
Definition: _zm_ai_wasp.gsc:1279
‪ZM_AAT_THUNDER_WALL_NAME
‪#define ZM_AAT_THUNDER_WALL_NAME
Definition: aat_zm.gsh:7
‪ZM_AAT_FIRE_WORKS_NAME
‪#define ZM_AAT_FIRE_WORKS_NAME
Definition: aat_zm.gsh:6
‪init
‪function init()
Definition: _zm_ai_wasp.gsc:60
‪MELEE_RANGE_SQ
‪#define MELEE_RANGE_SQ
Definition: _zm_ai_wasp.gsc:1278
‪N_SWARM_SIZE
‪#define N_SWARM_SIZE
Definition: _zm_ai_wasp.gsc:46
‪N_MAX_WASPS_PER_PLAYER
‪#define N_MAX_WASPS_PER_PLAYER
Definition: _zm_ai_wasp.gsc:44
‪parasite_drop_item
‪function parasite_drop_item(v_parasite_origin)
Definition: _zm_ai_wasp.gsc:446
‪PARASITE_ROUND_RING_FX
‪#define PARASITE_ROUND_RING_FX
Definition: _zm_ai_wasp.gsh:9
‪N_WASP_PLAYER_SCALAR
‪#define N_WASP_PLAYER_SCALAR
Definition: _zm_ai_wasp.gsc:50
‪ZM_WASP_ROUND_VISIONSET
‪#define ZM_WASP_ROUND_VISIONSET
Definition: _zm_ai_wasp.gsh:4
‪PlayFx
‪function PlayFx(name)
Definition: _counteruav.gsc:390