‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_escort_drone.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\util_shared;
7 #using scripts\shared\vehicle_shared;
8 #using scripts\shared\vehicle_ai_shared;
9 #using scripts\shared\flag_shared;
10 
11 #using scripts\shared\abilities\_ability_power;
12 
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\statemachine.gsh;
15 
16 #insert scripts\shared\ai\utility.gsh;
17 
18 #define DRONE_HUD_MARKED_TARGET "hud_proto_rts_secure_target"
19 #define DRONE_HUD_ELEM_CONSTANT_SIZE true
20 
21 #precache( "material", DRONE_HUD_MARKED_TARGET );
22 #precache( "fx", "_t6/electrical/fx_elec_sp_emp_stun_quadrotor" );
23 
24 #namespace escort_drone;
25 
26 ‪REGISTER_SYSTEM( "escort_drone", &‪__init__, undefined )
27 
28 function ‪__init__()
29 {
30  level._effect[ "escort_drone_stun" ] = "_t6/electrical/fx_elec_sp_emp_stun_quadrotor";
31 }
32 
33 function ‪escort_drone_think( player )
34 {
35  assert( IsDefined( player ) );
36 
37  self.n_tetherMax = player._gadgets_player.escortTetherMaxDist;
38  self.n_tetherMin = player._gadgets_player.escortTetherMinDist;
39 
40  self.n_tetherMaxSq = self.n_tetherMax * self.n_tetherMax;
41  self.n_tetherMinSq = self.n_tetherMin * self.n_tetherMin;
42 
43  self.n_target_time = player._gadgets_player.escortTargetAcquireTime;
44  self.n_burstCountMin = player._gadgets_player.escortBurstCountMin;
45  self.n_burstCountMax = player._gadgets_player.escortBurstCountMax;
46  self.n_burstWaitTime = player._gadgets_player.escortBurstWaitTime;
47  self.n_burstPowerLoss = player._gadgets_player.escortBurstPowerLoss;
48 
49  self.n_BulletPowerLoss = player._gadgets_player.escortBulletPowerLoss;
50  self.n_ExplosionPowerLoss = player._gadgets_player.escortExplosionPowerLoss;
51  self.n_MiscPowerLoss = player._gadgets_player.escortMiscPowerLoss;
52 
53  self.maxhealth = 200;//TODO T7 - added this because the MP callbacks want it. Can probably get rid of this later
54  self EnableAimAssist();
55  self SetHoverParams( 25.0, 120.0, 80 );
56  self SetNearGoalNotifyDist( 30 );
57 
58  self.flyheight = GetDvarFloat( "g_quadrotorFlyHeight" );
59 
60  self.fovcosine = 0; // +/-90 degrees = 180
61  self.fovcosinebusy = 0.574; //+/- 55 degrees = 110 fov
62 
63  self.vehAirCraftCollisionEnabled = true;
64 
65  if ( !IsDefined( self.heightAboveGround ) )
66  {
67  //self.heightAboveGround = 100;
68  //making tune-able
69  self.heightAboveGround = player._gadgets_player.escortHoverHeight;
70  }
71 
72  if( !isdefined( self.goalradius ) )
73  {
74  self.goalradius = 300;
75  }
76 
77  if( !isdefined( self.goalpos ) )
78  {
79  self.goalpos = self.origin;
80  }
81 
82  self.original_vehicle_type = self.vehicletype;
83 
84  self.state_machine = ‪statemachine::create( "edbrain", self );
85  ‪main = self.state_machine ‪statemachine::add_state( "main", undefined, &‪escort_drone_main, undefined );
86  scripted = self.state_machine ‪statemachine::add_state( "scripted", undefined, &‪escort_drone_scripted, undefined );
87 
88  ‪vehicle_ai::add_interrupt_connection( "main", "scripted", "enter_vehicle" );
89  ‪vehicle_ai::add_interrupt_connection( "main", "scripted", "scripted" );
90  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "exit_vehicle" );
91  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "main" );
92  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "scripted_done" );
93 
94  self HidePart( "tag_viewmodel" );
95 
96  self.overrideVehicleDamage = &‪EscortDroneCallback_VehicleDamage;
97 
98  // Set the first state
99  if ( isdefined( self.script_startstate ) )
100  {
101  if( self.script_startstate == "off" )
102  {
103  self ‪escort_drone_off();
104  }
105  else
106  {
107  self.state_machine ‪statemachine::set_state( self.script_startstate );
108  }
109  }
110  else
111  {
112  // Set the first state
114  }
115 
116  self thread ‪escort_drone_set_team( self.team );
117 
118  // start the update
119  // No need for this update any more since all connections are on notifies
120  //self.state_machine statemachine::update( 0.05 );
121 }
122 
124 {
125  if( !IsAlive( self ) )
126  return false;
127 
128  driver = self GetSeatOccupant( 0 );
129  if( isdefined( driver ) )
130  return false;
131 
132  return true;
133 }
134 
136 {
137  self.state_machine ‪statemachine::set_state( "scripted" );
138 }
139 
141 {
142  self.state_machine ‪statemachine::set_state( "scripted" );
143  self ‪vehicle::lights_off();
144  self ‪vehicle::toggle_tread_fx( 0 );
145  self ‪vehicle::toggle_sounds( 0 );
146  if( !isdefined( self.‪emped ) )
147  {
148  self DisableAimAssist();
149  }
150  self.off = true;
151 
152 }
153 
155 {
156  self ‪vehicle::lights_on();
157  self ‪vehicle::toggle_tread_fx( 1 );
158  self ‪vehicle::toggle_sounds( 1 );
159  self EnableAimAssist();
160  self.off = undefined;
162 }
163 
165 {
166  self.goalpos = self.origin;
167  self.state_machine ‪statemachine::set_state( "main" );
168 }
169 
171 {
172  self thread ‪escort_drone_blink_lights();
173  self thread ‪escort_drone_fireupdate();
174  self thread ‪escort_drone_movementupdate();
175  self thread ‪escort_drone_collision();
176 }
177 
179 {
180  self endon( "death" );
181  self endon( "change_state" );
182 
183  max_range = 2000;
184 
185  no_target_delay = 0.05;
186 
187  self thread ‪hud_marker_create();
188 
189  while( 1 )
190  {
191  if ( IsDefined( self.enemy ) && self VehCanSee( self.enemy ) && self.enemy ‪is_in_combat() ) //only shoot at guys who are engaging the player
192  {
193  wait( self.n_target_time ); //Tune-able - Target Acquisition Time
194 
195  if ( IsDefined( self.enemy ) && DistanceSquared( self.enemy.origin, self.origin ) < max_range * max_range )
196  {
197  self SetTurretTargetEnt( self.enemy );
198  self ‪escort_drone_fire_for_time( RandomFloatRange( self.n_burstCountMin, self.n_burstCountMax ) ); //Tune-able - burst count
199  }
200 
201  wait ( self.n_burstWaitTime ); //Tune-able - Time between bursts
202  }
203  else
204  {
205  wait no_target_delay;
206  }
207  }
208 }
209 
210 function ‪hud_marker_create() // self = drone
211 {
212  hud_marked_target = NewHudElem();
213 
214  hud_marked_target.horzAlign = "right";
215  hud_marked_target.vertAlign = "middle";
216 
217  hud_marked_target.sort = 2;
218 
219  hud_marked_target.hidewheninmenu = true;
220  hud_marked_target.immunetodemogamehudsettings = true;
221 
222  const Z_OFFSET = 90;
223 
224  while ( isdefined( self ) )
225  {
226  if ( isdefined( self.enemy ) )
227  {
228  hud_marked_target.alpha = 1;
229 
230  hud_marked_target.x = self.enemy.origin[0];
231  hud_marked_target.y = self.enemy.origin[1];
232  hud_marked_target.z = self.enemy.origin[2] + Z_OFFSET;
233 
234  hud_marked_target SetShader( ‪DRONE_HUD_MARKED_TARGET, 5, 5 );
235  hud_marked_target SetWaypoint( ‪DRONE_HUD_ELEM_CONSTANT_SIZE );
236 
237  }
238  else
239  {
240  hud_marked_target.alpha = 0;
241  }
242 
244  }
245 
246  hud_marked_target Destroy();
247 }
248 
249 function ‪escort_drone_check_move( position )
250 {
251  results = PhysicsTraceEx( self.origin, position, (-15,-15,-5), (15,15,5), self );
252 
253  if( results["fraction"] == 1 )
254  {
255  return true;
256  }
257 
258  return false;
259 }
260 
262 {
263  if( isdefined( self.enemy ) )
264  {
265  if( IsAI( self.enemy ) )
266  offset = 45;
267  else // don't want quadrotors to fly above quadrotors
268  offset = -100;
269 
270  if( self.enemy.origin[2] + offset > goalpos[2] )
271  {
272  goal_z = self.enemy.origin[2] + offset;
273  if( goal_z > goalpos[2] + 400 )
274  {
275  goal_z = goalpos[2] + 400;
276  }
277  results = PhysicsTraceEx( goalpos, ( goalpos[0], goalpos[1], goal_z ), (-15,-15,-5), (15,15,5), self );
278 
279  if( results["fraction"] == 1 )
280  {
281  goalpos = ( goalpos[0], goalpos[1], goal_z );
282  }
283  }
284  }
285 
286  return goalpos;
287 }
288 
290 {
291  start = pos + (0,0,self.flyheight);
292  ‪end = pos + (0,0,-self.flyheight);
293  ‪trace = BulletTrace( start, ‪end, false, self, false, false );
294  ‪end = ‪trace["position"];
295 
296  pos = ‪end + (0,0,self.flyheight);
297 
298  z = self GetHeliHeightLockHeight( pos );
299  pos = ( pos[0], pos[1], z );
300 
301  return pos;
302 }
303 
305 {
306  self endon( "death" );
307  self endon( "change_state" );
308 
309  if( self.vehonpath )
310  {
311  self ‪flag::wait_till( "goal_reached" );
312  }
313 }
314 
316 {
317  self endon( "death" );
318  self endon( "change_state" );
319 
320  self ‪flag::clear( "goal_reached" );
321  self ‪util::waittill_any( "near_goal", "reached_end_node", "force_goal" );
322  self ‪flag::set( "goal_reached" );
323 }
324 
326 {
327  self endon( "death" );
328  self endon( "change_state" );
329 
330  assert( IsAlive( self ) );
331 
332  while ( !isdefined( self.owner ) )
333  {
334 
335  wait 2;
336  }
337 
338  // make sure when we start this that we get above the ground
339  old_goalpos = self.goalpos;
340  self.goalpos = self ‪make_sure_goal_is_well_above_ground( self.goalpos );
341 
342  if ( !self ‪flag::exists( "goal_reached" ) )
343  {
344  self ‪flag::init( "goal_reached" );
345  }
346 
347  goalfailures = 0;
348 
349  while( 1 )
350  {
351  self thread ‪goal_flag_monitor();
352 
354 
355  while ( !IsDefined( goalpos ) )
356  {
357  wait 3;
359  }
360 
361  self.goalpos = goalpos;
362 
363  self thread ‪escort_drone_blink_lights();
364  if( self SetVehGoalPos( goalpos, true, 2 ) )
365  {
366  goalfailures = 0;
367 
368  if( isdefined( self.goal_node ) )
369  self.goal_node.escort_drone_claimed = true;
370 
371  if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
372  {
373  if( RandomInt( 100 ) > 50 )
374  {
375  self SetLookAtEnt( self.enemy );
376  }
377  }
378 
379  self ‪util::waittill_any_timeout( 12, "near_goal", "force_goal", "reached_end_node" );
380 
381  if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
382  {
383  self SetLookAtEnt( self.enemy );
384  wait RandomFloatRange( 2, 3 );
385  self ClearLookAtEnt();
386  }
387  }
388  else
389  {
390  goalfailures++;
391 
392  if( isdefined( self.goal_node ) )
393  {
394  self.goal_node.escort_drone_fails = true;
395  }
396 
397  if( goalfailures == 1 )
398  {
399  wait 0.5;
400  continue; // try again
401  }
402  else if( goalfailures == 2 )
403  {
404  // just go up and down, then try to find another goal
405  goalpos = self.origin;
406  }
407  else if( goalfailures == 3 )
408  {
409  // try to fix our position and go up and down
410  goalpos = self.origin;
411  self SetVehGoalPos( goalpos, true );
412  self waittill( "near_goal" );
413  }
414  else if( goalfailures > 3 )
415  {
416  /#
417  println( "WARNING: Quadrotor can't find path to goal over 4 times." + self.origin + " " + goalpos );
418  line( self.origin, goalpos, (1,1,1), 1, 100 );
419  #/
420  // assign a new goal position because the one we have is probably bad
421  self.goalpos = ‪make_sure_goal_is_well_above_ground( goalpos );
422  }
423 
424  old_goalpos = goalpos;
425 
426  offset = ( RandomFloatRange(-50,50), RandomFloatRange(-50,50), RandomFloatRange(50, 150) );
427 
428  goalpos = goalpos + offset;
429 
431 
432  if( self ‪escort_drone_check_move( goalpos ) )
433  {
434  self SetVehGoalPos( goalpos, true );
435  self ‪util::waittill_any( "near_goal", "force_goal", "start_vehiclepath" );
436 
437  wait RandomFloatRange( 1, 3 );
438 
439  if( !self.vehonpath )
440  {
441  self SetVehGoalPos( old_goalpos, true );
442  self ‪util::waittill_any( "near_goal", "force_goal", "start_vehiclepath" );
443  }
444  }
445  wait 0.5;
446  }
447  }
448 }
449 
451 {
452  nodes = GetNodesInRadiusSorted( self.origin, 200, 0, 500, "Path" );
453 
454  if( nodes.size == 0 )
455  {
456  nodes = GetNodesInRadiusSorted( self.goalpos, 3000, 0, 2000, "Path" );
457  }
458 
459  foreach( node in nodes )
460  {
461  if( node.type == "BAD NODE" )
462  {
463  continue;
464  }
465 
466  return ‪make_sure_goal_is_well_above_ground( node.origin );
467  }
468 
469  return self.origin;
470 }
471 
473 {
474  position = self.origin;
475 
476  if ( IsDefined( self.owner ) )
477  {
478  n_distToPlayerSq = Distance2DSquared( self.origin, self.owner.origin );
479 
480  if ( n_distToPlayerSq >= self.n_tetherMaxSq )
481  {
482  forward_vector = anglestoforward( self.owner.angles ) * self.n_tetherMin;
483  position = self.owner.origin + ( forward_vector + (0,0,100) );
484  }
485  }
486 
487  adjustedgoalpos = position;
488 
489  if( isdefined( adjustedgoalpos ) )
490  {
491  position = adjustedgoalpos;
492  }
493 
494  position = self GetClosestPointOnNavVolume( position, 200 );
495 
496  return position;
497 }
498 
500 {
501  self.origin = self ‪escort_drone_get_closest_node();
502 }
503 
505 {
506  self waittill( "exit_vehicle", player );
507 
508  player.ignoreme = false;
509  player DisableInvulnerability();
510 
511  self SetHeliHeightLock( false );
512  self EnableAimAssist();
513  self.attachedpath = undefined;
515  self.goalpos = self.origin;
516 }
517 
519 {
520  // do nothing state
521  driver = self GetSeatOccupant( 0 );
522  if( isdefined(driver) )
523  {
524  self DisableAimAssist();
525  self SetHeliHeightLock( true );
526  self thread ‪escort_drone_set_team( driver.team );
527  driver.ignoreme = true;
528  driver EnableInvulnerability();
529 
530  self thread ‪escort_drone_exit_vehicle();
531  self thread ‪escort_drone_collision_player();
532  }
533 
534  if( isdefined( self.goal_node ) && isdefined( self.goal_node.escort_drone_claimed ) )
535  {
536  self.goal_node.escort_drone_claimed = undefined;
537  }
538 
539  self ClearTargetEntity();
540  self CancelAIMove();
541  self ClearVehGoalPos();
542  self PathVariableOffsetClear();
543  self PathFixedOffsetClear();
544  self ClearLookAtEnt();
545 }
546 
548 {
549  if( isdefined( self.damage_fx_ent ) )
550  {
551  if( self.damage_fx_ent.effect == effect )
552  {
553  // already playing
554  return;
555  }
556  self.damage_fx_ent delete();
557  }
558 
559 
560  ent = ‪Spawn( "script_model", ( 0, 0, 0 ) );
561  ent SetModel( "tag_origin" );
562  ent.origin = self GetTagOrigin( tag );
563  ent.angles = self GetTagAngles( tag );
564  ent NotSolid();
565  ent Hide();
566  ent LinkTo( self, tag );
567  ent.effect = effect;
568  playfxontag( effect, ent, "tag_origin" );
569  ent playsound("veh_qrdrone_sparks");
570 
571 
572  self.damage_fx_ent = ent;
573 }
574 
576 {
577  if( isdefined( self.damage_fx_ent ) )
578  {
579  self.damage_fx_ent delete();
580  }
581 
582  if( isdefined( self.stun_fx ) )
583  {
584  self.stun_fx delete();
585  }
586 }
587 
588 function ‪escort_drone_fire_for_time( totalFireTime )
589 {
590  self endon( "crash_done" );
591  self endon( "change_state" );
592  self endon( "death" );
593 
594  if( isdefined( self.‪emped ) )
595  return;
596 
597  weapon = self SeatGetWeapon( 0 );
598  fireTime = weapon.fireTime;
599  time = 0;
600 
601  self.owner ‪ability_power::power_loss_event( undefined, self.n_burstPowerLoss, "drone_fired" );
602 
603  fireCount = 1;
604 
605  while( time < totalFireTime && !isdefined( self.‪emped ) )
606  {
607  self FireWeapon();
608 
609  fireCount++;
610  wait fireTime;
611  time += fireTime;
612  }
613 }
614 
615 
617 {
618  self endon( "crash_done" );
619  self endon( "death" );
620 
621  while( 1 )
622  {
623  self waittill( "veh_predictedcollision", velocity, normal );
624  if( normal[2] >= 0.6 )
625  {
626  self notify( "veh_collision", velocity, normal );
627  }
628  }
629 }
630 
632 {
633  self endon( "change_state" );
634  self endon( "crash_done" );
635  self endon( "death" );
636 
637  while( 1 )
638  {
639  self waittill( "veh_collision", velocity, normal );
640  driver = self GetSeatOccupant( 0 );
641  if( isdefined( driver ) && LengthSquared( velocity ) > 70*70 )
642  {
643  Earthquake( 0.25, 0.25, driver.origin, 50 );
644  driver PlayRumbleOnEntity( "damage_heavy" );
645  }
646  }
647 }
648 
650 {
651  self endon( "change_state" );
652  self endon( "crash_done" );
653  self endon( "death" );
654 
655  if( !IsAlive( self ) )
656  {
658  }
659 
660  while( 1 )
661  {
662  self waittill( "veh_collision", velocity, normal );
663  ang_vel = self GetAngularVelocity() * 0.5;
664  self SetAngularVelocity( ang_vel );
665 
666  // bounce off walls
667  if( normal[2] < 0.6 || ( IsAlive( self ) && !isdefined( self.‪emped ) ) )
668  {
669  self SetVehVelocity( self.velocity + normal * 90 );
670  self PlaySound( "veh_qrdrone_wall" );
671  if( normal[2] < 0.6 )
672  {
673  fx_origin = self.origin - normal * 28;
674  }
675  else
676  {
677  fx_origin = self.origin - normal * 10;
678  }
679  //PlayFX( level._effect[ "escort_drone_nudge" ], fx_origin, normal );
680  }
681  else
682  {
683 
684  if( isdefined( self.‪emped ) )
685  {
686  if( isdefined( self.bounced ) )
687  {
688  self playsound( "veh_qrdrone_wall" );
689  self SetVehVelocity( (0,0,0) );
690  self SetAngularVelocity( (0,0,0) );
691  if( self.angles[0] < 0 )
692  {
693  if( self.angles[0] < -15 )
694  {
695  self.angles = ( -15, self.angles[1], self.angles[2] );
696  }
697  else if( self.angles[0] > -10 )
698  {
699  self.angles = ( -10, self.angles[1], self.angles[2] );
700  }
701  }
702  else
703  {
704  if( self.angles[0] > 15 )
705  {
706  self.angles = ( 15, self.angles[1], self.angles[2] );
707  }
708  else if( self.angles[0] < 10 )
709  {
710  self.angles = ( 10, self.angles[1], self.angles[2] );
711  }
712  }
713 
714  self.bounced = undefined;
715  self notify( "landed" );
716  return;
717  }
718  else
719  {
720  self.bounced = true;
721  self SetVehVelocity( self.velocity + normal * 120 );
722  self playsound( "veh_qrdrone_wall" );
723  if( normal[2] < 0.6 )
724  {
725  fx_origin = self.origin - normal * 28;
726  }
727  else
728  {
729  fx_origin = self.origin - normal * 10;
730  }
731  //PlayFX( level._effect[ "escort_drone_nudge" ], fx_origin, normal );
732  }
733  }
734  else
735  {
736  //CreateDynEntAndLaunch( self.deathmodel, self.origin, self.angles, self.origin, self.velocity * 0.01, level._effect[ "escort_drone_crash" ], 1 );
737  self playsound( "veh_qrdrone_explo" );
738  self notify( "crash_done" );
739  }
740  }
741  }
742 }
743 
744 function ‪escort_drone_set_team( team )
745 {
746  self.team = team;
747 
748  if( !isdefined( self.off ) )
749  {
751  }
752 }
753 
755 {
756  self endon( "death" );
757 
758  self ‪vehicle::lights_off();
759  wait 0.1;
760  self ‪vehicle::lights_on();
761 }
762 
764 {
765  self endon( "death" );
766  self endon( "emped" );
767  self endon( "landed" );
768 
769  while( isdefined( self.‪emped ) )
770  {
771  velocity = self.velocity; // setting the angles clears the velocity so we save it off and set it back
772  self.angles = ( self.angles[0] * 0.85, self.angles[1], self.angles[2] * 0.85 );
773  ang_vel = self GetAngularVelocity() * 0.85;
774  self SetAngularVelocity( ang_vel );
775  self SetVehVelocity( velocity );
777  }
778 }
779 
781 {
782  self endon( "death" );
783  self notify( "emped" );
784  self endon( "emped" );
785 
786  self.emped = true;
787 
788  PlaySoundAtPosition( "veh_qrdrone_emp_down", self.origin );
789  self ‪escort_drone_off();
790 
791  self SetPhysAcceleration( ( 0, 0, -600 ) );
793  self thread ‪escort_drone_collision();
794 
795  if( !isdefined( self.stun_fx ) )
796  {
797  self.stun_fx = ‪Spawn( "script_model", self.origin );
798  self.stun_fx SetModel( "tag_origin" );
799  self.stun_fx LinkTo( self, "tag_origin", (0,0,0), (0,0,0) );
800  PlayFXOnTag( level._effect[ "escort_drone_stun" ], self.stun_fx, "tag_origin" );
801  }
802 
803  wait RandomFloatRange( 4, 7 );
804 
805  self.stun_fx delete();
806 
807  self.emped = undefined;
808  self SetPhysAcceleration( ( 0, 0, 0 ) );
809  self ‪escort_drone_on();
810  self playsound ("veh_qrdrone_boot_qr");
811 }
812 
813 function ‪escort_drone_temp_bullet_shield( invulnerable_time )
814 {
815  self notify( "bullet_shield" );
816  self endon( "bullet_shield" );
817 
818  self.bullet_shield = true;
819 
820  wait invulnerable_time;
821 
822  if( isdefined( self ) )
823  {
824  self.bullet_shield = undefined;
825  wait 3;
826  if( isdefined( self ) && self.health < 40 )
827  {
828  self.health = 40;
829  }
830  }
831 }
832 
833 function ‪EscortDroneCallback_VehicleDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName )
834 {
835  driver = self GetSeatOccupant( 0 );
836 
837  if( weapon.isEmp && sMeansOfDeath != "MOD_IMPACT" )
838  {
839  if( !isdefined( driver ) )
840  {
841  if( !isdefined( self.off ) )
842  {
843  self thread ‪escort_drone_emped();
844  }
845  }
846  }
847 
848  power_loss = iDamage * ‪escort_drone_power_loss_multiplier( sMeansOfDeath );
849 
850  if ( self.owner.cclass_power.powerRemaining > power_loss )
851  {
852  self.owner ‪ability_power::power_loss_event( undefined, power_loss, "shooter" );
853  }
854  else if ( self.owner.cclass_power.powerRemaining > 0 )
855  {
856  self.owner ‪ability_power::power_loss_event( undefined, self.owner.cclass_power.powerRemaining, "shooter" );
857  }
858 
859  iDamage = 1;
860 
861  return iDamage;
862 }
863 
864 function ‪escort_drone_power_loss_multiplier( sMeansOfDeath )
865 {
866  switch(sMeansOfDeath)
867  {
868  case "MOD_CRUSH":
869  case "MOD_TELEFRAG":
870  case "MOD_SUICIDE":
871  case "MOD_DROWN":
872  case "MOD_HIT_BY_OBJECT":
873  case "MOD_FALLING":
874  case "MOD_PROJECTILE":
875  case "MOD_BURNED":
876  case "MOD_HEAD_SHOT":
877  case "MOD_UNKNOWN":
878  case "MOD_TRIGGER_HURT":
879  case "MOD_MELEE":
880  case "MOD_MELEE_WEAPON_BUTT":
881  return self.n_MiscPowerLoss;
882  break;
883 
884  case "MOD_EXPLOSIVE":
885  case "MOD_PROJECTILE_SPLASH":
886  case "MOD_GRENADE":
887  case "MOD_GRENADE_SPLASH":
888  return self.n_ExplosionPowerLoss;
889  break;
890 
891  case "MOD_PISTOL_BULLET":
892  case "MOD_RIFLE_BULLET":
893  case "MOD_IMPACT":
894  return self.n_BulletPowerLoss;
895  break;
896  }
897 }
898 
899 function ‪is_in_combat()
900 {
901  if ( IsDefined( self.archetype ) && IsDefined ( self.str_awareness_state ) && self.str_awareness_state == ‪STATE_COMBAT )
902  {
903  return true;
904  }
905 
906  return false;
907 }
‪add_interrupt_connection
‪function add_interrupt_connection(from_state_name, to_state_name, on_notify, checkfunc)
Definition: statemachine_shared.gsc:90
‪escort_drone_get_closest_node
‪function escort_drone_get_closest_node()
Definition: _escort_drone.gsc:450
‪add_state
‪function add_state(name, enter_func, update_func, exit_func, reenter_func)
Definition: statemachine_shared.gsc:59
‪lights_off
‪function lights_off(localClientNum)
Definition: vehicle_shared.csc:652
‪set_state
‪function set_state(name, state_params)
Definition: statemachine_shared.gsc:133
‪escort_drone_start_ai
‪function escort_drone_start_ai()
Definition: _escort_drone.gsc:164
‪escort_drone_emped
‪function escort_drone_emped()
Definition: _escort_drone.gsc:780
‪escort_drone_adjust_goal_for_enemy_height
‪function escort_drone_adjust_goal_for_enemy_height(goalpos)
Definition: _escort_drone.gsc:261
‪toggle_tread_fx
‪function toggle_tread_fx(on)
Definition: vehicle_shared.gsc:3357
‪escort_drone_fireupdate
‪function escort_drone_fireupdate()
Definition: _escort_drone.gsc:178
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪escort_drone_play_single_fx_on_tag
‪function escort_drone_play_single_fx_on_tag(effect, tag)
Definition: _escort_drone.gsc:547
‪STATE_COMBAT
‪#define STATE_COMBAT
Definition: shared.gsh:432
‪escort_drone_movementupdate
‪function escort_drone_movementupdate()
Definition: _escort_drone.gsc:325
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪waittill_any_timeout
‪function waittill_any_timeout(n_timeout, string1, string2, string3, string4, string5)
Definition: util_shared.csc:423
‪escort_drone_teleport_to_nearest_node
‪function escort_drone_teleport_to_nearest_node()
Definition: _escort_drone.gsc:499
‪power_loss_event
‪function power_loss_event(slot, eAttacker, val, source)
Definition: _ability_power.gsc:199
‪escort_drone_collision
‪function escort_drone_collision()
Definition: _escort_drone.gsc:649
‪escort_drone_level_out_for_landing
‪function escort_drone_level_out_for_landing()
Definition: _escort_drone.gsc:763
‪DRONE_HUD_ELEM_CONSTANT_SIZE
‪#define DRONE_HUD_ELEM_CONSTANT_SIZE
Definition: _escort_drone.gsc:19
‪waittill_pathing_done
‪function waittill_pathing_done()
Definition: _escort_drone.gsc:304
‪escort_drone_cleanup_fx
‪function escort_drone_cleanup_fx()
Definition: _escort_drone.gsc:575
‪escort_drone_exit_vehicle
‪function escort_drone_exit_vehicle()
Definition: _escort_drone.gsc:504
‪escort_drone_scripted
‪function escort_drone_scripted()
Definition: _escort_drone.gsc:518
‪goal_flag_monitor
‪function goal_flag_monitor()
Definition: _escort_drone.gsc:315
‪is_in_combat
‪function is_in_combat()
Definition: _escort_drone.gsc:899
‪end
‪function end(final)
Definition: _killcam.gsc:511
‪escort_drone_temp_bullet_shield
‪function escort_drone_temp_bullet_shield(invulnerable_time)
Definition: _escort_drone.gsc:813
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪DRONE_HUD_MARKED_TARGET
‪#define DRONE_HUD_MARKED_TARGET
Definition: _escort_drone.gsc:18
‪create
‪function create(name, origin, team, shader, alpha, scale)
Definition: objpoints_shared.gsc:32
‪__init__
‪function __init__()
Definition: _escort_drone.gsc:28
‪EscortDroneCallback_VehicleDamage
‪function EscortDroneCallback_VehicleDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName)
Definition: _escort_drone.gsc:833
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪escort_drone_predicted_collision
‪function escort_drone_predicted_collision()
Definition: _escort_drone.gsc:616
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪escort_drone_off
‪function escort_drone_off()
Definition: _escort_drone.gsc:140
‪emped
‪function emped(down_time)
Definition: _siegebot.gsc:1359
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪make_sure_goal_is_well_above_ground
‪function make_sure_goal_is_well_above_ground(pos)
Definition: _escort_drone.gsc:289
‪init
‪function init()
Definition: struct.csc:1
‪escort_drone_find_new_position
‪function escort_drone_find_new_position()
Definition: _escort_drone.gsc:472
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪escort_drone_collision_player
‪function escort_drone_collision_player()
Definition: _escort_drone.gsc:631
‪main
‪function main()
Definition: _global_fx.csc:17
‪exists
‪function exists(str_flag)
Definition: flag_shared.csc:43
‪hud_marker_create
‪function hud_marker_create()
Definition: _escort_drone.gsc:210
‪escort_drone_check_move
‪function escort_drone_check_move(position)
Definition: _escort_drone.gsc:249
‪escort_drone_power_loss_multiplier
‪function escort_drone_power_loss_multiplier(sMeansOfDeath)
Definition: _escort_drone.gsc:864
‪escort_drone_on
‪function escort_drone_on()
Definition: _escort_drone.gsc:154
‪toggle_sounds
‪function toggle_sounds(on)
Definition: vehicle_shared.gsc:3379
‪escort_drone_start_scripted
‪function escort_drone_start_scripted()
Definition: _escort_drone.gsc:135
‪escort_drone_set_team
‪function escort_drone_set_team(team)
Definition: _escort_drone.gsc:744
‪lights_on
‪function lights_on(localClientNum, team)
Definition: vehicle_shared.csc:404
‪escort_drone_think
‪function escort_drone_think(player)
Definition: _escort_drone.gsc:33
‪escort_drone_main
‪function escort_drone_main()
Definition: _escort_drone.gsc:170
‪can_enter_main
‪function can_enter_main()
Definition: _escort_drone.gsc:123
‪escort_drone_blink_lights
‪function escort_drone_blink_lights()
Definition: _escort_drone.gsc:754
‪escort_drone_fire_for_time
‪function escort_drone_fire_for_time(totalFireTime)
Definition: _escort_drone.gsc:588
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265