‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_qrdrone.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\challenges_shared;
4 #using scripts\shared\clientfield_shared;
5 #using scripts\shared\hostmigration_shared;
6 #using scripts\shared\hud_shared;
7 #using scripts\shared\killstreaks_shared;
8 #using scripts\shared\math_shared;
9 #using scripts\shared\popups_shared;
10 #using scripts\shared\scoreevents_shared;
11 #using scripts\shared\util_shared;
12 #using scripts\shared\weapons\_heatseekingmissile;
13 #using scripts\shared\weapons\_weaponobjects;
14 
15 #using scripts\mp\_challenges;
16 #using scripts\mp\_util;
17 #using scripts\mp\gametypes\_hostmigration;
18 #using scripts\mp\gametypes\_shellshock;
19 #using scripts\mp\gametypes\_spawning;
20 #using scripts\mp\killstreaks\_ai_tank;
21 #using scripts\mp\killstreaks\_airsupport;
22 #using scripts\mp\killstreaks\_killstreakrules;
23 #using scripts\mp\killstreaks\_killstreaks;
24 #using scripts\mp\killstreaks\_remote_weapons;
25 
26 #insert scripts\mp\_hacker_tool.gsh;
27 #insert scripts\shared\shared.gsh;
28 #insert scripts\shared\version.gsh;
29 
30 #define UAV_REMOTE_FLY_TIME 60
31 #define UAV_REMOTE_AIM_ASSIST_RANGE 200
32 #define UAV_REMOTE_MAX_PAST_RANGE 200
33 #define UAV_REMOTE_MIN_HELI_PROXIMITY 150
34 #define UAV_REMOTE_MAX_HELI_PROXIMITY 300
35 #define UAV_REMOTE_PAST_RANGE_COUNTDOWN 6.1
36 #define UAV_REMOTE_HELI_RANGE_COUNTDOWN 6.1
37 #define UAV_REMOTE_COLLISION_RADIUS 18
38 #define UAV_REMOTE_Z_OFFSET -9
39 #define UAV_REMOTE_MODEL "veh_t6_drone_quad_rotor_mp"
40 #define UAV_REMOTE_MODEL_ENEMY "veh_t6_drone_quad_rotor_mp_alt"
41 #define UAV_DEATH_MODEL "veh_t6_drone_quad_rotor_mp"
42 #define QRDRONE_MAX_HEALTH 225
43 
44 #precache( "string", "MP_REMOTE_UAV_PLACE" );
45 #precache( "string", "MP_REMOTE_UAV_CANNOT_PLACE" );
46 #precache( "string", "SPLASHES_DESTROYED_REMOTE_UAV" );
47 #precache( "string", "SPLASHES_MARKED_BY_REMOTE_UAV" );
48 #precache( "string", "SPLASHES_REMOTE_UAV_MARKED" );
49 #precache( "string", "SPLASHES_TURRET_MARKED_BY_REMOTE_UAV" );
50 #precache( "string", "SPLASHES_REMOTE_UAV_ASSIST" );
51 #precache( "string", "KILLSTREAK_EARNED_QRDRONE" );
52 #precache( "string", "KILLSTREAK_QRDRONE_NOT_AVAILABLE" );
53 #precache( "string", "KILLSTREAK_QRDRONE_INBOUND" );
54 #precache( "string", "KILLSTREAK_QRDRONE_HACKED" );
55 #precache( "eventstring", "mpl_killstreak_qrdrone" );
56 #precache( "fx", "killstreaks/fx_drgnfire_light_green_3p" );
57 #precache( "fx", "killstreaks/fx_drgnfire_light_red_3p" );
58 #precache( "fx", "killstreaks/fx_drgnfire_light_green_1p" );
59 #precache( "fx", "weapon/fx_muz_md_rifle_3p" );
60 #precache( "fx", "killstreaks/fx_drgnfire_explosion" );
61 #precache( "fx", "killstreaks/fx_drgnfire_impact_sparks" );
62 #precache( "fx", "killstreaks/fx_drgnfire_damage_state" );
63 #precache( "fx", "killstreaks/fx_drgnfire_rotor_wash_runner" );
64 
65 #namespace qrdrone;
66 
67 function ‪init()
68 {
69  level.qrdrone_vehicle = "qrdrone_mp";
70 
71  level.ai_tank_stun_fx = "killstreaks/fx_agr_emp_stun";
72 
73  level.QRDrone_minigun_flash = "weapon/fx_muz_md_rifle_3p";
74  level.QRDrone_fx["explode"] = "killstreaks/fx_drgnfire_explosion";
75 
76 // level._effect[ "quadrotor_crash" ] = "_t6/destructibles/fx_quadrotor_crash01";
77  level._effect[ "quadrotor_nudge" ] = "killstreaks/fx_drgnfire_impact_sparks";
78  level._effect[ "quadrotor_damage" ] = "killstreaks/fx_drgnfire_damage_state";
79 // level._effect[ "quadrotor_death" ] = "_t6/destructibles/fx_quadrotor_death01";
80 
81  level.QRDrone_dialog["launch"][0] = "ac130_plt_yeahcleared";
82  level.QRDrone_dialog["launch"][1] = "ac130_plt_rollinin";
83  level.QRDrone_dialog["launch"][2] = "ac130_plt_scanrange";
84 
85  level.QRDrone_dialog["out_of_range"][0] = "ac130_plt_cleanup";
86  level.QRDrone_dialog["out_of_range"][1] = "ac130_plt_targetreset";
87 
88  level.QRDrone_dialog["track"][0] = "ac130_fco_moreenemy";
89  level.QRDrone_dialog["track"][1] = "ac130_fco_getthatguy";
90  level.QRDrone_dialog["track"][2] = "ac130_fco_guymovin";
91  level.QRDrone_dialog["track"][3] = "ac130_fco_getperson";
92  level.QRDrone_dialog["track"][4] = "ac130_fco_guyrunnin";
93  level.QRDrone_dialog["track"][5] = "ac130_fco_gotarunner";
94  level.QRDrone_dialog["track"][6] = "ac130_fco_backonthose";
95  level.QRDrone_dialog["track"][7] = "ac130_fco_gonnagethim";
96  level.QRDrone_dialog["track"][8] = "ac130_fco_personnelthere";
97  level.QRDrone_dialog["track"][9] = "ac130_fco_rightthere";
98  level.QRDrone_dialog["track"][10] = "ac130_fco_tracking";
99 
100  level.QRDrone_dialog["tag"][0] = "ac130_fco_nice";
101  level.QRDrone_dialog["tag"][1] = "ac130_fco_yougothim";
102  level.QRDrone_dialog["tag"][2] = "ac130_fco_yougothim2";
103  level.QRDrone_dialog["tag"][3] = "ac130_fco_okyougothim";
104 
105  level.QRDrone_dialog["assist"][0] = "ac130_fco_goodkill";
106  level.QRDrone_dialog["assist"][1] = "ac130_fco_thatsahit";
107  level.QRDrone_dialog["assist"][2] = "ac130_fco_directhit";
108  level.QRDrone_dialog["assist"][3] = "ac130_fco_rightontarget";
109 
110  level.QRDrone_lastDialogTime = 0;
111 
112  level.QRDrone_noDeployZones = GetEntArray( "no_vehicles", "targetname" );
113 
114  level._effect["qrdrone_prop"] = "_t6/weapon/qr_drone/fx_qr_wash_3p";
115 
116 /#
117  ‪util::set_dvar_if_unset( "scr_QRDroneFlyTime", 60 );
118 #/
119  //killstreaks::register( "qrdrone", "killstreak_qrdrone", "killstreak_qrdrone", "qrdrone_used",&tryUseQRDrone );
120  //killstreaks::register_alt_weapon( "qrdrone", "qrdrone_turret" );
121  //killstreaks::register_strings( "qrdrone", &"KILLSTREAK_EARNED_QRDRONE", &"KILLSTREAK_QRDRONE_NOT_AVAILABLE", &"KILLSTREAK_QRDRONE_INBOUND", undefined, &"KILLSTREAK_QRDRONE_HACKED" );
122  //killstreaks::register_dialog( "qrdrone", "mpl_killstreak_qrdrone", "kls_recondrone_used", "", "kls_recondrone_enemy", "", "kls_recondrone_ready" );
123  //killstreaks::override_entity_camera_in_demo("qrdrone", true);
124 
125  ‪clientfield::register( "helicopter", "qrdrone_state", ‪VERSION_SHIP, 3, "int" );
126  ‪clientfield::register( "helicopter", "qrdrone_timeout", ‪VERSION_SHIP, 1, "int" );
127  ‪clientfield::register( "helicopter", "qrdrone_countdown", ‪VERSION_SHIP, 1, "int" );
128 
129  ‪clientfield::register( "vehicle", "qrdrone_state", ‪VERSION_SHIP, 3, "int" );
130  ‪clientfield::register( "vehicle", "qrdrone_timeout", ‪VERSION_SHIP, 1, "int" );
131  ‪clientfield::register( "vehicle", "qrdrone_countdown", ‪VERSION_SHIP, 1, "int" );
132  ‪clientfield::register( "vehicle", "qrdrone_out_of_range", ‪VERSION_SHIP, 1, "int" );
133 
134 
135  level.qrdroneOnBlowUp = &‪qrdrone::QRDrone_blowup;
136  level.qrdroneOnDamage = &‪qrdrone::QRDrone_damageWatcher;
137 }
138 
139 function ‪tryUseQRDrone( lifeId )
140 {
141  if ( self ‪util::isUsingRemote() || isdefined( level.nukeIncoming ) )
142  {
143  return false;
144  }
145 
146  if (!self IsOnGround())
147  {
148  self iPrintLnBold( &"KILLSTREAK_QRDRONE_NOT_PLACEABLE" );
149  return false;
150  }
151 
152  streakName = "TODO";
153  ‪result = self ‪giveCarryQRDrone( lifeId, streakName );
154 
155  self.isCarrying = false;
156  return ( ‪result );
157 }
158 
159 
160 function ‪giveCarryQRDrone( lifeId, streakName )
161 {
162  // create carry object
163  carryQRDrone = ‪createCarryQRDrone( streakName, self );
164 
165  // give carry object and wait for placement (blocking loop)
166  self ‪setCarryingQRDrone( carryQRDrone );
167 
168  // we're back, what happened?
169  if ( isAlive( self ) && isdefined( carryQRDrone ) )
170  {
171  // if it placed, start the killstreak at that location
172  origin = carryQRDrone.origin;
173  angles = self.angles;
174  carryQRDrone.soundEnt delete();
175  carryQRDrone delete();
176 
177  ‪result = self ‪startQRDrone( lifeId, streakName, origin, angles );
178  }
179  else
180  {
181  // cancelled placement or died
182  ‪result = false;
183  }
184 
185  return ‪result;
186 }
187 
188 
189 // Carry Remote UAV
190 
191 
192 function ‪createCarryQRDrone( streakName, owner )
193 {
194  pos = owner.origin + ( anglesToForward( owner.angles ) * 4 ) + ( anglesToUp( owner.angles ) * 50 );
195 
196  carryQRDrone = spawnTurret( "misc_turret", pos, GetWeapon( "auto_gun_turret" ) );
197  carryQRDrone.turretType = "sentry";
198  carryQRDrone SetTurretType(carryQRDrone.turretType);
199  carryQRDrone.origin = pos;
200  carryQRDrone.angles = owner.angles;
201 
202  carryQRDrone.canBePlaced = true;
203  carryQRDrone makeUnusable();
204  carryQRDrone.owner = owner;
205  carryQRDrone SetOwner( carryQRDrone.owner );
206  carryQRDrone.scale = 3;
207  carryQRDrone.inHeliProximity = false;
208 
209  carryQRDrone thread ‪carryQRDrone_handleExistence();
210 
211  carryQRDrone.rangeTrigger = GetEnt( "qrdrone_range", "targetname" );
212  if ( !isdefined( carryQRDrone.rangeTrigger ) )
213  {
214  carryQRDrone.maxHeight = int(‪airsupport::getMinimumFlyHeight());
215  carryQRDrone.maxDistance = 3600;
216  }
217  carryQRDrone.minHeight = level.mapCenter[2] - 800;
218 
219  // apparently can't call playLoopSound on a turret?
220  carryQRDrone.soundEnt = ‪spawn( "script_origin", carryQRDrone.origin );
221  carryQRDrone.soundEnt.angles = carryQRDrone.angles;
222  carryQRDrone.soundEnt.origin = carryQRDrone.origin;
223  carryQRDrone.soundEnt linkTo( carryQRDrone );
224  carryQRDrone.soundEnt playLoopSound( "recondrone_idle_high" );
225 
226  return carryQRDrone;
227 }
228 
229 function ‪watchForAttack( )
230 {
231  self endon ( "death" );
232  self endon ( "disconnect" );
233  self endon ( "place_carryQRDrone" );
234  self endon ( "cancel_carryQRDrone" );
235 
236  for ( ;; )
237  {
239 
240  if ( self attackButtonPressed() )
241  {
242  self notify( "place_carryQRDrone" );
243  }
244  }
245 }
246 
247 function ‪setCarryingQRDrone( carryQRDrone )
248 {
249  self endon ( "death" );
250  self endon ( "disconnect" );
251 
252  carryQRDrone thread ‪carryQRDrone_setCarried( self );
253 
254  if ( !carryQRDrone.canBePlaced )
255  {
256  if ( self.team != "spectator" )
257  self iPrintLnBold( &"KILLSTREAK_QRDRONE_NOT_PLACEABLE" );
258  if ( isdefined( carryQRDrone.soundEnt ) )
259  carryQRDrone.soundEnt delete();
260  carryQRDrone delete();
261  return;
262  }
263 
264  self.isCarrying = false;
265  carryQRDrone.carriedBy = undefined;
266 
267  carryQRDrone playSound( "sentry_gun_plant" );
268  carryQRDrone notify ( "placed" );
269 }
270 
271 function ‪carryQRDrone_setCarried( carrier )
272 {
273  self setCanDamage( false );
274  self setContents( 0 );
275 
276  self.carriedBy = carrier;
277  carrier.isCarrying = true;
278 
279  carrier thread ‪updateCarryQRDronePlacement( self );
280  self notify ( "carried" );
281 }
282 
283 
285 {
286  if ( isdefined( level.QRDrone_noDeployZones ) && level.QRDrone_noDeployZones.size )
287  {
288  foreach( zone in level.QRDrone_noDeployZones )
289  {
290  if ( self isTouching( zone ) )
291  return true;
292  }
293  }
294  return false;
295 }
296 
297 
298 function ‪updateCarryQRDronePlacement( carryQRDrone )
299 {
300  self endon ( "death" );
301  self endon ( "disconnect" );
302  level endon ( "game_ended" );
303 
304  carryQRDrone endon ( "placed" );
305  carryQRDrone endon ( "death" );
306 
307  carryQRDrone.canBePlaced = true;
308  lastCanPlaceCarryQRDrone = -1; // force initial update
309 
310  for( ;; )
311  {
312  heightOffset = ‪UAV_REMOTE_COLLISION_RADIUS;
313  switch( self getStance() )
314  {
315  case "stand":
316  heightOffset = 40;
317  break;
318  case "crouch":
319  heightOffset = 25;
320  break;
321  case "prone":
322  heightOffset = 10;
323  break;
324  }
325 
326  placement = self CanPlayerPlaceVehicle( 22, 22, 50, heightOffset, 0, 0 );
327  carryQRDrone.origin = placement[ "origin" ] + ( anglesToUp(self.angles) * ( ‪UAV_REMOTE_COLLISION_RADIUS - ‪UAV_REMOTE_Z_OFFSET ) );
328  carryQRDrone.angles = placement[ "angles" ];
329  carryQRDrone.canBePlaced = self isOnGround() && placement[ "result" ] && carryQRDrone ‪QRDrone_in_range() && !carryQRDrone ‪isInRemoteNoDeploy();
330 
331  if ( carryQRDrone.canBePlaced != lastCanPlaceCarryQRDrone )
332  {
333  if ( carryQRDrone.canBePlaced )
334  {
335  // if they're holding it in launch position just launch now
336  if ( self attackButtonPressed() )
337  self notify( "place_carryQRDrone" );
338  }
339  else
340  {
341  }
342  }
343 
344  lastCanPlaceCarryQRDrone = carryQRDrone.canBePlaced;
346  }
347 }
348 
349 
351 {
352  level endon ( "game_ended" );
353  self endon("death");
354  self.owner endon ( "place_carryQRDrone" );
355  self.owner endon ( "cancel_carryQRDrone" );
356 
357  self.owner ‪util::waittill_any( "death", "disconnect", "joined_team", "joined_spectators" );
358 
359  if ( isdefined( self ) )
360  {
361  self delete();
362  }
363 }
364 
366 {
367  level endon( "game_ended" );
368  self endon ( "disconnect" );
369 
370  wait(0.7);
371 
372 }
373 
374 
375 function ‪startQRDrone( lifeId, streakName, origin, angles )
376 {
378  self ‪util::setUsingRemote( streakName );
379  self ‪util::freeze_player_controls( true );
380 
381  // blocking function waiting for the tablet to be switched to
382  ‪result = self ‪killstreaks::init_ride_killstreak( "qrdrone" );
383 
384  if ( ‪result != "success" || level.gameEnded )
385  {
386  if ( ‪result != "disconnect" )
387  {
388  self ‪util::freeze_player_controls( false );
389  self ‪killstreakrules::isKillstreakAllowed( "qrdrone", self.team );
390  self notify( "qrdrone_unlock" );
392  }
393  return false;
394  }
395 
396  team = self.team;
397  killstreak_id = self ‪killstreakrules::killstreakStart( "qrdrone", team, false, true );
398  if ( killstreak_id == -1 )
399  {
400  self notify( "qrdrone_unlock" );
401  self ‪util::freeze_player_controls( false );
403  return false;
404  }
405 
406  self notify( "qrdrone_unlock" );
407  QRDrone = ‪createQRDrone( lifeId, self, streakName, origin, angles, killstreak_id );
408  self ‪util::freeze_player_controls( false );
409  if ( isdefined( QRDrone ) )
410  {
411  self thread QRDrone_Ride( lifeId, QRDrone, streakName );
412  QRDrone waittill( "end_remote" );
413 
414  ‪killstreakrules::killstreakStop( "qrdrone", team, killstreak_id );
415  return true;
416  }
417  else
418  {
419  self iPrintLnBold( &"MP_TOO_MANY_VEHICLES" );
421  ‪killstreakrules::killstreakStop( "qrdrone", team, killstreak_id );
422  return false;
423  }
424 }
425 
427 {
428  // lock
429  lockSpot = ‪spawn( "script_origin", self.origin );
430  lockSpot hide();
431  self playerLinkTo( lockSpot );
432 
433  // wait for unlock
434  self thread ‪clearPlayerLockFromQRDroneLaunch( lockSpot );
435 }
436 
437 
439 {
440  level endon( "game_ended" );
441 
442  msg = self ‪util::waittill_any_return( "disconnect", "death", "qrdrone_unlock" );
443 
444  lockSpot delete();
445 }
446 
447 
448 function ‪createQRDrone( lifeId, owner, streakName, origin, angles, killstreak_id )
449 {
450  QRDrone = spawnHelicopter( owner, origin, angles, level.qrdrone_vehicle, ‪UAV_REMOTE_MODEL );
451  if ( !isdefined( QRDrone ) )
452  return undefined;
453 
454  QRDrone.lifeId = lifeId;
455  QRDrone.team = owner.team;
456  QRDrone.pers["team"] = owner.team;
457  QRDrone.owner = owner;
458  QRDrone ‪clientfield::set( "enemyvehicle", ‪ENEMY_VEHICLE_ACTIVE );
459  QRDrone.health = 999999; // keep it from dying anywhere in code
460  QRDrone.maxHealth = 250; // this is the health we'll check
461  QRDrone.damageTaken = 0;
462  QRDrone.destroyed = false;
463  QRDrone setCanDamage( true );
464  QRDrone EnableAimAssist();
465 
466  QRDrone.smoking = false;
467  QRDrone.inHeliProximity = false;
468  QRDrone.heliType = "qrdrone";
469  QRDrone.markedPlayers = [];
470  QRDrone.isStunned = false;
471  QRDrone SetEnemyModel( ‪UAV_REMOTE_MODEL_ENEMY );
472  QRDrone SetDrawInfrared( true );
473 
474  QRDrone.killCamEnt = QRDrone.owner;
475 
476  owner ‪weaponobjects::addWeaponObjectToWatcher( "qrdrone", QRDrone );
477  QRDrone thread ‪QRDrone_explode_on_notify(killstreak_id);
478  QRDrone thread ‪QRDrone_explode_on_game_end();
479 
480  QRDrone thread ‪QRDrone_leave_on_timeout( streakName );
481  QRDrone thread ‪QRDrone_watch_distance();
482  QRDrone thread ‪QRDrone_watch_for_exit();
483 
484  QRDrone thread ‪deleteOnKillbrush( owner );
485 
486  // make the qrdrone targetable
487  Target_Set( QRDrone, (0,0,0) );
488  Target_SetTurretAquire( QRDrone, false );
489 
490  QRDrone.numFlares = 0;
491  QRDrone.flareOffset = (0,0,-100);
492  QRDrone thread ‪heatseekingmissile::MissileTarget_LockOnMonitor( self, "end_remote" ); // monitors missle lock-ons
494 
495  QRDrone.emp_fx = ‪spawn( "script_model", self.origin );
496  QRDrone.emp_fx SetModel( "tag_origin" );
497  QRDrone.emp_fx LinkTo( self, "tag_origin", (0,0,-20) + AnglesToForward(self.angles) * 6 );
498 
499  // create the influencers
500  QRDrone ‪spawning::create_entity_enemy_influencer( "small_vehicle", QRDrone.team );
501  QRDrone ‪spawning::create_entity_enemy_influencer( "qrdrone_cylinder", QRDrone.team );
502 
503  return QRDrone;
504 }
505 
506 
507 function ‪QRDrone_ride( lifeId, QRDrone, streakName )
508 {
509  QRDrone.playerLinked = true;
510  self.restoreAngles = self.angles;
511 
512  QRDrone usevehicle( self, 0 );
513  self ‪util::clientNotify( "qrfutz" );
514  self ‪killstreaks::play_killstreak_start_dialog( "qrdrone", self.pers["team"] );
515 
516  self AddWeaponStat( GetWeapon( "killstreak_qrdrone" ), "used", 1 );
517 
518  self.qrdrone_rideLifeId = lifeId;
519  self.QRDrone = QRDrone;
520 
521  self thread ‪QRDrone_delayLaunchDialog( QRDrone );
522  self thread ‪QRDrone_fireGuns( QRDrone );
523  QRDrone thread ‪play_lockon_sounds( self );
524 
525  if ( isdefined( level.qrdrone_vision ) )
526  self ‪setVisionsetWaiter();
527 }
528 
529 function ‪QRDrone_delayLaunchDialog( QRDrone )
530 {
531  level endon( "game_ended" );
532  self endon ( "disconnect" );
533  QRDrone endon ( "death" );
534  QRDrone endon ( "end_remote" );
535  QRDrone endon ( "end_launch_dialog" );
536 
537  wait( 3 );
538  self ‪QRDrone_dialog( "launch" );
539 }
540 
541 function ‪QRDrone_Unlink( QRDrone )
542 {
543  if ( isdefined( QRDrone ) )
544  {
545  QRDrone.playerLinked = false;
546  self ‪destroyHud();
547 
548  if ( isdefined( self.viewlockedentity ) )
549  {
550  self Unlink();
551  if ( isdefined(level.gameEnded) && level.gameEnded )
552  {
553  self ‪util::freeze_player_controls( true );
554  }
555  }
556  }
557 }
558 
559 
560 function ‪QRDrone_endride( QRDrone )
561 {
562  if ( isdefined( QRDrone ) )
563  {
564  QRDrone notify( "end_remote" );
565 
567 
568  self setPlayerAngles( self.restoreAngles );
569 
570  if ( isalive(self) )
571  {
573  }
574 
575  self thread ‪QRDrone_freezeBuffer();
576  }
577  self.QRDrone = undefined;
578 }
579 
580 function ‪play_lockon_sounds( player )
581 {
582  player endon("disconnect");
583  self endon( "death" );
584  self endon ( "blowup" );
585  self endon ( "crashing" );
586  level endon ( "game_ended" );
587  self endon ( "end_remote" );
588 
589  self.lockSounds = ‪spawn( "script_model", self.origin);
590  wait ( 0.1 );
591  self.lockSounds LinkTo( self, "tag_player" );
592 
593  while ( true )
594  {
595  self waittill( "locking on" );
596 
597  while ( true )
598  {
599  if ( ‪enemy_locking() )
600  {
601  //self.lockSounds PlaySoundToPlayer( "uin_alert_lockon_start", player );
602  //wait ( 0.3 );
603 
604  self.lockSounds PlaySoundToPlayer( "uin_alert_lockon", player );
605  wait ( 0.125 );
606  }
607 
608  if ( ‪enemy_locked() )
609  {
610  self.lockSounds PlaySoundToPlayer( "uin_alert_lockon", player );
611  wait ( 0.125 );
612  }
613 
614  if ( !‪enemy_locking() && !‪enemy_locked() )
615  {
616  self.lockSounds StopSounds();
617  break;
618  }
619  }
620  }
621 }
622 
624 {
625  if ( isdefined(self.locking_on) && self.locking_on )
626  return true;
627 
628  return false;
629 }
630 
631 function ‪enemy_locked()
632 {
633  if ( isdefined(self.locked_on) && self.locked_on )
634  return true;
635 
636  return false;
637 }
638 
639 
641 {
642  self endon( "disconnect" );
643  self endon( "death" );
644  level endon( "game_ended" );
645 
646  self ‪util::freeze_player_controls( true );
647  wait( 0.5 );
648  self ‪util::freeze_player_controls( false );
649 }
650 
651 
652 function ‪QRDrone_playerExit( QRDrone )
653 {
654  level endon( "game_ended" );
655  self endon ( "disconnect" );
656  QRDrone endon ( "death" );
657  QRDrone endon ( "end_remote" );
658 
659  // delay exit for transition into remote
660  wait( 2 );
661 
662  while( true )
663  {
664  timeUsed = 0;
665  while( self UseButtonPressed() )
666  {
667  timeUsed += 0.05;
668  if( timeUsed > 0.75 )
669  {
670  QRDrone thread ‪QRDrone_leave();
671  return;
672  }
674  }
676  }
677 }
678 
680 {
681  if ( isdefined(self) )
682  {
683  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
684  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
685  watcher thread ‪weaponobjects::waitAndDetonate( self, 0.0);
686  }
687 }
688 
689 function ‪deleteOnKillbrush(player)
690 {
691  player endon("disconnect");
692  self endon("death");
693 
694  killbrushes = [];
695  hurt = GetEntArray( "trigger_hurt","classname" );
696 
697  foreach( trig in hurt )
698  {
699  if ( trig.origin[2] <= player.origin[2] && ( !isDefined( trig.script_parameters ) || trig.script_parameters != "qrdrone_safe" ) )
700  {
701  killbrushes[ killbrushes.size ] = trig;
702  }
703  }
704 
705  crate_triggers = GetEntArray( "crate_kill_trigger", "targetname" );
706 
707  while(1)
708  {
709  for (i = 0; i < killbrushes.size; i++)
710  {
711  if (self istouching(killbrushes[i]) )
712  {
713  self ‪touchedKillbrush();
714  return;
715  }
716  }
717 
718  foreach( trigger in crate_triggers )
719  {
720  if ( trigger.active && self istouching(trigger) )
721  {
722  self ‪touchedKillbrush();
723  return;
724  }
725  }
726 
727  if ( isdefined( level.levelKillbrushes ) )
728  {
729  foreach( trigger in level.levelKillbrushes )
730  {
731  if (self istouching(trigger) )
732  {
733  self ‪touchedKillbrush();
734  return;
735  }
736  }
737  }
738 
739  if ( level.script == "mp_castaway" )
740  {
741  origin = self.origin - ( 0, 0, 12 );
742  water = GetWaterHeight( origin );
743 
744  if ( water - origin[2] > 0 )
745  {
746  self ‪touchedKillbrush();
747  return;
748  }
749  }
750 
751  wait( 0.1 );
752  }
753 }
754 
756 {
757  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
758  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
759  watcher thread ‪weaponobjects::waitAndDetonate( self, 0.0);
760 }
761 
762 function ‪QRDrone_get_damage_effect( health_pct )
763 {
764  if( health_pct > .5 )
765  {
766  return level._effect[ "quadrotor_damage" ];
767  }
768 
769  return undefined;
770 }
771 
772 function ‪QRDrone_play_single_fx_on_tag( effect, tag )
773 {
774  if( isdefined( self.damage_fx_ent ) )
775  {
776  if( self.damage_fx_ent.effect == effect )
777  {
778  // already playing
779  return;
780  }
781  self.damage_fx_ent delete();
782  }
783 
784 
785 // ent = spawn( "script_model", ( 0, 0, 0 ) );
786 // ent SetModel( "tag_origin" );
787 // ent.origin = self GetTagOrigin( tag );
788 // ent.angles = self GetTagAngles( tag );
789 // ent NotSolid();
790 // ent Hide();
791 // ent LinkTo( self, tag );
792 // ent.effect = effect;
793 // playfxontag( effect, ent, "tag_origin" );
794 // ent playsound("veh_qrdrone_sparks");
795 //
796 //
797 // self.damage_fx_ent = ent;
798 
799  playfxontag( effect, self, "tag_origin" );
800 
801 }
802 
803 function ‪QRDrone_update_damage_fx( health_percent )
804 {
805  effect = ‪QRDrone_get_damage_effect( health_percent );
806  if( isdefined( effect ) )
807  {
808  ‪QRDrone_play_single_fx_on_tag( effect, "tag_origin" );
809  }
810  else
811  {
812  if( isdefined( self.damage_fx_ent ) )
813  {
814  self.damage_fx_ent delete();
815  }
816  }
817 }
818 
820 {
821  self endon( "death" );
822 
823  self.maxhealth = 999999;
824  self.health = self.maxhealth;
825  self.maxhealth = ‪QRDRONE_MAX_HEALTH;
826 
827  low_health = false;
828  damage_taken = 0;
829 
830  for ( ;; )
831  {
832  self waittill( "damage", ‪damage, attacker, dir, point, mod, model, tag, part, weapon, flags );
833 
834  if( !isdefined( attacker ) || !isplayer( attacker ) )
835  continue;
836 
837  self.owner playrumbleonentity("damage_heavy");
838 
839 /#
840  self.damage_debug = ( ‪damage + " (" + weapon.name + ")" );
841 #/
842 
843  if ( mod == "MOD_RIFLE_BULLET" || mod == "MOD_PISTOL_BULLET")
844  {
845  if ( isPlayer( attacker ) )
846  {
847  if ( attacker HasPerk( "specialty_armorpiercing" ) )
848  {
849  ‪damage += int( ‪damage * level.cac_armorpiercing_data );
850  }
851  }
852 
853  if (weapon.weapClass == "spread")
854  ‪damage = ‪damage * 2;
855  }
856 
857  if ( weapon.isEmp && (mod == "MOD_GRENADE_SPLASH"))
858  {
859  damage_taken += ( ‪QRDRONE_MAX_HEALTH );
860  ‪damage = 0;
861  }
862 
863  if (!self.‪isStunned)
864  {
865  if ( weapon.isStun && (mod == "MOD_GRENADE_SPLASH" || mod == "MOD_GAS") )
866  {
867  self.isStunned = true;
868  self ‪QRDrone_stun( 2 );
869  }
870  }
871 
872  self.attacker = attacker;
873 
874  self.owner SendKillstreakDamageEvent( int(‪damage) );
875 
876  damage_taken += ‪damage;
877 
878 
879  if ( damage_taken >= ‪QRDRONE_MAX_HEALTH )
880  {
881  //this is for HUD screen scramble
882  self.owner SendKillstreakDamageEvent( 200 );
883 
884  self ‪QRDrone_death( attacker, weapon, dir, mod );
885  return;
886  }
887  else
888  {
889  ‪QRDrone_update_damage_fx( float(damage_taken) / ‪QRDRONE_MAX_HEALTH );
890  }
891  }
892 }
893 
894 function ‪QRDrone_stun( duration )
895 {
896  self endon( "death" );
897  self notify( "stunned" );
898 
899  //PlayFX( level.ai_tank_stun_fx, self.origin + (0,0,-20) + AnglesToForward(self.angles) * 6, AnglestoForward(self.angles) );
900 
901  self.owner ‪util::freeze_player_controls( true );
902 
903  if (isdefined(self.owner.fullscreen_static))
904  {
905  self.owner thread ‪remote_weapons::stunStaticFX( duration );
906  }
907  wait ( duration );
908 
909  self.owner ‪util::freeze_player_controls( false );
910 
911  self.isStunned = false;
912 }
913 
914 function ‪QRDrone_death( attacker, weapon, dir, damageType )
915 {
916  if( isdefined( self.damage_fx_ent ) )
917  {
918  self.damage_fx_ent delete();
919  }
920 
921  if ( isdefined(attacker) && IsPlayer(attacker) && attacker != self.owner)
922  {
923  level thread ‪popups::DisplayTeamMessageToAll( &"SCORE_DESTROYED_QRDRONE", attacker );
924  if ( self.owner ‪util::IsEnemyPlayer( attacker ) )
925  {
926  attacker ‪challenges::destroyedQRDrone( damageType, weapon );
927  //scoreevents::processScoreEvent( "destroyed_qrdrone", attacker, self.owner, weapon );
928  attacker AddWeaponStat( weapon, "destroyed_qrdrone", 1 );
929  attacker ‪challenges::addFlySwatterStat( weapon, self );
930  attacker AddWeaponStat( weapon, "destroyed_controlled_killstreak", 1 );
931  }
932  else
933  {
934  //Destroyed Friendly Killstreak
935  }
936  }
937 
938  self thread ‪QRDrone_crash_movement( attacker, dir );
939  if ( weapon.isEmp )
940  {
941  PlayFXOnTag( level.ai_tank_stun_fx, self.emp_fx, "tag_origin" );
942  }
943 
944  self waittill( "crash_done" );
945 
946  if ( isdefined(self.emp_fx) )
947  {
948  self.emp_fx delete();
949  }
950  // A dynEnt will be spawned in the collision thread when it hits the ground and "crash_done" notify will be sent
951  //self freeVehicle();
952  //wait 20;
953  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
954  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
955  watcher thread ‪weaponobjects::waitAndDetonate( self, 0.0, attacker, weapon );
956 }
957 
958 function ‪death_fx()
959 {
960  playfxontag( self.deathfx, self, self.deathfxtag );
961  self playsound("veh_qrdrone_sparks");
962 }
963 
964 function ‪QRDrone_crash_movement( attacker, hitdir )
965 {
966  self endon( "crash_done" );
967  self endon( "death" );
968  self notify( "crashing" );
969 
970  // take away driver control
971  self takeplayercontrol();
972 
973  self SetMaxPitchRoll( 90, 180 );
974  self SetPhysAcceleration( ( 0, 0, -800 ) );
975 
976  side_dir = VectorCross( hitdir, (0,0,1) );
977  side_dir_mag = RandomFloatRange( -100, 100 );
978  side_dir_mag += ‪math::sign( side_dir_mag ) * 80;
979  side_dir *= side_dir_mag;
980 
981  velocity = self GetVelocity();
982  self SetVehVelocity( velocity + (0,0,100) + VectorNormalize( side_dir ) );
983 
984  ang_vel = self GetAngularVelocity();
985  ang_vel = ( ang_vel[0] * 0.3, ang_vel[1], ang_vel[2] * 0.3 );
986 
987  yaw_vel = RandomFloatRange( 0, 210 ) * ‪math::sign( ang_vel[1] );
988  yaw_vel += ‪math::sign( yaw_vel ) * 180;
989 
990  ang_vel += ( RandomFloatRange( -100, 100 ), yaw_vel, RandomFloatRange( -200, 200 ) );
991 
992  self SetAngularVelocity( ang_vel );
993 
994  self.crash_accel = RandomFloatRange( 75, 110 );
995 
996  self thread ‪QRDrone_crash_accel();
997  self thread ‪QRDrone_collision();
998 
999  //drone death sounds JM - play 1 shot hit, turn off main loop, thread dmg loop
1000  self playsound("veh_qrdrone_dmg_hit");
1001  self thread ‪QRDrone_dmg_snd();
1002 
1003  wait 0.1;
1004 
1005  if( RandomInt( 100 ) < 40 )
1006  {
1007  self thread ‪QRDrone_fire_for_time( RandomFloatRange( 0.7, 2.0 ) );
1008  }
1009 
1010  wait 2;
1011 
1012  // failsafe notify
1013  self notify( "crash_done" );
1014 }
1015 
1016 
1018 {
1019  dmg_ent = ‪spawn("script_origin", self.origin);
1020  dmg_ent linkto (self);
1021  dmg_ent PlayLoopSound ("veh_qrdrone_dmg_loop");
1022  self ‪util::waittill_any("crash_done", "death");
1023  dmg_ent stoploopsound(.2);
1024  wait (2);
1025  dmg_ent delete();
1026 }
1027 
1028 function ‪QRDrone_fire_for_time( totalFireTime )
1029 {
1030  self endon( "crash_done" );
1031  self endon( "change_state" );
1032  self endon( "death" );
1033 
1034  weapon = self SeatGetWeapon( 0 );
1035  fireTime = weapon.fireTime;
1036  time = 0;
1037 
1038  fireCount = 1;
1039 
1040  while( time < totalFireTime )
1041  {
1042  self FireWeapon();
1043  fireCount++;
1044  wait fireTime;
1045  time += fireTime;
1046  }
1047 }
1048 
1050 {
1051  self endon( "crash_done" );
1052  self endon( "death" );
1053 
1054  count = 0;
1055 
1056  while( 1 )
1057  {
1058  velocity = self GetVelocity();
1059  self SetVehVelocity( velocity + AnglesToUp( self.angles ) * self.crash_accel );
1060  self.crash_accel *= 0.98;
1061 
1062  wait 0.1;
1063 
1064  count++;
1065  if( count % 8 == 0 )
1066  {
1067  if( RandomInt( 100 ) > 40 )
1068  {
1069  if( velocity[2] > 150.0 )
1070  {
1071  self.crash_accel *= 0.75;
1072  }
1073  else if( velocity[2] < 40.0 && count < 60 )
1074  {
1075  if( Abs( self.angles[0] ) > 30 || Abs( self.angles[2] ) > 30 )
1076  {
1077  self.crash_accel = RandomFloatRange( 160, 200 );
1078  }
1079  else
1080  {
1081  self.crash_accel = RandomFloatRange( 85, 120 );
1082  }
1083  }
1084  }
1085  }
1086  }
1087 }
1088 
1090 {
1091  self endon( "crash_done" );
1092  self endon( "death" );
1093 
1094  while( 1 )
1095  {
1096  self waittill( "veh_collision", velocity, normal );
1097  ang_vel = self GetAngularVelocity() * 0.5;
1098  self SetAngularVelocity( ang_vel );
1099 
1100  velocity = self GetVelocity();
1101 
1102  // bounce off walls
1103  if( normal[2] < 0.7 )
1104  {
1105  self SetVehVelocity( velocity + normal * 70 );
1106  self playsound ("veh_qrdrone_wall");
1107  PlayFX( level._effect[ "quadrotor_nudge" ], self.origin );
1108  }
1109  else
1110  {
1111  //self.crash_accel *= 0.5;
1112  //self SetVehVelocity( self.velocity * 0.8 );
1113 // CreateDynEntAndLaunch( self.deathmodel, self.origin, self.angles, self.origin, velocity * 0.03, level._effect[ "quadrotor_crash" ], 1 );
1114  self playsound ("veh_qrdrone_explo");
1115  self notify( "crash_done" );
1116  }
1117  }
1118 }
1119 
1120 function ‪QRDrone_watch_distance( zoffset, minHeightOverride )
1121 {
1122  self endon ("death" );
1123 
1124  self.owner ‪inithud();
1125 
1126  // Reset the ui model. Setting it dircetly to 0 doest seem to do it
1127  self ‪clientfield::set( "qrdrone_out_of_range", 1 );
1129  self ‪clientfield::set( "qrdrone_out_of_range", 0 );
1130 
1131  qrdrone_height = ‪struct::get( "qrdrone_height", "targetname");
1132  if ( isdefined(qrdrone_height) )
1133  {
1134  self.maxHeight = qrdrone_height.origin[2];
1135  }
1136  else
1137  {
1138  self.maxHeight = int(‪airsupport::getMinimumFlyHeight());
1139  }
1140 
1141  if( isdefined( zoffset ) )
1142  self.maxHeight += zoffset;
1143 
1144  self.maxDistance = 12800;
1145 
1146  self.minHeight = level.mapCenter[2] - 800;
1147  if( isdefined( minHeightOverride ) )
1148  self.minHeight = minHeightOverride;
1149 
1150  // ent to put headicon on for pointing to inside of map when they go out of range
1151  self.centerRef = ‪spawn( "script_model", level.mapCenter );
1152 
1153  // shouldn't be possible to start out of range, but just in case
1154  inRangePos = self.origin;
1155 
1156  self.rangeCountdownActive = false;
1157 
1158  // loop
1159  while ( true )
1160  {
1161  if ( !self ‪QRDrone_in_range() )
1162  {
1163  // increase static with distance from exit point or distance to heli in proximity
1164  staticAlpha = 0;
1165  while ( !self ‪QRDrone_in_range() )
1166  {
1167  if ( !self.rangeCountdownActive )
1168  {
1169  self.rangeCountdownActive = true;
1170  self thread ‪QRDrone_rangeCountdown();
1171  }
1172  if ( isdefined( self.heliInProximity ) )
1173  {
1174  dist = distance( self.origin, self.heliInProximity.origin );
1176  }
1177  else
1178  {
1179  dist = distance( self.origin, inRangePos );
1180  staticAlpha = min( .7, dist/‪UAV_REMOTE_MAX_PAST_RANGE );
1181  }
1182 
1183  self.owner ‪set_static_alpha( staticAlpha, self );
1184 
1186  }
1187 
1188  // end countdown
1189  self notify( "in_range" );
1190  self.rangeCountdownActive = false;
1191 
1192  // fade out static
1193  self thread ‪QRDrone_staticFade( staticAlpha );
1194  }
1195  inRangePos = self.origin;
1197  }
1198 }
1199 
1200 
1202 {
1203  if ( self.origin[2] < self.maxHeight && self.origin[2] > self.minHeight && !self.inHeliProximity )
1204  {
1205  if ( self isMissileInsideHeightLock() )
1206  {
1207  return true;
1208  }
1209  }
1210  return false;
1211 }
1212 
1213 
1214 function ‪QRDrone_staticFade( staticAlpha )
1215 {
1216  self endon ( "death" );
1217  while( self ‪QRDrone_in_range() )
1218  {
1219  staticAlpha -= 0.05;
1220  if ( staticAlpha < 0 )
1221  {
1222  self.owner ‪set_static_alpha( staticAlpha, self );
1223  break;
1224  }
1225  self.owner ‪set_static_alpha( staticAlpha, self );
1226 
1228  }
1229 }
1230 
1231 
1233 {
1234  self endon( "death" );
1235  self endon( "in_range" );
1236 
1237  if ( isdefined( self.heliInProximity ) )
1239  else
1241 
1243 
1244  self.owner notify( "stop_signal_failure" );
1245 
1246  if( isdefined( self.distance_shutdown_override ) )
1247  {
1248  return [[ self.distance_shutdown_override ]]();
1249  }
1250 
1251  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1252  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1253  watcher thread ‪weaponobjects::waitAndDetonate(self,0);
1254 }
1255 
1256 
1257 function ‪QRDrone_explode_on_notify( killstreak_id )
1258 {
1259  self endon ( "death" );
1260  self endon( "end_ride" );
1261 
1262  self.owner ‪util::waittill_any( "disconnect", "joined_team", "joined_spectators" );
1263 
1264  if( isdefined( self.owner ) )
1265  {
1267  self.owner ‪destroyHud();
1268  self.owner ‪QRDrone_endride( self );
1269  }
1270  else
1271  {
1272  ‪killstreakrules::killstreakStop( "qrdrone", self.team, killstreak_id );
1273  }
1274 
1275  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1276  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1277  watcher thread ‪weaponobjects::waitAndDetonate(self,0);
1278 }
1279 
1280 
1282 {
1283  self endon ( "death" );
1284 
1285  level waittill( "game_ended" );
1286 
1287  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1288  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1289  watcher ‪weaponobjects::waitAndDetonate(self,0);
1290  self.owner ‪QRDrone_endride( self );
1291 }
1292 
1293 
1294 function ‪QRDrone_leave_on_timeout( killstreakName )
1295 {
1296  qrdrone = self;
1297  qrdrone endon ( "death" );
1298 
1299  if ( !level.vehiclesTimed )
1300  return;
1301 
1302  qrdrone.flyTime = 60.0;
1303  waittime = self.flyTime - 10;
1304 /#
1305  ‪util::set_dvar_int_if_unset( "scr_QRDroneFlyTime", qrdrone.flyTime );
1306  qrdrone.flyTime = GetDvarInt( "scr_QRDroneFlyTime" );
1307  waittime = self.flyTime - 10;
1308  if( waittime < 0 )
1309  {
1310  wait( qrdrone.flyTime );
1311  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1312  watcher = qrdrone.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1313  watcher thread ‪weaponobjects::waitAndDetonate(qrdrone,0);
1314  return;
1315  }
1316 #/
1317 
1318  qrdrone thread ‪killstreaks::WaitForTimeout( killstreakName, waittime, &‪QRDrone_leave_on_timeout_callback, "death" );
1319 }
1320 
1322 {
1323  qrdrone = self;
1324 
1325  qrdrone ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_BLINK );
1326  qrdrone ‪clientfield::set( "qrdrone_countdown", 1 );
1328 
1329  qrdrone ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_FINAL_BLINK );
1330  qrdrone ‪clientfield::set( "qrdrone_timeout", 1 );
1332 
1333  qrdrone ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1334  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1335  watcher thread ‪weaponobjects::waitAndDetonate(self,0);
1336 }
1337 
1338 
1340 {
1341  level endon( "game_ended" );
1342  self endon( "death" );
1343 
1344  // disengage player
1345  self notify( "leaving" );
1346  self.owner ‪QRDrone_Unlink( self );
1347  self.owner ‪QRDrone_endride( self );
1348 
1349  // remove
1350  self notify( "death" );
1351 }
1352 
1354 {
1355  return self UseButtonPressed();
1356 }
1357 
1359 {
1360  level endon( "game_ended" );
1361  self endon( "death" );
1362  self.owner endon( "disconnect" );
1363 
1364  wait( 1 );
1365 
1366  while( true )
1367  {
1368  timeUsed = 0;
1369  while( self.owner ‪QRDrone_exit_button_pressed() )
1370  {
1371  timeUsed += 0.05;
1372  if ( timeUsed > 0.25 )
1373  {
1374  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1375  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1376  watcher thread ‪weaponobjects::waitAndDetonate( self, 0.0, self.owner );
1377  return;
1378  }
1380  }
1382  }
1383 }
1384 
1386 {
1387  if ( level.gameEnded )
1388  {
1389  return;
1390  }
1391 
1392  if( isdefined( self.owner ) )
1393  {
1394  if ( self.playerLinked == true )
1395  self.owner ‪QRDrone_Unlink( self );
1396 
1397  self.owner ‪QRDrone_endride( self );
1398  }
1399 
1400  if ( isdefined( self.scrambler ) )
1401  self.scrambler delete();
1402 
1403  if ( isdefined(self) && isdefined( self.centerRef ) )
1404  self.centerRef delete();
1405 
1406  Target_SetTurretAquire( self, false );
1407 
1408  if( isdefined( self.damage_fx_ent ) )
1409  {
1410  self.damage_fx_ent delete();
1411  }
1412 
1413  if ( isdefined( self.emp_fx ) )
1414  {
1415  self.emp_fx delete();
1416  }
1417 
1418  self delete();
1419 }
1420 
1421 
1423 {
1424  playFXOnTag( level.chopper_fx["light"]["belly"], self, "tag_light_nose" );
1426  playFXOnTag( level.chopper_fx["light"]["tail"], self, "tag_light_tail1" );
1427 }
1428 
1429 
1430 function ‪QRDrone_dialog( dialogGroup )
1431 {
1432  if ( dialogGroup == "tag" )
1433  waitTime = 1000;
1434  else
1435  waitTime = 5000;
1436 
1437  if ( getTime() - level.QRDrone_lastDialogTime < waitTime )
1438  return;
1439 
1440  level.QRDrone_lastDialogTime = getTime();
1441 
1442  randomIndex = randomInt( level.QRDrone_dialog[ dialogGroup ].size );
1443  soundAlias = level.QRDrone_dialog[ dialogGroup ][ randomIndex ];
1444 
1445  self playLocalSound( soundAlias );
1446 }
1447 
1449 {
1450  level endon( "game_ended" );
1451  self endon( "death" );
1452  self endon( "end_remote" );
1453 
1454  while( true )
1455  {
1456  inHeliProximity = false;
1457 
1458  if ( !self.inHeliProximity && inHeliProximity )
1459  self.inHeliProximity = true;
1460  else if ( self.inHeliProximity && !inHeliProximity )
1461  {
1462  self.inHeliProximity = false;
1463  self.heliInProximity = undefined;
1464  }
1465 
1467  }
1468 }
1469 
1470 
1472 {
1473  self.owner endon("disconnect");
1474  self endon("death");
1475 
1476  while( self.owner attackbuttonpressed() )
1478 
1479  watcher = self.owner ‪weaponobjects::getWeaponObjectWatcher( "qrdrone" );
1480 
1481  while( !self.owner attackbuttonpressed() )
1483 
1484  self ‪clientfield::set( "qrdrone_state", ‪QRDRONE_FX_DEATH );
1485  watcher thread ‪weaponobjects::waitAndDetonate(self,0);
1486 
1487  self.owner thread ‪hud::fade_to_black_for_x_sec( GetDvarfloat( "scr_rcbomb_fadeOut_delay" ), GetDvarfloat( "scr_rcbomb_fadeOut_timeIn" ), GetDvarfloat( "scr_rcbomb_fadeOut_timeBlack" ), GetDvarfloat( "scr_rcbomb_fadeOut_timeOut" ) );
1488 }
1489 
1490 function ‪QRDrone_fireGuns( QRDrone )
1491 {
1492  self endon ( "disconnect" );
1493  QRDrone endon ( "death" );
1494  QRDrone endon ( "blowup" );
1495  QRDrone endon ( "crashing" );
1496  level endon ( "game_ended" );
1497  QRDrone endon ( "end_remote" );
1498 
1499  // transition into remote
1500  wait( 1 );
1501 
1502  while ( true )
1503  {
1504  if ( self AttackButtonPressed() )
1505  {
1506  QRDrone FireWeapon();
1507  weapon = GetWeapon( "qrdrone_turret" );
1508  fireTime = weapon.fireTime;
1509 
1510  wait( fireTime );
1511  }
1512  else
1513  {
1515  }
1516  }
1517 }
1518 
1519 function ‪QRDrone_blowup(attacker, weapon)
1520 {
1521  self.owner endon("disconnect");
1522  self endon ("death");
1523 
1524  self notify("blowup");
1525 
1526  explosionOrigin = self.origin;
1527  explosionAngles = self.angles;
1528 
1529  if ( !isdefined( attacker ) )
1530  {
1531  attacker = self.owner;
1532  }
1533 
1534  origin = self.origin + (0,0,10);
1535  radius = 256;
1536  min_damage = 10;
1537  max_damage = 35;
1538 
1539  if ( isdefined(attacker) )
1540  {
1541  self radiusDamage( origin, radius, max_damage, min_damage, attacker, "MOD_EXPLOSIVE", self.weapon );
1542  }
1543  PhysicsExplosionSphere( origin, radius, radius, 1, max_damage, min_damage );
1545 
1546  // CDC - play rc car exlposion sound TO DO replace with final explo sound after effects are in
1547  playsoundatposition("veh_qrdrone_explo", self.origin);
1548 
1549  PlayFX( level.QRDrone_fx["explode"] , explosionOrigin, (0, 0, 1 ));
1550 
1551  self Hide();
1552  if( isdefined(self.owner))
1553  {
1554  self.owner ‪util::clientNotify("qrdrone_blowup");
1555 
1556  if ( attacker != self.owner )
1557  {
1558  level.globalKillstreaksDestroyed++;
1559  attacker AddWeaponStat( self.weapon, "destroyed", 1 );
1560  }
1562 
1563  self.owner ‪util::freeze_player_controls( true );
1564  self.owner SendKillstreakDamageEvent( 600 );
1565  wait(0.75);
1566  self.owner thread ‪hud::fade_to_black_for_x_sec( 0, 0.25, 0.1, 0.25 );
1567  wait(0.25);
1568  self.owner ‪QRDrone_Unlink( self );
1569  self.owner ‪util::freeze_player_controls( false );
1570 
1571  if ( isdefined( self.neverDelete ) && self.neverDelete )
1572  {
1573  return;
1574  }
1575  }
1576 
1578 }
1579 
1580 // self == player
1582 {
1583  self endon("disconnect");
1584 
1585  self UseServerVisionset( true );
1586  self SetVisionSetForPlayer( level.qrdrone_vision, 1 );
1587 
1588  self.QRDrone waittill("end_remote");
1589 
1590  self UseServerVisionset( false );
1591 }
1592 
1593 function ‪inithud()
1594 {
1595  /*self.fullscreen_static = newclienthudelem( self );
1596  self.fullscreen_static.x = 0;
1597  self.fullscreen_static.y = 0;
1598  self.fullscreen_static.horzAlign = "fullscreen";
1599  self.fullscreen_static.vertAlign = "fullscreen";
1600  self.fullscreen_static.hidewhendead = false;
1601  self.fullscreen_static.hidewheninmenu = true;
1602  self.fullscreen_static.immunetodemogamehudsettings = true;
1603  self.fullscreen_static.sort = 0;
1604  self.fullscreen_static SetShader( "tow_filter_overlay_no_signal", 640, 480 );
1605  self.fullscreen_static.alpha = 0;*/
1606 }
1607 
1608 function ‪destroyHud()
1609 {
1610  if( isdefined(self) )
1611  {
1612  self notify ( "stop_signal_failure" );
1613  self.flashingSignalFailure = false;
1614  self ‪clientfield::set_to_player( "static_postfx", 0 );
1615 
1616  if ( isdefined( self.fullscreen_static ) )
1617  self.fullscreen_static ‪destroy();
1618 
1620  self ‪util::clientNotify( "nofutz" );
1621  }
1622 }
1623 
1624 function ‪set_static_alpha( alpha, drone )
1625 {
1626  if ( isdefined( self.fullscreen_static ) )
1627  {
1628  self.fullscreen_static.alpha = alpha;
1629  }
1630 
1631  if ( alpha > 0 )
1632  {
1633  if( !isdefined( self.flashingSignalFailure ) || !self.flashingSignalFailure )
1634  {
1635  self thread ‪flash_signal_failure( drone );
1636  self.flashingSignalFailure = true;
1637  if ( self IsRemoteControlling() )
1638  self ‪clientfield::set_to_player( "static_postfx", 1 );
1639  }
1640  }
1641  else
1642  {
1643  self notify ( "stop_signal_failure" );
1644  drone ‪clientfield::set( "qrdrone_out_of_range", 0 );
1645  self.flashingSignalFailure = false;
1646  self ‪clientfield::set_to_player( "static_postfx", 0 );
1647  }
1648 }
1649 
1650 function ‪flash_signal_failure( drone )
1651 {
1652  self endon( "stop_signal_failure" );
1653  drone endon( "death" );
1654  drone ‪clientfield::set( "qrdrone_out_of_range", 1 );
1655  i = 0;
1656  for ( ;; )
1657  {
1658  drone PlaySoundToPlayer( "uin_alert_lockon", self );
1659  if ( i < 5 )
1660  wait ( .6 );
1661  else if ( i < 6 )
1662  wait ( 0.5 );
1663  else
1664  wait ( .3 );
1665  i++;
1666  }
1667 }
‪QRDrone_staticFade
‪function QRDrone_staticFade(staticAlpha)
Definition: _qrdrone.gsc:1214
‪init_ride_killstreak
‪function init_ride_killstreak(streak, always_allow=false)
Definition: _killstreaks.gsc:2237
‪QRDrone_Unlink
‪function QRDrone_Unlink(QRDrone)
Definition: _qrdrone.gsc:541
‪QRDrone_delayLaunchDialog
‪function QRDrone_delayLaunchDialog(QRDrone)
Definition: _qrdrone.gsc:529
‪UAV_REMOTE_MAX_PAST_RANGE
‪#define UAV_REMOTE_MAX_PAST_RANGE
Definition: _qrdrone.gsc:32
‪init
‪function init()
Definition: _qrdrone.gsc:67
‪UAV_REMOTE_Z_OFFSET
‪#define UAV_REMOTE_Z_OFFSET
Definition: _qrdrone.gsc:38
‪WaitForTimeout
‪function WaitForTimeout(killstreak, duration, callback, endCondition1, endCondition2, endCondition3)
Definition: _killstreaks.gsc:2913
‪QRDrone_ride
‪function QRDrone_ride(lifeId, QRDrone, streakName)
Definition: _qrdrone.gsc:507
‪setVisionsetWaiter
‪function setVisionsetWaiter()
Definition: _qrdrone.gsc:1581
‪QRDRONE_FX_FINAL_BLINK
‪#define QRDRONE_FX_FINAL_BLINK
Definition: shared.gsh:337
‪QRDrone_death
‪function QRDrone_death(attacker, weapon, dir, damageType)
Definition: _qrdrone.gsc:914
‪carryQRDrone_handleExistence
‪function carryQRDrone_handleExistence()
Definition: _qrdrone.gsc:350
‪startQRDrone
‪function startQRDrone(lifeId, streakName, origin, angles)
Definition: _qrdrone.gsc:375
‪set_to_player
‪function set_to_player(str_field_name, n_value)
Definition: clientfield_shared.gsc:58
‪tryUseQRDrone
‪function tryUseQRDrone(lifeId)
Definition: _qrdrone.gsc:139
‪updateCarryQRDronePlacement
‪function updateCarryQRDronePlacement(carryQRDrone)
Definition: _qrdrone.gsc:298
‪sign
‪function sign(x)
Definition: math_shared.csc:164
‪touchedKillbrush
‪function touchedKillbrush()
Definition: _qrdrone.gsc:679
‪MissileTarget_ProximityDetonateIncomingMissile
‪function MissileTarget_ProximityDetonateIncomingMissile(endon1, endon2, allowDirectDamage)
Definition: _heatseekingmissile.gsc:1085
‪QRDrone_watch_distance
‪function QRDrone_watch_distance(zoffset, minHeightOverride)
Definition: _qrdrone.gsc:1120
‪getMinimumFlyHeight
‪function getMinimumFlyHeight()
Definition: _airsupport.gsc:167
‪QRDrone_explode_on_notify
‪function QRDrone_explode_on_notify(killstreak_id)
Definition: _qrdrone.gsc:1257
‪MissileTarget_LockOnMonitor
‪function MissileTarget_LockOnMonitor(player, endon1, endon2)
Definition: _heatseekingmissile.gsc:950
‪addWeaponObjectToWatcher
‪function addWeaponObjectToWatcher(watcherName, weapon_instance)
Definition: _weaponobjects.gsc:784
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪waittill_any_return
‪function waittill_any_return(string1, string2, string3, string4, string5, string6, string7)
Definition: util_shared.csc:212
‪play_killstreak_start_dialog
‪function play_killstreak_start_dialog(killstreakType, team, killstreakId)
Definition: _killstreaks.gsc:1905
‪set_dvar_int_if_unset
‪function set_dvar_int_if_unset(dvar, value, reset)
Definition: _util.gsc:453
‪QRDrone_watch_for_exit
‪function QRDrone_watch_for_exit()
Definition: _qrdrone.gsc:1358
‪QRDrone_force_destroy
‪function QRDrone_force_destroy()
Definition: _qrdrone.gsc:755
‪QRDrone_collision
‪function QRDrone_collision()
Definition: _qrdrone.gsc:1089
‪QRDRONE_MAX_HEALTH
‪#define QRDRONE_MAX_HEALTH
Definition: _qrdrone.gsc:42
‪UAV_REMOTE_MODEL
‪#define UAV_REMOTE_MODEL
Definition: _qrdrone.gsc:39
‪play_lockon_sounds
‪function play_lockon_sounds(player)
Definition: _qrdrone.gsc:580
‪waitLongDurationWithHostMigrationPause
‪function waitLongDurationWithHostMigrationPause(duration)
Definition: hostmigration_shared.gsc:216
‪addFlySwatterStat
‪function addFlySwatterStat(weapon, aircraft)
Definition: challenges_shared.gsc:86
‪UAV_REMOTE_PAST_RANGE_COUNTDOWN
‪#define UAV_REMOTE_PAST_RANGE_COUNTDOWN
Definition: _qrdrone.gsc:35
‪ENEMY_VEHICLE_ACTIVE
‪#define ENEMY_VEHICLE_ACTIVE
Definition: _hacker_tool.gsh:2
‪QRDrone_dmg_snd
‪function QRDrone_dmg_snd()
Definition: _qrdrone.gsc:1017
‪destroyRemoteHUD
‪function destroyRemoteHUD()
Definition: _remote_weapons.gsc:498
‪QRDrone_in_range
‪function QRDrone_in_range()
Definition: _qrdrone.gsc:1201
‪clearPlayerLockFromQRDroneLaunch
‪function clearPlayerLockFromQRDroneLaunch(lockSpot)
Definition: _qrdrone.gsc:438
‪freeze_player_controls
‪function freeze_player_controls(b_frozen=true)
Definition: util_shared.gsc:2474
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪destroyHud
‪function destroyHud()
Definition: _qrdrone.gsc:1608
‪QRDRONE_FX_BLINK
‪#define QRDRONE_FX_BLINK
Definition: shared.gsh:336
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪deleteOnKillbrush
‪function deleteOnKillbrush(player)
Definition: _qrdrone.gsc:689
‪flash_signal_failure
‪function flash_signal_failure(drone)
Definition: _qrdrone.gsc:1650
‪QRDrone_exit_button_pressed
‪function QRDrone_exit_button_pressed()
Definition: _qrdrone.gsc:1353
‪waitAndDetonate
‪function waitAndDetonate(object, delay, attacker, weapon)
Definition: _weaponobjects.gsc:615
‪isUsingRemote
‪function isUsingRemote()
Definition: util_shared.gsc:2705
‪IsEnemyPlayer
‪function IsEnemyPlayer(player)
Definition: util_shared.csc:1220
‪UAV_REMOTE_MODEL_ENEMY
‪#define UAV_REMOTE_MODEL_ENEMY
Definition: _qrdrone.gsc:40
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪carryQRDrone_setCarried
‪function carryQRDrone_setCarried(carrier)
Definition: _qrdrone.gsc:271
‪set_static_alpha
‪function set_static_alpha(alpha, drone)
Definition: _qrdrone.gsc:1624
‪getWeaponObjectWatcher
‪function getWeaponObjectWatcher(name)
Definition: _weaponobjects.gsc:1176
‪QRDrone_cleanup
‪function QRDrone_cleanup()
Definition: _qrdrone.gsc:1385
‪QRDrone_stun
‪function QRDrone_stun(duration)
Definition: _qrdrone.gsc:894
‪switch_to_last_non_killstreak_weapon
‪function switch_to_last_non_killstreak_weapon(immediate, awayfromBall)
Definition: killstreaks_shared.gsc:36
‪removeRemoteWeapon
‪function removeRemoteWeapon()
Definition: _qrdrone.gsc:365
‪stunStaticFX
‪function stunStaticFX(duration)
Definition: _remote_weapons.gsc:483
‪createCarryQRDrone
‪function createCarryQRDrone(streakName, owner)
Definition: _qrdrone.gsc:192
‪enemy_locking
‪function enemy_locking()
Definition: _qrdrone.gsc:623
‪isStunned
‪function isStunned()
Definition: util_shared.gsc:813
‪UAV_REMOTE_COLLISION_RADIUS
‪#define UAV_REMOTE_COLLISION_RADIUS
Definition: _qrdrone.gsc:37
‪isKillstreakAllowed
‪function isKillstreakAllowed(hardpointType, team)
Definition: _killstreakrules.gsc:352
‪QRDrone_endride
‪function QRDrone_endride(QRDrone)
Definition: _qrdrone.gsc:560
‪watchForAttack
‪function watchForAttack()
Definition: _qrdrone.gsc:229
‪QRDrone_play_single_fx_on_tag
‪function QRDrone_play_single_fx_on_tag(effect, tag)
Definition: _qrdrone.gsc:772
‪setUsingRemote
‪function setUsingRemote(remoteName, set_killstreak_delay_killcam=true)
Definition: _util.gsc:569
‪create_entity_enemy_influencer
‪function create_entity_enemy_influencer(name, team)
Definition: _spawning.gsc:310
‪death_fx
‪function death_fx()
Definition: _qrdrone.gsc:958
‪inithud
‪function inithud()
Definition: _qrdrone.gsc:1593
‪DisplayTeamMessageToAll
‪function DisplayTeamMessageToAll(message, player)
Definition: popups_shared.gsc:122
‪fade_to_black_for_x_sec
‪function fade_to_black_for_x_sec(startwait, blackscreenwait, fadeintime, fadeouttime, shaderName)
Definition: hud_shared.gsc:250
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪QRDrone_blowup
‪function QRDrone_blowup(attacker, weapon)
Definition: _qrdrone.gsc:1519
‪destroyedQRDrone
‪function destroyedQRDrone(damageType, weapon)
Definition: challenges_shared.gsc:1382
‪giveCarryQRDrone
‪function giveCarryQRDrone(lifeId, streakName)
Definition: _qrdrone.gsc:160
‪QRDrone_leave
‪function QRDrone_leave()
Definition: _qrdrone.gsc:1339
‪killstreakStop
‪function killstreakStop(hardpointType, team, id)
Definition: _killstreakrules.gsc:293
‪QRDrone_light_fx
‪function QRDrone_light_fx()
Definition: _qrdrone.gsc:1422
‪UAV_REMOTE_HELI_RANGE_COUNTDOWN
‪#define UAV_REMOTE_HELI_RANGE_COUNTDOWN
Definition: _qrdrone.gsc:36
‪QRDrone_fireGuns
‪function QRDrone_fireGuns(QRDrone)
Definition: _qrdrone.gsc:1490
‪QRDrone_get_damage_effect
‪function QRDrone_get_damage_effect(health_pct)
Definition: _qrdrone.gsc:762
‪QRDrone_watchHeliProximity
‪function QRDrone_watchHeliProximity()
Definition: _qrdrone.gsc:1448
‪QRDrone_leave_on_timeout_callback
‪function QRDrone_leave_on_timeout_callback()
Definition: _qrdrone.gsc:1321
‪QRDrone_rangeCountdown
‪function QRDrone_rangeCountdown()
Definition: _qrdrone.gsc:1232
‪killstreakStart
‪function killstreakStart(hardpointType, team, hacked, displayTeamMessage)
Definition: _killstreakrules.gsc:184
‪QRDrone_fire_for_time
‪function QRDrone_fire_for_time(totalFireTime)
Definition: _qrdrone.gsc:1028
‪clientNotify
‪function clientNotify(event)
Definition: util_shared.gsc:1416
‪lockPlayerForQRDroneLaunch
‪function lockPlayerForQRDroneLaunch()
Definition: _qrdrone.gsc:426
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪isInRemoteNoDeploy
‪function isInRemoteNoDeploy()
Definition: _qrdrone.gsc:284
‪QRDrone_freezeBuffer
‪function QRDrone_freezeBuffer()
Definition: _qrdrone.gsc:640
‪QRDrone_detonateWaiter
‪function QRDrone_detonateWaiter()
Definition: _qrdrone.gsc:1471
‪QRDrone_update_damage_fx
‪function QRDrone_update_damage_fx(health_percent)
Definition: _qrdrone.gsc:803
‪QRDRONE_FX_DEATH
‪#define QRDRONE_FX_DEATH
Definition: shared.gsh:338
‪set_dvar_if_unset
‪function set_dvar_if_unset(dvar, value, reset)
Definition: _util.gsc:420
‪QRDrone_crash_movement
‪function QRDrone_crash_movement(attacker, hitdir)
Definition: _qrdrone.gsc:964
‪clear_using_remote
‪function clear_using_remote(immediate, skipNotify)
Definition: _killstreaks.gsc:2403
‪destroy
‪function destroy(watcher, owner)
Definition: _decoy.gsc:108
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪UAV_REMOTE_MAX_HELI_PROXIMITY
‪#define UAV_REMOTE_MAX_HELI_PROXIMITY
Definition: _qrdrone.gsc:34
‪result
‪function result(death, attacker, mod, weapon)
Definition: _zm_aat_blast_furnace.gsc:46
‪enemy_locked
‪function enemy_locked()
Definition: _qrdrone.gsc:631
‪UAV_REMOTE_MIN_HELI_PROXIMITY
‪#define UAV_REMOTE_MIN_HELI_PROXIMITY
Definition: _qrdrone.gsc:33
‪QRDrone_playerExit
‪function QRDrone_playerExit(QRDrone)
Definition: _qrdrone.gsc:652
‪setCarryingQRDrone
‪function setCarryingQRDrone(carryQRDrone)
Definition: _qrdrone.gsc:247
‪rcbomb_earthquake
‪function rcbomb_earthquake(position)
Definition: _shellshock.gsc:87
‪QRDrone_crash_accel
‪function QRDrone_crash_accel()
Definition: _qrdrone.gsc:1049
‪QRDrone_leave_on_timeout
‪function QRDrone_leave_on_timeout(killstreakName)
Definition: _qrdrone.gsc:1294
‪createQRDrone
‪function createQRDrone(lifeId, owner, streakName, origin, angles, killstreak_id)
Definition: _qrdrone.gsc:448
‪QRDrone_damageWatcher
‪function QRDrone_damageWatcher()
Definition: _qrdrone.gsc:819
‪QRDrone_explode_on_game_end
‪function QRDrone_explode_on_game_end()
Definition: _qrdrone.gsc:1281
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪QRDrone_dialog
‪function QRDrone_dialog(dialogGroup)
Definition: _qrdrone.gsc:1430