‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_zm_ai_dogs.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\clientfield_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 
12 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\version.gsh;
15 
16 #insert scripts\shared\aat_zm.gsh;
17 #using scripts\zm\_util;
18 #using scripts\zm\_zm;
19 #using scripts\zm\_zm_audio;
20 #using scripts\zm\_zm_net;
21 #using scripts\zm\_zm_powerups;
22 #using scripts\zm\_zm_score;
23 #using scripts\zm\_zm_spawner;
24 #using scripts\zm\_zm_stats;
25 #using scripts\zm\_zm_utility;
26 
27 #using scripts\shared\ai\zombie_utility;
28 
29 #insert scripts\zm\_zm_utility.gsh;
30 
31 #precache( "fx", "zombie/fx_dog_lightning_buildup_zmb" );
32 #precache( "fx", "zombie/fx_dog_eyes_zmb" );
33 #precache( "fx", "zombie/fx_dog_explosion_zmb" );
34 #precache( "fx", "zombie/fx_dog_fire_trail_zmb" );
35 
36 #define ZM_DOGS_HERO_WEAPON_KILL_POWER 2
37 
38 #namespace zm_ai_dogs;
39 
40 ‪REGISTER_SYSTEM( "zm_ai_dogs", &‪__init__, "aat" )
41 
42 function ‪__init__()
43 {
44  ‪clientfield::register( "actor", "dog_fx", ‪VERSION_SHIP, 1, "int" );
45 
47  ‪init();
48 }
49 
50 function ‪init()
51 {
52  level.dogs_enabled = true;
53  level.dog_rounds_enabled = false;
54  level.dog_round_count = 1;
55 
56  level.dog_spawners = [];
57 
58  //utility::flag_init( "dog_round" );
59  level ‪flag::init( "dog_clips" );
60 
61  if ( GetDvarString( "zombie_dog_animset" ) == "" )
62  {
63  SetDvar( "zombie_dog_animset", "zombie" );
64  }
65 
66  if ( GetDvarString( "scr_dog_health_walk_multiplier" ) == "" )
67  {
68  SetDvar( "scr_dog_health_walk_multiplier", "4.0" );
69  }
70 
71  if ( GetDvarString( "scr_dog_run_distance" ) == "" )
72  {
73  SetDvar( "scr_dog_run_distance", "500" );
74  }
75 
76  level.melee_range_sav = GetDvarString( "ai_meleeRange" );
77  level.melee_width_sav = GetDvarString( "ai_meleeWidth" );
78  level.melee_height_sav = GetDvarString( "ai_meleeHeight" );
79 
80  ‪zombie_utility::set_zombie_var( "dog_fire_trail_percent", 50 );
81 
82  // AAT IMMUNITIES
88 
89  // Init dog targets - mainly for testing purposes.
90  // If you spawn a dog without having a dog round, you'll get SREs on hunted_by.
92 
93  level thread ‪dog_clip_monitor();
94 }
95 
96 function ‪init_dog_fx()
97 {
98  level._effect[ "lightning_dog_spawn" ] = "zombie/fx_dog_lightning_buildup_zmb";
99  level._effect[ "dog_eye_glow" ] = "zombie/fx_dog_eyes_zmb";
100  level._effect[ "dog_gib" ] = "zombie/fx_dog_explosion_zmb";
101  level._effect[ "dog_trail_fire" ] = "zombie/fx_dog_fire_trail_zmb";
102 }
103 
104 //
105 // If you want to enable dog rounds, then call this.
106 // Specify an override func if needed.
108 {
109  level.dog_rounds_enabled = true;
110 
111  if( !isdefined( level.dog_round_track_override ) )
112  {
113  level.dog_round_track_override =&‪dog_round_tracker;
114  }
115 
116  level thread [[level.dog_round_track_override]]();
117 }
118 
119 
121 {
122  level.dog_spawners = getEntArray( "zombie_dog_spawner", "script_noteworthy" );
123  later_dogs = getentarray("later_round_dog_spawners", "script_noteworthy" );
124  level.dog_spawners = ArrayCombine( level.dog_spawners, later_dogs, true, false );
125 
126  if( level.dog_spawners.size == 0 )
127  {
128  return;
129  }
130 
131  for( i = 0; i < level.dog_spawners.size; i++ )
132  {
133  if ( ‪zm_spawner::is_spawner_targeted_by_blocker( level.dog_spawners[i] ) )
134  {
135  level.dog_spawners[i].is_enabled = false;
136  }
137  else
138  {
139  level.dog_spawners[i].is_enabled = true;
140  level.dog_spawners[i].script_forcespawn = true;
141  }
142  }
143 
144  assert( level.dog_spawners.size > 0 );
145  level.dog_health = 100;
146 
147  array::thread_all( level.dog_spawners,&‪spawner::add_spawn_function,&‪dog_init );
148 }
149 
150 
152 {
153  level endon( "intermission" );
154  level endon( "end_of_round" );
155  level endon( "restart_round" );
156 
157  level.dog_targets = getplayers();
158  for( i = 0 ; i < level.dog_targets.size; i++ )
159  {
160  level.dog_targets[i].hunted_by = 0;
161  }
162 
163  level endon( "kill_round" );
164 
165  if( level.intermission )
166  {
167  return;
168  }
169 
170  level.dog_intermission = true;
171  level thread ‪dog_round_aftermath();
172  players = GetPlayers();
173  array::thread_all( players,&‪play_dog_round );
174  wait(1);
175  level thread ‪zm_audio::sndAnnouncerPlayVox("dogstart");
176  wait(6);
177 
178  if( level.dog_round_count < 3 )
179  {
180  max = players.size * 6;
181  }
182  else
183  {
184  max = players.size * 8;
185  }
186 
187  level.zombie_total = max;
189 
190 
191 
192  count = 0;
193  while( true )
194  {
195  // added ability to pause spawning
196  level ‪flag::wait_till( "spawn_zombies" );
197 
198  while( ‪zombie_utility::get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 )
199  {
200  wait 0.1;
201  }
202 
203  num_player_valid = ‪zm_utility::get_number_of_valid_players();
204 
205  while( ‪zombie_utility::get_current_zombie_count() >= num_player_valid * 2 )
206  {
207  wait( 2 );
208  num_player_valid = ‪zm_utility::get_number_of_valid_players();
209  }
210 
211  //update the player array.
212  players = GetPlayers();
213  favorite_enemy = ‪get_favorite_enemy();
214 
215  if ( isdefined( level.dog_spawn_func ) )
216  {
217  spawn_loc = [[level.dog_spawn_func]]( level.dog_spawners, favorite_enemy );
218 
219  ai = ‪zombie_utility::spawn_zombie( level.dog_spawners[0] );
220  if( isdefined( ai ) )
221  {
222  ai.favoriteenemy = favorite_enemy;
223  spawn_loc thread ‪dog_spawn_fx( ai, spawn_loc );
224  level.zombie_total--;
225  count++;
226  level ‪flag::set( "dog_clips" );
227  }
228  }
229  else
230  {
231  // Default method
232  spawn_point = ‪dog_spawn_factory_logic( favorite_enemy );
233  ai = ‪zombie_utility::spawn_zombie( level.dog_spawners[0] );
234 
235  if( isdefined( ai ) )
236  {
237  ai.favoriteenemy = favorite_enemy;
238  spawn_point thread ‪dog_spawn_fx( ai, spawn_point );
239  level.zombie_total--;
240  count++;
241  level ‪flag::set( "dog_clips" );
242  }
243  }
244 
245 
246  ‪waiting_for_next_dog_spawn( count, max );
247  }
248 }
249 
250 function ‪waiting_for_next_dog_spawn( count, max )
251 {
252  default_wait = 1.5;
253 
254  if( level.dog_round_count == 1)
255  {
256  default_wait = 3;
257  }
258  else if( level.dog_round_count == 2)
259  {
260  default_wait = 2.5;
261  }
262  else if( level.dog_round_count == 3)
263  {
264  default_wait = 2;
265  }
266  else
267  {
268  default_wait = 1.5;
269  }
270 
271  default_wait = default_wait - ( count / max );
272 
273  default_wait = max( default_wait, 0.05 );
274 
275  wait( default_wait );
276 }
277 
279 {
280  level waittill( "last_ai_down", e_last );
281 
282  level thread ‪zm_audio::sndMusicSystem_PlayState( "dog_end" );
283 
284  power_up_origin = level.last_dog_origin;
285  if ( isdefined(e_last) )
286  {
287  power_up_origin = e_last.origin;
288  }
289 
290  if( isdefined( power_up_origin ) )
291  {
292  level thread ‪zm_powerups::specific_powerup_drop( "full_ammo", power_up_origin );
293  }
294 
295  wait(2);
296  ‪util::clientNotify( "dog_stop" );
297  wait(6);
298  level.dog_intermission = false;
299 
300  //level thread dog_round_aftermath();
301 
302 }
303 
304 
305 //
306 // In Factory, there's a single spawner and the struct is passed in as the second argument.
307 function ‪dog_spawn_fx( ai, ent )
308 {
309  ai endon( "death" );
310 
311  /*if ( !IsDefined(ent) )
312  {
313  ent = struct::get( self.target, "targetname" );
314  }*/
315 
316  ai SetFreeCameraLockOnAllowed( false );
317 // if ( isdefined( ent ) )
318  {
319  Playfx( level._effect["lightning_dog_spawn"], ent.origin );
320  playsoundatposition( "zmb_hellhound_prespawn", ent.origin );
321  wait( 1.5 );
322  playsoundatposition( "zmb_hellhound_bolt", ent.origin );
323 
324  Earthquake( 0.5, 0.75, ent.origin, 1000);
325  //PlayRumbleOnPosition("explosion_generic", ent.origin);
326  playsoundatposition( "zmb_hellhound_spawn", ent.origin );
327 
328  // face the enemy
329  if ( IsDefined( ai.favoriteenemy ) )
330  {
331  angle = VectorToAngles( ai.favoriteenemy.origin - ent.origin );
332  angles = ( ai.angles[0], angle[1], ai.angles[2] );
333  }
334  else
335  {
336  angles = ent.angles;
337  }
338  ai ForceTeleport( ent.origin, angles );
339  }
340 
341  assert( isdefined( ai ), "Ent isn't defined." );
342  assert( IsAlive( ai ), "Ent is dead." );
343  assert( ai.isdog, "Ent isn't a dog;" );
344  assert( ‪zm_utility::is_magic_bullet_shield_enabled( ai ), "Ent doesn't have a magic bullet shield." );
345 
348 
349  wait( 0.1 ); // dog should come out running after this wait
350  ai show();
351  ai SetFreeCameraLockOnAllowed( true );
352  ai.ignoreme = false; // don't let attack dogs give chase until the wolf is visible
353  ai notify( "visible" );
354 }
355 
356 
357 //
358 // Dog spawning logic for Factory.
359 // Makes use of the _zm_zone_manager and specially named structs for each zone to
360 // indicate dog spawn locations instead of constantly using ents.
361 //
362 function ‪dog_spawn_factory_logic( favorite_enemy)
363 {
364  dog_locs = array::randomize( level.zm_loc_types[ "dog_location" ] );
365  //assert( dog_locs.size > 0, "Dog Spawner locs array is empty." );
366 
367  for( i = 0; i < dog_locs.size; i++ )
368  {
369  if( isdefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[i] )
370  {
371  continue;
372  }
373 
374  if( !isdefined( favorite_enemy ) )
375  {
376  continue;
377  }
378 
379  dist_squared = DistanceSquared( dog_locs[i].origin, favorite_enemy.origin );
380  if( dist_squared > ( 400 * 400 ) && dist_squared < ( 1000 * 1000 ) )
381  {
382  level.old_dog_spawn = dog_locs[i];
383  return dog_locs[i];
384  }
385  }
386 
387  return dog_locs[0];
388 }
389 
390 
392 {
393  dog_targets = getplayers();
394  least_hunted = dog_targets[0];
395  for( i = 0; i < dog_targets.size; i++ )
396  {
397  if ( !isdefined( dog_targets[i].hunted_by ) )
398  {
399  dog_targets[i].hunted_by = 0;
400  }
401 
402  if( !‪zm_utility::is_player_valid( dog_targets[i] ) )
403  {
404  continue;
405  }
406 
407  if( !‪zm_utility::is_player_valid( least_hunted ) )
408  {
409  least_hunted = dog_targets[i];
410  }
411 
412  if( dog_targets[i].hunted_by < least_hunted.hunted_by )
413  {
414  least_hunted = dog_targets[i];
415  }
416 
417  }
418  // do not return the default first player if he is invalid
419  if( !‪zm_utility::is_player_valid( least_hunted ) )
420  {
421  return undefined;
422  }
423  else
424  {
425  least_hunted.hunted_by += 1;
426 
427  return least_hunted;
428  }
429 
430 }
431 
432 
434 {
435  players = getplayers();
436 
437  if( level.dog_round_count == 1 )
438  {
439  level.dog_health = 400;
440  }
441  else if( level.dog_round_count == 2 )
442  {
443  level.dog_health = 900;
444  }
445  else if( level.dog_round_count == 3 )
446  {
447  level.dog_health = 1300;
448  }
449  else if( level.dog_round_count == 4 )
450  {
451  level.dog_health = 1600;
452  }
453 
454  if( level.dog_health > 1600 )
455  {
456  level.dog_health = 1600;
457  }
458 }
459 
461 {
462  if( level ‪flag::get("dog_round" ) )
463  {
464  wait(7);
465  while( level.dog_intermission )
466  {
467  wait(0.5);
468  }
469  ‪zm::increment_dog_round_stat("finished");
470  }
471 
472  level.sndMusicSpecialRound = false;
473 }
474 
476 {
477  level.dog_round_count = 1;
478 
479  // PI_CHANGE_BEGIN - JMA - making dog rounds random between round 5 thru 7
480  // NOTE: RandomIntRange returns a random integer r, where min <= r < max
481 
482  level.next_dog_round = level.round_number + randomintrange( 4, 7 );
483  // PI_CHANGE_END
484 
485  old_spawn_func = level.round_spawn_func;
486  old_wait_func = level.round_wait_func;
487 
488  while ( 1 )
489  {
490  level waittill ( "between_round_over" );
491 
492  if ( level.round_number == level.next_dog_round )
493  {
494  level.sndMusicSpecialRound = true;
495  old_spawn_func = level.round_spawn_func;
496  old_wait_func = level.round_wait_func;
498  level.round_spawn_func = &‪dog_round_spawning;
499  level.round_wait_func = &‪dog_round_wait_func;
500 
501  level.next_dog_round = level.round_number + randomintrange( 4, 6 );
502  }
503  else if ( level ‪flag::get( "dog_round" ) )
504  {
506  level.round_spawn_func = old_spawn_func;
507  level.round_wait_func = old_wait_func;
508  level.dog_round_count += 1;
509  }
510  }
511 }
512 
513 
515 {
516  level ‪flag::set( "dog_round" );
517  level ‪flag::set( "special_round" );
518  level ‪flag::set( "dog_clips" );
519 
520  level notify( "dog_round_starting" );
521  level thread ‪zm_audio::sndMusicSystem_PlayState( "dog_start" );
522  ‪util::clientNotify( "dog_start" );
523 
524  if(isdefined(level.dog_melee_range))
525  {
526  SetDvar( "ai_meleeRange", level.dog_melee_range );
527  }
528  else
529  {
530  SetDvar( "ai_meleeRange", 100 );
531  }
532 }
533 
534 
536 {
537  level ‪flag::clear( "dog_round" );
538  level ‪flag::clear( "special_round" );
539  level ‪flag::clear( "dog_clips" );
540 
541  level notify( "dog_round_ending" );
542  ‪util::clientNotify( "dog_stop" );
543 
544  SetDvar( "ai_meleeRange", level.melee_range_sav );
545  SetDvar( "ai_meleeWidth", level.melee_width_sav );
546  SetDvar( "ai_meleeHeight", level.melee_height_sav );
547 }
548 
549 
551 {
552  self playlocalsound( "zmb_dog_round_start" );
553  variation_count =5;
554 
555  wait(4.5);
556 
557  players = getplayers();
558  num = randomintrange(0,players.size);
559  players[num] ‪zm_audio::create_and_play_dialog( "general", "dog_spawn" );
560 }
561 
562 
563 function ‪dog_init()
564 {
565  self.targetname = "zombie_dog";
566  self.script_noteworthy = undefined;
567  self.animname = "zombie_dog";
568  self.ignoreall = true;
569  self.ignoreme = true; // don't let attack dogs give chase until the wolf is visible
570  self.allowdeath = true; // allows death during animscripted calls
571  self.allowpain = false;
572  self.force_gib = true; // needed to make sure this guy does gibs
573  self.is_zombie = true; // needed for melee.gsc in the animscripts
574  // out both legs and then the only allowed stance should be prone.
575  self.gibbed = false;
576  self.head_gibbed = false;
577  self.default_goalheight = 40;
578  self.ignore_inert = true;
579 
580  self.holdfire = true;
581 
582  // self.disableArrivals = true;
583  // self.disableExits = true;
584  self.grenadeawareness = 0;
585  self.badplaceawareness = 0;
586 
587  self.ignoreSuppression = true;
588  self.suppressionThreshold = 1;
589  self.noDodgeMove = true;
590  self.dontShootWhileMoving = true;
591  self.pathenemylookahead = 0;
592 
593  self.badplaceawareness = 0;
594  self.chatInitialized = false;
595 
596  self.team = level.zombie_team;
597  self.heroweapon_kill_power = ‪ZM_DOGS_HERO_WEAPON_KILL_POWER;
598 
599  self AllowPitchAngle( 1 );
600  self setPitchOrient();
601  self setAvoidanceMask( "avoid none" );
602 
603  self PushActors( true );
604 
605  health_multiplier = 1.0;
606  if ( GetDvarString( "scr_dog_health_walk_multiplier" ) != "" )
607  {
608  health_multiplier = GetDvarFloat( "scr_dog_health_walk_multiplier" );
609  }
610 
611  self.maxhealth = int( level.dog_health * health_multiplier );
612  self.health = int( level.dog_health * health_multiplier );
613 
614  self.freezegun_damage = 0;
615 
616  self.zombie_move_speed = "sprint";
617  self.a.nodeath = true;//Always explode on death
618 
619  self thread ‪dog_run_think();
620  self thread ‪dog_stalk_audio();
621 
623  self ghost();
624  self thread ‪util::magic_bullet_shield();
625 
626  self thread ‪dog_death();
627 
628  level thread ‪zm_spawner::zombie_death_event( self );
631 
632  self.a.disablePain = true;
633  self ‪zm_utility::disable_react(); // SUMEET - zombies dont use react feature.
634  self ClearGoalVolume();
635 
636  self.flame_damage_time = 0;
637  self.meleeDamage = 40;
638 
639  self.thundergun_knockdown_func =&‪dog_thundergun_knockdown;
640 
641  self ‪zm_spawner::zombie_history( "zombie_dog_spawn_init -> Spawned = " + self.origin );
642 
643  if ( isdefined(level.achievement_monitor_func) )
644  {
645  self [[level.achievement_monitor_func]]();
646  }
647 }
648 
649 function ‪dog_death()
650 {
651  self waittill( "death" );
652 
653  if( ‪zombie_utility::get_current_zombie_count() == 0 && level.zombie_total == 0 )
654  {
655 
656  level.last_dog_origin = self.origin;
657  level notify( "last_ai_down", self );
658 
659  }
660 
661  // score
662  if( IsPlayer( self.attacker ) )
663  {
664  event = "death";
665  if ( self.damageweapon.isBallisticKnife )
666  {
667  event = "ballistic_knife_death";
668  }
669 
670  if ( !‪IS_TRUE( self.deathpoints_already_given ) )
671  {
672  self.attacker ‪zm_score::player_add_points( event, self.damagemod, self.damagelocation, true );
673  }
674 
675  if( isdefined(level.hero_power_update))
676  {
677  [[level.hero_power_update]]( self.attacker, self );
678  }
679 
680  if( RandomIntRange(0,100) >= 80 )
681  {
682  self.attacker ‪zm_audio::create_and_play_dialog( "kill", "hellhound" );
683  }
684 
685  //stats
686  self.attacker ‪zm_stats::increment_client_stat( "zdogs_killed" );
687  self.attacker ‪zm_stats::increment_player_stat( "zdogs_killed" );
688  }
689 
690  // switch to inflictor when SP DoDamage supports it
691  if( isdefined( self.attacker ) && isai( self.attacker ) )
692  {
693  self.attacker notify( "killed", self );
694  }
695 
696  // sound
697  self stoploopsound();
698 
699  // just explode if we died on an incline greater than 10 degrees
700  if ( !‪IS_TRUE( self.‪a.nodeath ) )
701  {
702  ‪trace = GroundTrace( self.origin + ( 0, 0, 10 ), self.origin - ( 0, 0, 30 ), false, self );
703  if ( ‪trace["fraction"] < 1 )
704  {
705  pitch = Acos( VectorDot( ‪trace["normal"], ( 0, 0, 1 ) ) );
706  if ( pitch > 10 )
707  {
708  self.a.nodeath = true;
709  }
710  }
711  }
712 
713  if ( isdefined( self.‪a.nodeath ) )
714  {
715  level thread ‪dog_explode_fx( self.origin );
716  self delete();
717  }
718  else
719  {
720  self notify( "bhtn_action_notify", "death" );
721  }
722 }
723 
724 
725 function ‪dog_explode_fx( origin )
726 {
727  PlayFX( level._effect["dog_gib"], origin );
728  PlaySoundAtPosition( "zmb_hellhound_explode", origin );
729 }
730 
731 
732 // this is where zombies go into attack mode, and need different attributes set up
734 {
735  self ‪zm_spawner::zombie_history( "zombie_setup_attack_properties()" );
736 
737  self thread ‪dog_behind_audio();
738 
739  // allows zombie to attack again
740  self.ignoreall = false;
741 
742  //self.pathEnemyFightDist = 64;
743  self.meleeAttackDist = 64;
744 
745  // turn off transition anims
746  self.disableArrivals = true;
747  self.disableExits = true;
748 
749  if ( isdefined( level.dog_setup_func ) )
750  {
751  self [[level.dog_setup_func]]();
752  }
753 }
754 
755 
756 //COLLIN'S Audio Scripts
758 {
759  self waittill("death");
760  self stopsounds();
761 }
762 
764 {
765  self thread ‪stop_dog_sound_on_death();
766 
767  self endon("death");
768  self ‪util::waittill_any( "dog_running", "dog_combat" );
769 
770  self notify( "bhtn_action_notify", "close" );
771  wait( 3 );
772 
773  while(1)
774  {
775  players = GetPlayers();
776  for(i=0;i<players.size;i++)
777  {
778  dogAngle = AngleClamp180( vectorToAngles( self.origin - players[i].origin )[1] - players[i].angles[1] );
779 
780  if(isAlive(players[i]) && !isdefined(players[i].revivetrigger))
781  {
782  if ((abs(dogAngle) > 90) && distance2d(self.origin,players[i].origin) > 100)
783  {
784  self notify( "bhtn_action_notify", "close" );
785  wait( 3 );
786  }
787  }
788  }
789 
790  wait(.75);
791  }
792 }
793 
794 
795 //
796 // Keeps dog_clips up if there is a dog running around in the level.
798 {
799  clips_on = false;
800  level.dog_clips = GetEntArray( "dog_clips", "targetname" );
801  while (1)
802  {
803  for ( i=0; i<level.dog_clips.size; i++ )
804  {
805  // level.dog_clips[i] TriggerEnable( false );
806  level.dog_clips[i] ConnectPaths();
807  }
808 
809  level ‪flag::wait_till( "dog_clips" );
810 
811  if(isdefined(level.no_dog_clip) && level.no_dog_clip == true)
812  {
813  return;
814  }
815 
816  for ( i=0; i<level.dog_clips.size; i++ )
817  {
818  // level.dog_clips[i] TriggerEnable( true );
819  level.dog_clips[i] DisconnectPaths();
821  }
822 
823  dog_is_alive = true;
824  while ( dog_is_alive || level ‪flag::get( "dog_round" ) )
825  {
826  dog_is_alive = false;
827  dogs = GetEntArray( "zombie_dog", "targetname" );
828  for ( i=0; i<dogs.size; i++ )
829  {
830  if ( IsAlive(dogs[i]) )
831  {
832  dog_is_alive = true;
833  }
834  }
835  wait( 1 );
836  }
837 
838  level ‪flag::clear( "dog_clips" );
839  wait(1);
840  }
841 }
842 
843 //
844 // Allows dogs to be spawned independent of the round spawning
845 function ‪special_dog_spawn( num_to_spawn, spawners, spawn_point )
846 {
847  dogs = GetAISpeciesArray( "all", "zombie_dog" );
848 
849  if ( isdefined( dogs ) && dogs.size >= 9 )
850  {
851  return false;
852  }
853 
854  if ( !isdefined(num_to_spawn) )
855  {
856  num_to_spawn = 1;
857  }
858 
859  spawn_point = undefined;
860  count = 0;
861  while ( count < num_to_spawn )
862  {
863  //update the player array.
864  players = GetPlayers();
865  favorite_enemy = ‪get_favorite_enemy();
866 
867  if ( isdefined( spawners ) )
868  {
869  if ( !isdefined( spawn_point ) )
870  {
871  spawn_point = spawners[ RandomInt(spawners.size) ];
872  }
873  ai = ‪zombie_utility::spawn_zombie( spawn_point );
874 
875  if( isdefined( ai ) )
876  {
877  ai.favoriteenemy = favorite_enemy;
878  spawn_point thread ‪dog_spawn_fx( ai );
879  count++;
880  level ‪flag::set( "dog_clips" );
881  }
882  }
883  else
884  {
885  if ( isdefined( level.dog_spawn_func ) )
886  {
887  spawn_loc = [[level.dog_spawn_func]]( level.dog_spawners, favorite_enemy );
888 
889  ai = ‪zombie_utility::spawn_zombie( level.dog_spawners[0] );
890  if( isdefined( ai ) )
891  {
892  ai.favoriteenemy = favorite_enemy;
893  spawn_loc thread ‪dog_spawn_fx( ai, spawn_loc );
894  count++;
895  level ‪flag::set( "dog_clips" );
896  }
897  }
898  else
899  {
900  // Default method
901  spawn_point = ‪dog_spawn_factory_logic( favorite_enemy );
902  ai = ‪zombie_utility::spawn_zombie( level.dog_spawners[0] );
903 
904  if( isdefined( ai ) )
905  {
906  ai.favoriteenemy = favorite_enemy;
907  spawn_point thread ‪dog_spawn_fx( ai, spawn_point );
908  count++;
909  level ‪flag::set( "dog_clips" );
910  }
911  }
912  }
913 
914  ‪waiting_for_next_dog_spawn( count, num_to_spawn );
915  }
916 
917  return true;
918 }
919 
921 {
922  self endon( "death" );
923 
924  // these should go back in when the stalking stuff is put back in, the visible check will do for now
925  //self util::waittill_any( "dog_running", "dog_combat" );
926  //self playsound( "zdog_close" );
927  self waittill( "visible" );
928 
929  // decrease health
930  if ( self.health > level.dog_health )
931  {
932  self.maxhealth = level.dog_health;
933  self.health = level.dog_health;
934  }
935 
936  // start glowing eyes & fire trail
937  self ‪clientfield::set( "dog_fx", 1 );
938  self playloopsound( "zmb_hellhound_loop_fire" );
939 
940  //Check to see if the enemy is not valid anymore
941  while( true )
942  {
943  if( !‪zm_utility::is_player_valid(self.favoriteenemy) )
944  {
945  //We are targetting an invalid player - select another one
946  self.favoriteenemy = ‪get_favorite_enemy();
947  }
948  if( isdefined( level.custom_dog_target_validity_check ) )
949  {
950  self [[ level.custom_dog_target_validity_check ]]();
951  }
952  wait( 0.2 );
953 
954  }
955 }
956 
958 {
959  self endon( "death" );
960  self endon( "dog_running" );
961  self endon( "dog_combat" );
962 
963  while(1)
964  {
965  self notify( "bhtn_action_notify", "ambient" );
966  wait randomfloatrange(2,4);
967  }
968 }
969 
971 {
972  self endon( "death" );
973 
974  ‪damage = int( self.maxhealth * 0.5 );
975  self DoDamage( ‪damage, player.origin, player );
976 }
‪get_favorite_enemy
‪function get_favorite_enemy()
Definition: _zm_ai_dogs.gsc:391
‪disable_react
‪function disable_react()
Definition: _zm_utility.gsc:4747
‪special_dog_spawn
‪function special_dog_spawn(num_to_spawn, spawners, spawn_point)
Definition: _zm_ai_dogs.gsc:845
‪waiting_for_next_dog_spawn
‪function waiting_for_next_dog_spawn(count, max)
Definition: _zm_ai_dogs.gsc:250
‪increment_client_stat
‪function increment_client_stat(stat_name, include_gametype)
Definition: _zm_stats.gsc:389
‪dog_clip_monitor
‪function dog_clip_monitor()
Definition: _zm_ai_dogs.gsc:797
‪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
‪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
‪increment_dog_round_stat
‪function increment_dog_round_stat(stat)
Definition: _zm.gsc:7006
‪stop_magic_bullet_shield
‪function stop_magic_bullet_shield(ent)
Definition: util_shared.gsc:2100
‪zmbAIVox_NotifyConvert
‪function zmbAIVox_NotifyConvert()
Definition: _zm_audio.gsc:1354
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪set_zombie_var
‪function set_zombie_var(zvar, value, is_float=false, column=1, is_team_based=false)
Definition: zombie_utility.gsc:1434
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪sndAnnouncerPlayVox
‪function sndAnnouncerPlayVox(type, player)
Definition: _zm_audio.gsc:1319
‪init_dog_fx
‪function init_dog_fx()
Definition: _zm_ai_dogs.gsc:96
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪dog_round_aftermath
‪function dog_round_aftermath()
Definition: _zm_ai_dogs.gsc:278
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪play_dog_round
‪function play_dog_round()
Definition: _zm_ai_dogs.gsc:550
‪a
‪function add_remove_list a
Definition: util_shared.csc:906
‪stop_dog_sound_on_death
‪function stop_dog_sound_on_death()
Definition: _zm_ai_dogs.gsc:757
‪dog_behind_audio
‪function dog_behind_audio()
Definition: _zm_ai_dogs.gsc:763
‪gib
‪function gib(attacker)
Definition: _amws.gsc:1072
‪register_immunity
‪function register_immunity(name, archetype, immune_trigger, immune_result_direct, immune_result_indirect)
Definition: aat_shared.gsc:305
‪is_player_valid
‪function is_player_valid(player, checkIgnoreMeFlag, ignore_laststand_players)
Definition: skeleton.gsc:256
‪dog_thundergun_knockdown
‪function dog_thundergun_knockdown(player, gib)
Definition: _zm_ai_dogs.gsc:970
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪round_spawn_failsafe
‪function round_spawn_failsafe()
Definition: zombie_utility.gsc:1806
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪sndMusicSystem_PlayState
‪function sndMusicSystem_PlayState(state)
Definition: _zm_audio.gsc:1042
‪dog_spawn_factory_logic
‪function dog_spawn_factory_logic(favorite_enemy)
Definition: _zm_ai_dogs.gsc:362
‪zombie_history
‪function zombie_history(msg)
Definition: _zm_spawner.gsc:2863
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪dog_round_spawning
‪function dog_round_spawning()
Definition: _zm_ai_dogs.gsc:151
‪dog_round_start
‪function dog_round_start()
Definition: _zm_ai_dogs.gsc:514
‪dog_init
‪function dog_init()
Definition: _zm_ai_dogs.gsc:563
‪dog_round_wait_func
‪function dog_round_wait_func()
Definition: _zm_ai_dogs.gsc:460
‪dog_spawner_init
‪function dog_spawner_init()
Definition: _zm_ai_dogs.gsc:120
‪ZM_AAT_DEAD_WIRE_NAME
‪#define ZM_AAT_DEAD_WIRE_NAME
Definition: aat_zm.gsh:5
‪dog_round_stop
‪function dog_round_stop()
Definition: _zm_ai_dogs.gsc:535
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪dog_health_increase
‪function dog_health_increase()
Definition: _zm_ai_dogs.gsc:433
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪ZM_AAT_TURNED_NAME
‪#define ZM_AAT_TURNED_NAME
Definition: aat_zm.gsh:8
‪get_number_of_valid_players
‪function get_number_of_valid_players()
Definition: _zm_utility.gsc:1666
‪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
‪zombie_death_event
‪function zombie_death_event(zombie)
Definition: _zm_spawner.gsc:2195
‪dog_spawn_fx
‪function dog_spawn_fx(ai, ent)
Definition: _zm_ai_dogs.gsc:307
‪dog_round_tracker
‪function dog_round_tracker()
Definition: _zm_ai_dogs.gsc:475
‪dog_run_think
‪function dog_run_think()
Definition: _zm_ai_dogs.gsc:920
‪clientNotify
‪function clientNotify(event)
Definition: util_shared.gsc:1416
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪dog_stalk_audio
‪function dog_stalk_audio()
Definition: _zm_ai_dogs.gsc:957
‪dog_death
‪function dog_death()
Definition: _zm_ai_dogs.gsc:649
‪get_current_zombie_count
‪function get_current_zombie_count()
Definition: zombie_utility.gsc:2018
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪ZM_DOGS_HERO_WEAPON_KILL_POWER
‪#define ZM_DOGS_HERO_WEAPON_KILL_POWER
Definition: _zm_ai_dogs.gsc:36
‪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
‪dog_explode_fx
‪function dog_explode_fx(origin)
Definition: _zm_ai_dogs.gsc:725
‪zombie_setup_attack_properties_dog
‪function zombie_setup_attack_properties_dog()
Definition: _zm_ai_dogs.gsc:733
‪ZM_AAT_THUNDER_WALL_NAME
‪#define ZM_AAT_THUNDER_WALL_NAME
Definition: aat_zm.gsh:7
‪add_spawn_function
‪function add_spawn_function(spawn_func, param1, param2, param3, param4, param5)
Definition: spawner_shared.gsc:3252
‪ZM_AAT_FIRE_WORKS_NAME
‪#define ZM_AAT_FIRE_WORKS_NAME
Definition: aat_zm.gsh:6
‪init
‪function init()
Definition: _zm_ai_dogs.gsc:50
‪ARCHETYPE_ZOMBIE_DOG
‪#define ARCHETYPE_ZOMBIE_DOG
Definition: archetype_shared.gsh:11
‪enable_dog_rounds
‪function enable_dog_rounds()
Definition: _zm_ai_dogs.gsc:107
‪__init__
‪function __init__()
Definition: _zm_ai_dogs.gsc:42
‪is_magic_bullet_shield_enabled
‪function is_magic_bullet_shield_enabled(ent)
Definition: _zm_utility.gsc:3474
‪magic_bullet_shield
‪function magic_bullet_shield(ent)
Definition: util_shared.gsc:1997