‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
zombie.gsc
Go to the documentation of this file.
1 #using scripts\shared\ai_shared;
2 #using scripts\shared\callbacks_shared;
3 #using scripts\shared\clientfield_shared;
4 #using scripts\shared\fx_shared;
5 #using scripts\shared\math_shared;
6 #using scripts\shared\scene_shared;
7 #using scripts\shared\spawner_shared;
8 #using scripts\shared\util_shared;
9 #using scripts\shared\array_shared;
10 
11 #using scripts\shared\ai\systems\animation_state_machine_utility;
12 #using scripts\shared\ai\systems\animation_state_machine_notetracks;
13 #using scripts\shared\ai\systems\animation_state_machine_mocomp;
14 #using scripts\shared\ai\archetype_locomotion_utility;
15 #using scripts\shared\ai\archetype_utility;
16 #using scripts\shared\ai\systems\behavior_tree_utility;
17 #using scripts\shared\ai\systems\blackboard;
18 #using scripts\shared\ai\systems\debug;
19 #using scripts\shared\ai\systems\gib;
20 #using scripts\shared\ai\zombie_utility;
21 #using scripts\shared\ai\zombie_death;
22 #using scripts\shared\ai\zombie_shared;
23 #using scripts\codescripts\struct;
24 #using scripts\shared\ai\archetype_mocomps_utility;
25 
26 //INTERFACE
27 #using scripts\shared\ai\systems\ai_interface;
28 #using scripts\shared\ai\archetype_zombie_interface;
29 
30 #insert scripts\shared\ai\archetype_damage_effects.gsh;
31 
32 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
33 #insert scripts\shared\ai\systems\animation_state_machine.gsh;
34 #insert scripts\shared\ai\systems\behavior.gsh;
35 #insert scripts\shared\ai\systems\behavior_tree.gsh;
36 #insert scripts\shared\ai\systems\blackboard.gsh;
37 #insert scripts\shared\ai\systems\gib.gsh;
38 #insert scripts\shared\ai\utility.gsh;
39 #insert scripts\shared\ai\zombie.gsh;
40 #insert scripts\shared\shared.gsh;
41 #insert scripts\shared\version.gsh;
42 
43 #namespace ZombieBehavior;
44 
45 function autoexec ‪init()
46 {
47  // INIT BEHAVIORS
49 
50  // INIT BLACKBOARD
54 
55  // INIT ZOMBIE ON SPAWN
57 
59  "actor",
62  1,
63  "int");
64 
66  "actor",
69  1,
70  "counter" );
71 
73 }
74 
75 function private ‪InitZombieBehaviorsAndASM()
76 {
77  ‪BT_REGISTER_ACTION( "zombieMoveAction", &‪zombieMoveAction, &‪zombieMoveActionUpdate, undefined );
78  ‪BT_REGISTER_API( "zombieTargetService", &‪zombieTargetService );
79  ‪BT_REGISTER_API( "zombieCrawlerCollisionService", &‪zombieCrawlerCollision);
80  ‪BT_REGISTER_API( "zombieTraversalService", &‪zombieTraversalService);
81 
82  ‪BT_REGISTER_API( "zombieIsAtAttackObject", &‪zombieIsAtAttackObject );
83  ‪BT_REGISTER_API( "zombieShouldAttackObject", &‪zombieShouldAttackObject );
84  ‪BT_REGISTER_API( "zombieShouldMelee", &‪zombieShouldMeleeCondition );
85  ‪BT_REGISTER_API( "zombieShouldJumpMelee", &‪zombieShouldJumpMeleeCondition );
86  ‪BT_REGISTER_API( "zombieShouldJumpUnderwaterMelee", &‪zombieShouldJumpUnderwaterMelee );
87  ‪BT_REGISTER_API( "zombieGibLegsCondition", &‪zombieGibLegsCondition );
88  ‪BT_REGISTER_API( "zombieShouldDisplayPain", &‪zombieShouldDisplayPain );
89  ‪BT_REGISTER_API( "isZombieWalking", &‪isZombieWalking );
90 
91  ‪BT_REGISTER_API( "zombieShouldMeleeSuicide", &‪zombieShouldMeleeSuicide );
92  ‪BT_REGISTER_API( "zombieMeleeSuicideStart", &‪zombieMeleeSuicideStart );
93  ‪BT_REGISTER_API( "zombieMeleeSuicideUpdate", &‪zombieMeleeSuicideUpdate );
94  ‪BT_REGISTER_API( "zombieMeleeSuicideTerminate", &‪zombieMeleeSuicideTerminate );
95 
96  ‪BT_REGISTER_API( "zombieShouldJuke", &‪zombieShouldJukeCondition );
97  ‪BT_REGISTER_API( "zombieJukeActionStart", &‪zombieJukeActionStart );
98  ‪BT_REGISTER_API( "zombieJukeActionTerminate", &‪zombieJukeActionTerminate );
99 
100  ‪BT_REGISTER_API( "zombieDeathAction", &‪zombieDeathAction );
101 
102  ‪BT_REGISTER_API( "zombieJukeService", &‪zombieJuke );
103  ‪BT_REGISTER_API( "zombieStumbleService", &‪zombieStumble );
104  ‪BT_REGISTER_API( "zombieStumbleCondition", &‪zombieShouldStumbleCondition );
105  ‪BT_REGISTER_API( "zombieStumbleActionStart", &‪zombieStumbleActionStart );
106 
107  ‪BT_REGISTER_API( "zombieAttackObjectStart", &‪zombieAttackObjectStart );
108  ‪BT_REGISTER_API( "zombieAttackObjectTerminate", &‪zombieAttackObjectTerminate );
109 
110  ‪BT_REGISTER_API( "wasKilledByInterdimensionalGun", &‪wasKilledByInterdimensionalGunCondition);
111  ‪BT_REGISTER_API( "wasCrushedByInterdimensionalGunBlackhole", &‪wasCrushedByInterdimensionalGunBlackholeCondition);
112  ‪BT_REGISTER_API( "zombieIDGunDeathUpdate", &‪zombieIDGunDeathUpdate);
113  ‪BT_REGISTER_API( "zombieVortexPullUpdate", &‪zombieIDGunDeathUpdate); //for doa
114 
115  ‪BT_REGISTER_API( "zombieHasLegs", &‪zombieHasLegs);
116  ‪BT_REGISTER_API( "zombieShouldProceduralTraverse", &‪zombieShouldProceduralTraverse );
117 
120 
121  // ------- ZOMBIE DEATH -----------//
122  ‪ASM_REGISTER_MOCOMP( "mocomp_death_idgun@zombie", &‪zombieIDGunDeathMocompStart, undefined, undefined);
123  ‪ASM_REGISTER_MOCOMP( "mocomp_vortex_pull@zombie", &‪zombieIDGunDeathMocompStart, undefined, undefined); //for doa
127  ‪ASM_REGISTER_MOCOMP( "mocomp_zombie_idle@zombie", &‪zombieZombieIdleMocompStart, undefined, undefined );
128 
129  ‪ASM_REGISTER_MOCOMP( "mocomp_attack_object@zombie", &‪zombieAttackObjectMocompStart, &‪zombieAttackObjectMocompUpdate, undefined );
130 }
131 
133 {
134  // CREATE BLACKBOARD
136 
137  // USE UTILITY BLACKBOARD
139 
140  // CREATE INTERFACE
142 
143  // CREATE ZOMBIE BLACKBOARD
148  ‪BB_REGISTER_ATTRIBUTE( ‪WHICH_BOARD_PULL_TYPE, undefined, undefined );
149  ‪BB_REGISTER_ATTRIBUTE( ‪BOARD_ATTACK_SPOT, undefined, undefined );
150  ‪BB_REGISTER_ATTRIBUTE( ‪GRAPPLE_DIRECTION, undefined, undefined );
154  ‪BB_REGISTER_ATTRIBUTE( ‪KNOCKDOWN_DIRECTION, undefined, undefined );
155  ‪BB_REGISTER_ATTRIBUTE( ‪KNOCKDOWN_TYPE, undefined, undefined );
158 
159  // REGISTER ANIMSCRIPTED CALLBACK
160  self.___ArchetypeOnAnimscriptedCallback = &‪ArchetypeZombieOnAnimscriptedCallback;
161 
162  // ENABLE DEBUGGING IN ODYSSEY
164 
165 }
166 
168 {
169  // UNREGISTER THE BLACKBOARD
170  entity.__blackboard = undefined;
171 
172  // REREGISTER BLACKBOARD
174 }
175 
177 {
179 }
180 
181 function private ‪ArchetypeZombieSpecialEffectsCallback( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName )
182 {
183  specialDayEffectChance = GetDvarInt("tu6_ffotd_zombieSpecialDayEffectsChance", 0);
184 
185  if( specialDayEffectChance && RandomInt(100) < specialDayEffectChance )
186  {
187  if( IsDefined( eAttacker ) && IsPlayer( eAttacker ) )
188  {
190  }
191  }
192 
193  return iDamage;
194 }
195 
196 // ------- BLACKBOARD -----------//
197 
199 {
200  if( IsDefined( self.zombie_arms_position ) )
201  {
202  if( self.zombie_arms_position == "up" )
203  return ‪ARMS_UP;
204  return ‪ARMS_DOWN;
205  }
206 
207  return ‪ARMS_UP;
208 }
209 
211 {
212  if ( IsDefined( self.zombie_move_speed ) )
213  {
214  if( self.zombie_move_speed == "walk" )
215  {
217  }
218  else if( self.zombie_move_speed == "run" )
219  {
221  }
222  else if( self.zombie_move_speed == "sprint" )
223  {
225  }
226  else if( self.zombie_move_speed == "super_sprint" )
227  {
229  }
230  else if( self.zombie_move_speed == "jump_pad_super_sprint" )
231  {
233  }
234  else if( self.zombie_move_speed == "burned" )
235  {
237  }
238  else if( self.zombie_move_speed == "slide" )
239  {
241  }
242  }
244 }
245 
247 {
248  if( IsDefined( self.variant_type ) )
249  {
250  return self.variant_type;
251  }
252  return 0;
253 }
254 
256 {
257  if( self.missingLegs )
258  return ‪HAS_LEGS_NO;
259  return ‪HAS_LEGS_YES;
260 }
261 
263 {
264  if( IsDefined( self.should_turn ) && self.should_turn )
265  {
266  return ‪SHOULD_TURN;
267  }
268  return ‪SHOULD_NOT_TURN;
269 }
270 
272 {
273  if( IsDefined( self.damage_direction ) )
274  {
275  return self.damage_direction;
276  }
278 }
279 
281 {
282  if ( isdefined( self.low_gravity_variant ) )
283  {
284  return self.low_gravity_variant;
285  }
286 
287  return 0;
288 }
289 
290 // ------- BLACKBOARD -----------//
291 
292 function ‪isZombieWalking( behaviorTreeEntity )
293 {
294  return !‪IS_TRUE(behaviorTreeEntity.missingLegs);
295 }
296 
297 function ‪zombieShouldDisplayPain( behaviorTreeEntity )
298 {
299  if( ‪IS_TRUE( behaviorTreeEntity.suicidalDeath ) )
300  return false;
301 
302  return !‪IS_TRUE(behaviorTreeEntity.missingLegs);
303 }
304 
305 function ‪zombieShouldJukeCondition( behaviorTreeEntity )
306 {
307  if ( IsDefined( behaviorTreeEntity.juke ) && ( behaviorTreeEntity.juke == "left" || behaviorTreeEntity.juke == "right" ) )
308  {
309  return true;
310  }
311 
312  return false;
313 }
314 
315 function ‪zombieShouldStumbleCondition( behaviorTreeEntity )
316 {
317  if ( isDefined( behaviorTreeEntity.stumble ) )
318  {
319  return true;
320  }
321  return false;
322 }
323 
324 function private ‪zombieJukeActionStart( behaviorTreeEntity )
325 {
326  ‪Blackboard::SetBlackBoardAttribute( behaviorTreeEntity, ‪JUKE_DIRECTION, behaviorTreeEntity.juke );
327 
328  if ( IsDefined( behaviorTreeEntity.jukeDistance ) )
329  {
330  ‪Blackboard::SetBlackBoardAttribute( behaviorTreeEntity, ‪JUKE_DISTANCE, behaviorTreeEntity.jukeDistance );
331  }
332  else
333  {
334  //default to short although this should never happen
335  ‪Blackboard::SetBlackBoardAttribute( behaviorTreeEntity, ‪JUKE_DISTANCE, "short" );
336  }
337 
338  behaviorTreeEntity.jukeDistance = undefined;
339  behaviorTreeEntity.juke = undefined;
340 }
341 
342 function private ‪zombieJukeActionTerminate( behaviorTreeEntity )
343 {
344  behaviorTreeEntity ClearPath();
345 }
346 
347 function private ‪zombieStumbleActionStart( behaviorTreeEntity )
348 {
349  behaviorTreeEntity.stumble = undefined;
350 }
351 
352 function private ‪zombieAttackObjectStart( behaviorTreeEntity )
353 {
354  behaviorTreeEntity.is_inert = true;
355 }
356 
357 function private ‪zombieAttackObjectTerminate( behaviorTreeEntity )
358 {
359  behaviorTreeEntity.is_inert = false;
360 }
361 
362 function ‪zombieGibLegsCondition( behaviorTreeEntity)
363 {
365 }
366 
367 function ‪zombieNotetrackMeleeFire( entity )
368 {
369  if ( ‪IS_TRUE( entity.aat_turned ) )
370  {
371  if ( IsDefined( entity.enemy ) && !isPlayer( entity.enemy ) )
372  {
373  if ( entity.enemy.archetype == ‪ARCHETYPE_ZOMBIE && ‪IS_TRUE( entity.enemy.allowDeath ))
374  {
375  ‪GibServerUtils::GibHead( entity.enemy );
377  entity.enemy Kill();
378  entity.n_aat_turned_zombie_kills++; // Tracked in _zm_aat_turned.gsc
379  }
380  else if ( ( entity.enemy.archetype == ‪ARCHETYPE_ZOMBIE_QUAD || entity.enemy.archetype == ‪ARCHETYPE_SPIDER ) && ‪IS_TRUE( entity.enemy.allowDeath ))
381  {
382  entity.enemy Kill();
383  entity.n_aat_turned_zombie_kills++; // Tracked in _zm_aat_turned.gsc
384  }
385  else if( ‪IS_TRUE(entity.enemy.canBeTargetedByTurnedZombies) )
386  {
387  entity Melee();
388  }
389  }
390  }
391  else
392  {
393  if ( IsDefined( entity.enemy ) && ( ‪IS_TRUE( entity.enemy.bgb_in_plain_sight_active ) || ‪IS_TRUE( entity.enemy.bgb_idle_eyes_active ) ) )
394  {
395  return;
396  }
397 
398  if ( IsDefined( entity.enemy ) && ‪IS_TRUE( entity.enemy.allow_zombie_to_target_ai ) )
399  {
400  if ( entity.enemy.health > 0 )
401  {
402  entity.enemy DoDamage( entity.meleeWeapon.meleeDamage, entity.origin, entity, entity, "none", "MOD_MELEE" );
403  }
404  return;
405  }
406 
407  entity Melee();
408  /#
409  Record3DText( "melee", self.origin, ‪RED, "Script", entity );
410  #/
411 
412  if ( ‪zombieShouldAttackObject( entity ) )
413  {
414  if ( IsDefined( level.attackableCallback ) )
415  {
416  entity.attackable [[ level.attackableCallback ]]( entity );
417  }
418  }
419  }
420 }
421 
422 function ‪zombieNotetrackCrushFire( behaviorTreeEntity )
423 {
424  behaviorTreeEntity delete();
425 }
426 
427 function ‪zombieTargetService( behaviorTreeEntity)
428 {
429  if ( isdefined( behaviorTreeEntity.enablePushTime ) )
430  {
431  if ( GetTime() >= behaviorTreeEntity.enablePushTime )
432  {
433  behaviorTreeEntity PushActors( true );
434  behaviorTreeEntity.enablePushTime = undefined;
435  }
436  }
437 
438  if( ‪IS_TRUE( behaviorTreeEntity.disableTargetService ) )
439  {
440  return false;
441  }
442 
443  if ( ‪IS_TRUE( behaviorTreeEntity.ignoreall ) )
444  {
445  return false;
446  }
447 
448  specificTarget = undefined;
449 
450  // Check if there is a point of interest
451  if( IsDefined( level.zombieLevelSpecificTargetCallback ) )
452  {
453  specificTarget = [[level.zombieLevelSpecificTargetCallback]]();
454  }
455 
456  if( IsDefined( specificTarget ) )
457  {
458  behaviorTreeEntity SetGoal( specificTarget.origin );
459  }
460  else if( isdefined( behaviorTreeEntity.v_zombie_custom_goal_pos ) )
461  {
462  goalPos = behaviorTreeEntity.v_zombie_custom_goal_pos;
463 
464  if ( isdefined( behaviorTreeEntity.n_zombie_custom_goal_radius ) )
465  {
466  behaviorTreeEntity.goalradius = behaviorTreeEntity.n_zombie_custom_goal_radius;
467  }
468 
469  behaviorTreeEntity SetGoal( goalPos );
470  }
471  else
472  {
473  player = ‪zombie_utility::get_closest_valid_player( self.origin, self.ignore_player );
474 
475  if( !IsDefined( player ) )
476  {
477  if( IsDefined( self.ignore_player ) )
478  {
479  if(isDefined(level._should_skip_ignore_player_logic) && [[level._should_skip_ignore_player_logic]]() )
480  {
481  return false;
482  }
483 
484  self.ignore_player = [];
485  }
486 
487  self SetGoal( self.origin );
488  return false;
489  }
490  else
491  {
492  if ( IsDefined( player.last_valid_position ) )
493  {
494  if( !‪IS_TRUE( self.zombie_do_not_update_goal ) )
495  {
496  if( ‪IS_TRUE( level.zombie_use_zigzag_path ) )
497  {
498  behaviorTreeEntity ‪zombieUpdateZigZagGoal();
499  }
500  else
501  {
502  behaviorTreeEntity SetGoal( player.last_valid_position );
503  }
504  }
505 
506  return true;
507  }
508  else
509  {
510  if( !‪IS_TRUE( self.zombie_do_not_update_goal ) )
511  {
512  behaviorTreeEntity SetGoal( behaviorTreeEntity.origin );
513  }
514 
515  return false;
516  }
517  }
518  }
519 }
520 
522 {
523  AIProfile_BeginEntry( "zombieUpdateZigZagGoal" );
524 
525  const ‪ZM_ZOMBIE_HEIGHT = 72;
526  const ZM_ZOMBIE_ZIGZAG_GOAL_TOLERENCE_DIST = 72;
527  const ZM_ZOMBIE_ZIGZAZ_ACTIVATION_DIST = 250;
528  shouldRepath = false;
529 
530  if ( !shouldRepath && IsDefined( self.favoriteenemy ) )
531  {
532  if ( !IsDefined( self.nextGoalUpdate ) || self.nextGoalUpdate <= GetTime() )
533  {
534  // It's been a while, repath!
535  shouldRepath = true;
536  }
537  else if ( DistanceSquared( self.origin, self.favoriteenemy.origin ) <= ‪SQR( ZM_ZOMBIE_ZIGZAZ_ACTIVATION_DIST ) )
538  {
539  // Repath if close to the enemy.
540  shouldRepath = true;
541  }
542  else if ( IsDefined( self.pathGoalPos ) )
543  {
544  // Repath if close to the current goal position.
545  distanceToGoalSqr = DistanceSquared( self.origin, self.pathGoalPos );
546 
547  shouldRepath = distanceToGoalSqr < ‪SQR( ZM_ZOMBIE_ZIGZAG_GOAL_TOLERENCE_DIST );
548  }
549  }
550 
551  if ( ‪IS_TRUE( self.keep_moving ) )
552  {
553  if ( GetTime() > self.keep_moving_time )
554  {
555  self.keep_moving = false;
556  }
557  }
558 
559  if ( shouldRepath )
560  {
561  goalPos = self.favoriteenemy.origin;
562  if ( IsDefined( self.favoriteenemy.last_valid_position ) )
563  {
564  goalPos = self.favoriteenemy.last_valid_position;
565  }
566 
567  // Fist set the position directly to the current goal position
568  self SetGoal( goalPos );
569 
570  // Randomize zig-zag path following if 20+ feet away from the enemy. This will override the goal position set earlier if needed.
571  if ( DistanceSquared( self.origin, goalPos ) > ‪SQR( ZM_ZOMBIE_ZIGZAZ_ACTIVATION_DIST ) )
572  {
573  self.keep_moving = true;
574  self.keep_moving_time = GetTime() + 250;
575  path = self CalcApproximatePathToPosition( goalPos,false );
576 
577  /#
578  if ( GetDvarInt( "ai_debugZigZag" ) )
579  {
580  for ( index = 1; index < path.size; index++ )
581  {
582  RecordLine( path[index - 1], path[index], ‪ORANGE, "Animscript", self );
583  }
584  }
585  #/
586 
587  if( IsDefined( level._zombieZigZagDistanceMin ) && IsDefined( level._zombieZigZagDistanceMax ) )
588  {
589  min = level._zombieZigZagDistanceMin;
590  max = level._zombieZigZagDistanceMax;
591  }
592  else
593  {
594  min = 240;
595  max = 600;
596  }
597 
598  deviationDistance = RandomIntRange( min, max ); // 20 to 50 feet
599 
600  segmentLength = 0;
601 
602  // Walks the current path to find the point where the AI should deviate from their normal path.
603  for ( index = 1; index < path.size; index++ )
604  {
605  currentSegLength = Distance( path[index - 1], path[index] );
606 
607  if ( ( segmentLength + currentSegLength ) > deviationDistance )
608  {
609  remainingLength = deviationDistance - segmentLength;
610 
611  seedPosition = path[index - 1] + ( VectorNormalize( path[index] - path[index - 1] ) * remainingLength );
612 
613  /# RecordCircle( seedPosition, 2, ‪ORANGE, "Animscript", self ); #/
614 
615  innerZigZagRadius = 0;
616  outerZigZagRadius = 96;
617 
618  // Find a point offset from the deviation point along the path.
619  queryResult = PositionQuery_Source_Navigation(
620  seedPosition,
621  innerZigZagRadius,
622  outerZigZagRadius,
623  0.5 * ‪ZM_ZOMBIE_HEIGHT,
624  16,
625  self,
626  16 );
627 
628  PositionQuery_Filter_InClaimedLocation( queryResult, self );
629 
630  if ( queryResult.data.size > 0 )
631  {
632  point = queryResult.data[ RandomInt( queryResult.data.size ) ];
633 
634  // Use the deviated point as the path instead.
635  self SetGoal( point.origin );
636  }
637 
638  break;
639  }
640 
641  segmentLength += currentSegLength;
642  }
643  }
644 
645  if( IsDefined( level._zombieZigZagTimeMin ) && IsDefined( level._zombieZigZagTimeMax ) )
646  {
647  minTime = level._zombieZigZagTimeMin;
648  maxTime = level._zombieZigZagTimeMax;
649  }
650  else
651  {
652  minTime = 2500;
653  maxTime = 3500;
654  }
655 
656  // Force repathing after a certain amount of time to smooth out movement.
657  self.nextGoalUpdate = GetTime() + RandomIntRange(minTime, maxTime);
658  }
659 
660  AIProfile_EndEntry();
661 }
662 
663 // turn off actor pushing if a regular zombie is too close
664 function ‪zombieCrawlerCollision( behaviorTreeEntity )
665 {
666  if ( !‪IS_TRUE( behaviorTreeEntity.missingLegs ) && !‪IS_TRUE( behaviorTreeEntity.knockdown ) )
667  {
668  return false;
669  }
670 
671  if ( IsDefined( behaviorTreeEntity.dontPushTime ) )
672  {
673  if ( GetTime() < behaviorTreeEntity.dontPushTime )
674  {
675  return true;
676  }
677  }
678 
679  zombies = GetAITeamArray( level.zombie_team );
680  foreach( zombie in zombies )
681  {
682  if ( zombie == behaviorTreeEntity )
683  {
684  continue;
685  }
686 
687  if ( ‪IS_TRUE( zombie.missingLegs ) || ‪IS_TRUE( zombie.knockdown ) )
688  {
689  continue;
690  }
691 
692  dist_sq = DistanceSquared( behaviorTreeEntity.origin, zombie.origin );
693  if ( dist_sq < ‪ZM_CRAWLER_PUSH_DIST_SQ )
694  {
695  behaviorTreeEntity PushActors( false );
696  behaviorTreeEntity.dontPushTime = GetTime() + ‪ZM_CRAWLER_PUSH_DISABLE_TIME;
697  return true;
698  }
699  }
700 
701  behaviorTreeEntity PushActors( true );
702  return false;
703 }
704 
705 function ‪zombieTraversalService( entity )
706 {
707  if ( isdefined( entity.traverseStartNode ) )
708  {
709  entity PushActors( false );
710  return true;
711  }
712 
713  return false;
714 }
715 
716 function ‪zombieIsAtAttackObject( entity )
717 {
718  if ( ‪IS_TRUE( entity.missingLegs ) )
719  {
720  return false;
721  }
722 
723  if ( IsDefined( entity.enemyoverride ) && IsDefined( entity.enemyoverride[1] ) )
724  {
725  return false;
726  }
727 
728  if ( IsDefined( entity.favoriteenemy ) && ‪IS_TRUE( entity.favoriteenemy.b_is_designated_target ) )
729  {
730  return false;
731  }
732 
733  if ( ‪IS_TRUE( entity.aat_turned ) )
734  {
735  return false;
736  }
737 
738  if ( IsDefined( entity.attackable ) && ‪IS_TRUE( entity.attackable.is_active ) )
739  {
740  if ( !IsDefined( entity.attackable_slot ) )
741  {
742  return false;
743  }
744 
745  //if ( entity IsAtGoal() )
746  //{
747  // entity.is_at_attackable = true;
748  // return true;
749  //}
750 
751  dist = Distance2DSquared( entity.origin, entity.attackable_slot.origin );
752  if ( dist < 256 )
753  {
754  height_offset = Abs( entity.origin[2] - entity.attackable_slot.origin[2] );
755  if ( height_offset < 32 )
756  {
757  entity.is_at_attackable = true;
758  return true;
759  }
760  }
761 
762  //yawToObject = AngleClamp180( entity.angles[ 1 ] - entity.attackable_slot.angles[ 1 ] );
763  //if( abs( yawToObject ) > ZM_MELEE_YAW )
764  //{
765  // return false;
766  //}
767 
768  }
769 
770  return false;
771 }
772 
773 function ‪zombieShouldAttackObject( entity )
774 {
775  if ( ‪IS_TRUE( entity.missingLegs ) )
776  {
777  return false;
778  }
779 
780  if ( IsDefined( entity.enemyoverride ) && IsDefined( entity.enemyoverride[1] ) )
781  {
782  return false;
783  }
784 
785  if ( IsDefined( entity.favoriteenemy ) && ‪IS_TRUE( entity.favoriteenemy.b_is_designated_target ) )
786  {
787  return false;
788  }
789 
790  if ( ‪IS_TRUE( entity.aat_turned ) )
791  {
792  return false;
793  }
794 
795  if ( IsDefined( entity.attackable ) && ‪IS_TRUE( entity.attackable.is_active ) )
796  {
797  if ( ‪IS_TRUE( entity.is_at_attackable ) )
798  {
799  return true;
800  }
801  }
802 
803  return false;
804 }
805 
806 function ‪zombieShouldMeleeCondition( behaviorTreeEntity )
807 {
808  if( IsDefined( behaviorTreeEntity.enemyoverride ) && IsDefined( behaviorTreeEntity.enemyoverride[1] ) )
809  {
810  return false;
811  }
812 
813  if( !IsDefined( behaviortreeentity.enemy ) )
814  {
815  return false;
816  }
817 
818  if( IsDefined( behaviorTreeEntity.marked_for_death ) )
819  {
820  return false;
821  }
822 
823  if( ‪IS_TRUE( behaviorTreeEntity.ignoreMelee ) )
824  {
825  return false;
826  }
827 
828  if( DistanceSquared( behaviorTreeEntity.origin, behaviorTreeEntity.enemy.origin ) > ‪ZM_MELEE_DIST_SQ )
829  {
830  return false;
831  }
832 
833  yawToEnemy = AngleClamp180( behaviorTreeEntity.angles[ 1 ] - ‪GET_YAW( behaviorTreeEntity, behaviorTreeEntity.enemy.origin ) );
834  if( abs( yawToEnemy ) > ‪ZM_MELEE_YAW )
835  {
836  return false;
837  }
838 
839  return true;
840 }
841 
842 #define ZM_MELEE_JUMP_DISTANCE_ABOVE 60
843 #define ZM_MELEE_JUMP_DIST 180
844 #define ZM_MELEE_JUMP_CHANCE 0.5
845 function ‪zombieShouldJumpMeleeCondition( behaviorTreeEntity )
846 {
847  if ( !‪IS_TRUE( behaviorTreeEntity.low_gravity ) )
848  {
849  return false;
850  }
851 
852  if( IsDefined( behaviorTreeEntity.enemyoverride ) && IsDefined( behaviorTreeEntity.enemyoverride[1] ) )
853  {
854  return false;
855  }
856 
857  if( !IsDefined( behaviortreeentity.enemy ) )
858  {
859  return false;
860  }
861 
862  if( IsDefined( behaviorTreeEntity.marked_for_death ) )
863  {
864  return false;
865  }
866 
867  if( ‪IS_TRUE( behaviorTreeEntity.ignoreMelee ) )
868  {
869  return false;
870  }
871 
872  if ( behaviorTreeEntity.enemy IsOnGround() )
873  {
874  return false;
875  }
876 
877  jumpChance = GetDvarFloat( "zmMeleeJumpChance", ‪ZM_MELEE_JUMP_CHANCE );
878  if ( ( ( behaviorTreeEntity GetEntityNumber() % 10 ) / 10 ) > jumpChance )
879  {
880  return false;
881  }
882 
883  predictedPosition = behaviorTreeEntity.enemy.origin + behaviorTreeEntity.enemy GetVelocity() * ‪SERVER_FRAME * 2;
884 
885  jumpDistanceSq = ‪pow( GetDvarInt( "zmMeleeJumpDistance", ‪ZM_MELEE_JUMP_DIST ), 2 );
886 
887  if( Distance2DSquared( behaviorTreeEntity.origin, predictedPosition ) > jumpDistanceSq )
888  {
889  return false;
890  }
891 
892  yawToEnemy = AngleClamp180( behaviorTreeEntity.angles[ 1 ] - ‪GET_YAW( behaviorTreeEntity, behaviorTreeEntity.enemy.origin ) );
893  if( abs( yawToEnemy ) > ‪ZM_MELEE_YAW )
894  {
895  return false;
896  }
897 
898  heightToEnemy = behaviorTreeEntity.enemy.origin[2] - behaviorTreeEntity.origin[2];
899  if ( heightToEnemy <= GetDvarInt( "zmMeleeJumpHeightDifference", ‪ZM_MELEE_JUMP_DISTANCE_ABOVE ) )
900  {
901  return false;
902  }
903 
904  return true;
905 }
906 
907 #define ZM_MELEE_JUMP_DISTANCE_ABOVE_WATER 48
908 #define ZM_MIN_IN_WATER_DEPTH 48
909 #define ZM_MELEE_WATER_JUMP_DIST 64
910 function ‪zombieShouldJumpUnderwaterMelee( behaviorTreeEntity )
911 {
912  if( IsDefined( behaviorTreeEntity.enemyoverride ) && IsDefined( behaviorTreeEntity.enemyoverride[1] ) )
913  {
914  return false;
915  }
916 
917  if( !IsDefined( behaviortreeentity.enemy ) )
918  {
919  return false;
920  }
921 
922  if( IsDefined( behaviorTreeEntity.marked_for_death ) )
923  {
924  return false;
925  }
926 
927  if( ‪IS_TRUE( behaviorTreeEntity.ignoreMelee ) )
928  {
929  return false;
930  }
931 
932  if ( behaviorTreeEntity.enemy IsOnGround() )
933  {
934  return false;
935  }
936 
937  if ( behaviorTreeEntity DepthInWater() < ‪ZM_MIN_IN_WATER_DEPTH )
938  {
939  return false;
940  }
941 
942  jumpDistanceSq = ‪pow( GetDvarInt( "zmMeleeWaterJumpDistance", ‪ZM_MELEE_WATER_JUMP_DIST ), 2 );
943 
944  if( Distance2DSquared( behaviorTreeEntity.origin, behaviorTreeEntity.enemy.origin ) > jumpDistanceSq )
945  {
946  return false;
947  }
948 
949  yawToEnemy = AngleClamp180( behaviorTreeEntity.angles[ 1 ] - ‪GET_YAW( behaviorTreeEntity, behaviorTreeEntity.enemy.origin ) );
950  if( abs( yawToEnemy ) > ‪ZM_MELEE_YAW )
951  {
952  return false;
953  }
954 
955  heightToEnemy = behaviorTreeEntity.enemy.origin[2] - behaviorTreeEntity.origin[2];
956  if ( heightToEnemy <= GetDvarInt( "zmMeleeJumpUnderwaterHeightDifference", ‪ZM_MELEE_JUMP_DISTANCE_ABOVE_WATER ) )
957  {
958  return false;
959  }
960 
961  return true;
962 }
963 
964 function ‪zombieStumble( behaviorTreeEntity )
965 {
966  if ( ‪IS_TRUE( behaviorTreeEntity.missingLegs ) )
967  {
968  return false;
969  }
970  if ( !‪IS_TRUE( behaviorTreeEntity.canStumble ) )
971  {
972  return false;
973  }
974  if ( !IsDefined( behaviorTreeEntity.zombie_move_speed ) || behaviorTreeEntity.zombie_move_speed != "sprint" )
975  {
976  return false;
977  }
978  if ( IsDefined( behaviorTreeEntity.stumble ) )
979  {
980  return false;
981  }
982  if (!IsDefined( behaviorTreeEntity.next_stumble_time ) )
983  {
984  behaviorTreeEntity.next_stumble_time = GetTime() + RandomIntRange( ‪ZM_STUMBLE_TIME_MIN, ‪ZM_STUMBLE_TIME_MAX );
985  }
986  if ( GetTime() > behaviorTreeEntity.next_stumble_time )
987  {
988  if ( RandomInt( 100 ) < ‪ZM_STUMBLE_CHANCE )
989  {
990  closestPlayer = ArrayGetClosest( behaviorTreeEntity.origin, level.players );
991  if( DistanceSquared( closestPlayer.origin, behaviorTreeEntity.origin ) > ‪ZM_STUMBLE_MIN_DISTANCE_SQ )
992  {
993  if ( IsDefined( behaviorTreeEntity.next_juke_time ) )
994  {
995  behaviorTreeEntity.next_juke_time = undefined;
996  }
997 
998  behaviorTreeEntity.next_stumble_time = undefined;
999  behaviorTreeEntity.stumble = true;
1000  return true;
1001  }
1002  }
1003  }
1004  return false;
1005 }
1006 
1007 function ‪zombieJuke( behaviorTreeEntity )
1008 {
1009  if ( !behaviorTreeEntity ‪ai::has_behavior_attribute( "can_juke" ) )
1010  {
1011  return false;
1012  }
1013 
1014  if( !behaviorTreeEntity ‪ai::get_behavior_attribute( "can_juke" ) )
1015  {
1016  return false;
1017  }
1018 
1019  if ( ‪IS_TRUE( behaviorTreeEntity.missingLegs ) )
1020  {
1021  return false;
1022  }
1023 
1024  if ( behaviorTreeEntity ZombieBehavior::bb_getlocomotionspeedtype() != ‪LOCOMOTION_SPEED_WALK )
1025  {
1026  if ( behaviorTreeEntity ‪ai::has_behavior_attribute( "spark_behavior" ) && !behaviorTreeEntity ‪ai::get_behavior_attribute( "spark_behavior" ) )
1027  {
1028  return false;
1029  }
1030  }
1031 
1032  if ( IsDefined( behaviorTreeEntity.juke ) )
1033  {
1034  return false;
1035  }
1036 
1037  if ( !IsDefined( behaviorTreeEntity.next_juke_time ) )
1038  {
1039  behaviorTreeEntity.next_juke_time = GetTime() + RandomIntRange( ‪ZM_JUKE_TIME_MIN, ‪ZM_JUKE_TIME_MAX );
1040  }
1041 
1042  if ( GetTime() > behaviorTreeEntity.next_juke_time )
1043  {
1044  behaviorTreeEntity.next_juke_time = undefined;
1045 
1046  if ( RandomInt( 100 ) < ‪ZM_JUKE_CHANCE || ( behaviorTreeEntity ‪ai::has_behavior_attribute( "spark_behavior" ) && behaviorTreeEntity ‪ai::get_behavior_attribute( "spark_behavior" ) ) )
1047  {
1048 
1049  if ( IsDefined( behaviorTreeEntity.next_stumble_time ) )
1050  {
1051  behaviorTreeEntity.next_stumble_time = undefined;
1052  }
1053 
1054  forwardOffset = 15;
1055  behaviorTreeEntity.ignoreBackwardPosition = true; //TODO remove this temp var
1056 
1057  if( ‪math::cointoss() ) //decide if going to be short or long juke
1058  {
1059  //try long juke
1060  ‪jukeDistance = 101;
1061  behaviorTreeEntity.jukeDistance = "long";
1062 
1063  switch( behaviorTreeEntity ZombieBehavior::bb_getlocomotionspeedtype() )
1064  {
1067  forwardOffset = 122;
1068  break;
1070  forwardOffset = 129;
1071  break;
1072  }
1073 
1074  behaviorTreeEntity.juke = ‪AiUtility::calculateJukeDirection( behaviorTreeEntity, forwardOffset, ‪jukeDistance );
1075  //juke == forward -> can't juke left or right
1076  }
1077 
1078  if ( !IsDefined( behaviorTreeEntity.juke ) || behaviorTreeEntity.juke == "forward" ) // could not long juke
1079  {
1080  //long juke didn't work out, so try short juke
1081  ‪jukeDistance = 69;
1082  behaviorTreeEntity.jukeDistance = "short";
1083 
1084  switch( behaviorTreeEntity ZombieBehavior::bb_getlocomotionspeedtype() )
1085  {
1088  forwardOffset = 127;
1089  break;
1091  forwardOffset = 148;
1092  break;
1093  }
1094 
1095  behaviorTreeEntity.juke = ‪AiUtility::calculateJukeDirection( behaviorTreeEntity, forwardOffset, ‪jukeDistance );
1096  if( behaviorTreeEntity.juke == "forward" )
1097  {
1098  //both juke checks failed, so don't juke at all
1099  behaviorTreeEntity.juke = undefined;
1100  behaviorTreeEntity.jukeDistance = undefined;
1101  return false;
1102  }
1103  }
1104 
1105  }
1106 
1107 
1108  }
1109 }
1110 
1111 function ‪zombieDeathAction( behaviorTreeEntity )
1112 {
1113  //insert anything that needs to be done right before zombie death
1114 }
1115 
1116 function ‪wasKilledByInterdimensionalGunCondition( behaviorTreeEntity )
1117 {
1118  if( isdefined( behaviorTreeEntity.interdimensional_gun_kill ) &&
1119  !isdefined( behaviorTreeEntity.killby_interdimensional_gun_hole ) &&
1120  IsAlive( behaviorTreeEntity ) )
1121  {
1122  return true;
1123  }
1124 
1125  return false;
1126 }
1127 
1129 {
1130  if(isdefined(behaviorTreeEntity.killby_interdimensional_gun_hole))
1131  {
1132  return true;
1133  }
1134 
1135  return false;
1136 }
1137 
1138 function ‪zombieIDGunDeathMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1139 {
1140  entity OrientMode( "face angle", entity.angles[1] );
1141  entity AnimMode(‪AI_ANIM_USE_BOTH_DELTAS_NOCLIP);
1142  entity.pushable = false;
1143  entity.blockingPain = true;
1144  entity PathMode( "dont move" );
1145 
1146  entity.hole_pull_speed = 0;
1147 }
1148 
1149 function ‪zombieMeleeJumpMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1150 {
1151  entity OrientMode( "face enemy" );
1152  entity AnimMode( ‪AI_ANIM_USE_BOTH_DELTAS_NOCLIP, false );
1153  entity.pushable = false;
1154  entity.blockingPain = true;
1155  entity.clampToNavMesh = false;
1156  entity PushActors( false );
1157 
1158  entity.jumpStartPosition = entity.origin;
1159 }
1160 
1161 function ‪zombieMeleeJumpMocompUpdate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1162 {
1163  normalizedTime = ( ( entity GetAnimTime( mocompAnim ) * GetAnimLength( mocompAnim ) ) + mocompAnimBlendOutTime ) / mocompDuration;
1164 
1165  if (normalizedTime > 0.5)
1166  {
1167  entity OrientMode( "face angle", entity.angles[1] );
1168  }
1169 
1170  speed = 5;
1171 
1172  if ( IsDefined( entity.zombie_move_speed ) )
1173  {
1174  switch ( entity.zombie_move_speed )
1175  {
1176  case "walk":
1177  speed = 5;
1178  break;
1179  case "run":
1180  speed = 6;
1181  break;
1182  case "sprint":
1183  speed = 7;
1184  break;
1185  }
1186  }
1187 
1188  newPosition = entity.origin + AnglesToForward( entity.angles ) * speed;
1189 
1190  // Test that the new position only moves the zombie across valid navmesh.
1191  newTestPosition = ( newPosition[0], newPosition[1], entity.jumpStartPosition[2] );
1192  newValidPosition = GetClosestPointOnNavMesh( newTestPosition, 12, 20 );
1193 
1194  if ( IsDefined( newValidPosition ) )
1195  {
1196  // New position appears to be valid.
1197  newValidPosition = ( newValidPosition[0], newValidPosition[1], entity.origin[2] );
1198  }
1199  else
1200  {
1201  // New position is not above navmesh, prevent all lateral movement.
1202  newValidPosition = entity.origin;
1203  }
1204 
1205  // Prevent zombie from penetrating the ground.
1206  groundPoint = GetClosestPointOnNavMesh( newValidPosition, 12, 20 );
1207  if ( IsDefined( groundPoint ) && groundPoint[2] > newValidPosition[2] )
1208  {
1209  newValidPosition = ( newValidPosition[0], newValidPosition[1], groundPoint[2] );
1210  }
1211 
1212  entity ForceTeleport( newValidPosition );
1213 }
1214 
1215 function ‪zombieMeleeJumpMocompTerminate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1216 {
1217  entity.pushable = true;
1218  entity.blockingPain = false;
1219  entity.clampToNavMesh = true;
1220  entity PushActors( true );
1221 
1222  groundPoint = GetClosestPointOnNavMesh( entity.origin, 12 );
1223  if ( IsDefined( groundPoint ) )
1224  {
1225  entity ForceTeleport( groundPoint );
1226  }
1227 }
1228 
1229 // Offset also defined in _zm_weap_idgun.gsc
1230 #define VORTEX_Z_OFFSET 36
1231 
1232 function ‪zombieIDGunDeathUpdate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1233 {
1234  if(!isdefined(entity.killby_interdimensional_gun_hole))
1235  {
1236  entity_eye = entity GetEye();
1237 
1238  // if world is paused unpause entity to be pulled into vortex
1239  if( entity IsPaused() )
1240  {
1241  entity SetIgnorePauseWorld( true );
1242  entity SetEntityPaused( false );
1243  }
1244 
1245  if ( entity.b_vortex_repositioned !== true )
1246  {
1247  entity.b_vortex_repositioned = true;
1248  v_nearest_navmesh_point = GetClosestPointOnNavMesh( entity.damageOrigin, ‪VORTEX_Z_OFFSET, 15 );
1249  if ( isdefined(v_nearest_navmesh_point) )
1250  {
1251  f_distance = Distance( entity.damageOrigin, v_nearest_navmesh_point);
1252 
1253  // Added 5 units to offset to capture a larger set of points
1254  if ( f_distance < ‪VORTEX_Z_OFFSET + 5 )
1255  {
1256  entity.damageOrigin = entity.damageOrigin + ( 0, 0, ‪VORTEX_Z_OFFSET);
1257  }
1258  }
1259  }
1260 
1261  entity_center = entity.origin + ( ( entity_eye - entity.origin ) / 2 );
1262  flyingDir = entity.damageOrigin - entity_center;
1263  lengthFromHole = Length(flyingDir);
1264 
1265  if(lengthFromHole < entity.hole_pull_speed)
1266  {
1267  entity.killby_interdimensional_gun_hole = true;
1268  entity.allowdeath = true;
1269  entity.takedamage = true;
1270  entity.aiOverrideDamage = undefined;
1271  entity.magic_bullet_shield = false;
1272  level notify("interdimensional_kill",entity);
1273  if( IsDefined( entity.interdimensional_gun_weapon ) && IsDefined( entity.interdimensional_gun_attacker ) )
1274  {
1275  entity ‪kill(entity.origin, entity.interdimensional_gun_attacker, entity.interdimensional_gun_attacker, entity.interdimensional_gun_weapon);
1276  }
1277  else
1278  {
1279  entity ‪kill( entity.origin );
1280  }
1281  }
1282  else
1283  {
1284  if(entity.hole_pull_speed < ‪ZM_IDGUN_HOLE_PULL_MAX_SPEED)
1285  {
1286  entity.hole_pull_speed += ‪ZM_IDGUN_HOLE_PULL_ACC;
1287 
1288  if(entity.hole_pull_speed > ‪ZM_IDGUN_HOLE_PULL_MAX_SPEED)
1289  entity.hole_pull_speed = ‪ZM_IDGUN_HOLE_PULL_MAX_SPEED;
1290  }
1291 
1292  flyingDir = VectorNormalize(flyingDir);
1293  entity ForceTeleport(entity.origin + flyingDir * entity.hole_pull_speed);
1294  }
1295  }
1296 }
1297 
1298 function ‪zombieIDGunHoleDeathMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1299 {
1300  entity OrientMode( "face angle", entity.angles[1] );
1301  entity AnimMode(‪AI_ANIM_USE_BOTH_DELTAS_NOCLIP);
1302  entity.pushable = false;
1303 }
1304 
1305 function ‪zombieIDGunHoleDeathMocompTerminate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1306 {
1307  if( !‪IS_TRUE( entity.interdimensional_gun_kill_vortex_explosion ) )
1308  {
1309  entity hide();
1310  }
1311 }
1312 
1313 function private ‪zombieTurnMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1314 {
1315  entity OrientMode( "face angle", entity.angles[1] );
1316  entity AnimMode( ‪AI_ANIM_USE_ANGLE_DELTAS, false );
1317 }
1318 
1319 function private ‪zombieTurnMocompUpdate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1320 {
1321  normalizedTime = ( entity GetAnimTime( mocompAnim ) + mocompAnimBlendOutTime ) / mocompDuration;
1322 
1323  if ( normalizedTime > 0.25 )
1324  {
1325  entity OrientMode( "face motion" );
1326  entity AnimMode( ‪AI_ANIM_MOVE_CODE, false );
1327  }
1328 }
1329 
1330 function private ‪zombieTurnMocompTerminate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1331 {
1332  entity OrientMode( "face motion" );
1333  entity AnimMode( ‪AI_ANIM_MOVE_CODE, false );
1334 }
1335 
1336 function ‪zombieHasLegs( behaviorTreeEntity )
1337 {
1338  if( behaviorTreeEntity.missingLegs === true )
1339  {
1340  return false;
1341  }
1342 
1343  return true;
1344 }
1345 
1347 {
1348  return IsDefined( entity.traverseStartNode ) &&
1349  IsDefined( entity.traverseEndNode ) &&
1350  entity.traverseStartNode.spawnflags & ‪SPAWNFLAG_PATH_PROCEDURAL &&
1351  entity.traverseEndNode.spawnflags & ‪SPAWNFLAG_PATH_PROCEDURAL;
1352 }
1353 
1354 function ‪zombieShouldMeleeSuicide( behaviorTreeEntity )
1355 {
1356  if( !behaviorTreeEntity ‪ai::get_behavior_attribute( "suicidal_behavior" ) )
1357  {
1358  return false;
1359  }
1360 
1361  if( ‪IS_TRUE( behaviorTreeEntity.magic_bullet_shield ) )
1362  {
1363  return false;
1364  }
1365 
1366  if( !IsDefined( behaviortreeentity.enemy ) )
1367  {
1368  return false;
1369  }
1370 
1371  if( IsDefined( behaviorTreeEntity.marked_for_death ) )
1372  {
1373  return false;
1374  }
1375 
1376  if( DistanceSquared( behaviorTreeEntity.origin, behaviorTreeEntity.enemy.origin ) > ‪ZOMBIE_SUICIDE_RANGE_SQ )
1377  {
1378  return false;
1379  }
1380 
1381  return true;
1382 }
1383 
1384 function ‪zombieMeleeSuicideStart( behaviorTreeEntity )
1385 {
1386  behaviorTreeEntity.blockingPain = true;
1387 
1388  if( IsDefined( level.zombieMeleeSuicideCallback ) )
1389  {
1390  behaviorTreeEntity thread [[level.zombieMeleeSuicideCallback]](behaviorTreeEntity);
1391  }
1392 }
1393 
1394 function ‪zombieMeleeSuicideUpdate( behaviorTreeEntity )
1395 {
1396 
1397 }
1398 
1399 function ‪zombieMeleeSuicideTerminate( behaviorTreeEntity )
1400 {
1401  if( IsAlive( behaviorTreeEntity ) && ‪zombieShouldMeleeSuicide( behaviorTreeEntity ) )
1402  {
1403  behaviorTreeEntity.takedamage = true;
1404  behaviorTreeEntity.allowDeath = true;
1405 
1406  // SUMEET : I dont like how this is being done but have to do this, as killing an entity in
1407  // Terminate functon can lead to an interrupt that might get dropped by the behavior tree update
1408  if( IsDefined( level.zombieMeleeSuicideDoneCallback ) )
1409  {
1410  behaviorTreeEntity thread [[level.zombieMeleeSuicideDoneCallback]](behaviorTreeEntity);
1411  }
1412  }
1413 }
1414 
1415 // ------- ZOMBIE LOCOMOTION -----------//
1416 function ‪zombieMoveAction( behaviorTreeEntity, asmStateName )
1417 {
1418  behaviorTreeEntity.moveTime = GetTime();
1419  behaviorTreeEntity.moveOrigin = behaviorTreeEntity.origin;
1420 
1421  ‪AnimationStateNetworkUtility::RequestState( behaviorTreeEntity, asmStateName );
1422 
1423  //Stumble at the end of the current move animation
1424  if( IsDefined( behaviorTreeEntity.stumble ) && !IsDefined( behaviorTreeEntity.move_anim_end_time ) )
1425  {
1426  stumbleActionResult = behaviorTreeEntity ASTSearch( IString( asmStateName ) );
1427  stumbleActionAnimation = ‪AnimationStateNetworkUtility::SearchAnimationMap( behaviorTreeEntity, stumbleActionResult[ ‪ASM_ALIAS_ATTRIBUTE ] );
1428 
1429  behaviorTreeEntity.move_anim_end_time = behaviorTreeEntity.moveTime + GetAnimLength( stumbleActionAnimation );
1430  }
1431 
1432  if( IsDefined( behaviorTreeEntity.zombieMoveActionCallback ) )
1433  {
1434  behaviorTreeEntity [[behaviorTreeEntity.zombieMoveActionCallback]]( behaviorTreeEntity );
1435  }
1436 
1437  return ‪BHTN_RUNNING;
1438 }
1439 
1440 // Looping Action will always return BHTN_RUNNING and request the state again when the ASM_STATE_COMPLETE
1441 function ‪zombieMoveActionUpdate( behaviorTreeEntity, asmStateName )
1442 {
1443  if ( IsDefined( behaviorTreeEntity.move_anim_end_time ) && ( GetTime() >= behaviorTreeEntity.move_anim_end_time ) )
1444  {
1445  behaviorTreeEntity.move_anim_end_time = undefined;
1446  return ‪BHTN_SUCCESS;
1447  }
1448 
1449  if ( !‪IS_TRUE( behaviorTreeEntity.missingLegs ) && ( GetTime() - behaviorTreeEntity.moveTime > ‪ZM_MOVE_TIME ) )
1450  {
1451  distSq = Distance2DSquared( behaviorTreeEntity.origin, behaviorTreeEntity.moveOrigin );
1452  if ( distSq < ‪ZM_MOVE_DIST_SQ )
1453  {
1454  behaviorTreeEntity SetAvoidanceMask( "avoid all" );
1455  behaviorTreeEntity.cant_move = true;
1456 
1457  if ( IsDefined( behaviorTreeEntity.cant_move_cb ) )
1458  {
1459  behaviorTreeEntity [[ behaviorTreeEntity.cant_move_cb ]]();
1460  }
1461  }
1462  else
1463  {
1464  behaviorTreeEntity SetAvoidanceMask( "avoid none" );
1465  behaviorTreeEntity.cant_move = false;
1466  }
1467 
1468  behaviorTreeEntity.moveTime = GetTime();
1469  behaviorTreeEntity.moveOrigin = behaviorTreeEntity.origin;
1470  }
1471 
1472  if( behaviorTreeEntity ASMGetStatus() == ‪ASM_STATE_COMPLETE )
1473  {
1474  if( behaviorTreeEntity IsCurrentBTActionLooping() )
1475  ‪zombieMoveAction( behaviorTreeEntity, asmStateName );
1476  else
1477  return ‪BHTN_SUCCESS;
1478  }
1479 
1480  return ‪BHTN_RUNNING;
1481 }
1482 
1483 function ‪zombieMoveActionTerminate( behaviorTreeEntity, asmStateName )
1484 {
1485  if ( !‪IS_TRUE( behaviorTreeEntity.missingLegs ) )
1486  {
1487  behaviorTreeEntity SetAvoidanceMask( "avoid none" );
1488  }
1489 
1490  return ‪BHTN_SUCCESS;
1491 }
1492 
1493 // ------- ZOMBIE DEATH GIB OVERRIDE -----------//
1495 {
1497 }
1498 
1499 #define CLOSE_EXPLOSIVE SQR(60)
1500 function private ‪ZombieGibKilledAnhilateOverride( inflictor, attacker, ‪damage, meansOfDeath, weapon, dir, hitLoc, offsetTime ) // self = AI
1501 {
1502  // Level must opt-in to anhilation
1503  if( !‪IS_TRUE( level.zombieAnhilationEnabled ) )
1504  return ‪damage;
1505 
1506  if( ‪IS_TRUE( self.forceAnhilateOnDeath ) )
1507  {
1510  return ‪damage;
1511  }
1512 
1513  // Forced anhilation for players
1514  if( IsDefined( attacker ) && IsPlayer( attacker ) && ( ‪IS_TRUE( attacker.forceAnhilateOnDeath ) || ‪IS_TRUE( level.forceAnhilateOnDeath ) ) )
1515  {
1518  return ‪damage;
1519  }
1520 
1521  // Generic anhilation
1522  attackerDistance = 0;
1523 
1524  if ( IsDefined( attacker ) )
1525  {
1526  attackerDistance = DistanceSquared( attacker.origin, self.origin );
1527  }
1528 
1529  isExplosive = IsInArray(
1530  ‪array(
1531  "MOD_CRUSH",
1532  "MOD_GRENADE",
1533  "MOD_GRENADE_SPLASH",
1534  "MOD_PROJECTILE",
1535  "MOD_PROJECTILE_SPLASH",
1536  "MOD_EXPLOSIVE" ),
1537  meansOfDeath );
1538 
1539  if ( IsDefined( weapon.weapclass ) && weapon.weapclass == "turret" )
1540  {
1541  // Annihilate AI's from turrent explosives that are inflicted at a close distance.
1542  if ( IsDefined( inflictor ) )
1543  {
1544  isDirectExplosive = IsInArray(
1545  ‪array(
1546  "MOD_GRENADE",
1547  "MOD_GRENADE_SPLASH",
1548  "MOD_PROJECTILE",
1549  "MOD_PROJECTILE_SPLASH",
1550  "MOD_EXPLOSIVE" ),
1551  meansOfDeath );
1552 
1553  isCloseExplosive = DistanceSquared( inflictor.origin, self.origin ) <= ‪CLOSE_EXPLOSIVE;
1554 
1555  if ( isDirectExplosive && isCloseExplosive )
1556  {
1559  }
1560  }
1561  }
1562 
1563  return ‪damage;
1564 }
1565 
1566 
1567 function private ‪zombieZombieIdleMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1568 {
1569  if( IsDefined( entity.enemyoverride ) && IsDefined( entity.enemyoverride[1] ) && entity != entity.enemyoverride[1] )
1570  {
1571  entity OrientMode( "face direction", entity.enemyoverride[1].origin - entity.origin );
1572  entity AnimMode( ‪AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS, false );
1573  }
1574  else
1575  {
1576  entity OrientMode( "face current" );
1577  entity AnimMode( ‪AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS, false );
1578  }
1579 }
1580 
1581 function private ‪zombieAttackObjectMocompStart( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1582 {
1583  if( IsDefined( entity.attackable_slot ) )
1584  {
1585  entity OrientMode( "face angle", entity.attackable_slot.angles[1] );
1586  entity AnimMode( ‪AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS, false );
1587  }
1588  else
1589  {
1590  entity OrientMode( "face current" );
1591  entity AnimMode( ‪AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS, false );
1592  }
1593 }
1594 
1595 function private ‪zombieAttackObjectMocompUpdate( entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration )
1596 {
1597  if( IsDefined( entity.attackable_slot ) )
1598  {
1599  entity ForceTeleport( entity.attackable_slot.origin );
1600  }
1601 }
1602 
1603 
‪JUKE_DISTANCE
‪#define JUKE_DISTANCE
Definition: blackboard.gsh:134
‪HAS_LEGS_YES
‪#define HAS_LEGS_YES
Definition: blackboard.gsh:165
‪ZOMBIE_SUICIDE_RANGE_SQ
‪#define ZOMBIE_SUICIDE_RANGE_SQ
Definition: zombie.gsh:49
‪zombieShouldJukeCondition
‪function zombieShouldJukeCondition(behaviorTreeEntity)
Definition: zombie.gsc:305
‪GIB_LEGS_RIGHT_LEG_FLAG
‪#define GIB_LEGS_RIGHT_LEG_FLAG
Definition: gib.gsh:28
‪zombieShouldStumbleCondition
‪function zombieShouldStumbleCondition(behaviorTreeEntity)
Definition: zombie.gsc:315
‪ASM_STATE_COMPLETE
‪#define ASM_STATE_COMPLETE
Definition: animation_state_machine.gsh:15
‪ARMS_UP
‪#define ARMS_UP
Definition: blackboard.gsh:186
‪LOCOMOTION_SPEED_JUMP_PAD_SUPER_SPRINT
‪#define LOCOMOTION_SPEED_JUMP_PAD_SUPER_SPRINT
Definition: blackboard.gsh:160
‪zombieStumbleActionStart
‪function private zombieStumbleActionStart(behaviorTreeEntity)
Definition: zombie.gsc:347
‪ZM_MELEE_JUMP_CHANCE
‪#define ZM_MELEE_JUMP_CHANCE
Definition: zombie.gsc:844
‪AddAIOverrideDamageCallback
‪function AddAIOverrideDamageCallback(entity, callback, addToFront)
Definition: archetype_utility.gsc:542
‪BOARD_ATTACK_SPOT
‪#define BOARD_ATTACK_SPOT
Definition: blackboard.gsh:171
‪zombieShouldDisplayPain
‪function zombieShouldDisplayPain(behaviorTreeEntity)
Definition: zombie.gsc:297
‪BT_REGISTER_API
‪#define BT_REGISTER_API(name, function)
Definition: behavior.gsh:1
‪zombieTargetService
‪function zombieTargetService(behaviorTreeEntity)
Definition: zombie.gsc:427
‪zombieStumble
‪function zombieStumble(behaviorTreeEntity)
Definition: zombie.gsc:964
‪AddAIOverrideKilledCallback
‪function AddAIOverrideKilledCallback(entity, callback)
Definition: archetype_utility.gsc:618
‪ZM_MOVE_TIME
‪#define ZM_MOVE_TIME
Definition: zombie.gsh:52
‪zombieIDGunHoleDeathMocompStart
‪function zombieIDGunHoleDeathMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1298
‪zombieShouldProceduralTraverse
‪function zombieShouldProceduralTraverse(entity)
Definition: zombie.gsc:1346
‪WHICH_BOARD_PULL_TYPE
‪#define WHICH_BOARD_PULL_TYPE
Definition: blackboard.gsh:170
‪zombieJukeActionStart
‪function private zombieJukeActionStart(behaviorTreeEntity)
Definition: zombie.gsc:324
‪WHIRLWIND_SPEED
‪#define WHIRLWIND_SPEED
Definition: blackboard.gsh:232
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪zombieAttackObjectStart
‪function private zombieAttackObjectStart(behaviorTreeEntity)
Definition: zombie.gsc:352
‪ZM_MELEE_JUMP_DIST
‪#define ZM_MELEE_JUMP_DIST
Definition: zombie.gsc:843
‪BHTN_RUNNING
‪#define BHTN_RUNNING
Definition: behavior_tree.gsh:9
‪cointoss
‪function cointoss()
Definition: math_shared.csc:171
‪zombieTurnMocompStart
‪function private zombieTurnMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1313
‪LOCOMOTION_SPEED_WALK
‪#define LOCOMOTION_SPEED_WALK
Definition: blackboard.gsh:156
‪ARMS_POSITION
‪#define ARMS_POSITION
Definition: blackboard.gsh:185
‪BB_REGISTER_ATTRIBUTE
‪#define BB_REGISTER_ATTRIBUTE(name, defaultValue, getter)
Definition: blackboard.gsh:1
‪ASM_REGISTER_NOTETRACK_HANDLER
‪#define ASM_REGISTER_NOTETRACK_HANDLER(notetrackname, handlerfunction)
Definition: animation_state_machine.gsh:4
‪zombieJuke
‪function zombieJuke(behaviorTreeEntity)
Definition: zombie.gsc:1007
‪ZOMBIE_CLIENTFIELD
‪#define ZOMBIE_CLIENTFIELD
Definition: zombie.gsh:61
‪ASM_ZOMBIE_CRUSH_NOTETRACK
‪#define ASM_ZOMBIE_CRUSH_NOTETRACK
Definition: zombie.gsh:26
‪GET_YAW
‪#define GET_YAW(__self, __org)
Definition: utility.gsh:26
‪VORTEX_Z_OFFSET
‪#define VORTEX_Z_OFFSET
Definition: zombie.gsc:1230
‪zombieAttackObjectMocompUpdate
‪function private zombieAttackObjectMocompUpdate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1595
‪zombieIDGunDeathUpdate
‪function zombieIDGunDeathUpdate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1232
‪ZM_STUMBLE_MIN_DISTANCE_SQ
‪#define ZM_STUMBLE_MIN_DISTANCE_SQ
Definition: zombie.gsh:40
‪zombieTurnMocompUpdate
‪function private zombieTurnMocompUpdate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1319
‪LOCOMOTION_SPEED_SPRINT
‪#define LOCOMOTION_SPEED_SPRINT
Definition: blackboard.gsh:158
‪RegisterZombieInterfaceAttributes
‪function RegisterZombieInterfaceAttributes()
Definition: archetype_zombie_interface.gsc:6
‪zombieTurnMocompTerminate
‪function private zombieTurnMocompTerminate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1330
‪SHOULD_TURN
‪#define SHOULD_TURN
Definition: blackboard.gsh:138
‪SetBlackBoardAttribute
‪function SetBlackBoardAttribute(entity, attributeName, attributeValue)
Definition: blackboard.gsc:56
‪zombieAttackObjectMocompStart
‪function private zombieAttackObjectMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1581
‪ZM_MELEE_JUMP_DISTANCE_ABOVE
‪#define ZM_MELEE_JUMP_DISTANCE_ABOVE
Definition: zombie.gsc:842
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪CLOSE_EXPLOSIVE
‪#define CLOSE_EXPLOSIVE
Definition: zombie.gsc:1499
‪SQR
‪#define SQR(__var)
Definition: shared.gsh:293
‪ZM_STUMBLE_TIME_MAX
‪#define ZM_STUMBLE_TIME_MAX
Definition: zombie.gsh:38
‪RegisterUtilityBlackboardAttributes
‪function RegisterUtilityBlackboardAttributes()
Definition: archetype_utility.gsc:139
‪Annihilate
‪function Annihilate(entity)
Definition: gib.gsc:393
‪ZM_MELEE_JUMP_DISTANCE_ABOVE_WATER
‪#define ZM_MELEE_JUMP_DISTANCE_ABOVE_WATER
Definition: zombie.gsc:907
‪zombieHasLegs
‪function zombieHasLegs(behaviorTreeEntity)
Definition: zombie.gsc:1336
‪ASM_ZOMBIE_MELEE_NOTETRACK
‪#define ASM_ZOMBIE_MELEE_NOTETRACK
Definition: zombie.gsh:24
‪GRAPPLE_DIRECTION
‪#define GRAPPLE_DIRECTION
Definition: blackboard.gsh:136
‪RED
‪#define RED
Definition: shared.gsh:175
‪calculateJukeDirection
‪function calculateJukeDirection(entity, entityRadius, jukeDistance)
Definition: archetype_locomotion_utility.gsc:447
‪SearchAnimationMap
‪function SearchAnimationMap(entity, aliasName)
Definition: animation_state_machine_utility.gsc:9
‪zombieMeleeSuicideUpdate
‪function zombieMeleeSuicideUpdate(behaviorTreeEntity)
Definition: zombie.gsc:1394
‪BB_GetLocomotionSpeedType
‪function BB_GetLocomotionSpeedType()
Definition: zombie.gsc:210
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪pow
‪function pow(base, exp)
Definition: math_shared.gsc:544
‪has_behavior_attribute
‪function has_behavior_attribute(attribute)
Definition: ai_shared.gsc:198
‪ZombieGibKilledAnhilateOverride
‪function private ZombieGibKilledAnhilateOverride(inflictor, attacker, damage, meansOfDeath, weapon, dir, hitLoc, offsetTime)
Definition: zombie.gsc:1500
‪LOCOMOTION_SHOULD_TURN
‪#define LOCOMOTION_SHOULD_TURN
Definition: blackboard.gsh:137
‪ZM_CRAWLER_PUSH_DIST_SQ
‪#define ZM_CRAWLER_PUSH_DIST_SQ
Definition: zombie.gsh:21
‪zombieUpdateZigZagGoal
‪function zombieUpdateZigZagGoal()
Definition: zombie.gsc:521
‪LOCOMOTION_SPEED_SUPER_SPRINT
‪#define LOCOMOTION_SPEED_SUPER_SPRINT
Definition: blackboard.gsh:159
‪ARMS_DOWN
‪#define ARMS_DOWN
Definition: blackboard.gsh:187
‪ArchetypeZombieOnAnimscriptedCallback
‪function private ArchetypeZombieOnAnimscriptedCallback(entity)
Definition: zombie.gsc:167
‪zombieDeathAction
‪function zombieDeathAction(behaviorTreeEntity)
Definition: zombie.gsc:1111
‪ZM_IDGUN_HOLE_PULL_MAX_SPEED
‪#define ZM_IDGUN_HOLE_PULL_MAX_SPEED
Definition: zombie.gsh:29
‪zombieShouldJumpUnderwaterMelee
‪function zombieShouldJumpUnderwaterMelee(behaviorTreeEntity)
Definition: zombie.gsc:910
‪IDGUN_DAMAGE_DIRECTION
‪#define IDGUN_DAMAGE_DIRECTION
Definition: blackboard.gsh:168
‪ENABLE_BLACKBOARD_DEBUG_TRACKING
‪#define ENABLE_BLACKBOARD_DEBUG_TRACKING(self)
Definition: blackboard.gsh:7
‪BLACKHOLEBOMB_PULL_STATE
‪#define BLACKHOLEBOMB_PULL_STATE
Definition: blackboard.gsh:249
‪BB_GetVariantType
‪function BB_GetVariantType()
Definition: zombie.gsc:246
‪AI_ANIM_MOVE_CODE
‪#define AI_ANIM_MOVE_CODE
Definition: animation_state_machine.gsh:77
‪zombieGibLegsCondition
‪function zombieGibLegsCondition(behaviorTreeEntity)
Definition: zombie.gsc:362
‪ASM_REGISTER_MOCOMP
‪#define ASM_REGISTER_MOCOMP(name, initFunction, updateFunction, terminateFunction)
Definition: animation_state_machine.gsh:1
‪zombieMoveActionUpdate
‪function zombieMoveActionUpdate(behaviorTreeEntity, asmStateName)
Definition: zombie.gsc:1441
‪LOCOMOTION_SPEED_TYPE
‪#define LOCOMOTION_SPEED_TYPE
Definition: blackboard.gsh:155
‪kill
‪function kill(ent_1, str_tag1, ent_2, str_tag2, str_beam_type)
Definition: beam_shared.csc:41
‪AI_ANIM_USE_BOTH_DELTAS_NOCLIP
‪#define AI_ANIM_USE_BOTH_DELTAS_NOCLIP
Definition: animation_state_machine.gsh:83
‪zombieShouldMeleeCondition
‪function zombieShouldMeleeCondition(behaviorTreeEntity)
Definition: zombie.gsc:806
‪GIB_LEGS_LEFT_LEG_FLAG
‪#define GIB_LEGS_LEFT_LEG_FLAG
Definition: gib.gsh:29
‪zombieMoveActionTerminate
‪function zombieMoveActionTerminate(behaviorTreeEntity, asmStateName)
Definition: zombie.gsc:1483
‪InitZombieBehaviorsAndASM
‪function private InitZombieBehaviorsAndASM()
Definition: zombie.gsc:75
‪zombieIDGunHoleDeathMocompTerminate
‪function zombieIDGunHoleDeathMocompTerminate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1305
‪zombieAttackObjectTerminate
‪function private zombieAttackObjectTerminate(behaviorTreeEntity)
Definition: zombie.gsc:357
‪SHOULD_NOT_TURN
‪#define SHOULD_NOT_TURN
Definition: blackboard.gsh:139
‪zombieMeleeSuicideTerminate
‪function zombieMeleeSuicideTerminate(behaviorTreeEntity)
Definition: zombie.gsc:1399
‪zombieZombieIdleMocompStart
‪function private zombieZombieIdleMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1567
‪BB_GetLowGravityVariant
‪function BB_GetLowGravityVariant()
Definition: zombie.gsc:280
‪SERVER_FRAME
‪#define SERVER_FRAME
Definition: shared.gsh:264
‪ZM_MELEE_DIST_SQ
‪#define ZM_MELEE_DIST_SQ
Definition: skeleton.gsh:4
‪ZM_IDGUN_HOLE_PULL_ACC
‪#define ZM_IDGUN_HOLE_PULL_ACC
Definition: zombie.gsh:28
‪ZM_JUKE_CHANCE
‪#define ZM_JUKE_CHANCE
Definition: zombie.gsh:34
‪DAMAGE_DIRECTION_BACK
‪#define DAMAGE_DIRECTION_BACK
Definition: blackboard.gsh:332
‪zombieJukeActionTerminate
‪function private zombieJukeActionTerminate(behaviorTreeEntity)
Definition: zombie.gsc:342
‪ZM_STUMBLE_CHANCE
‪#define ZM_STUMBLE_CHANCE
Definition: zombie.gsh:39
‪ZM_MIN_IN_WATER_DEPTH
‪#define ZM_MIN_IN_WATER_DEPTH
Definition: zombie.gsc:908
‪IsGibbed
‪function IsGibbed(localClientNum, entity, gibFlag)
Definition: gib.csc:734
‪zombieTraversalService
‪function zombieTraversalService(entity)
Definition: zombie.gsc:705
‪increment
‪function increment(str_field_name, n_increment_count=1)
Definition: clientfield_shared.gsc:110
‪BB_GetDamageDirection
‪function BB_GetDamageDirection()
Definition: archetype_utility.gsc:344
‪ARCHETYPE_SPIDER
‪#define ARCHETYPE_SPIDER
Definition: archetype_shared.gsh:41
‪zombieIDGunDeathMocompStart
‪function zombieIDGunDeathMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1138
‪zombieMoveAction
‪function zombieMoveAction(behaviorTreeEntity, asmStateName)
Definition: zombie.gsc:1416
‪isZombieWalking
‪function isZombieWalking(behaviorTreeEntity)
Definition: zombie.gsc:292
‪ZM_CRAWLER_PUSH_DISABLE_TIME
‪#define ZM_CRAWLER_PUSH_DISABLE_TIME
Definition: zombie.gsh:22
‪LOCOMOTION_SPEED_BURNED
‪#define LOCOMOTION_SPEED_BURNED
Definition: blackboard.gsh:161
‪array
‪function filter array
Definition: array_shared.csc:16
‪BB_GetHasLegsStatus
‪function BB_GetHasLegsStatus()
Definition: zombie.gsc:255
‪zombieNotetrackMeleeFire
‪function zombieNotetrackMeleeFire(entity)
Definition: zombie.gsc:367
‪get_closest_valid_player
‪function get_closest_valid_player(origin, ignore_player)
Definition: skeleton.gsc:321
‪jukeDistance
‪var jukeDistance
Definition: archetype_apothicon_fury.gsc:1168
‪zombieShouldMeleeSuicide
‪function zombieShouldMeleeSuicide(behaviorTreeEntity)
Definition: zombie.gsc:1354
‪zombieMeleeJumpMocompStart
‪function zombieMeleeJumpMocompStart(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1149
‪HAS_LEGS_NO
‪#define HAS_LEGS_NO
Definition: blackboard.gsh:166
‪BHTN_SUCCESS
‪#define BHTN_SUCCESS
Definition: behavior_tree.gsh:8
‪ZM_JUKE_TIME_MAX
‪#define ZM_JUKE_TIME_MAX
Definition: zombie.gsh:33
‪ARCHETYPE_ZOMBIE
‪#define ARCHETYPE_ZOMBIE
Definition: archetype_shared.gsh:10
‪add_archetype_spawn_function
‪function add_archetype_spawn_function(archetype, spawn_func)
Definition: ai_shared.csc:23
‪zombieMeleeJumpMocompTerminate
‪function zombieMeleeJumpMocompTerminate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1215
‪ZM_MELEE_YAW
‪#define ZM_MELEE_YAW
Definition: skeleton.gsh:2
‪zombieMeleeSuicideStart
‪function zombieMeleeSuicideStart(behaviorTreeEntity)
Definition: zombie.gsc:1384
‪ZOMBIE_SPECIAL_DAY_EFFECTS_CLIENTFIELD
‪#define ZOMBIE_SPECIAL_DAY_EFFECTS_CLIENTFIELD
Definition: zombie.gsh:62
‪wasCrushedByInterdimensionalGunBlackholeCondition
‪function wasCrushedByInterdimensionalGunBlackholeCondition(behaviorTreeEntity)
Definition: zombie.gsc:1128
‪KNOCKDOWN_TYPE
‪#define KNOCKDOWN_TYPE
Definition: blackboard.gsh:210
‪WHIRLWIND_NORMAL
‪#define WHIRLWIND_NORMAL
Definition: blackboard.gsh:233
‪ASM_ALIAS_ATTRIBUTE
‪#define ASM_ALIAS_ATTRIBUTE
Definition: animation_state_machine.gsh:22
‪LOW_GRAVITY_VARIANT
‪#define LOW_GRAVITY_VARIANT
Definition: blackboard.gsh:119
‪gib_random_parts
‪function gib_random_parts()
Definition: zombie_utility.gsc:2979
‪CreateBlackBoardForEntity
‪function CreateBlackBoardForEntity(entity)
Definition: blackboard.gsc:77
‪VERSION_TU6_FFOTD_020416_0
‪#define VERSION_TU6_FFOTD_020416_0
Definition: version.gsh:50
‪SPAWNFLAG_PATH_PROCEDURAL
‪#define SPAWNFLAG_PATH_PROCEDURAL
Definition: shared.gsh:84
‪ArchetypeZombieSpecialEffectsInit
‪function ArchetypeZombieSpecialEffectsInit()
Definition: zombie.gsc:176
‪HAS_LEGS_TYPE
‪#define HAS_LEGS_TYPE
Definition: blackboard.gsh:164
‪zombieIsAtAttackObject
‪function zombieIsAtAttackObject(entity)
Definition: zombie.gsc:716
‪init
‪function autoexec init()
Definition: zombie.gsc:45
‪KNOCKDOWN_DIRECTION
‪#define KNOCKDOWN_DIRECTION
Definition: blackboard.gsh:208
‪JUKE_DIRECTION
‪#define JUKE_DIRECTION
Definition: blackboard.gsh:133
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪AI_ANIM_USE_ANGLE_DELTAS
‪#define AI_ANIM_USE_ANGLE_DELTAS
Definition: animation_state_machine.gsh:80
‪LOCOMOTION_SPEED_SLIDE
‪#define LOCOMOTION_SPEED_SLIDE
Definition: blackboard.gsh:162
‪zombieNotetrackCrushFire
‪function zombieNotetrackCrushFire(behaviorTreeEntity)
Definition: zombie.gsc:422
‪ArchetypeZombieSpecialEffectsCallback
‪function private ArchetypeZombieSpecialEffectsCallback(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName)
Definition: zombie.gsc:181
‪ZM_MELEE_WATER_JUMP_DIST
‪#define ZM_MELEE_WATER_JUMP_DIST
Definition: zombie.gsc:909
‪RequestState
‪function RequestState(entity, stateName)
Definition: animation_state_machine_utility.gsc:8
‪AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS
‪#define AI_ANIM_USE_BOTH_DELTAS_ZONLY_PHYSICS
Definition: animation_state_machine.gsh:85
‪ORANGE
‪#define ORANGE
Definition: shared.gsh:179
‪ARCHETYPE_ZOMBIE_QUAD
‪#define ARCHETYPE_ZOMBIE_QUAD
Definition: archetype_shared.gsh:21
‪GibHead
‪function GibHead(entity)
Definition: gib.gsc:443
‪ZM_JUKE_TIME_MIN
‪#define ZM_JUKE_TIME_MIN
Definition: zombie.gsh:32
‪BB_IDGunGetDamageDirection
‪function BB_IDGunGetDamageDirection()
Definition: zombie.gsc:271
‪BB_GetArmsPosition
‪function BB_GetArmsPosition()
Definition: zombie.gsc:198
‪BT_REGISTER_ACTION
‪#define BT_REGISTER_ACTION(name, initFunction, updateFunction, terminateFunction)
Definition: behavior.gsh:4
‪wasKilledByInterdimensionalGunCondition
‪function wasKilledByInterdimensionalGunCondition(behaviorTreeEntity)
Definition: zombie.gsc:1116
‪get_behavior_attribute
‪function get_behavior_attribute(attribute)
Definition: ai_shared.gsc:184
‪ArchetypeZombieBlackboardInit
‪function ArchetypeZombieBlackboardInit()
Definition: zombie.gsc:132
‪zombieCrawlerCollision
‪function zombieCrawlerCollision(behaviorTreeEntity)
Definition: zombie.gsc:664
‪BB_GetShouldTurn
‪function BB_GetShouldTurn()
Definition: zombie.gsc:262
‪ZM_STUMBLE_TIME_MIN
‪#define ZM_STUMBLE_TIME_MIN
Definition: zombie.gsh:37
‪LOCOMOTION_SPEED_RUN
‪#define LOCOMOTION_SPEED_RUN
Definition: blackboard.gsh:157
‪CreateInterfaceForEntity
‪function CreateInterfaceForEntity(entity)
Definition: ai_interface.gsc:110
‪zombieSpawnSetup
‪function zombieSpawnSetup()
Definition: zombie_utility.gsc:28
‪ZM_ZOMBIE_HEIGHT
‪#define ZM_ZOMBIE_HEIGHT
Definition: _zm_behavior.gsh:23
‪zombieShouldAttackObject
‪function zombieShouldAttackObject(entity)
Definition: zombie.gsc:773
‪VARIANT_TYPE
‪#define VARIANT_TYPE
Definition: blackboard.gsh:118
‪ArchetypeZombieDeathOverrideInit
‪function ArchetypeZombieDeathOverrideInit()
Definition: zombie.gsc:1494
‪zombieMeleeJumpMocompUpdate
‪function zombieMeleeJumpMocompUpdate(entity, mocompAnim, mocompAnimBlendOutTime, mocompAnimFlag, mocompDuration)
Definition: zombie.gsc:1161
‪ZM_MOVE_DIST_SQ
‪#define ZM_MOVE_DIST_SQ
Definition: zombie.gsh:53
‪zombieShouldJumpMeleeCondition
‪function zombieShouldJumpMeleeCondition(behaviorTreeEntity)
Definition: zombie.gsc:845