‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_amws.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\math_shared;
4 #using scripts\shared\statemachine_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\shared\array_shared;
7 #using scripts\shared\util_shared;
8 
9 #using scripts\shared\weapons\_heatseekingmissile;
10 
11 #using scripts\shared\vehicle_shared;
12 #using scripts\shared\vehicle_death_shared;
13 #using scripts\shared\vehicle_ai_shared;
14 
15 #insert scripts\shared\shared.gsh;
16 #insert scripts\shared\statemachine.gsh;
17 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
18 
19 #using scripts\shared\ai\systems\blackboard;
20 #using scripts\shared\ai\blackboard_vehicle;
21 #insert scripts\shared\ai\utility.gsh;
22 
23 #using scripts\shared\turret_shared;
24 
25 #define AMWS_MAX_TIME_AT_SAME_POSITION 1.0
26 #define AMWS_CHANGE_POSITION_TOATTACK_TARGET_DELAY 0.5
27 
28 #define AMWS_MOVE_DIST_MIN 80
29 #define AMWS_MOVE_DIST_MAX 500
30 #define AMWS_AWAY_FROM_CHARACTER 200
31 
32 #define AMWS_EVADE_DIST_MIN 120
33 #define AMWS_EVADE_DIST_MAX 360
34 #define AMWS_EVADE_HALF_HEIGHT ( AMWS_MOVE_DIST_MAX * 0.5 )
35 #define AMWS_EVADE_POINT_SPACING_FACTOR ( 1.5 )
36 #define AMWS_ACCELERATION VAL( self.settings.default_move_acceleration, 10.0 )
37 
38 #define AMWS_ENEMY_TOO_CLOSE_DIST ( 0.8 * 0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) )
39 
40 #define AMWS_REPATH_RANGE 100
41 
42 #define WEAPON_REGULAR "amws_gun_turret"
43 #define WEAPON_STATIONARY "amws_gun_turret_stationary"
44 
45 #using_animtree( "generic" );
46 
47 #namespace amws;
48 
49 ‪REGISTER_SYSTEM( "amws", &‪__init__, undefined )
50 
51 function ‪__init__()
52 {
53  vehicle::add_main_callback( "amws", &‪amws_initialize );
54 }
55 
57 {
58  self UseAnimTree( #animtree );
59 
60  Target_Set( self, ( 0, 0, 0 ) );
61 
64 
65  self.health = self.healthdefault;
66 
68 
69  self EnableAimAssist();
70  self SetNearGoalNotifyDist( 40 );
71 
72  self.fovcosine = 0; // +/-90 degrees = 180
73  self.fovcosinebusy = 0.574; //+/- 55 degrees = 110 fov
74 
75  self.vehAirCraftCollisionEnabled = true;
76 
77  assert( isdefined( self.scriptbundlesettings ) );
78 
79  self.settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
80  self.goalRadius = 999999;
81  self.goalHeight = 512;
82  self SetGoal( self.origin, false, self.goalRadius, self.goalHeight );
83 
84  //self.waittime_before_delete = 40;
85  self.delete_on_death = false;
86 
87  self.overrideVehicleDamage = &‪drone_callback_damage;
88 
89  self thread ‪vehicle_ai::nudge_collision();
90 
91  self.cobra = false;
92  self ASMRequestSubstate( "locomotion@movement" );
93 
94  self.variant = "light_weight";
95  if( IsSubStr( self.vehicleType, "pamws" ) )
96  {
97  self.variant = "armored";
98  }
99 
100  self ‪vehicle_ai::Cooldown( "cobra_up", 10 );
101 
102  //disable some cybercom abilities
103  if( IsDefined( level.vehicle_initializer_cb ) )
104  {
105  [[level.vehicle_initializer_cb]]( self );
106  }
107 
108  ‪defaultRole();
109 }
110 
111 function ‪defaultRole()
112 {
114 
115  self ‪vehicle_ai::get_state_callbacks( "combat" ).enter_func = &‪state_combat_enter;
116  self ‪vehicle_ai::get_state_callbacks( "combat" ).update_func = &‪state_combat_update;
117  self ‪vehicle_ai::get_state_callbacks( "driving" ).update_func = &‪state_driving_update;
118  self ‪vehicle_ai::get_state_callbacks( "emped" ).update_func = &‪state_emped_update;
119  self ‪vehicle_ai::get_state_callbacks( "surge" ).update_func = &‪state_surge_update;
120  self ‪vehicle_ai::get_state_callbacks( "surge" ).exit_func = &‪state_surge_exit;
121 
122  self ‪vehicle_ai::get_state_callbacks( "death" ).update_func = &‪state_death_update;
123 
124  self ‪vehicle_ai::add_state( "stationary",
128 
129  ‪vehicle_ai::add_interrupt_connection( "stationary", "scripted", "enter_scripted" );
130  ‪vehicle_ai::add_interrupt_connection( "stationary", "emped", "emped" );
131  ‪vehicle_ai::add_interrupt_connection( "stationary", "off", "shut_off" );
132  ‪vehicle_ai::add_interrupt_connection( "stationary", "driving", "enter_vehicle" );
133  ‪vehicle_ai::add_interrupt_connection( "stationary", "pain", "pain" );
134  ‪vehicle_ai::add_interrupt_connection( "stationary", "surge", "surge" );
135 
136  ‪vehicle_ai::add_utility_connection( "stationary", "combat" );
137  ‪vehicle_ai::add_utility_connection( "combat", "stationary" );
138 
139  self ‪vehicle_ai::StartInitialState( "combat" );
140 }
141 
142 // ----------------------------------------------
143 // State: death
144 // ----------------------------------------------
145 function ‪state_death_update( params )
146 {
147  self endon( "death" );
148 
149  death_type = ‪vehicle_ai::get_death_type( params );
150  if ( !isdefined( death_type ) )
151  {
152  params.death_type = "gibbed";
153  death_type = params.death_type;
154  }
155 
156  if ( death_type === "suicide_crash" )
157  {
158  self ‪death_suicide_crash( params );
159  }
160 
162 }
163 
164 function ‪death_suicide_crash( params )
165 {
166  self endon( "death" );
167 
168  goaldir = AnglesToForward( self.angles );
169  goalDist = RandomFloatRange( 300, 400 );
170  goalpos = self.origin + goaldir * goalDist;
171  self SetMaxSpeedScale( 50 * ‪MPH_TO_INCHES_PER_SEC / ( self GetMaxSpeed( true ) ) );
172  self SetMaxAccelerationScale( 50 / self GetDefaultAcceleration() );
173  self SetSpeed( self.settings.surgespeedmultiplier * self.settings.defaultMoveSpeed );
174  self SetVehGoalPos( goalpos, false );
175  self ‪util::waittill_any_timeout( 3.5, "near_goal", "veh_collision" );
176 
177  self SetMaxSpeedScale( 0.1 );
178  self SetSpeed( 0.1 );
181  self.death_type = "gibbed";
182 }
183 
184 // ----------------------------------------------
185 // State: driving
186 // ----------------------------------------------
187 function ‪state_driving_update( params )
188 {
189  self endon( "change_state" );
190  self endon( "death" );
191 
192  driver = self GetSeatOccupant( 0 );
193 
194  if ( isPlayer( driver ) )
195  {
196  while ( true )
197  {
198  driver endon( "disconnect" );
199 
201 
202  if ( self.cobra === false )
203  {
204  self ‪cobra_raise();
205  }
206  else
207  {
208  self ‪cobra_retract();
209  }
210  }
211  }
212 }
213 
214 // rise up and turn into a turret
215 function ‪cobra_raise()
216 {
217  self.cobra = true;
218  if ( isdefined( self.settings.cobra_fx_1 ) && isdefined( self.settings.cobra_tag_1 ) )
219  {
220  PlayFxOnTag( self.settings.cobra_fx_1, self, self.settings.cobra_tag_1 );
221  }
222  self ASMRequestSubstate( "cobra@stationary" );
223  self ‪vehicle_ai::waittill_asm_complete( "cobra@stationary", 4 );
224  self laserOn();
225 }
226 
227 // retract turret and be mobile again
229 {
230  self.cobra = false;
231  self laserOff();
232  self notify( "disable_lens_flare" );
233  self ASMRequestSubstate( "locomotion@movement" );
234  self ‪vehicle_ai::waittill_asm_complete( "locomotion@movement", 4 );
235 }
236 
237 // ----------------------------------------------
238 // State: emped
239 // ----------------------------------------------
240 function ‪state_emped_update( params )
241 {
242  self endon ("death");
243  self endon ("change_state");
244 
245  angles = self GetTagAngles( "tag_turret" );
246  self SetTurretTargetRelativeAngles( ( 45, angles[1] - self.angles[1], 0 ), 0 );
247  angles = self GetTagAngles( "tag_gunner_turret1" );
248  self SetTurretTargetRelativeAngles( ( 45, angles[1] - self.angles[1], 0 ), 1 );
249 
251 }
252 
253 // ----------------------------------------------
254 // State: surge
255 // ----------------------------------------------
256 function ‪state_surge_update( params )
257 {
258  self endon( "change_state" );
259  self endon( "death" );
260 
261  self SetMaxSpeedScale( 50 * ‪MPH_TO_INCHES_PER_SEC / ( self GetMaxSpeed( true ) ) );
262  self SetMaxAccelerationScale( 50 / self GetDefaultAcceleration() );
263 
265 }
266 
267 function ‪state_surge_exit( params )
268 {
269  self SetMaxSpeedScale( 0.1 );
270  self SetSpeed( 0.1 );
273 }
274 
275 // ----------------------------------------------
276 // State: stationary
277 // ----------------------------------------------
278 function ‪state_stationary_enter( params )
279 {
282  self SetBrake( 1 );
283  //self SetVehWeapon( GetWeapon( WEAPON_STATIONARY ) );
284 }
285 
286 function ‪state_stationary_update( params )
287 {
288  self endon( "death" );
289  self endon( "change_state" );
290 
291  self notify( "stop_rocket_firing_thread" );
294 
295  wait 1;
296 
297  self ‪cobra_raise();
298 
299  minTime = 6; // don't retract before this
300  maxTime = 12; // retract after this
301  transformWhenEnemyClose = ( RandomInt( 100 ) < 25 );
302  losePatientTime = 3 + RandomFloat( 2 ); // retract if don't see enemy for this long
303 
304  ‪startTime = GetTime();
305  ‪vehicle_ai::Cooldown( "rocket", 2 );
306 
307  evade_now = false;
308 
309  while ( true )
310  {
311  // /# self vehicle_ai::UpdatePersonalThreatBias_Bots( 800, 2.0 ); #/ // give bots more threat (for testing purposes -- DO NOT CHECK IN active)
312 
313  evade_now = ( ( ( self.settings.evade_enemies_locked_on_me === true ) && self.locked_on ) || ( ( self.settings.evade_enemies_locking_on_me === true ) && self.locking_on ) );
314 
315  if ( ‪vehicle_ai::TimeSince( ‪startTime ) > maxTime || evade_now )
316  {
317  break;
318  }
319 
320  if( isdefined( self.enemy ) )
321  {
322  distSqr = DistanceSquared( self.enemy.origin, self.origin );
323 
324  // check get out of stationary state
325  if ( ‪vehicle_ai::TimeSince( ‪startTime ) > minTime )
326  {
327  // enemy is too close, emergency transform
328  if ( transformWhenEnemyClose && distSqr < ‪SQR( ‪AMWS_AWAY_FROM_CHARACTER ) )
329  {
330  break;
331  }
332 
333  // haven't seen enemy for too long, transform
334  if ( !self VehSeenRecently( self.enemy, losePatientTime ) )
335  {
336  break;
337  }
338  }
339 
340  if ( self VehCanSee( self.enemy ) )
341  {
342  if( distSqr < ‪SQR( self.settings.engagementDistMax * 3 ) )
343  {
344  self SetTurretTargetEnt( self.enemy, (0,0,-5) );
345  self SetGunnerTargetEnt( self.enemy, (0,0,-5), 0 );
346 
347  if ( ‪vehicle_ai::IsCooldownReady( "rocket" ) && self.turretontarget && self.gib_rocket !== true )
348  {
349  self thread ‪FireRocketLauncher( self.enemy );
350  ‪vehicle_ai::Cooldown( "rocket", self.settings.rocketcooldown );
351  }
352 
353  weapon = self SeatGetWeapon( 1 );
354  if ( weapon.name=="none" )
355  idx = 0;
356  else
357  idx = 1;
358 
359  self ‪vehicle_ai::fire_for_time( 1, idx, self.enemy, 0.5 );
360  }
361  else
362  {
363  break;
364  }
365  }
366  }
367 
368  wait 0.1;
369  }
370 
371  self notify( "stop_rocket_firing_thread" );
374 
375  if ( evade_now )
376  {
378  }
379  else
380  {
382  }
383 
384  self ‪cobra_retract();
385 
387 }
388 
389 function ‪state_stationary_update_wait( wait_time ) // self == sentient
390 {
392 }
393 
394 function ‪state_stationary_exit( params )
395 {
396  //self SetVehWeapon( GetWeapon( WEAPON_REGULAR ) );
399  self SetBrake( 0 );
400  self ‪vehicle_ai::Cooldown( "cobra_up", 10 );
401 }
402 
403 // ----------------------------------------------
404 // State: combat
405 // ----------------------------------------------
406 function ‪state_combat_enter( params )
407 {
408  self thread ‪turretFireUpdate();
409 }
410 
412 {
413  return ‪VAL( self.settings.ai_uses_minigun, true );
414 }
415 
417 {
418  weapon = self SeatGetWeapon( 1 );
419  if ( weapon.name=="none" )
420  return;
421 
422  self endon( "death" );
423  self endon( "change_state" );
424 
425  self SetOnTargetAngle( 7 );
426  self SetOnTargetAngle( 7, 0 );
427 
428 
429 
430 
431  while( 1 )
432  {
433  if ( self.avoid_shooting_owner === true && isdefined( self.owner ) )
434  {
436  {
437  wait 0.5;
438  continue;
439  }
440  }
441 
442  if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) && DistanceSquared( self.enemy.origin, self.origin ) < ‪SQR( self.settings.engagementDistMax * 3 ) )
443  {
444  self SetGunnerTargetEnt( self.enemy, (0,0,0), 0 );
445 
446  if ( self ‪is_ai_using_minigun() )
447  {
448  self SetTurretSpinning( true );
449  }
450 
451  wait 0.05; // allow gunner1ontarget to update before checking
452 
453  if ( !self.gunner1ontarget )
454  {
455  wait 0.5;
456  }
457 
458  if ( self.gunner1ontarget )
459  {
460  if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
461  {
462  self ‪vehicle_ai::fire_for_time( RandomFloatRange( self.settings.burstFireDurationMin, self.settings.burstFireDurationMax ), 1, self.enemy );
463  }
464 
465  if ( self ‪is_ai_using_minigun() )
466  {
467  self SetTurretSpinning( false );
468  }
469 
470  if( isdefined( self.enemy ) && IsAI( self.enemy ) )
471  {
472  wait( RandomFloatRange( self.settings.burstFireAIDelayMin, self.settings.burstFireAIDelayMax ) );
473  }
474  else
475  {
476  wait( RandomFloatRange( self.settings.burstFireDelayMin, self.settings.burstFireDelayMax ) );
477  }
478  }
479  else
480  {
481  wait 0.5;
482  }
483  }
484  else
485  {
486  wait 0.4;
487  }
488  }
489 }
490 
491 function ‪state_combat_update( params )
492 {
493  self endon( "change_state" );
494  self endon( "death" );
495 
496  lastTimeChangePosition = 0;
497  self.shouldGotoNewPosition = false;
498  self.lastTimeTargetInSight = 0;
499 
501  self.lock_evading = 0; // for use with self.locked_on and self.locking_on
502 
503  for( ;; )
504  {
505  if ( self.lock_evading == 0 )
506  {
507  self SetSpeed( self.settings.defaultMoveSpeed );
508  self SetAcceleration( ‪AMWS_ACCELERATION );
509  }
510 
511  if ( RandomInt( 100 ) < 3 && ‪vehicle_ai::IsCooldownReady( "cobra_up" ) && ( self.lock_evading == 0 ))
512  {
513  if ( isdefined( self.enemy ) && DistanceSquared( self.enemy.origin, self.origin ) > ‪SQR( ‪AMWS_AWAY_FROM_CHARACTER ) )
514  {
515  if( DistanceSquared( self.enemy.origin, self.origin ) < ‪SQR( self.settings.engagementDistMax * 2 ) )
516  {
518  }
519  }
520  }
521 
522 
523  // /# self vehicle_ai::UpdatePersonalThreatBias_Bots( 800, 2.0 ); #/ // give bots more threat (for testing purposes -- DO NOT CHECK IN active)
524 
525 
526  // evaluate lock threats to engage them
527  if ( self.settings.engage_enemies_locked_on_me === true && self.locked_on )
528  {
529  self ‪vehicle_ai::UpdatePersonalThreatBias_AttackerLockedOnToMe( ‪VAL( self.settings.enemies_locked_on_me_threat_bias, 5000 ), ‪VAL( self.settings.enemies_locked_on_me_threat_bias_duration, 1.0 ) );
530  self.shouldGotoNewPosition = true;
531  }
532  else if ( self.settings.engage_enemies_locking_on_me === true && self.locking_on )
533  {
534  self ‪vehicle_ai::UpdatePersonalThreatBias_AttackerLockingOnToMe( ‪VAL( self.settings.enemies_locking_on_me_threat_bias, 2000 ), ‪VAL( self.settings.enemies_locking_on_me_threat_bias_duration, 1.0 ) );
535  self.shouldGotoNewPosition = true;
536  }
537 
538 
539  // evalate lock threats for evading
540  self.lock_evading = 0;
541  if ( self.settings.evade_enemies_locked_on_me === true )
542  {
543  self.lock_evading |= self.locked_on;
544  }
545  if ( self.settings.evade_enemies_locking_on_me === true )
546  {
547  self.lock_evading |= self.locking_on;
548  self.lock_evading |= self.locking_on_hacking;
549  }
550 
551 
552  if ( ‪IS_TRUE( self.inpain ) )
553  {
554  wait 0.1;
555  }
556  else if ( !IsDefined( self.enemy ) )
557  {
558  should_slow_down_at_goal = true;
559 
560  if ( self.lock_evading )
561  {
562  self.current_pathto_pos = ‪GetNextMovePosition_evasive( self.lock_evading );
563  should_slow_down_at_goal = false;
564  }
565  else
566  {
567  self.current_pathto_pos = ‪GetNextMovePosition_wander();
568  }
569 
570  if ( IsDefined( self.current_pathto_pos ) )
571  {
572  if ( self SetVehGoalPos( self.current_pathto_pos, should_slow_down_at_goal, true ) )
573  {
575  self thread ‪path_update_interrupt();
577  self notify( "amws_end_interrupt_watch" );
578  self playsound ("veh_amws_scan");
579  }
580  }
581 
582  self ‪state_combat_update_wait( 0.5 );
583  }
584  else
585  {
586  self SetTurretTargetEnt( self.enemy );
587 
588  if ( self vehCanSee( self.enemy ) )
589  {
590  self.lastTimeTargetInSight = GetTime();
591  }
592 
593  if ( self.shouldGotoNewPosition == false )
594  {
595  if ( GetTime() > lastTimeChangePosition + 1000 * ‪AMWS_MAX_TIME_AT_SAME_POSITION )
596  {
597  self.shouldGotoNewPosition = true;
598  }
599  else if ( GetTime() > self.lastTimeTargetInSight + 1000 * ‪AMWS_CHANGE_POSITION_TOATTACK_TARGET_DELAY )
600  {
601  self.shouldGotoNewPosition = true;
602  }
603  }
604 
605  if ( self.shouldGotoNewPosition )
606  {
607  should_slow_down_at_goal = true;
608 
609  if ( self.lock_evading )
610  {
611  self.current_pathto_pos = ‪GetNextMovePosition_evasive( self.lock_evading );
612  should_slow_down_at_goal = false;
613  }
614  else
615  {
616  self.current_pathto_pos = ‪GetNextMovePosition_tactical( self.enemy );
617  }
618 
619 
620  if ( IsDefined( self.current_pathto_pos ) )
621  {
622  if ( self SetVehGoalPos( self.current_pathto_pos, should_slow_down_at_goal, true ) )
623  {
625  self thread ‪path_update_interrupt();
627  self notify( "amws_end_interrupt_watch" );
628  }
629 
630  if ( isdefined( self.enemy ) && ‪vehicle_ai::IsCooldownReady( "rocket", 0.5 ) && self VehCanSee( self.enemy ) && self.gib_rocket !== true )
631  {
632  self thread ‪aim_and_fire_rocket_launcher( 0.4 ); // call as thread to prevent blocking movement while aiming rockets
633  }
634 
635  lastTimeChangePosition = GetTime();
636  self.shouldGotoNewPosition = false;
637  }
638  }
639 
640  self ‪state_combat_update_wait( 0.5 );
641  }
642  }
643 }
644 
645 function ‪aim_and_fire_rocket_launcher( aim_time ) // self == amws
646 {
647  self endon( "death" );
648  self endon( "change_state" );
649  self notify( "stop_rocket_firing_thread" );
650  self endon( "stop_rocket_firing_thread" );
651 
652  if ( !self.turretontarget )
653  {
654  wait aim_time;
655  }
656 
657  if ( isdefined( self.enemy ) && self.turretontarget )
658  {
659  ‪vehicle_ai::Cooldown( "rocket", self.settings.rocketcooldown );
660  self thread ‪FireRocketLauncher( self.enemy );
661  }
662 }
663 
664 function ‪state_combat_update_wait( wait_time ) // self == sentient
665 {
666  self ‪waittill_weapon_lock_or_timeout( wait_time );
667 }
668 
669 function ‪waittill_weapon_lock_or_timeout( wait_time ) // self == sentient
670 {
671  if ( self.lock_evade_now === true )
672  {
673  perform_evasion_reaction_wait = true;
674  }
675  else
676  {
677  locked_on_notify = undefined;
678  locking_on_notify = undefined;
679 
680  reacting_to_locks = ( self.settings.evade_enemies_locked_on_me === true ) || ( self.settings.engage_enemies_locked_on_me === true );
681  reacting_to_locking = ( self.settings.evade_enemies_locking_on_me === true ) || ( self.settings.engage_enemies_locking_on_me === true );
682 
683  previous_locked_on_to_me = self.locked_on;
684  previous_locking_on_to_me = self.locking_on;
685 
686  if ( reacting_to_locks )
687  {
688  locked_on_notify = "missle_lock";
689  }
690 
691  if ( reacting_to_locking )
692  {
693  locking_on_notify = "locking on";
694  }
695 
696  self ‪util::waittill_any_timeout( wait_time, "damage", locking_on_notify, locked_on_notify );
697 
698  locked_on_to_me_just_changed = previous_locked_on_to_me != self.locked_on && self.locked_on;
699  locking_on_to_me_just_changed = previous_locking_on_to_me != self.locking_on && self.locking_on;
700 
701  perform_evasion_reaction_wait = ( ( reacting_to_locks && locked_on_to_me_just_changed ) || ( reacting_to_locking && locking_on_to_me_just_changed ) );
702  }
703 
704  // perform evasion reaction time if need be
705  if ( perform_evasion_reaction_wait )
707 }
708 
709 function ‪wait_evasion_reaction_time() // self == vehicle with setting
710 {
711  wait RandomFloatRange( ‪VAL( self.settings.enemy_evasion_reaction_time_min, 0.1 ), ‪VAL( self.settings.enemy_evasion_reaction_time_max, 0.2 ) );
712 }
713 
714 function ‪FireRocketLauncher( enemy )
715 {
716  self endon( "death" );
717  self endon( "change_state" );
718  self notify( "stop_rocket_firing_thread" );
719  self endon( "stop_rocket_firing_thread" );
720 
721  if ( isdefined( enemy ) )
722  {
723  self SetTurretTargetEnt( enemy );
724  self ‪util::waittill_any_timeout( 1, "turret_on_target" );
725 
726  if ( self.variant == "armored" )
727  {
728  ‪vehicle_ai::fire_for_rounds( 1, 0, enemy );
729  }
730  else
731  {
732  ‪vehicle_ai::fire_for_rounds( 2, 0, enemy );
733  }
734  }
735 }
736 
737 function ‪GetNextMovePosition_wander() // no self.enemy
738 {
739  if( self.goalforced )
740  {
741  return self.goalpos;
742  }
743 
744  queryMultiplier = 1.5;
745 
746  queryResult = PositionQuery_Source_Navigation( self.origin, ‪AMWS_MOVE_DIST_MIN, ‪AMWS_MOVE_DIST_MAX * queryMultiplier, 0.5 * ‪AMWS_MOVE_DIST_MAX, 3 * self.radius * queryMultiplier, self, self.radius * queryMultiplier );
747  if ( queryResult.data.size == 0 )
748  {
749  // try to move a little bit away since we couldn't find any points in the first position query
750  queryResult = PositionQuery_Source_Navigation( self.origin, 36, 120, 240, self.radius, self );
751  }
752 
753  PositionQuery_Filter_DistanceToGoal( queryResult, self );
755  PositionQuery_Filter_InClaimedLocation( queryResult, self );
756 
757  best_point = undefined;
758  best_score = -999999;
759 
760  foreach ( point in queryResult.data )
761  {
762  randomScore = randomFloatRange( 0, 100 );
763  distToOriginScore = point.distToOrigin2D * 0.2;
764 
765  if( point.inClaimedLocation )
766  {
767  point.score -= 500;
768  }
769 
770  point.score += randomScore + distToOriginScore;
771 
772  if ( point.score > best_score )
773  {
774  best_score = point.score;
775  best_point = point;
776  }
777  }
778 
779  /# self.debug_ai_move_to_points_considered = queryResult.data; #/
780 
781  if( !isdefined( best_point ) )
782  {
783  /# self.debug_ai_movement_type = "wander ( 0 / " + queryResult.data.size + " )"; #/
784  /# self.debug_ai_move_to_point = undefined; #/
785  return undefined;
786  }
787 
788  /# self.debug_ai_movement_type = "wander - " + queryResult.data.size; #/
789  /# self.debug_ai_move_to_point = best_point.origin; #/
790  return best_point.origin;
791 }
792 
793 function ‪GetNextMovePosition_evasive( client_flags )
794 {
795  assert( isdefined( client_flags ) );
796 
797  self SetSpeed( self.settings.defaultMoveSpeed * ‪VAL( self.settings.lock_evade_speed_boost, 2.0 ) );
798  self SetAcceleration( ‪AMWS_ACCELERATION * ‪VAL( self.settings.lock_evade_acceleration_boost, 2.0 ) );
799 
800  // query points to where to evade
801  queryResult = PositionQuery_Source_Navigation( self.origin,
802  ‪VAL( self.settings.lock_evade_dist_min, ‪AMWS_EVADE_DIST_MIN ),
803  ‪VAL( self.settings.lock_evade_dist_max, ‪AMWS_EVADE_DIST_MAX ),
804  ‪math::clamp( ‪VAL( self.settings.lock_evade_dist_half_height, ‪AMWS_EVADE_HALF_HEIGHT ), 0.1, 99000 ),
805  ‪VAL( self.settings.lock_evade_point_spacing_factor, ‪AMWS_EVADE_POINT_SPACING_FACTOR ) * self.radius,
806  self );
807 
808  // initial filter
809  PositionQuery_Filter_InClaimedLocation( queryResult, self );
810  //note: goalpos related filters intentionally left out as the amws is trying to evade getting killed by a rocket
811 
812  // process claimed location score
813  foreach ( point in queryResult.data )
814  {
815  if( point.inClaimedLocation )
816  {
817  ADD_POINT_SCORE( point, "inClaimedLocation", -500 );
818  }
819  }
820 
821  remaining_lock_threats_to_evaluate = 3; // used as iteration cap
822 
823  remaining_flags_to_process = client_flags;
824  for ( i = 0; remaining_flags_to_process && remaining_lock_threats_to_evaluate > 0 && i < level.players.size; i++ )
825  {
826  attacker = level.players[ i ];
827  if ( isdefined( attacker ) )
828  {
829  client_flag = ( 1 << attacker getEntityNumber() );
830  if ( client_flag & remaining_flags_to_process )
831  {
832  // filter directness relative to lock threat
833  PositionQuery_Filter_Directness( queryResult, self.origin, attacker.origin );
834 
835  // update score based on directness
836  foreach ( point in queryResult.data )
837  {
838  abs_directness = Abs( point.directness );
839  if( abs_directness < 0.2 )
840  {
841  ADD_POINT_SCORE( point, "evading_directness", 200 );
842  }
843  else if ( abs_directness > ‪VAL( self.settings.lock_evade_enemy_line_of_sight_directness, 0.9 ) )
844  {
845  ADD_POINT_SCORE( point, "evading_directness_line_of_sight", -101 );
846  }
847  }
848 
849  // update for next threat
850  remaining_flags_to_process &= ~client_flag;
851  remaining_lock_threats_to_evaluate--;
852  }
853  }
854  }
855 
856  // give a point "ahead" of the amws more points
857  PositionQuery_Filter_Directness( queryResult, self.origin, self.origin + ( AnglesToForward( self.angles ) * ‪AMWS_EVADE_DIST_MAX ) );
858  foreach ( point in queryResult.data )
859  {
860  if( point.directness > 0.5 )
861  {
862  ADD_POINT_SCORE( point, "prefer forward motion", 105 );
863  }
864  }
865 
866  // score points
867  best_point = undefined;
868  best_score = -999999;
869 
870  foreach ( point in queryResult.data )
871  {
872  if ( point.score > best_score )
873  {
874  best_score = point.score;
875  best_point = point;
876  }
877  }
878 
879  self.lock_evade_now = false;
880 
881  self ‪vehicle_ai::PositionQuery_DebugScores( queryResult );
882 
883  /# self.debug_ai_move_to_points_considered = queryResult.data; #/
884 
885  if( !isdefined( best_point ) )
886  {
887  /# self.debug_ai_movement_type = "evasive ( 0 / " + queryResult.data.size + " )"; #/
888  /# self.debug_ai_move_to_point = undefined; #/
889  return undefined;
890  }
891 
892  /# self.debug_ai_movement_type = "evasive - " + queryResult.data.size; #/
893  /# self.debug_ai_move_to_point = best_point.origin; #/
894  return best_point.origin;
895 }
896 
898 {
899  if( self.goalforced )
900  {
901  return self.goalpos;
902  }
903 
904  // distance based multipliers
905  selfDistToTarget = Distance2D( self.origin, enemy.origin );
906 
907  goodDist = 0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax );
908 
909  tooCloseDist = ‪AMWS_ENEMY_TOO_CLOSE_DIST;
910  closeDist = 1.2 * goodDist;
911  farDist = 3 * goodDist;
912 
913  queryMultiplier = MapFloat( closeDist, farDist, 1, 3, selfDistToTarget );
914  preferedDirectness = 0;
915  if ( selfDistToTarget > goodDist )
916  {
917  preferedDirectness = MapFloat( closeDist, farDist, 0, 1, selfDistToTarget );
918  }
919  else
920  {
921  preferedDirectness = MapFloat( tooCloseDist * 0.4, tooCloseDist, -1, -0.6, selfDistToTarget );
922  }
923 
924  preferedDistAwayFromOrigin = 300;
925  randomness = 30;
926 
927  // query
928  queryResult = PositionQuery_Source_Navigation( self.origin, ‪AMWS_MOVE_DIST_MIN, ‪AMWS_MOVE_DIST_MAX * queryMultiplier, 0.5 * ‪AMWS_MOVE_DIST_MAX, 2 * self.radius * queryMultiplier, self, 1 * self.radius * queryMultiplier );
929 
930  // filter
931  PositionQuery_Filter_Directness( queryResult, self.origin, enemy.origin );
932  PositionQuery_Filter_DistanceToGoal( queryResult, self );
934  PositionQuery_Filter_InClaimedLocation( queryResult, self );
935  ‪vehicle_ai::PositionQuery_Filter_EngagementDist( queryResult, enemy, self.settings.engagementDistMin, self.settings.engagementDistMax );
936 
937  if ( isdefined( self.avoidEntities ) && isdefined( self.avoidEntitiesDistance ) )
938  {
939  ‪vehicle_ai::PositionQuery_Filter_DistAwayFromTarget( queryResult, self.avoidEntities, self.avoidEntitiesDistance, -500 );
940  }
941 
942  // score points
943  best_point = undefined;
944  best_score = -999999;
945 
946  foreach ( point in queryResult.data )
947  {
948  // directness
949  diffToPreferedDirectness = abs( point.directness - preferedDirectness );
950  directnessScore = MapFloat( 0, 1, 100, 0, diffToPreferedDirectness );
951  if ( diffToPreferedDirectness > 0.2 )
952  {
953  directnessScore -= 200;
954  }
955  ADD_POINT_SCORE( point, "directnessRaw", point.directness );
956  ADD_POINT_SCORE( point, "directness", directnessScore );
957 
958  // distance from origin
959  ADD_POINT_SCORE( point, "distToOrigin", MapFloat( 0, preferedDistAwayFromOrigin, 0, 100, point.distToOrigin2D ) );
960 
961  // distance to target
962  targetDistScore = 0;
963  if ( point.targetDist < tooCloseDist )
964  {
965  targetDistScore -= 200;
966  }
967 
968  if( point.inClaimedLocation )
969  {
970  ADD_POINT_SCORE( point, "inClaimedLocation", -500 );
971  }
972 
973  ADD_POINT_SCORE( point, "distToTarget", targetDistScore );
974 
975  ADD_POINT_SCORE( point, "random", randomFloatRange( 0, randomness ) );
976 
977  if ( point.score > best_score )
978  {
979  best_score = point.score;
980  best_point = point;
981  }
982  }
983 
984  self ‪vehicle_ai::PositionQuery_DebugScores( queryResult );
985 
986  /# self.debug_ai_move_to_points_considered = queryResult.data; #/
987 
988  if( !isdefined( best_point ) )
989  {
990  /# self.debug_ai_movement_type = "tactical ( 0 / " + queryResult.data.size + " )"; #/
991  /# self.debug_ai_move_to_point = undefined; #/
992  return undefined;
993  }
994 
995 /#
996  if ( ‪IS_TRUE( GetDvarInt("hkai_debugPositionQuery") ) )
997  {
998  recordLine( self.origin, best_point.origin, (0.3,1,0) );
999  recordLine( self.origin, enemy.origin, (1,0,0.4) );
1000  }
1001 #/
1002 
1003  /# self.debug_ai_movement_type = "tactical - " + queryResult.data.size; #/
1004  /# self.debug_ai_move_to_point = best_point.origin; #/
1005 
1006  return best_point.origin;
1007 }
1008 
1009 function ‪path_update_interrupt_by_attacker() //self == vehicle
1010 {
1011  self endon( "death" );
1012  self endon( "change_state" );
1013  self endon( "near_goal" );
1014  self endon( "reached_end_node" );
1015  self endon( "amws_end_interrupt_watch" );
1016 
1017  self ‪util::waittill_any( "locking on", "missile_lock", "damage" );
1018 
1019  if ( self.locked_on || self.locking_on )
1020  {
1021  /# self.debug_ai_move_to_points_considered = []; #/
1022  /# self.debug_ai_movement_type = "interrupted"; #/
1023  /# self.debug_ai_move_to_point = undefined; #/
1024 
1025  self ClearVehGoalPos(); // do this to prevent the "stopping" of the vehicle
1026 
1027  self.lock_evade_now = true;
1028  }
1029 
1030  self notify( "near_goal" );
1031 }
1032 
1034 {
1035  self endon( "death" );
1036  self endon( "change_state" );
1037  self endon( "near_goal" );
1038  self endon( "reached_end_node" );
1039  self endon( "amws_end_interrupt_watch" );
1040 
1041  wait 1;
1042 
1043  while( 1 )
1044  {
1045  if( isdefined( self.current_pathto_pos ) )
1046  {
1047  if( distance2dSquared( self.current_pathto_pos, self.goalpos ) > ‪SQR( self.goalradius ) )
1048  {
1049  wait 0.2;
1050  self notify( "near_goal" );
1051  }
1052  }
1053 
1054  if ( isdefined( self.enemy ) )
1055  {
1056  if( self VehCanSee( self.enemy ) && distance2dSquared( self.origin, self.enemy.origin ) < ‪SQR( ‪AMWS_ENEMY_TOO_CLOSE_DIST ) )
1057  {
1058  self notify( "near_goal" );
1059  }
1060 
1061  if ( ‪vehicle_ai::IsCooldownReady( "rocket" ) && ‪vehicle_ai::IsCooldownReady( "rocket_launcher_check" ) )
1062  {
1063  ‪vehicle_ai::Cooldown( "rocket_launcher_check", 2.5 );
1064  self notify( "near_goal" );
1065  }
1066  }
1067 
1068  wait 0.2;
1069  }
1070 }
1071 
1072 function ‪gib( attacker )
1073 {
1074  if ( self.gibbed !== true )
1075  {
1077  self.gibbed = true;
1078  self.death_type = "suicide_crash";
1079  self ‪kill( self.origin + (0,0,10), attacker );
1080  }
1081 }
1082 
1083 function ‪drone_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
1084 {
1085  iDamage = ‪vehicle_ai::shared_callback_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal );
1086 
1087  return iDamage;
1088 }
‪AMWS_MAX_TIME_AT_SAME_POSITION
‪#define AMWS_MAX_TIME_AT_SAME_POSITION
Definition: _amws.gsc:25
‪add_interrupt_connection
‪function add_interrupt_connection(from_state_name, to_state_name, on_notify, checkfunc)
Definition: statemachine_shared.gsc:90
‪startTime
‪class AnimationAdjustmentInfoZ startTime
‪add_state
‪function add_state(name, enter_func, update_func, exit_func, reenter_func)
Definition: statemachine_shared.gsc:59
‪evaluate_connections
‪function evaluate_connections(eval_func, params)
Definition: statemachine_shared.gsc:266
‪waittill_weapon_lock_or_timeout
‪function waittill_weapon_lock_or_timeout(wait_time)
Definition: _amws.gsc:669
‪death_suicide_crash
‪function death_suicide_crash(params)
Definition: _amws.gsc:164
‪drone_callback_damage
‪function drone_callback_damage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal)
Definition: _amws.gsc:1083
‪AMWS_ENEMY_TOO_CLOSE_DIST
‪#define AMWS_ENEMY_TOO_CLOSE_DIST
Definition: _amws.gsc:38
‪ClearAllLookingAndTargeting
‪function ClearAllLookingAndTargeting()
Definition: vehicle_ai_shared.gsc:697
‪state_surge_exit
‪function state_surge_exit(params)
Definition: _amws.gsc:267
‪AMWS_EVADE_DIST_MAX
‪#define AMWS_EVADE_DIST_MAX
Definition: _amws.gsc:33
‪wait_evasion_reaction_time
‪function wait_evasion_reaction_time()
Definition: _amws.gsc:709
‪ClearAllMovement
‪function ClearAllMovement(zeroOutSpeed=false)
Definition: vehicle_ai_shared.gsc:707
‪AMWS_CHANGE_POSITION_TOATTACK_TARGET_DELAY
‪#define AMWS_CHANGE_POSITION_TOATTACK_TARGET_DELAY
Definition: _amws.gsc:26
‪IsCooldownReady
‪function IsCooldownReady(name, timeForward_seconds)
Definition: vehicle_ai_shared.gsc:1968
‪state_death_update
‪function state_death_update(params)
Definition: _amws.gsc:145
‪AMWS_EVADE_POINT_SPACING_FACTOR
‪#define AMWS_EVADE_POINT_SPACING_FACTOR
Definition: _amws.gsc:35
‪aim_and_fire_rocket_launcher
‪function aim_and_fire_rocket_launcher(aim_time)
Definition: _amws.gsc:645
‪waittill_vehicle_move_up_button_pressed
‪function waittill_vehicle_move_up_button_pressed()
Definition: util_shared.gsc:2443
‪nudge_collision
‪function nudge_collision()
Definition: vehicle_ai_shared.gsc:437
‪state_combat_update
‪function state_combat_update(params)
Definition: _amws.gsc:491
‪cobra_retract
‪function cobra_retract()
Definition: _amws.gsc:228
‪VAL
‪#define VAL(__var, __default)
Definition: shared.gsh:272
‪UpdatePersonalThreatBias_AttackerLockingOnToMe
‪function UpdatePersonalThreatBias_AttackerLockingOnToMe(threat_bias, bias_duration, get_perfect_info, update_last_seen)
Definition: vehicle_ai_shared.gsc:2269
‪path_update_interrupt_by_attacker
‪function path_update_interrupt_by_attacker()
Definition: _amws.gsc:1009
‪fire_for_rounds
‪function fire_for_rounds(fireCount, turretIdx, target)
Definition: vehicle_ai_shared.gsc:197
‪defaultstate_death_update
‪function defaultstate_death_update(params)
Definition: vehicle_ai_shared.gsc:1355
‪waittill_any_timeout
‪function waittill_any_timeout(n_timeout, string1, string2, string3, string4, string5)
Definition: util_shared.csc:423
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪SQR
‪#define SQR(__var)
Definition: shared.gsh:293
‪MPH_TO_INCHES_PER_SEC
‪#define MPH_TO_INCHES_PER_SEC
Definition: shared.gsh:268
‪FireRocketLauncher
‪function FireRocketLauncher(enemy)
Definition: _amws.gsc:714
‪gib
‪function gib(attacker)
Definition: _amws.gsc:1072
‪path_update_interrupt
‪function path_update_interrupt()
Definition: _amws.gsc:1033
‪state_combat_update_wait
‪function state_combat_update_wait(wait_time)
Definition: _amws.gsc:664
‪shared_callback_damage
‪function shared_callback_damage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal)
Definition: vehicle_ai_shared.gsc:726
‪__init__
‪function __init__()
Definition: _amws.gsc:51
‪AMWS_MOVE_DIST_MAX
‪#define AMWS_MOVE_DIST_MAX
Definition: _amws.gsc:29
‪StartInitialState
‪function StartInitialState(defaultState="combat")
Definition: vehicle_ai_shared.gsc:866
‪UpdatePersonalThreatBias_AttackerLockedOnToMe
‪function UpdatePersonalThreatBias_AttackerLockedOnToMe(threat_bias, bias_duration, get_perfect_info, update_last_seen)
Definition: vehicle_ai_shared.gsc:2264
‪defaultstate_emped_update
‪function defaultstate_emped_update(params)
Definition: vehicle_ai_shared.gsc:1465
‪state_stationary_update_wait
‪function state_stationary_update_wait(wait_time)
Definition: _amws.gsc:389
‪friendly_fire_shield
‪function friendly_fire_shield()
Definition: vehicle_shared.gsc:2194
‪state_surge_update
‪function state_surge_update(params)
Definition: _amws.gsc:256
‪kill
‪function kill(ent_1, str_tag1, ent_2, str_tag2, str_beam_type)
Definition: beam_shared.csc:41
‪AMWS_EVADE_DIST_MIN
‪#define AMWS_EVADE_DIST_MIN
Definition: _amws.gsc:32
‪defaultRole
‪function defaultRole()
Definition: _amws.gsc:111
‪GetNextMovePosition_tactical
‪function GetNextMovePosition_tactical(enemy)
Definition: _amws.gsc:897
‪state_combat_enter
‪function state_combat_enter(params)
Definition: _amws.gsc:406
‪Cooldown
‪function Cooldown(name, time_seconds)
Definition: vehicle_ai_shared.gsc:1943
‪InitLockField
‪function InitLockField(target)
Definition: _heatseekingmissile.gsc:695
‪init_state_machine_for_role
‪function init_state_machine_for_role(rolename)
Definition: vehicle_ai_shared.gsc:1034
‪waittill_pathing_done
‪function waittill_pathing_done(maxtime=15)
Definition: vehicle_ai_shared.gsc:340
‪PositionQuery_DebugScores
‪function PositionQuery_DebugScores(queryResult)
Definition: vehicle_ai_shared.gsc:2010
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪state_stationary_update
‪function state_stationary_update(params)
Definition: _amws.gsc:286
‪fire_for_time
‪function fire_for_time(n_time, n_index=0)
Definition: turret_shared.gsc:953
‪defaultstate_surge_update
‪function defaultstate_surge_update(params)
Definition: vehicle_ai_shared.gsc:1524
‪PositionQuery_Filter_OutOfGoalAnchor
‪function PositionQuery_Filter_OutOfGoalAnchor(queryResult, tolerance=1)
Definition: vehicle_ai_shared.gsc:2104
‪GetNextMovePosition_wander
‪function GetNextMovePosition_wander()
Definition: _amws.gsc:737
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪do_gib_dynents
‪function do_gib_dynents()
Definition: vehicle_shared.gsc:2880
‪AMWS_AWAY_FROM_CHARACTER
‪#define AMWS_AWAY_FROM_CHARACTER
Definition: _amws.gsc:30
‪state_stationary_enter
‪function state_stationary_enter(params)
Definition: _amws.gsc:278
‪waittill_asm_complete
‪function waittill_asm_complete(substate_to_wait, timeout=10)
Definition: vehicle_ai_shared.gsc:374
‪PositionQuery_Filter_EngagementDist
‪function PositionQuery_Filter_EngagementDist(queryResult, enemy, engagementDistanceMin, engagementDistanceMax)
Definition: vehicle_ai_shared.gsc:2116
‪RegisterVehicleBlackBoardAttributes
‪function RegisterVehicleBlackBoardAttributes()
Definition: blackboard_vehicle.gsc:24
‪CreateBlackBoardForEntity
‪function CreateBlackBoardForEntity(entity)
Definition: blackboard.gsc:77
‪is_ai_using_minigun
‪function is_ai_using_minigun()
Definition: _amws.gsc:411
‪TimeSince
‪function TimeSince(startTimeInMilliseconds)
Definition: vehicle_ai_shared.gsc:1930
‪owner_in_line_of_fire
‪function owner_in_line_of_fire()
Definition: vehicle_ai_shared.gsc:264
‪turretFireUpdate
‪function turretFireUpdate()
Definition: _amws.gsc:416
‪add_utility_connection
‪function add_utility_connection(from_state_name, to_state_name, checkfunc, defaultScore)
Definition: statemachine_shared.gsc:112
‪cobra_raise
‪function cobra_raise()
Definition: _amws.gsc:215
‪GetNextMovePosition_evasive
‪function GetNextMovePosition_evasive(client_flags)
Definition: _amws.gsc:793
‪PositionQuery_Filter_DistAwayFromTarget
‪function PositionQuery_Filter_DistAwayFromTarget(queryResult, targetArray, distance, tooClosePenalty)
Definition: vehicle_ai_shared.gsc:2168
‪AMWS_MOVE_DIST_MIN
‪#define AMWS_MOVE_DIST_MIN
Definition: _amws.gsc:28
‪get_script_bundle
‪function get_script_bundle(str_type, str_name)
Definition: struct.csc:45
‪clamp
‪function clamp(val, val_min, val_max)
Definition: math_shared.csc:16
‪AMWS_EVADE_HALF_HEIGHT
‪#define AMWS_EVADE_HALF_HEIGHT
Definition: _amws.gsc:34
‪AMWS_ACCELERATION
‪#define AMWS_ACCELERATION
Definition: _amws.gsc:36
‪state_stationary_exit
‪function state_stationary_exit(params)
Definition: _amws.gsc:394
‪state_emped_update
‪function state_emped_update(params)
Definition: _amws.gsc:240
‪get_state_callbacks
‪function get_state_callbacks(statename)
Definition: vehicle_ai_shared.gsc:927
‪state_driving_update
‪function state_driving_update(params)
Definition: _amws.gsc:187
‪amws_initialize
‪function amws_initialize()
Definition: _amws.gsc:56
‪get_death_type
‪function get_death_type(params)
Definition: vehicle_ai_shared.gsc:1323