‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
ai_sniper_shared.gsc
Go to the documentation of this file.
1 #using scripts\shared\util_shared;
2 #using scripts\shared\ai_shared;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\spawner_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\codescripts\struct;
7 #using scripts\shared\ai\systems\blackboard;
8 
9 #insert scripts\shared\shared.gsh;
10 #insert scripts\shared\ai\systems\blackboard.gsh;
11 
12 #namespace ai_sniper;
13 
14 ‪REGISTER_SYSTEM( "ai_sniper", &‪ai_sniper::__init__, undefined )
15 
16 function ‪__init__()
17 {
18  thread ‪init_node_scan();
19 }
20 
31 function ‪init_node_scan( targetName )
32 {
34 
35  if ( !isDefined( targetName ) )
36  targetName = "ai_sniper_node_scan";
37 
38  /*
39  Snipers reach a node and the node connects to a lasing path
40  If the node targets another node, they will stop the behavior and move on when they finish one loop
41 
42  Simple point arrays - refer back to node
43  [struct]
44  targetname: ai_sniper_nodescan
45  target: <targetname> of node they are part of
46 
47  Complex point paths - node refers to entry point
48  [node] (sniping destination node)
49  script_noteworthy: ai_sniper_nodescan
50  script_linkto: <script_linkname> of a given node of a path
51 
52  */
53 
54  // Lase points that refer directly back to node in a "dumb" array
55  structList = ‪struct::get_array( targetName, "targetname" );
56  pointList = GetEntArray( targetName, "targetname" );
57  foreach ( struct in structList )
58  pointList[pointlist.size] = struct;
59 
60  foreach ( point in pointList )
61  {
62  if ( isDefined( point.target ) )
63  {
64  node = getnode( point.target, "targetname" );
65  if ( isDefined( node ) )
66  {
67  if ( !isDefined( node.lase_points ) )
68  node.lase_points = [];
69  node.lase_points[node.lase_points.size] = point;
70  }
71  }
72  }
73 
74  // Nodes that refer to an entry point in a lasing path
75  nodeList = GetNodeArray( targetName, "script_noteworthy" );
76  foreach ( node in nodeList )
77  {
78  if ( isDefined( node.script_linkto ) )
79  {
80  node.lase_path = ‪struct::get( node.script_linkto, "script_linkname" );
81  if ( !isDefined( node.lase_path ) )
82  node.lase_path = GetEnt( node.script_linkto, "script_linkname" );
83  }
84  }
85 }
86 
87 
96 function ‪agent_init( )
97 {
100  self thread ‪ai_sniper::goal_watcher_target();
101 }
102 
103 function ‪goal_wait_notify_lase( node )
104 {
105  if ( !isDefined( node ) )
106  return;
107 
108  if ( !isDefined( node.lase_points ) && !isDefined( node.lase_path ) )
109  return;
110 
111  self notify("goal_wait_notify_lase");
112  self endon("goal_wait_notify_lase");
113  self endon("death");
114  self endon("lase_points");
115 
116  if ( ‪IS_TRUE( self.patroller ) )
118 
119  // Wait till the guy arrives right on the goal
120  goalPos = node.origin;
121  if ( isDefined( self.pathGoalPos ) )
122  goalPos = self.pathGoalPos;
123  if( IsDefined( self.arrivalFinalPos ) )
124  goalPos = self.arrivalFinalPos;
125  while ( DistanceSquared( self.origin, goalPos ) > (16 * 16) )
127 
128  self notify( "lase_goal", node );
129 }
130 
132 {
133  self notify("goal_watcher_patrol");
134  self endon("goal_watcher_patrol");
135  self endon("death");
136 
137  while ( 1 )
138  {
139  self waittill ("patrol_goal", node );
140 
141  self ‪goal_wait_notify_lase( node );
142  }
143 }
144 
146 {
147  self notify("goal_watcher_target");
148  self endon("goal_watcher_target");
149  self endon("death");
150 
151  if ( isDefined( self.target ) && !‪IS_TRUE( self.patroller ) )
152  {
153  node = GetNode( self.target, "targetname" );
154 
155  if ( isDefined( node ) )
156  {
157  self waittill( "goal" );
158 
159  self ‪goal_wait_notify_lase( node );
160  }
161  }
162 }
163 
165 {
166  self notify("patrol_lase_goal_waiter");
167  self endon("patrol_lase_goal_waiter");
168  self endon("death");
169 
170  while ( 1 )
171  {
172  was_stealth = false;
173 
174  self waittill ("lase_goal", node );
175 
176  if ( isDefined( node.lase_path ) )
177  self thread ‪actor_lase_points_behavior( node.lase_path );
178  else
179  self thread ‪actor_lase_points_behavior( node.lase_points );
180 
181  // Turn off stealth
182  if ( self ‪ai::has_behavior_attribute( "stealth" ) )
183  {
184  was_stealth = self ‪ai::get_behavior_attribute( "stealth" );
185  self ‪ai::set_behavior_attribute( "stealth", false );
186  }
187 
188  if ( isDefined( self.currentgoal ) && isDefined( self.currentgoal.target ) && self.currentgoal.target != "" )
189  {
190  // Stop here
191  self SetGoal( node, true );
192  self waittill( "lase_points_loop" );
193 
194  // Then continue patrolling after we finished the lasing loop
195  self notify("lase_points");
196  self LaserOff();
197  self.holdfire = false;
199 
200  if ( isDefined( self.ai_sniper_prev_goal_radius ) )
201  {
202  self.goalradius = self.ai_sniper_prev_goal_radius;
203  self.ai_sniper_prev_goal_radius = undefined;
204  }
205 
206  if ( isDefined( self.currentgoal ) )
207  self thread ‪ai::patrol( self.currentgoal );
208 
209  if ( was_stealth && self ‪ai::has_behavior_attribute( "stealth" ) )
210  self ‪ai::set_behavior_attribute( "stealth", self.awarenesslevelcurrent != "combat" );
211  }
212  else
213  {
214  // Lase forever
215  break;
216  }
217  }
218 }
219 
230 function ‪actor_lase_points_behavior( entity_or_point_array )
231 {
232  self notify("lase_points");
233  self endon("lase_points");
234  self endon("death");
235 
236  // dont actually pull the trigger
237  self.holdfire = true;
238 
239  // aim at target even when visually obstructed
240  self.blindaim = true;
241 
242  // dont relocate just stay put
243  if ( !isDefined( self.ai_sniper_prev_goal_radius ) )
244  self.ai_sniper_prev_goal_radius = self.goalradius;
245  self.goalradius = 8;
246 
247  // Stand as still as possible
248  if ( IsDefined( self.__blackboard ) && isDefined( self.script_parameters ) && self.script_parameters == "steady" )
250 
251  if ( !isDefined( entity_or_point_array ) && isDefined( self.target ) )
252  entity_or_point_array = ‪struct::get( self.target, "targetname" );
253 
254  if ( !isDefined( entity_or_point_array ) || ( isArray( entity_or_point_array ) && entity_or_point_array.size == 0 ) )
255  {
256  /# IPrintLnBold( "actor_lase_points_behavior - invalid entity_or_point_array" ); #/
257  return;
258  }
259 
260  firstPoint = undefined;
261  if ( isArray( entity_or_point_array ) )
262  firstPoint = entity_or_point_array[0];
263  else
264  firstPoint = entity_or_point_array;
265 
266  if ( !isDefined( self.lase_ent ) )
267  {
268  self.lase_ent = ‪Spawn( "script_model", ‪lase_point( firstPoint ) );
269  self.lase_ent SetModel("tag_origin");
270  self.lase_ent.velocity = (100, 0, 0);
271  self thread ‪util::delete_on_death( self.lase_ent );
272  }
273 
274  // so shoot_at_target doesnt think its dead and stop
275  if ( self.lase_ent.health <= 0 )
276  self.lase_ent.health = 1;
277  self thread ‪ai::shoot_at_target( "shoot_until_target_dead", self.lase_ent );
278 
279  self.lase_ent thread ‪target_lase_points( entity_or_point_array, self );
280  self.lase_ent thread ‪target_lase_points_ally_track( self GetEye(), entity_or_point_array, self );
281 
282  self thread ‪actor_lase_force_laser_on();
283  self thread ‪actor_lase_laser_off_on_death();
284 }
285 
296 {
297  if ( !isDefined( self.lase_ent ) )
298  return;
299 
300  self notify("lase_points");
301 
302  self.holdfire = false;
303 
304  self.blindaim = false;
305 
306  self.lase_ent delete();
307  self.lase_ent = undefined;
308 
309  self clearentitytarget();
310 
311  if ( isDefined( self.ai_sniper_prev_goal_radius ) )
312  {
313  self.goalradius = self.ai_sniper_prev_goal_radius;
314  self.ai_sniper_prev_goal_radius = undefined;
315  }
316 
317  self LaserOff();
318 
319  if ( IsDefined( self.__blackboard ) )
321 }
322 
324 {
325  self endon("death");
326  self endon("lase_points");
327 
328  lastTransition = GetTime();
329 
330  while ( 1 )
331  {
332  // Turn on laser all the time as long as actor is not currently turning to face new general direction
333  if ( self asmIsTransDecRunning() )
334  {
335  // Playing turning animation etc
336  lastTransition = GetTime();
337  self LaserOff();
338  }
339  else if ( GetTime() - lastTransition > 350 )
340  {
341  self LaserOn();
342  }
343 
345  }
346 }
347 
349 {
350  self endon("lase_points");
351 
352  self waittill("death");
353 
354  if ( isDefined( self ) )
355  self LaserOff();
356 }
357 
358 function ‪lase_point( entity_or_point )
359 {
360  if ( !isDefined( entity_or_point ) )
361  return (0, 0, 0);
362 
363  ‪result = entity_or_point;
364 
365  if ( !isVec( entity_or_point ) && isDefined( entity_or_point.origin ) )
366  {
367  ‪result = entity_or_point.origin;
368 
369  if ( isPlayer( entity_or_point ) || isActor( entity_or_point ) )
370  ‪result = entity_or_point GetEye();
371  }
372 
373  return ‪result;
374 }
375 
385 function ‪target_lase_points_ally_track( v_eye, entity_or_point_array, a_owner )
386 {
387  self notify("actor_lase_points_player_track");
388  self endon("actor_lase_points_player_track");
389 
390  self endon("death");
391 
392  if ( !isDefined( level.target_lase_allyList ) )
393  level.target_lase_allyList = [];
394  if ( !isDefined( level.target_lase_nextAllyListUpdate ) )
395  level.target_lase_nextAllyListUpdate = 0;
396 
397  while ( 1 )
398  {
399  dirLaser = VectorNormalize( self.origin - v_eye );
400 
401  if ( GetTime() > level.target_lase_nextAllyListUpdate )
402  {
403  level.target_lase_allyList = GetPlayers();
404 
405  actorList = GetAITeamArray( "allies" );
406  foreach ( actor in actorList )
407  {
408  if ( ‪IS_TRUE( actor.ignoreme ) )
409  continue;
410 
411  if ( isAlive( actor ) )
412  level.target_lase_allyList[level.target_lase_allyList.size] = actor;
413  }
414 
415  level.target_lase_nextAllyListUpdate = GetTime() + 1000;
416  }
417 
418  for ( i = 0; i < level.target_lase_allyList.size; i++ )
419  {
420  ally = level.target_lase_allyList[i];
421 
422  if ( !isAlive( ally ) )
423  continue;
424 
425  if ( ally IsNoTarget() || ‪IS_TRUE( ally.ignoreme ) )
426  continue;
427 
428  allyEye = ‪lase_point( ally );
429 
430  // Make sure ally is in reasonable view
431  dirAlly = VectorNormalize( allyEye - v_eye );
432  if ( VectorDot( dirLaser, dirAlly ) < 0.7 )
433  continue;
434 
435  // If ally is within a short distance from the laser
436  nearestPointAlongLaser = PointOnSegmentNearestToPoint( v_eye, self.origin, allyEye );
437  if ( DistanceSquared( allyEye, nearestPointAlongLaser ) < 200 * 200 )
438  {
439  if ( SightTracePassed( v_eye, allyEye, false, undefined ) )
440  {
441  if ( isDefined( a_owner ) )
442  a_owner notify( "alert", "combat", allyEye, ally );
443  self ‪target_lase_fire_at( v_eye, ally, a_owner );
444  break;
445  }
446  }
447  }
448 
450  }
451 }
452 
453 function ‪target_lase_fire_at( v_eye, entity_or_point, a_owner, allow_interrupts = true ) // self = laser targeting ent
454 {
455  sight_timeout = 7;
456 
457  if ( IsDefined(self.a_owner) && IsDefined(self.a_owner.laser_sight_timeout) )
458  sight_timeout = self.a_owner.laser_sight_timeout;
459 
460  self ‪target_lase_override( v_eye, entity_or_point, sight_timeout, a_owner, true, allow_interrupts );
461 }
462 
474 function ‪target_lase_points( entity_or_point_array, e_owner )
475 {
476  self notify("lase_points");
477  self endon("lase_points");
478  self endon("death");
479 
480  // Constants - turn into parameters?
481  pauseTime = RandomFloatRange( 2.0, 4.0 );
482 
483  if ( isArray( entity_or_point_array ) && entity_or_point_array.size <= 0 )
484  return;
485 
486  index = 0;
487  start = entity_or_point_array;
488 
489  while ( 1 )
490  {
491  while ( isDefined( self.lase_override ) )
492  {
494  continue;
495  }
496 
497  if ( isArray( entity_or_point_array ) )
498  {
499  self ‪target_lase_transition( entity_or_point_array[index], e_owner );
500  if ( !isVec( entity_or_point_array[index] ) && isDefined( entity_or_point_array[index].‪script_wait ) )
501  wait entity_or_point_array[index].script_wait;
502  }
503  else
504  {
505  entity_or_point_array = ‪target_lase_next( entity_or_point_array );
506  self ‪target_lase_transition( entity_or_point_array, e_owner );
507  if ( !isVec( entity_or_point_array ) && isDefined( entity_or_point_array.script_wait ) )
508  wait entity_or_point_array.script_wait;
509  }
510 
511  looped = false;
512  if ( isArray( entity_or_point_array ) )
513  {
514  index = index + 1;
515  if ( index >= entity_or_point_array.size )
516  {
517  index = 0;
518  looped = true;
519  }
520  }
521  else if ( entity_or_point_array == start )
522  {
523  looped = true;
524  }
525 
526  if ( looped )
527  {
528  self notify("lase_points_loop");
529  if ( isDefined( e_owner ) )
530  e_owner notify("lase_points_loop");
531  }
532  }
533 }
534 
535 function ‪velocity_approach( endPosition, totalTime, b_early_out ) // self = object with velocity and origin
536 {
537  self notify("velocity_approach");
538  self endon("velocity_approach");
539  self endon( "death" );
540 
541  startPosition = self.origin;
542  startVelocity = self.velocity;
543  startVelocityDir = VectorNormalize( self.velocity );
544 
545  decelerateTime = totalTime * 4.0;
546  phase = Length( self.velocity ) / (decelerateTime * 2);
547  ‪startTime = GetTime();
548  totalTimeMs = totalTime * 1000;
549  timeEarlyOut = totalTimeMs * 0.75;
550  notified = false;
551  MAX_MAP = 65000;
552 
553  if ( !isDefined( b_early_out ) || b_early_out )
554  {
555  // Abort before getting all the way
556  self endon( "velocity_approach_early_out" );
557  }
558 
559  while ( (GetTime() - ‪startTime) < totalTimeMs )
560  {
561  // Even if we are not aborting early we still do the notify so that external logic knows when it happens
562  if ( !notified && (GetTime() - ‪startTime) > timeEarlyOut )
563  {
564  self notify( "velocity_approach_early_out" );
565  notified = true;
566  }
567 
568  deltaTime = float(GetTime() - ‪startTime) / 1000.0;
569 
570  // Brake the velocity to zero over decelerateTime
571  decelDeltaTime = min( deltaTime, decelerateTime );
572  posWithoutBraking = startPosition + (startVelocity * decelDeltaTime);
573  posWithBraking = posWithoutBraking + (startVelocityDir * phase * -0.5 * decelDeltaTime * decelDeltaTime);
574 
575  // Lerp that result to where we need to be over the total time
576  coef = deltaTime / totalTime;
577  coef = 1.0 - (0.5 + Cos( coef * 180 ) * 0.5); // Use Cos() to ramp it up and down at the ends
578  actualEndPosition = endPosition;
579 
580  assert( IsDefined( actualEndPosition ) );
581 
582  newOrigin = VectorLerp( posWithBraking, actualEndPosition, coef );
583 
584  self.velocity = (newOrigin - self.origin) / ‪SERVER_FRAME;
585  if ( newOrigin[0] > -MAX_MAP && newOrigin[0] < MAX_MAP && newOrigin[1] > -MAX_MAP && newOrigin[1] < MAX_MAP && newOrigin[2] > -MAX_MAP && newOrigin[2] < MAX_MAP )
586  self.origin = newOrigin;
587 
589  }
590 }
591 
603 function ‪target_lase_next( node )
604 {
605  if ( !isDefined( node ) )
606  return undefined;
607 
608  nextA = undefined;
609  nextB = undefined;
610 
611  // Path will randomly fork any time it encounters a node with both a target and a script_linkto
612  // (choosing one or the other at random)
613 
614  if ( isDefined( node.target ) && isDefined( node.script_linkto ) )
615  {
616  nextA = ‪struct::get( node.target, "targetname" );
617  nextB = ‪struct::get( node.script_linkto, "script_linkname" );
618  }
619  else if ( isDefined( node.target ) )
620  {
621  nextA = ‪struct::get( node.target, "targetname" );
622  }
623  else if ( isDefined( node.script_linkto ) )
624  {
625  nextA = ‪struct::get( node.script_linkto, "script_linkname" );
626  }
627 
628  if ( isDefined( nextA ) && isDefined( nextB ) )
629  {
630  if ( RandomFloatRange( 0.0, 1.0 ) < 0.5 )
631  return nextA;
632  return nextB;
633  }
634 
635  return nextA;
636 }
637 
638 
650 function ‪target_lase_transition( entity_or_point, owner )
651 {
652  self notify("target_lase_transition");
653  self endon("target_lase_transition");
654  self endon("death");
655 
656  if ( isEntity( entity_or_point ) )
657  {
658  // Lock onto entity and follow it around
659  entity_or_point endon("death");
660 
661  while ( 1 )
662  {
663  point = ‪lase_point( entity_or_point );
664 
665  delta = point - self.origin;
666  delta = delta * 0.2;
667  self.origin += delta;
668 
670  }
671  }
672  else
673  {
674  // Move over to point/struct
675  speed = 200.0;
676  point = ‪lase_point( entity_or_point );
677  time = Distance( point, self.origin ) / speed;
678 
679  early_out = false;
680  if ( IsDefined(owner) && IsDefined(owner.max_laser_transition_time) )
681  {
682  early_out = true;
683  time = Min(time, owner.max_laser_transition_time);
684  }
685 
686  if ( time > 0 )
687  {
688  self thread ‪velocity_approach( point, time, early_out );
689  self waittill( "velocity_approach_early_out" );
690  }
691  }
692 }
693 
707 function ‪target_lase_override( v_eye, entity_or_point, sight_timeout, a_owner, ‪fire_weapon, allow_interrupts = true )
708 {
709  if ( (IsDefined(self.lase_override) && ( !allow_interrupts || self.lase_override == entity_or_point) ))
710  return;
711 
712  self notify("target_lase_override");
713  self endon("target_lase_override");
714  self endon("death");
715 
716  self.lase_override = entity_or_point;
717 
718  self thread ‪target_lase_transition( entity_or_point, a_owner );
719 
720  outOfSightTime = 0.0;
721  reTargetTime = 0.0;
722 
723  delayBeforeFiring = 0.0;
724 
725  if ( IsDefined(a_owner.lase_fire_delay) )
726  {
727  delayBeforeFiring = a_owner.lase_fire_delay;
728  }
729 
730  if ( !isDefined( ‪fire_weapon ) )
731  ‪fire_weapon = true;
732 
733  while ( 1 )
734  {
735  if ( reTargetTime >= delayBeforeFiring )
736  {
737  if ( isActor( a_owner ) )
738  {
739  a_owner.holdfire = !‪fire_weapon;
740 
741  if ( ‪fire_weapon )
742  a_owner.sniper_last_fire = GetTime();
743  }
744  }
745 
746  if ( !isDefined( entity_or_point ) || outOfSightTime >= sight_timeout )
747  {
748  self notify("target_lase_transition");
749  break;
750  }
751 
752  if ( !SightTracePassed( v_eye, ‪lase_point( entity_or_point ), false, undefined ) )
753  outOfSightTime += ‪SERVER_FRAME;
754  else
755  outOfSightTime = 0.0;
756 
757 
758  reTargetTime += ‪SERVER_FRAME;
759 
761  }
762 
763  if ( isActor( a_owner ) )
764  a_owner.holdfire = true;
765 
766  self.lase_override = undefined;
767 }
768 
779 function ‪is_firing( a_owner )
780 {
781  if ( !isDefined( a_owner ) )
782  return false;
783 
784  if ( !isDefined( a_owner.sniper_last_fire ) )
785  return false;
786 
787  return ( GetTime() - a_owner.sniper_last_fire ) < 3000;
788 }
‪lase_point
‪function lase_point(entity_or_point)
Definition: ai_sniper_shared.gsc:358
‪goal_wait_notify_lase
‪function goal_wait_notify_lase(node)
Definition: ai_sniper_shared.gsc:103
‪startTime
‪class AnimationAdjustmentInfoZ startTime
‪goal_watcher_target
‪function goal_watcher_target()
Definition: ai_sniper_shared.gsc:145
‪actor_lase_force_laser_on
‪function actor_lase_force_laser_on()
Definition: ai_sniper_shared.gsc:323
‪actor_lase_points_behavior
‪function actor_lase_points_behavior(entity_or_point_array)
Definition: ai_sniper_shared.gsc:230
‪stop_shoot_at_target
‪function stop_shoot_at_target()
Definition: ai_shared.gsc:491
‪__init__
‪function __init__()
Definition: ai_sniper_shared.gsc:16
‪target_lase_next
‪function target_lase_next(node)
Definition: ai_sniper_shared.gsc:603
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪init_node_scan
‪function init_node_scan(targetName)
Definition: ai_sniper_shared.gsc:31
‪SetBlackBoardAttribute
‪function SetBlackBoardAttribute(entity, attributeName, attributeValue)
Definition: blackboard.gsc:56
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪target_lase_points_ally_track
‪function target_lase_points_ally_track(v_eye, entity_or_point_array, a_owner)
Definition: ai_sniper_shared.gsc:385
‪is_firing
‪function is_firing(a_owner)
Definition: ai_sniper_shared.gsc:779
‪end_and_clean_patrol_behaviors
‪function end_and_clean_patrol_behaviors()
Definition: ai_shared.gsc:868
‪target_lase_transition
‪function target_lase_transition(entity_or_point, owner)
Definition: ai_sniper_shared.gsc:650
‪has_behavior_attribute
‪function has_behavior_attribute(attribute)
Definition: ai_shared.gsc:198
‪goal_watcher_patrol
‪function goal_watcher_patrol()
Definition: ai_sniper_shared.gsc:131
‪SERVER_FRAME
‪#define SERVER_FRAME
Definition: shared.gsh:264
‪script_wait
‪function script_wait(called_from_spawner=false)
Definition: util_shared.gsc:1930
‪actor_lase_stop
‪function actor_lase_stop()
Definition: ai_sniper_shared.gsc:295
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪target_lase_points
‪function target_lase_points(entity_or_point_array, e_owner)
Definition: ai_sniper_shared.gsc:474
‪agent_init
‪function agent_init()
Definition: ai_sniper_shared.gsc:96
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪target_lase_override
‪function target_lase_override(v_eye, entity_or_point, sight_timeout, a_owner, fire_weapon, allow_interrupts=true)
Definition: ai_sniper_shared.gsc:707
‪set_behavior_attribute
‪function set_behavior_attribute(attribute, value)
Definition: ai_shared.gsc:159
‪target_lase_fire_at
‪function target_lase_fire_at(v_eye, entity_or_point, a_owner, allow_interrupts=true)
Definition: ai_sniper_shared.gsc:453
‪velocity_approach
‪function velocity_approach(endPosition, totalTime, b_early_out)
Definition: ai_sniper_shared.gsc:535
‪result
‪function result(death, attacker, mod, weapon)
Definition: _zm_aat_blast_furnace.gsc:46
‪patrol_lase_goal_waiter
‪function patrol_lase_goal_waiter()
Definition: ai_sniper_shared.gsc:164
‪delete_on_death
‪function delete_on_death(ent)
Definition: util_shared.gsc:1796
‪get_behavior_attribute
‪function get_behavior_attribute(attribute)
Definition: ai_shared.gsc:184
‪patrol
‪function patrol(start_path_node)
Definition: ai_shared.gsc:729
‪shoot_at_target
‪function shoot_at_target(mode, target, tag, duration, setHealth, ignoreFirstShotWait)
Definition: ai_shared.gsc:380
‪CONTEXT
‪#define CONTEXT
Definition: blackboard.gsh:16
‪actor_lase_laser_off_on_death
‪function actor_lase_laser_off_on_death()
Definition: ai_sniper_shared.gsc:348
‪fire_weapon
‪function fire_weapon()
Definition: animation_shared.gsc:718
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265