‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
behavior_zombie_dog.gsc
Go to the documentation of this file.
1 #using scripts\shared\ai\systems\animation_state_machine_utility;
2 #using scripts\shared\ai\systems\animation_state_machine_notetracks;
3 #using scripts\shared\ai\archetype_utility;
4 #using scripts\shared\ai\systems\behavior_tree_utility;
5 #using scripts\shared\ai\systems\blackboard;
6 #using scripts\shared\ai\systems\ai_interface;
7 #using scripts\shared\ai\zombie;
8 #using scripts\shared\spawner_shared;
9 #using scripts\shared\ai\archetype_mocomps_utility;
10 #using scripts\shared\ai\archetype_zombie_dog_interface;
11 #using scripts\shared\ai_shared;
12 #using scripts\shared\math_shared;
13 
14 #insert scripts\shared\ai\systems\animation_state_machine.gsh;
15 #insert scripts\shared\ai\systems\behavior.gsh;
16 #insert scripts\shared\ai\systems\behavior_tree.gsh;
17 #insert scripts\shared\ai\systems\blackboard.gsh;
18 #insert scripts\shared\ai\utility.gsh;
19 #insert scripts\shared\ai\zombie.gsh;
20 
21 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
22 #insert scripts\shared\shared.gsh;
23 
24 #namespace ZombieDogBehavior;
25 
27 {
28  // INIT BLACKBOARD
30 
31  // ------- ZOMBIE DOG - SERVICES ----------- //
32  ‪BT_REGISTER_API( "zombieDogTargetService", &‪zombieDogTargetService );
33 
34  // ------- ZOMBIE DOG - CONDITIONS --------- //
35  ‪BT_REGISTER_API( "zombieDogShouldMelee", &‪zombieDogShouldMelee );
36  ‪BT_REGISTER_API( "zombieDogShouldWalk", &‪zombieDogShouldWalk );
37  ‪BT_REGISTER_API( "zombieDogShouldRun", &‪zombieDogShouldRun );
38 
39  // ------- ZOMBIE DOG - ACTIONS ------------ //
41 
43 
45 }
46 
47 function ‪ArchetypeZombieDogBlackboardInit() // self = AI
48 {
49  // CREATE BLACKBOARD
51 
52  // CREATE INTERFACE
54 
55  // USE UTILITY BLACKBOARD
57 
58  // CREATE ZOMBIE DOG BLACKBOARD
59  ‪BB_REGISTER_ATTRIBUTE( ‪LOW_GRAVITY, "normal", undefined );
62 
63  // REGISTER ANIMSCRIPTED CALLBACK
64  self.___ArchetypeOnAnimscriptedCallback = &‪ArchetypeZombieDogOnAnimscriptedCallback;
65 
66  // ENABLE DEBUGGING IN ODYSSEY
68 
69  // Custom attributes
70  self.kill_on_wine_coccon = true;
71 }
72 
74 {
75  // UNREGISTER THE BLACKBOARD
76  entity.__blackboard = undefined;
77 
78  // REREGISTER BLACKBOARD
80 }
81 
83 {
84  /#
85  if ( ‪IS_TRUE( self.isPuppet ) )
86  {
87  return ‪SHOULD_RUN_YES;
88  }
89  #/
90 
91  if ( ‪IS_TRUE( self.hasSeenFavoriteEnemy ) || ( ‪ai::HasAiAttribute( self, "sprint" ) && ‪ai::GetAiAttribute( self, "sprint" ) ) )
92  return ‪SHOULD_RUN_YES;
93  return ‪SHOULD_RUN_NO;
94 }
95 
97 {
98  if ( self ‪ai::has_behavior_attribute( "howl_chance" ) && ‪IS_TRUE( self.hasSeenFavoriteEnemy ) )
99  {
100  if ( !isdefined( self.shouldHowl ) )
101  {
102  chance = self ‪ai::get_behavior_attribute( "howl_chance" );
103  self.shouldHowl = RandomFloat( 1 ) <= chance;
104  }
105  if ( self.shouldHowl )
106  {
107  return ‪SHOULD_HOWL_YES;
108  }
109  else
110  {
111  return ‪SHOULD_HOWL_NO;
112  }
113  }
114 
115  return ‪SHOULD_HOWL_NO;
116 }
117 
118 function ‪GetYaw(org)
119 {
120  angles = VectorToAngles(org-self.origin);
121  return angles[1];
122 }
123 
124 // 0 if I'm facing my enemy, 90 if I'm side on, 180 if I'm facing away.
126 {
127  assert( IsDefined(self.enemy) );
128 
129  yaw = self.angles[1] - ‪GetYaw(self.enemy.origin);
130  yaw = AngleClamp180( yaw );
131 
132  if (yaw < 0)
133  {
134  yaw = -1 * yaw;
135  }
136 
137  return yaw;
138 }
139 
140 function ‪need_to_run()
141 {
142  run_dist_squared = ‪SQR( self ‪ai::get_behavior_attribute( "min_run_dist" ) );
143  run_yaw = 20;
144  run_pitch = 30;
145  run_height = 64;
146 
147  if ( self.health < self.maxhealth )
148  {
149  // dog took damage
150  return true;
151  }
152 
153  if ( !IsDefined( self.enemy ) || !IsAlive( self.enemy ) )
154  {
155  return false;
156  }
157 
158  if ( !self CanSee( self.enemy ) )
159  {
160  return false;
161  }
162 
163  dist = DistanceSquared( self.origin, self.enemy.origin );
164  if ( dist > run_dist_squared )
165  {
166  return false;
167  }
168 
169  height = self.origin[2] - self.enemy.origin[2];
170  if ( abs( height ) > run_height )
171  {
172  return false;
173  }
174 
175  yaw = self ‪AbsYawToEnemy();
176  if ( yaw > run_yaw )
177  {
178  return false;
179  }
180 
181  pitch = AngleClamp180( VectorToAngles( self.origin - self.enemy.origin )[0] );
182  if ( abs( pitch ) > run_pitch )
183  {
184  return false;
185  }
186 
187  return true;
188 }
189 
190 function private ‪is_target_valid( dog, target )
191 {
192  if( !IsDefined( target ) )
193  {
194  return false;
195  }
196 
197  if( !IsAlive( target ) )
198  {
199  return false;
200  }
201  if (!(dog.team == "allies"))
202  {
203  if( !IsPlayer( target ) && SessionModeIsZombiesGame())
204  {
205  return false;
206  }
207 
208  if( IsDefined(target.is_zombie) && target.is_zombie == true )
209  {
210  return false;
211  }
212  }
213 
214  if( IsPlayer( target ) && target.sessionstate == "spectator" )
215  {
216  return false;
217  }
218 
219  if( IsPlayer( target ) && target.sessionstate == "intermission" )
220  {
221  return false;
222  }
223 
224  if( ‪IS_TRUE(self.‪intermission) )
225  {
226  return false;
227  }
228 
229  if( ‪IS_TRUE( target.ignoreme ) )
230  {
231  return false;
232  }
233 
234  if( target IsNoTarget() )
235  {
236  return false;
237  }
238 
239  if( dog.team == target.team )
240  {
241  return false;
242  }
243 
244  //for additional level specific checks
245  if( IsPlayer( target ) && IsDefined( level.is_player_valid_override ) )
246  {
247  return [[ level.is_player_valid_override ]]( target );
248  }
249 
250  return true;
251 }
252 
253 function private ‪get_favorite_enemy( dog )
254 {
255  dog_targets = [];
256  if ( SessionModeIsZombiesGame() )
257  {
258  if (self.team == "allies")
259  {
260  dog_targets = GetAITeamArray( level.zombie_team );
261  }
262  else
263  {
264  dog_targets = getplayers();
265  }
266  }
267  else
268  {
269  dog_targets = ArrayCombine( getplayers(), GetAIArray(), false, false );
270  }
271  least_hunted = dog_targets[0];
272  closest_target_dist_squared = undefined;
273  for( i = 0; i < dog_targets.size; i++ )
274  {
275  if ( !isdefined( dog_targets[i].hunted_by ) )
276  {
277  dog_targets[i].hunted_by = 0;
278  }
279 
280  if( !‪is_target_valid( dog, dog_targets[i] ) )
281  {
282  continue;
283  }
284 
285  if( !‪is_target_valid( dog, least_hunted ) )
286  {
287  least_hunted = dog_targets[i];
288  }
289 
290  dist_squared = DistanceSquared( dog.origin, dog_targets[i].origin );
291  if( dog_targets[i].hunted_by <= least_hunted.hunted_by && ( !IsDefined( closest_target_dist_squared ) || dist_squared < closest_target_dist_squared ) )
292  {
293  least_hunted = dog_targets[i];
294  closest_target_dist_squared = dist_squared;
295  }
296  }
297  // do not return the default first player if he is invalid
298  if( !‪is_target_valid( dog, least_hunted ) )
299  {
300  return undefined;
301  }
302  else
303  {
304  least_hunted.hunted_by += 1;
305 
306  return least_hunted;
307  }
308 
309 }
310 
312 {
313  if ( IsPlayer( self ) )
314  return self.last_valid_position;
315  return self.origin;
316 }
317 
318 function ‪get_locomotion_target( behaviorTreeEntity )
319 {
320  ‪last_valid_position = behaviorTreeEntity.favoriteenemy ‪get_last_valid_position();
321  if ( !IsDefined( ‪last_valid_position ) )
322  return undefined;
323 
324  locomotion_target = ‪last_valid_position;
325  if ( ‪ai::has_behavior_attribute( "spacing_value" ) )
326  {
327  // calculate the point based on the spacing values
328  spacing_near_dist = ‪ai::get_behavior_attribute( "spacing_near_dist" );
329  spacing_far_dist = ‪ai::get_behavior_attribute( "spacing_far_dist" );
330  spacing_horz_dist = ‪ai::get_behavior_attribute( "spacing_horz_dist" );
331  spacing_value = ‪ai::get_behavior_attribute( "spacing_value" );
332 
333  // get the offset from our target and get a vector perpendicular to it
334  to_enemy = behaviorTreeEntity.favoriteenemy.origin - behaviorTreeEntity.origin;
335  perp = VectorNormalize( ( -to_enemy[1], to_enemy[0], 0 ) );
336 
337  // calculate the offset from the target
338  offset = perp * spacing_horz_dist * spacing_value;
339 
340  // lerp to actual target position based on distance
341  spacing_dist = ‪math::clamp( Length( to_enemy ), spacing_near_dist, spacing_far_dist );
342  lerp_amount = ‪math::clamp( ( spacing_dist - spacing_near_dist ) / ( spacing_far_dist - spacing_near_dist ), 0.0, 1.0 );
343  desired_point = ‪last_valid_position + ( offset * lerp_amount );
344 
345  // get the closest pathable point
346  desired_point = GetClosestPointOnNavMesh( desired_point, spacing_horz_dist * 1.2, 16 );
347  if ( IsDefined( desired_point ) )
348  {
350  //line( behaviorTreeEntity.origin, desired_point, ( 1.0, 1.0, 0.0 ), 0.9, 1 );
351  //#/
352  locomotion_target = desired_point;
353  }
354  }
355 
356  return locomotion_target;
357 }
358 
359 // ------- ZOMBIE DOG - TARGET SERVICE -----------//
360 function ‪zombieDogTargetService( behaviorTreeEntity )
361 {
362  // don't target if the round is over
363  if ( ‪IS_TRUE( level.intermission ) )
364  {
365  behaviorTreeEntity ClearPath();
366  return;
367  }
368 
369  // don't target if we're in puppet mode
370  /#
371  if ( ‪IS_TRUE( behaviortreeentity.isPuppet ) )
372  {
373  return;
374  }
375  #/
376 
377  // don't move if we don't have a target
378  if ( behaviorTreeEntity.ignoreall || behaviorTreeEntity.pacifist || ( isdefined( behaviorTreeEntity.favoriteenemy ) && !‪is_target_valid( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy ) ) )
379  {
380  if ( isdefined( behaviorTreeEntity.favoriteenemy ) && isdefined( behaviorTreeEntity.favoriteenemy.hunted_by ) && behaviorTreeEntity.favoriteenemy.hunted_by > 0 )
381  {
382  // if we had a target before, decrement its hunted count so it knows we're not after it anymore
383  behaviorTreeEntity.favoriteenemy.hunted_by--;
384  }
385  behaviorTreeEntity.favoriteenemy = undefined;
386  behaviorTreeEntity.hasSeenFavoriteEnemy = false;
387 
388  //if enemies are not valid, stay at the spot
389  if ( !behaviorTreeEntity.ignoreall )
390  {
391  behaviorTreeEntity SetGoal( behaviorTreeEntity.origin );
392  }
393 
394  return;
395  }
396 
397  // dog isn't in playable area yet
398  if ( ‪IS_TRUE( behaviorTreeEntity.ignoreme ) )
399  {
400  return;
401  }
402 
403  // calculate a favorite enemy if we don't have one (zombie mode does this in another script)
404  if( (!SessionModeIsZombiesGame() || behaviorTreeEntity.team == "allies") && !‪is_target_valid(behaviorTreeEntity, behaviorTreeEntity.favoriteenemy) )
405  {
406  behaviorTreeEntity.favoriteenemy = ‪get_favorite_enemy( behaviorTreeEntity );
407  }
408 
409  // have we seen our target yet?
410  if ( !‪IS_TRUE( behaviorTreeEntity.hasSeenFavoriteEnemy ) )
411  {
412  if ( IsDefined( behaviorTreeEntity.favoriteenemy ) && behaviorTreeEntity ‪need_to_run() )
413  {
414  behaviorTreeEntity.hasSeenFavoriteEnemy = true;
415  }
416  }
417 
418  // always move towards enemy
419  if ( IsDefined( behaviorTreeEntity.favoriteenemy ) )
420  {
421  if ( IsDefined( level.enemy_location_override_func ) )
422  {
423  goalPos = [[ level.enemy_location_override_func ]]( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy );
424 
425  if ( IsDefined( goalPos ) )
426  {
427  behaviorTreeEntity SetGoal( goalPos );
428  return;
429  }
430  }
431 
432  locomotion_target = ‪get_locomotion_target( behaviorTreeEntity );
433  if ( IsDefined( locomotion_target ) )
434  {
435  repathDist = 16;
436  if ( !IsDefined( behaviorTreeEntity.lastTargetPosition ) || DistanceSquared( behaviorTreeEntity.lastTargetPosition, locomotion_target ) > ‪SQR( repathDist ) || !behaviorTreeEntity HasPath() )
437  {
438  behaviorTreeEntity UsePosition( locomotion_target );
439  behaviorTreeEntity.lastTargetPosition = locomotion_target;
440  }
441  }
442  }
443 }
444 
445 // ------- ZOMBIE DOG - SHOULD MELEE CONDITION -----------//
446 function ‪zombieDogShouldMelee( behaviorTreeEntity )
447 {
448  // don't melee if we don't have a target
449  if ( behaviorTreeEntity.ignoreall || !‪is_target_valid( behaviorTreeEntity, behaviorTreeEntity.favoriteenemy ) )
450  {
451  return false;
452  }
453 
454  if ( !‪IS_TRUE( level.intermission ) )
455  {
456  meleeDist = 6 * 12; // 6 ft
457  if ( DistanceSquared( behaviorTreeEntity.origin, behaviorTreeEntity.favoriteenemy.origin ) < ‪SQR( meleeDist ) && behaviorTreeEntity CanSee( behaviorTreeEntity.favoriteenemy ) )
458  {
459  dog_eye = behaviorTreeEntity.origin + ( 0, 0, 40 );
460  enemy_eye = behaviorTreeEntity.favoriteenemy GetEye();
461 
463  ‪trace = PhysicsTrace( dog_eye, enemy_eye, (0, 0, 0), (0, 0, 0), self, clip_mask );
464  can_melee = ( ‪trace[ "fraction" ] == 1.0 || ( IsDefined( ‪trace[ "entity" ] ) && ‪trace[ "entity" ] == behaviorTreeEntity.favoriteenemy ) );
465  if ( ‪IS_TRUE( can_melee ) )
466  {
467  return true;
468  }
469  }
470  }
471 
472  return false;
473 }
474 
475 // ------- ZOMBIE DOG - SHOULD WALK CONDITION -----------//
476 function ‪zombieDogShouldWalk( behaviorTreeEntity )
477 {
479 }
480 
481 // ------- ZOMBIE DOG - SHOULD RUN CONDITION -----------//
482 function ‪zombieDogShouldRun( behaviorTreeEntity )
483 {
485 }
486 
487 // ------- ZOMBIE DOG - MELEE ACTION -----------//
489 {
490  if ( !IsDefined( self.enemy ) || !IsPlayer( self.enemy ) )
491  return false;
492 
493  height_diff = self.enemy.origin[2] - self.origin[2];
494 
495  low_enough = 30.0;
496 
497  if ( height_diff < low_enough && self.enemy GetStance() == "prone" )
498  {
499  return true;
500  }
501 
502  // check if the jumping melee attack origin would be in a solid
503  melee_origin = ( self.origin[0], self.origin[1], self.origin[2] + 65 );
504  enemy_origin = ( self.enemy.origin[0], self.enemy.origin[1], self.enemy.origin[2] + 32 );
505 
506  if ( !BulletTracePassed( melee_origin, enemy_origin, false, self ) )
507  {
508  return true;
509  }
510 
511  return false;
512 }
513 
514 function ‪zombieDogMeleeAction( behaviorTreeEntity, asmStateName )
515 {
516  behaviorTreeEntity ClearPath();
517 
518  context = "high";
519  if ( behaviorTreeEntity ‪use_low_attack() )
520  context = "low";
521  ‪Blackboard::SetBlackBoardAttribute( behaviorTreeEntity, ‪CONTEXT, context );
522 
523  ‪AnimationStateNetworkUtility::RequestState( behaviorTreeEntity, asmStateName );
524  return ‪BHTN_RUNNING;
525 }
526 
527 function ‪zombieDogMeleeActionTerminate( behaviorTreeEntity, asmStateName )
528 {
529  ‪Blackboard::SetBlackBoardAttribute( behaviorTreeEntity, ‪CONTEXT, undefined );
530 
531  return ‪BHTN_SUCCESS;
532 }
533 
534 function ‪zombieDogGravity( entity, attribute, oldValue, value )
535 {
537 }
‪SHOULD_RUN_NO
‪#define SHOULD_RUN_NO
Definition: blackboard.gsh:175
‪get_locomotion_target
‪function get_locomotion_target(behaviorTreeEntity)
Definition: behavior_zombie_dog.gsc:318
‪need_to_run
‪function need_to_run()
Definition: behavior_zombie_dog.gsc:140
‪BT_REGISTER_API
‪#define BT_REGISTER_API(name, function)
Definition: behavior.gsh:1
‪BB_GetShouldHowlStatus
‪function BB_GetShouldHowlStatus()
Definition: behavior_zombie_dog.gsc:96
‪get_favorite_enemy
‪function private get_favorite_enemy(dog)
Definition: behavior_zombie_dog.gsc:253
‪intermission
‪function intermission()
Definition: _zm.gsc:6542
‪SHOULD_HOWL
‪#define SHOULD_HOWL
Definition: blackboard.gsh:177
‪BHTN_RUNNING
‪#define BHTN_RUNNING
Definition: behavior_tree.gsh:9
‪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
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪get_last_valid_position
‪function get_last_valid_position()
Definition: behavior_zombie_dog.gsc:311
‪zombieDogGravity
‪function zombieDogGravity(entity, attribute, oldValue, value)
Definition: behavior_zombie_dog.gsc:534
‪HasAiAttribute
‪function HasAiAttribute(entity, attribute)
Definition: ai_interface.gsc:132
‪SetBlackBoardAttribute
‪function SetBlackBoardAttribute(entity, attributeName, attributeValue)
Definition: blackboard.gsc:56
‪PHYSICS_TRACE_MASK_CLIP
‪#define PHYSICS_TRACE_MASK_CLIP
Definition: shared.gsh:133
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪ArchetypeZombieDogOnAnimscriptedCallback
‪function private ArchetypeZombieDogOnAnimscriptedCallback(entity)
Definition: behavior_zombie_dog.gsc:73
‪zombieDogTargetService
‪function zombieDogTargetService(behaviorTreeEntity)
Definition: behavior_zombie_dog.gsc:360
‪SQR
‪#define SQR(__var)
Definition: shared.gsh:293
‪BB_GetShouldRunStatus
‪function BB_GetShouldRunStatus()
Definition: behavior_zombie_dog.gsc:82
‪RegisterUtilityBlackboardAttributes
‪function RegisterUtilityBlackboardAttributes()
Definition: archetype_utility.gsc:139
‪zombieDogShouldRun
‪function zombieDogShouldRun(behaviorTreeEntity)
Definition: behavior_zombie_dog.gsc:482
‪has_behavior_attribute
‪function has_behavior_attribute(attribute)
Definition: ai_shared.gsc:198
‪SHOULD_HOWL_NO
‪#define SHOULD_HOWL_NO
Definition: blackboard.gsh:179
‪SHOULD_RUN_YES
‪#define SHOULD_RUN_YES
Definition: blackboard.gsh:174
‪ENABLE_BLACKBOARD_DEBUG_TRACKING
‪#define ENABLE_BLACKBOARD_DEBUG_TRACKING(self)
Definition: blackboard.gsh:7
‪RegisterBehaviorScriptFunctions
‪function autoexec RegisterBehaviorScriptFunctions()
Definition: behavior_zombie_dog.gsc:26
‪ASM_ZOMBIE_DOG_MELEE_NOTETRACK
‪#define ASM_ZOMBIE_DOG_MELEE_NOTETRACK
Definition: skeleton.gsh:21
‪SHOULD_RUN
‪#define SHOULD_RUN
Definition: blackboard.gsh:173
‪zombieDogShouldMelee
‪function zombieDogShouldMelee(behaviorTreeEntity)
Definition: behavior_zombie_dog.gsc:446
‪PHYSICS_TRACE_MASK_PHYSICS
‪#define PHYSICS_TRACE_MASK_PHYSICS
Definition: shared.gsh:130
‪zombieDogShouldWalk
‪function zombieDogShouldWalk(behaviorTreeEntity)
Definition: behavior_zombie_dog.gsc:476
‪zombieNotetrackMeleeFire
‪function zombieNotetrackMeleeFire(entity)
Definition: zombie.gsc:367
‪GetAiAttribute
‪function GetAiAttribute(entity, attribute)
Definition: ai_interface.gsc:118
‪BHTN_SUCCESS
‪#define BHTN_SUCCESS
Definition: behavior_tree.gsh:8
‪zombieDogMeleeActionTerminate
‪function zombieDogMeleeActionTerminate(behaviorTreeEntity, asmStateName)
Definition: behavior_zombie_dog.gsc:527
‪add_archetype_spawn_function
‪function add_archetype_spawn_function(archetype, spawn_func)
Definition: ai_shared.csc:23
‪zombieDogMeleeAction
‪function zombieDogMeleeAction(behaviorTreeEntity, asmStateName)
Definition: behavior_zombie_dog.gsc:514
‪AbsYawToEnemy
‪function AbsYawToEnemy()
Definition: behavior_zombie_dog.gsc:125
‪CreateBlackBoardForEntity
‪function CreateBlackBoardForEntity(entity)
Definition: blackboard.gsc:77
‪SHOULD_HOWL_YES
‪#define SHOULD_HOWL_YES
Definition: blackboard.gsh:178
‪GetYaw
‪function GetYaw(org)
Definition: behavior_zombie_dog.gsc:118
‪use_low_attack
‪function use_low_attack()
Definition: behavior_zombie_dog.gsc:488
‪clamp
‪function clamp(val, val_min, val_max)
Definition: math_shared.csc:16
‪RequestState
‪function RequestState(entity, stateName)
Definition: animation_state_machine_utility.gsc:8
‪LOW_GRAVITY
‪#define LOW_GRAVITY
Definition: blackboard.gsh:120
‪BT_REGISTER_ACTION
‪#define BT_REGISTER_ACTION(name, initFunction, updateFunction, terminateFunction)
Definition: behavior.gsh:4
‪get_behavior_attribute
‪function get_behavior_attribute(attribute)
Definition: ai_shared.gsc:184
‪ARCHETYPE_ZOMBIE_DOG
‪#define ARCHETYPE_ZOMBIE_DOG
Definition: archetype_shared.gsh:11
‪CreateInterfaceForEntity
‪function CreateInterfaceForEntity(entity)
Definition: ai_interface.gsc:110
‪CONTEXT
‪#define CONTEXT
Definition: blackboard.gsh:16
‪is_target_valid
‪function private is_target_valid(dog, target)
Definition: behavior_zombie_dog.gsc:190
‪last_valid_position
‪function last_valid_position()
Definition: player_shared.gsc:58
‪RegisterZombieDogInterfaceAttributes
‪function RegisterZombieDogInterfaceAttributes()
Definition: archetype_zombie_dog_interface.gsc:6
‪ArchetypeZombieDogBlackboardInit
‪function ArchetypeZombieDogBlackboardInit()
Definition: behavior_zombie_dog.gsc:47