‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_vehicle.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 #using scripts\shared\array_shared;
3 #using scripts\shared\hud_util_shared;
4 #using scripts\shared\system_shared;
5 #using scripts\shared\util_shared;
6 #using scripts\shared\clientfield_shared;
7 #using scripts\mp\gametypes\_spawning;
8 #using scripts\mp\_util;
9 #using scripts\mp\killstreaks\_qrdrone;
10 #using scripts\mp\killstreaks\_rcbomb;
11 #using scripts\shared\vehicle_death_shared;
12 
13 #insert scripts\shared\shared.gsh;
14 
15 #using_animtree ( "mp_vehicles" );
16 
17 #namespace vehicle;
18 
19 ‪REGISTER_SYSTEM( "vehicle", &‪__init__, undefined )
20 
21 function ‪__init__()
22 {
23  // We can control whether vehicle occupants can take damage (such as from bullets)
24  SetDvar( "scr_veh_driversarehidden", "1" );
25  SetDvar( "scr_veh_driversareinvulnerable", "1" );
26 
27  // "cleanuptime" must pass before veh is considered for cleanup (either by abandonment or drift)
28  // these are given in seconds
29  SetDvar( "scr_veh_alive_cleanuptimemin", "119" );
30  SetDvar( "scr_veh_alive_cleanuptimemax", "120" );
31  SetDvar( "scr_veh_dead_cleanuptimemin", "20" );
32  SetDvar( "scr_veh_dead_cleanuptimemax", "30" );
33 
34  // These cleanuptime factors only modify cleanup due to abandonment or drift,
35  // i.e. the cleanup of an alive vehicle. Once the vehicle dies and becomes a
36  // husk, only the cleanuptimemin and cleanuptimemax values apply.
37  SetDvar( "scr_veh_cleanuptime_dmgfactor_min", "0.33" );
38  SetDvar( "scr_veh_cleanuptime_dmgfactor_max", "1.0" );
39  SetDvar( "scr_veh_cleanuptime_dmgfactor_deadtread", "0.25" ); // decrease the damage factor ( which scales wait time ) by this much for each tread that has been completely destroyed
40  SetDvar( "scr_veh_cleanuptime_dmgfraction_curve_begin", "0.0" ); // this is the amount of damage at which the damage factor affecting wait time will be at max
41  SetDvar( "scr_veh_cleanuptime_dmgfraction_curve_end", "1.0" ); // this is the amount of damage at which the damage factor affecting wait time will be at min
42 
43  SetDvar( "scr_veh_cleanupabandoned", "1" ); // Decide whether to cleanup abandoned vehicles
44  SetDvar( "scr_veh_cleanupdrifted", "1" ); // Decide whether to cleanup drifted vehicles
45  SetDvar( "scr_veh_cleanupmaxspeedmph", "1" ); // If it's going slower than this, then the vehicle can be cleaned up
46  SetDvar( "scr_veh_cleanupmindistancefeet", "75" ); // If it's at least this far from its original position, then the vehicle can be cleaned up
47  SetDvar( "scr_veh_waittillstoppedandmindist_maxtime", "10" );
48  SetDvar( "scr_veh_waittillstoppedandmindist_maxtimeenabledistfeet", "5" );
49 
50  // Respawn time is the wait between cleaning up an old vehicle
51  // and spawning a new replacement vehicle.
52  // these are given in seconds
53  SetDvar( "scr_veh_respawnafterhuskcleanup", "1" ); // if true, vehicle respawn kicks off after husk cleanup. otherwise, kicks off after live vehicle is killed
54  SetDvar( "scr_veh_respawntimemin", "50" );
55  SetDvar( "scr_veh_respawntimemax", "90" );
56  SetDvar( "scr_veh_respawnwait_maxiterations", "30" );
57  SetDvar( "scr_veh_respawnwait_iterationwaitseconds", "1" );
58 
59  SetDvar( "scr_veh_disablerespawn", "0" );//turn off the default respawning system, the game mode will need to take care of respawning us.
60  SetDvar( "scr_veh_disableoverturndamage", "0" );// turn on damage when the vehicle is overturned by default
61 
62  // Explodes when killed or when dvar scr_veh_explode_on_cleanup is not zero
63  SetDvar( "scr_veh_explosion_spawnfx", "1" ); // Whether or not to create an explosion FX when the vehicle is destroyed
64  SetDvar( "scr_veh_explosion_doradiusdamage", "1" ); // whether or not to hurt nearby entities when the vehicle is destroyed
65  SetDvar( "scr_veh_explosion_radius", "256" );
66  SetDvar( "scr_veh_explosion_mindamage", "20" );
67  SetDvar( "scr_veh_explosion_maxdamage", "200" );
68 
69 
70  SetDvar( "scr_veh_ondeath_createhusk", "1" ); // Whether or not to init a burnt-out husk for players to use as cover when the vehicle is destroyed
71  SetDvar( "scr_veh_ondeath_usevehicleashusk", "1" ); // if true, husks will be the vehicle entities themselves. otherwise, husk will be a spawn("script_model")
72  SetDvar( "scr_veh_explosion_husk_forcepointvariance", "30" ); // controls the "spin" when the vehicle husk is launched
73  SetDvar( "scr_veh_explosion_husk_horzvelocityvariance", "25" );
74  SetDvar( "scr_veh_explosion_husk_vertvelocitymin", "100" );
75  SetDvar( "scr_veh_explosion_husk_vertvelocitymax", "200" );
76 
77 
78  SetDvar( "scr_veh_explode_on_cleanup", "1" );
79  SetDvar( "scr_veh_disappear_maxwaittime", "60" );
80  SetDvar( "scr_veh_disappear_maxpreventdistancefeet", "30" );
81  SetDvar( "scr_veh_disappear_maxpreventvisibilityfeet", "150" );
82 
83  SetDvar( "scr_veh_health_tank", "1350" ); // default health
84 
85  level.vehicle_drivers_are_invulnerable = GetDvarint( "scr_veh_driversareinvulnerable" );
86 
87  level.onEjectOccupants =&‪vehicle_eject_all_occupants;// Callback function to allow custom code when a vehicle is overturned and needs to eject occupants
88 
89  level.vehicleHealths[ "panzer4_mp" ] = 2600;
90  level.vehicleHealths[ "t34_mp" ] = 2600;
91 
92  SetDvar( "scr_veh_health_jeep", "700" );
93 
94 
96  {
97  level.vehicle_explosion_effect = "_t6/vehicle/vexplosion/fx_vexplode_helicopter_exp_mp"; // kaboom!
98 
99  level.veh_husk_models = [];
100  level.veh_husk_effects = [];
101 
102  if ( isdefined( level.use_new_veh_husks ) )
103  {
104  level.veh_husk_models[ "t34_mp" ] = "veh_t34_destroyed_mp";
105  //level.veh_husk_models[ "panzer4_mp" ] = "veh_panzer4_destroyed_mp";
106  }
107 
108  if ( isdefined( level.onAddVehicleHusks) )
109  {
110  [[level.onAddVehicleHusks]]();
111  }
112 
113  //level._effect["tanksquish"] = "_t6/maps/see2/fx_body_blood_splat";//TODO T7 - contact FX team to get proper replacement
114  }
115 
116  // for clientscripts
117  chopper_player_get_on_gun = %int_huey_gunner_on;
118  chopper_door_open = %v_huey_door_open;
119  chopper_door_open_state = %v_huey_door_open_state;
120  chopper_door_closed_state = %v_huey_door_close_state;
121 
122  killbrushes = GetEntArray( "water_killbrush", "targetname" );
123 
124  foreach( brush in killbrushes )
125  {
126  brush thread ‪water_killbrush_think();
127  }
128 
129  return;
130 }
131 
133 {
134  for( ;; )
135  {
136  self waittill( "trigger", entity );
137 
138  if ( isdefined( entity ) )
139  {
140  if ( isdefined( entity.targetname ) )
141  {
142  if ( entity.targetname == "rcbomb" )
143  {
144  entity notify( "rcbomb_shutdown" );
145  }
146  else if ( entity.targetname == "talon" && !‪IS_TRUE( entity.dead ) )
147  {
148  entity notify( "death" );
149  }
150  }
151 
152  if ( isdefined( entity.heliType ) && entity.heliType == "qrdrone" )
153  {
155  }
156  }
157  }
158 }
159 
161 {
162 
163  /*
164  Vehicle damage effects are stored in level.vehicles_damage_states[]
165  where the array key is the GDT vehicle-type name for the particular vehicle.
166  For example, "sherman_mp" --> level.vehicles_damage_states["sherman_mp"]
167  The default MP vehicle is "defaultvehicle_mp". This is used for vehicles who do not have a custom entry in the vehicles_damage_states[] array.
168 
169  Here we setup the vehicle damage effects response behaviors for all vehicles, using a data structure layout as follows:
170  struct s_vehicle_damage_state
171  {
172  float health_percentage; // apply effect(s) from effect_array[] when vehicle health is <= this amount
173  struct s_effect_array
174  {
175  id damage_effect; // this is the damage effect to apply
176  string sound_effect; // this is the sound effect to play
177  string vehicle_tag; // this is the tag on the vehicle where the effect should be applied
178  } effect_array[];
179  };
180  So, when a vehicle's health percentage becomes <= s_vehicle_damage_effects.health_percentage,
181  all the effects listed in s_vehicle_damage_effects.effect_array[] are applied as defined
182  */
183 
184  // damage indices
185  k_mild_damage_index= 0;
186  k_moderate_damage_index= 1;
187  k_severe_damage_index= 2;
188  k_total_damage_index= 3;
189 
190  // health_percentage constants
191  k_mild_damage_health_percentage= 0.85;
192  k_moderate_damage_health_percentage= 0.55;
193  k_severe_damage_health_percentage= 0.35;
194  k_total_damage_health_percentage= 0;
195  level.k_mild_damage_health_percentage = k_mild_damage_health_percentage;
196  level.k_moderate_damage_health_percentage = k_moderate_damage_health_percentage;
197  level.k_severe_damage_health_percentage = k_severe_damage_health_percentage;
198  level.k_total_damage_health_percentage = k_total_damage_health_percentage;
199 
200  level.vehicles_damage_states= [];
201  level.vehicles_husk_effects = [];
202  level.vehicles_damage_treadfx = [];
203 
204  // setup the default vehicle
205  vehicle_name= ‪get_default_vehicle_name();
206  {
207  level.vehicles_damage_states[vehicle_name]= [];
208  level.vehicles_damage_treadfx[vehicle_name] = [];
209 
210  // mild damage
211  {
212  level.vehicles_damage_states[vehicle_name][k_mild_damage_index]= SpawnStruct();
213  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].health_percentage= k_mild_damage_health_percentage;
214  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array= [];
215  // effect '0' - placed @ "tag_origin"
216  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0]= SpawnStruct();
217  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].damage_effect= "_t6/vehicle/vfire/fx_tank_sherman_smldr"; // smoldering (smoke puffs)//TODO T7 - contact FX team to get proper replacement
218  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].sound_effect= undefined;
219  level.vehicles_damage_states[vehicle_name][k_mild_damage_index].effect_array[0].vehicle_tag= "tag_origin";
220  }
221  // moderate damage
222  {
223  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index]= SpawnStruct();
224  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].health_percentage= k_moderate_damage_health_percentage;
225  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array= [];
226  // effect '0' - placed @ "tag_origin"
227  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0]= SpawnStruct();
228  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].damage_effect= "_t6/vehicle/vfire/fx_vfire_med_12"; // flames & more smoke//TODO T7 - contact FX team to get proper replacement
229  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].sound_effect= undefined;
230  level.vehicles_damage_states[vehicle_name][k_moderate_damage_index].effect_array[0].vehicle_tag= "tag_origin";
231  }
232  // severe damage
233  {
234  level.vehicles_damage_states[vehicle_name][k_severe_damage_index]= SpawnStruct();
235  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].health_percentage= k_severe_damage_health_percentage;
236  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array= [];
237  // effect '0' - placed @ "tag_origin"
238  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0]= SpawnStruct();
239  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].damage_effect= "_t6/vehicle/vfire/fx_vfire_sherman"; // pillar of smoke//TODO T7 - contact FX team to get proper replacement
240  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].sound_effect= undefined;
241  level.vehicles_damage_states[vehicle_name][k_severe_damage_index].effect_array[0].vehicle_tag= "tag_origin";
242  }
243  // total damage
244  {
245  level.vehicles_damage_states[vehicle_name][k_total_damage_index]= SpawnStruct();
246  level.vehicles_damage_states[vehicle_name][k_total_damage_index].health_percentage= k_total_damage_health_percentage;
247  level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array= [];
248  // effect '0' - placed @ "tag_origin"
249  level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0]= SpawnStruct();
250  level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].damage_effect= "_t6/vehicle/vexplosion/fx_vexplode_helicopter_exp_mp";
251  level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].sound_effect= "vehicle_explo"; // kaboom!
252  level.vehicles_damage_states[vehicle_name][k_total_damage_index].effect_array[0].vehicle_tag= "tag_origin";
253  }
254 
255 
256  {
257  default_husk_effects = SpawnStruct();
258  default_husk_effects.damage_effect = undefined;
259  default_husk_effects.sound_effect = undefined;
260  default_husk_effects.vehicle_tag = "tag_origin";
261 
262  level.vehicles_husk_effects[ vehicle_name ] = default_husk_effects;
263  }
264  }
265 
266 // _t34::build_damage_states();
267 // _panzeriv::build_damage_states();
268 
269  return;
270 }
271 
272 //string
274  vehicle)
275 {
276  ‪name= "";
277 
278  if (isdefined(vehicle))
279  {
280  if (isdefined(vehicle.vehicletype))
281  {
282  ‪name= vehicle.vehicletype;
283  }
284  }
285 
286  return ‪name;
287 }
288 
289 //string
291 {
292  return "defaultvehicle_mp";
293 }
294 
295 //string
297  vehicle)
298 {
299  vehicle_name= ‪get_vehicle_name(vehicle);
300 
301  if ( !isdefined(level.vehicles_damage_states) || !isdefined(level.vehicles_damage_states[vehicle_name]))
302  {
303  vehicle_name= ‪get_default_vehicle_name();
304  }
305 
306  return vehicle_name;
307 }
308 
309 //int
311  vehicle)
312 {
313  if ( !isdefined( level.vehicles_damage_states ) )
314  return -1;
315 
316  damage_state_index= -1;
318 
319  for (test_index= 0; test_index<level.vehicles_damage_states[vehicle_name].size; test_index++)
320  {
321  if (vehicle.current_health_percentage<=level.vehicles_damage_states[vehicle_name][test_index].health_percentage)
322  {
323  damage_state_index= test_index;
324  }
325  else
326  {
327  break;
328  }
329  }
330 
331  return damage_state_index;
332 }
333 
334 
335 // called each time a vehicle takes damage
337  vehicle,
338  attacker)
339 {
340  if (vehicle.initial_state.health>0)
341  {
342  previous_damage_state_index= ‪get_vehicle_damage_state_index_from_health_percentage(vehicle);
343  vehicle.current_health_percentage= vehicle.health/vehicle.initial_state.health;
344  current_damage_state_index= ‪get_vehicle_damage_state_index_from_health_percentage(vehicle);
345  // if we have reached a new damage state, play associated effects
346  if (previous_damage_state_index!=current_damage_state_index)
347  {
348  vehicle notify ( "damage_state_changed" );
349  if (previous_damage_state_index<0)
350  {
351  start_damage_state_index= 0;
352  }
353  else
354  {
355  start_damage_state_index= previous_damage_state_index+1;
356  }
357  ‪play_damage_state_effects(vehicle, start_damage_state_index, current_damage_state_index);
358  if ( vehicle.health <= 0 )
359  {
360  vehicle ‪kill_vehicle(attacker);
361  }
362  }
363  }
364 }
365 
366 
368  vehicle,
369  start_damage_state_index,
370  end_damage_state_index)
371 {
372  vehicle_name= ‪get_vehicle_name_key_for_damage_states( vehicle );
373 
374  // play effects for all damage states from start_damage_state_index --> end_damage_state_index
375  for (damage_state_index= start_damage_state_index; damage_state_index<=end_damage_state_index; damage_state_index++)
376  {
377  for (effect_index= 0;
378  effect_index<level.vehicles_damage_states[vehicle_name][damage_state_index].effect_array.size;
379  effect_index++)
380  {
381  effects = level.vehicles_damage_states[ vehicle_name ][ damage_state_index ].effect_array[ effect_index ];
382  vehicle thread ‪play_vehicle_effects( effects );
383  }
384  }
385 
386  return;
387 }
388 
389 
390 function ‪play_vehicle_effects( effects, isDamagedTread )
391 {
392  self endon( "delete" );
393  self endon( "removed" );
394 
395  if ( !isdefined( isDamagedTread ) || isDamagedTread == 0 )
396  {
397  self endon( "damage_state_changed" );
398  }
399 
400  // if there is an associated sound effect, play it
401  if ( isdefined( effects.sound_effect ) )
402  {
403  self PlaySound( effects.sound_effect );
404  }
405 
406  waitTime = 0;
407  if ( isdefined ( effects.damage_effect_loop_time ) )
408  {
409  waitTime = effects.damage_effect_loop_time;
410  }
411 
412  while ( waitTime > 0 )
413  {
414  // if the specified effect was loaded, play it on the associated vehicle tag
415  if ( isdefined( effects.damage_effect ) )
416  {
417  PlayFxOnTag( effects.damage_effect, self, effects.vehicle_tag );
418  }
419  wait( waitTime );
420  }
421 }
422 
423 
425 {
426  vehicles = getentarray( "script_vehicle", "classname" );
427  array::thread_all( vehicles,&‪init_original_vehicle );
428 
429  if ( isdefined( vehicles ) )
430  {
431  return vehicles.size;
432  }
433 
434  return 0;
435 }
436 
437 
439 {
440  // Last time I tested, this is actually not called from anywhere
441 }
442 
443 
445 {
446  // Register vehicle husk
447  if ( !isdefined( level.vehicles_list ) )
448  {
449  level.vehicles_list = [];
450  }
451 
452  level.vehicles_list[ level.vehicles_list.size ] = self;
453 }
454 
455 
456 // Before spawning a new vehicle, we need to bookkeep our list
457 // of instantiated vehicles. If spawning the new vehicle would cause us to go
458 // over the max vehicle limit, then we need to force-delete
459 // the oldest (dead) ones to make room.
460 
462 {
463  if ( !isdefined( level.vehicles_list ) )
464  {
465  return true;
466  }
467  else
468  {
469  MAX_VEHICLES = GetMaxVehicles();
470 
471  {
472  // Consolidate array - Husks might have been cleaned up in the interim
473 
474  newArray = [];
475 
476  for ( i = 0; i < level.vehicles_list.size; i++ )
477  {
478  if ( isdefined( level.vehicles_list[ i ] ) )
479  {
480  newArray[ newArray.size ] = level.vehicles_list[ i ];
481  }
482  }
483 
484  level.vehicles_list = newArray;
485  }
486 
487 
488  // make sure there's room for one more
489  vehiclesToDelete = ( level.vehicles_list.size + 1 ) - MAX_VEHICLES;
490 
491 
492  if ( vehiclesToDelete > 0 )
493  {
494  newArray = [];
495 
496  for ( i = 0; i < level.vehicles_list.size; i++ )
497  {
498  vehicle = level.vehicles_list[ i ];
499 
500  if ( vehiclesToDelete > 0 )
501  {
502  // ".permanentlyRemoved" vehicles will never be really deleted
503  if ( isdefined( vehicle.is_husk ) && !isdefined( vehicle.permanentlyRemoved ) )
504  {
505  deleted = vehicle ‪husk_do_cleanup();
506 
507  if ( deleted )
508  {
509  vehiclesToDelete--;
510  continue;
511  }
512  }
513  }
514 
515  newArray[ newArray.size ] = vehicle;
516  }
517 
518  level.vehicles_list = newArray;
519  }
520 
521  return level.vehicles_list.size < MAX_VEHICLES;
522  }
523 }
524 
525 
534 function ‪init_vehicle()
535 {
536  self ‪register_vehicle();
537 
538 
539  // setting the tank health here so it is universal
540  // we should do the same for the other vehicles
541  if ( isdefined( level.vehicleHealths ) && isdefined( level.vehicleHealths[ self.vehicletype ] ) )
542  {
543  self.maxhealth = level.vehicleHealths[ self.vehicletype ];
544  }
545  else
546  {
547  self.maxhealth = GetDvarint( "scr_veh_health_tank");
548 /#
549  println( "No health specified for vehicle type "+self.vehicletype+"! Using default..." );
550 #/
551  }
552  self.health = self.maxhealth;
553 
555 
557 
558  ‪system::wait_till( "spawning" );
559 
560  // add the influencer to block all teams
562 }
563 
564 
566 {
567  if (self.initial_state.health>0)
568  {
569  self.current_health_percentage= self.health/self.initial_state.health;
570  self.previous_health_percentage= self.health/self.initial_state.health;
571  }
572  else
573  {
574  self.current_health_percentage= 1;
575  self.previous_health_percentage= 1;
576  }
577 
578  return;
579 }
580 
582 {
583  // this is a temporary hack trying to resolve the "!cent->pose.fx.effect"
584  // crash bug. Basically I think the bug is caused by deleteing the original
585  // tanks that were in the bsp
586  self.original_vehicle = true;
587 
588  self ‪init_vehicle();
589 }
590 
591 // debug code below is for a simple vehicle health bar
593 {
594  self endon( "transmute" );
595  self endon( "death" );
596  self endon( "delete" );
597 
598  while( 1 )
599  {
600  self waittill( "enter_vehicle", player );
601 
602  player thread ‪player_wait_exit_vehicle_t();
603 
604  player ‪player_update_vehicle_hud( true, self );
605  }
606 }
607 
608 
610 {
611  // Don't endon "death". Player will receive
612  // "exit_vehicle" message when killed in a vehicle
613  self endon( "disconnect" );
614 
615  self waittill( "exit_vehicle", vehicle );
616  self ‪player_update_vehicle_hud( false, vehicle );
617 }
618 
619 
621 {
622  self endon( "transmute" );
623  self endon( "death" );
624  self endon( "delete" );
625 
626  while( 1 )
627  {
628  self waittill ( "damage" );
629 
630  occupants = self GetVehOccupants();
631  if( isdefined( occupants ) )
632  {
633  for( i = 0; i < occupants.size; i++ )
634  {
635  occupants[i] ‪player_update_vehicle_hud( true, self );
636  }
637  }
638  }
639 }
640 
641 
642 function ‪player_update_vehicle_hud( show, vehicle )
643 {
644  if( show )
645  {
646  if ( !isdefined( self.vehicleHud ) )
647  {
648  self.vehicleHud = ‪hud::createBar( (1, 1, 1), 64, 16 );
649  self.vehicleHud ‪hud::setPoint( "CENTER", "BOTTOM", 0, -40 );
650  self.vehicleHud.alpha = 0.75;
651  }
652 
653  self.vehicleHud ‪hud::updateBar( vehicle.health / vehicle.initial_state.health );
654  }
655  else
656  {
657  if ( isdefined( self.vehicleHud ) )
658  {
659  self.vehicleHud ‪hud::destroyElem();
660  }
661  }
662 
663  if ( GetDvarString( "scr_vehicle_healthnumbers" )!= "" )
664  {
665  if ( GetDvarint( "scr_vehicle_healthnumbers" )!= 0 )
666  {
667  if( show )
668  {
669  if ( !isdefined( self.vehicleHudHealthNumbers ) )
670  {
671  self.vehicleHudHealthNumbers = ‪hud::createFontString( "default", 2.0 );
672  self.vehicleHudHealthNumbers ‪hud::setParent( self.vehicleHud );
673  self.vehicleHudHealthNumbers ‪hud::setPoint( "LEFT", "RIGHT", 8, 0 );
674  self.vehicleHudHealthNumbers.alpha = 0.75;
675  self.vehicleHudHealthNumbers.hideWhenInMenu = false;
676  self.vehicleHudHealthNumbers.archived = false;
677  }
678 
679  self.vehicleHudHealthNumbers setValue( vehicle.health );
680  }
681  else
682  {
683  if ( isdefined( self.vehicleHudHealthNumbers ) )
684  {
685  self.vehicleHudHealthNumbers ‪hud::destroyElem();
686  }
687  }
688  }
689  }
690 }
691 
692 
694 {
695  self thread ‪vehicle_abandoned_by_drift_t();
697  self thread ‪vehicle_damage_t();
699 
700  self thread ‪vehicle_recycle_spawner_t();
701  self thread ‪vehicle_disconnect_paths();
702 
703  // enable debug vehicle health bar
704  if( isdefined( level.enableVehicleHealthbar ) && level.enableVehicleHealthbar )
705  {
706  self thread ‪vehicle_wait_player_enter_t();
707  self thread ‪vehicle_wait_damage_t();
708  }
709 
710  self thread ‪vehicle_wait_tread_damage();
711 
713 
714  if (GetDvarint( "scr_veh_disableoverturndamage") == 0)
715  {
716  self thread ‪vehicle_overturn_suicide();
717  }
718 }
719 
733 function ‪build_template( type, model, typeoverride )
734 {
735  if( isdefined( typeoverride ) )
736  type = typeoverride;
737 
738  if( !isdefined( level.vehicle_death_fx ) )
739  level.vehicle_death_fx = [];
740  if( !isdefined( level.vehicle_death_fx[ type ] ) )
741  level.vehicle_death_fx[ type ] = []; // can have overrides
742 
743  level.vehicle_compassicon[ type ] = false;
744  level.vehicle_team[ type ] = "axis";
745  level.vehicle_life[ type ] = 999;
746  level.vehicle_hasMainTurret[ model ] = false;
747  level.vehicle_mainTurrets[ model ] = [];
748  level.vtmodel = model;
749  level.vttype = type;
750 }
751 
768 function ‪build_rumble( ‪rumble, scale, duration, radius, basetime, randomaditionaltime )
769 {
770  if( !isdefined( level.vehicle_rumble ) )
771  level.vehicle_rumble = [];
772  struct = ‪build_quake( scale, duration, radius, basetime, randomaditionaltime );
773  assert( isdefined( ‪rumble ) );
774  struct.rumble = ‪rumble;
775  level.vehicle_rumble[ level.vttype ] = struct;
776 }
777 
778 function ‪build_quake( scale, duration, radius, basetime, randomaditionaltime )
779 {
780  struct = spawnstruct();
781  struct.scale = scale;
782  struct.duration = duration;
783  struct.radius = radius;
784  if( isdefined( basetime ) )
785  struct.basetime = basetime;
786  if( isdefined( randomaditionaltime ) )
787  struct.randomaditionaltime = randomaditionaltime;
788  return struct;
789 }
790 
802 function ‪build_exhaust( effect )
803 {
804  level.vehicle_exhaust[ level.vtmodel ] = effect;
805 }
806 
807 
808 // =====================================================================================
809 // Abandonment Code
810 
812 {
813  self endon( "transmute" );
814  self endon( "death" );
815  self endon( "delete" );
816 
817  self ‪wait_then_cleanup_vehicle( "Drift Test", "scr_veh_cleanupdrifted" );
818 }
819 
820 
822 {
823  self endon( "transmute" );
824  self endon( "death" );
825  self endon( "delete" );
826 
827  self ‪wait_then_cleanup_vehicle( "Abandon Test", "scr_veh_cleanupabandoned" );
828 }
829 
830 
831 function ‪wait_then_cleanup_vehicle( test_name, cleanup_dvar_name )
832 {
833  self endon( "enter_vehicle" );
834 
836  self ‪do_alive_cleanup_wait( test_name );
837  self ‪wait_for_vehicle_to_stop_outside_min_radius(); // unoccupied vehicle can be being pushed!
838  self ‪cleanup( test_name, cleanup_dvar_name,&‪vehicle_recycle );
839 }
840 
841 
843 {
844  while ( 1 )
845  {
846  health_percentage = self.health / self.initial_state.health;
847 
848  self waittill( "damage" );
849 
850  health_percentage = self.health / self.initial_state.health;
851 
852  if ( isdefined( level.k_severe_damage_health_percentage ) && health_percentage < level.k_severe_damage_health_percentage )
853  break;
854  }
855 }
856 
857 
859 {
860  varnamePrefix = "scr_veh_" + state + "_cleanuptime";
861  minTime = getdvarfloat( varnamePrefix + "min" );
862  maxTime = getdvarfloat( varnamePrefix + "max" );
863 
864  if ( maxTime > minTime )
865  {
866  return RandomFloatRange( minTime, maxTime );
867  }
868  else
869  {
870  return maxTime;
871  }
872 }
873 
874 
875 function ‪do_alive_cleanup_wait( test_name )
876 {
877  initialRandomWaitSeconds = ‪get_random_cleanup_wait_time( "alive" );
878 
879  secondsWaited = 0.0;
880  seconds_per_iteration = 1.0;
881 
882  while ( true )
883  {
884  curve_begin = GetDvarfloat( "scr_veh_cleanuptime_dmgfraction_curve_begin" );
885  curve_end = GetDvarfloat( "scr_veh_cleanuptime_dmgfraction_curve_end" );
886 
887  factor_min = GetDvarfloat( "scr_veh_cleanuptime_dmgfactor_min" );
888  factor_max = GetDvarfloat( "scr_veh_cleanuptime_dmgfactor_max" );
889 
890  treadDeadDamageFactor = GetDvarfloat( "scr_veh_cleanuptime_dmgfactor_deadtread" );
891 
892 
893  damageFraction = 0.0;
894 
895  if ( self ‪is_vehicle() )
896  {
897  damageFraction = ( self.initial_state.health - self.health ) / self.initial_state.health;
898  }
899  else // is husk
900  {
901  damageFraction = 1.0;
902  }
903 
904  damageFactor = 0.0;
905 
906  if ( damageFraction <= curve_begin )
907  {
908  damageFactor = factor_max;
909  }
910  else if ( damageFraction >= curve_end )
911  {
912  damageFactor = factor_min;
913  }
914  else
915  {
916  dydx = ( factor_min - factor_max ) / ( curve_end - curve_begin );
917  damageFactor = factor_max + ( damageFraction - curve_begin ) * dydx;
918  }
919 
920  totalSecsToWait = initialRandomWaitSeconds * damageFactor;
921 
922  if ( secondsWaited >= totalSecsToWait )
923  {
924  break;
925  }
926 
927  wait seconds_per_iteration;
928  secondsWaited = secondsWaited + seconds_per_iteration;
929  }
930 }
931 
932 
933 function ‪do_dead_cleanup_wait( test_name )
934 {
935  total_secs_to_wait = ‪get_random_cleanup_wait_time( "dead" );
936 
937  seconds_waited = 0.0;
938  seconds_per_iteration = 1.0;
939 
940  while ( seconds_waited < total_secs_to_wait )
941  {
942  wait seconds_per_iteration;
943  seconds_waited = seconds_waited + seconds_per_iteration;
944  }
945 }
946 
947 
948 function ‪cleanup( test_name, cleanup_dvar_name, cleanup_func )
949 {
950  keep_waiting = true;
951 
952  while ( keep_waiting )
953  {
954  cleanupEnabled = !isdefined( cleanup_dvar_name )
955  || getdvarint( cleanup_dvar_name ) != 0;
956 
957  if ( cleanupEnabled != 0 )
958  {
959  self [[cleanup_func]]();
960  break;
961  }
962 
963  keep_waiting = false;
964  }
965 }
966 
968 {
969  self endon( "death" );
970  self endon( "delete" );
971 
972  vehicle_name= ‪get_vehicle_name(self);
973 
974  while ( 1 )
975  {
976  self waittill ( "broken", brokenNotify );
977  if ( brokenNotify == "left_tread_destroyed" )
978  {
979  if ( isdefined( level.vehicles_damage_treadfx[vehicle_name] ) && isdefined( level.vehicles_damage_treadfx[vehicle_name][0] ) )
980  {
981  self thread ‪play_vehicle_effects( level.vehicles_damage_treadfx[vehicle_name][0], true );
982  }
983  }
984  else if ( brokenNotify == "right_tread_destroyed" )
985  {
986  if ( isdefined( level.vehicles_damage_treadfx[vehicle_name] ) && isdefined( level.vehicles_damage_treadfx[vehicle_name][1] ) )
987  {
988  self thread ‪play_vehicle_effects( level.vehicles_damage_treadfx[vehicle_name][1], true );
989  }
990  }
991  }
992 }
993 
995 {
996  maxWaitTime = GetDvarfloat( "scr_veh_waittillstoppedandmindist_maxtime" );
997  iterationWaitSeconds = 1.0;
998 
999  maxWaitTimeEnableDistInches = 12 * GetDvarfloat( "scr_veh_waittillstoppedandmindist_maxtimeenabledistfeet" );
1000 
1001  initialOrigin = self.initial_state.origin;
1002 
1003  for ( totalSecondsWaited = 0.0; totalSecondsWaited < maxWaitTime; totalSecondsWaited += iterationWaitSeconds )
1004  {
1005  // We don't want to disappear it if someone is
1006  // currently pushing it with another vehicle
1007  speedMPH = self GetSpeedMPH();
1008  cutoffMPH = GetDvarfloat( "scr_veh_cleanupmaxspeedmph" );
1009 
1010  if ( speedMPH > cutoffMPH )
1011  {
1012  }
1013  else
1014  {
1015  break;
1016  }
1017 
1018  wait iterationWaitSeconds;
1019  }
1020 }
1021 
1022 
1024 {
1025  self endon( "transmute" );
1026  self endon( "death" );
1027  self endon( "delete" );
1028 
1029  while ( 1 )
1030  {
1031  self waittill( "exit_vehicle" );
1032 
1033  occupants = self GetVehOccupants();
1034 
1035  if ( occupants.size == 0 )
1036  {
1037  self ‪play_start_stop_sound( "tank_shutdown_sfx" );
1039  }
1040  }
1041 }
1042 
1043 
1044 function ‪play_start_stop_sound( sound_alias, modulation )
1045 {
1046  if ( isdefined( self.start_stop_sfxid ) )
1047  {
1048  //stopSound( self.start_stop_sfxid );
1049  }
1050 
1051  self.start_stop_sfxid = self playSound( sound_alias );
1052 }
1053 
1054 
1055 // this function should be replaced by code in cg_player.cpp cg_player()
1056 // we should just not be rendering the player when in a non-visible seat
1058 {
1059  self endon( "transmute" );
1060  self endon( "death" );
1061  self endon( "delete" );
1062 
1063  if ( IsDefined( self.vehicleClass ) && "artillery" == self.vehicleClass )
1064  {
1065  return;
1066  }
1067 
1068  //if ( self vehicle_is_tank() )
1069  {
1070  while ( 1 )
1071  {
1072  self waittill( "enter_vehicle", player, seat );
1073 
1074  isDriver = seat == 0;
1075 
1076  if ( GetDvarint( "scr_veh_driversarehidden" ) != 0
1077  && isDriver )
1078  {
1079  player Ghost();
1080  }
1081 
1082 
1083  {
1084  occupants = self GetVehOccupants();
1085 
1086  if ( occupants.size == 1 )
1087  {
1088  self ‪play_start_stop_sound( "tank_startup_sfx" );
1089  }
1090  }
1091 
1092 
1093  player thread ‪player_change_seat_handler_t( self );
1094  player thread ‪player_leave_vehicle_cleanup_t( self );
1095  }
1096  }
1097 }
1098 
1099 
1100 function ‪player_is_occupant_invulnerable( sMeansOfDeath )
1101 {
1102  if ( self IsRemoteControlling() )
1103  return false;
1104 
1105  if (!isdefined(level.vehicle_drivers_are_invulnerable))
1106  level.vehicle_drivers_are_invulnerable = false;
1107 
1108  invulnerable = ( level.vehicle_drivers_are_invulnerable && ( self ‪player_is_driver() ) );
1109 
1110  return invulnerable;
1111 }
1112 
1113 
1115 {
1116  if ( !isalive(self) )
1117  return false;
1118 
1119  vehicle = self GetVehicleOccupied();
1120 
1121  if ( isdefined( vehicle ) )
1122  {
1123  if ( IsDefined( vehicle.vehicleClass ) && "artillery" == vehicle.vehicleClass )
1124  {
1125  return false;
1126  }
1127 
1128  seat = vehicle GetOccupantSeat( self );
1129 
1130  if ( isdefined(seat) && seat == 0 )
1131  return true;
1132  }
1133 
1134  return false;
1135 }
1136 
1137 
1138 // this function should be replaced by code in cg_player.cpp cg_player()
1139 // we should just not be rendering the player when in a non-visible seat
1141 {
1142  self endon( "disconnect" );
1143  self endon( "exit_vehicle" );
1144 
1145  while ( 1 )
1146  {
1147  self waittill( "change_seat", vehicle, oldSeat, newSeat );
1148 
1149  isDriver = newSeat == 0;
1150 
1151  if ( isDriver )
1152  {
1153  if ( GetDvarint( "scr_veh_driversarehidden" ) != 0 )
1154  {
1155  self Ghost();
1156  }
1157  }
1158  else
1159  {
1160  self Show();
1161  }
1162  }
1163 }
1164 
1165 
1166 // this function should be replaced by code in cg_player.cpp cg_player()
1167 // we should just not be rendering the player when in a non-visible seat
1169 {
1170  self endon( "disconnect" );
1171  self waittill( "exit_vehicle" );
1172  currentWeapon = self getCurrentWeapon();
1173 
1174  if ( IsDefined( self.lastWeapon ) && self.lastWeapon != currentWeapon && self.lastWeapon != level.weaponNone )
1175  {
1176  self switchToWeapon( self.lastWeapon );
1177  }
1178 
1179  self Show();
1180 }
1181 
1182 
1184 {
1185  return self.vehicletype == "sherman_mp"
1186  || self.vehicletype == "panzer4_mp"
1187  || self.vehicletype == "type97_mp"
1188  || self.vehicletype == "t34_mp";
1189 }
1190 
1191 // =====================================================================================
1192 
1193 
1195 {
1196  if ( !isdefined( self.initial_state ) )
1197  {
1198  self.initial_state= SpawnStruct();
1199  }
1200 
1201  if ( isdefined( self.origin ) )
1202  {
1203  self.initial_state.origin= self.origin;
1204  }
1205 
1206  if ( isdefined( self.angles ) )
1207  {
1208  self.initial_state.angles= self.angles;
1209  }
1210 
1211  if ( isdefined( self.health ) )
1212  {
1213  self.initial_state.health= self.health;
1214  }
1215 
1217 
1218  return;
1219 }
1220 
1221 
1223 {
1224  return GetDvarint( "scr_veh_explode_on_cleanup" ) != 0;
1225 }
1226 
1227 
1229 {
1231  self.recycling = true;
1232  self ‪suicide();
1233 }
1234 
1236 {
1237  self endon( "transmute" );
1238  self endon( "death" );
1239  self endon( "delete" );
1240 
1241  worldup = anglestoup((0,90,0));
1242 
1243  overturned = 0;
1244 
1245  while (!overturned)
1246  {
1247  if ( isdefined( self.angles ) )
1248  {
1249  up = AnglesToUp( self.angles );
1250  dot = vectordot(up, worldup);
1251  if (dot <= 0.0)
1252  overturned = 1;
1253  }
1254 
1255  if (!overturned)
1256  wait (1.0);
1257  }
1258 }
1259 
1261 {
1262  self endon( "transmute" );
1263  self endon( "death" );
1264  self endon( "delete" );
1265 
1266  for(;;)
1267  {
1268  self waittill( "veh_ejectoccupants" );
1269 
1270  if ( isdefined( level.onEjectOccupants ) )
1271  {
1272  [[level.onEjectOccupants]]();
1273  }
1274 
1275  wait .25;
1276  }
1277 }
1278 
1280 {
1281  occupants = self GetVehOccupants();
1282  if ( isdefined( occupants ) )
1283  {
1284  for ( i = 0; i < occupants.size; i++ )
1285  {
1286  if ( isdefined( occupants[i] ) )
1287  {
1288  occupants[i] Unlink();
1289  }
1290  }
1291  }
1292 }
1293 
1295 {
1296  self endon( "transmute" );
1297  self endon( "death" );
1298  self endon( "delete" );
1299 
1301 
1302  seconds = RandomFloatRange( 5, 7 );
1303  wait seconds;
1304 
1305  damageOrigin = self.origin + (0,0,25);
1306  self finishVehicleRadiusDamage(self, self, 32000, 32000, 32000, 0, "MOD_EXPLOSIVE", level.weaponNone, damageOrigin, 400, -1, (0,0,1), 0);
1307 }
1308 
1309 function ‪suicide()
1310 {
1311  self ‪kill_vehicle( self );
1312 }
1313 
1314 function ‪kill_vehicle( attacker )
1315 {
1316  damageOrigin = self.origin + (0,0,1);
1317  self finishVehicleRadiusDamage(attacker, attacker, 32000, 32000, 10, 0, "MOD_EXPLOSIVE", level.weaponNone, damageOrigin, 400, -1, (0,0,1), 0);
1318 }
1319 
1320 function ‪value_with_default( preferred_value, default_value )
1321 {
1322  if ( isdefined( preferred_value ) )
1323  {
1324  return preferred_value;
1325  }
1326 
1327  return default_value;
1328 }
1329 
1330 
1331 function ‪vehicle_transmute( attacker )
1332 {
1333  deathOrigin = self.origin;
1334  deathAngles = self.angles;
1335 
1336 
1337  vehicle_name = ‪get_vehicle_name_key_for_damage_states( self );
1338 
1339 
1340  respawn_parameters = SpawnStruct();
1341  respawn_parameters.origin = self.initial_state.origin;
1342  respawn_parameters.angles = self.initial_state.angles;
1343  respawn_parameters.health = self.initial_state.health;
1344  respawn_parameters.targetname = ‪value_with_default( self.targetname, "" );
1345  respawn_parameters.vehicletype = ‪value_with_default( self.vehicletype, "" );
1346  respawn_parameters.destructibledef = self.destructibledef; // Vehicle may or may not be a destructible vehicle
1347 
1348 
1349  vehicleWasDestroyed = !isdefined( self.recycling );
1350 
1351  if ( vehicleWasDestroyed
1353  {
1354  ‪_spawn_explosion( deathOrigin );
1355 
1356  if ( vehicleWasDestroyed
1357  && GetDvarint( "scr_veh_explosion_doradiusdamage" ) != 0 )
1358  {
1359  // Vehicle is exploding, so damage nearby entities
1360  // Damage first, so doesn't affect other entities spawned
1361  // by this function
1362 
1363  explosionRadius = GetDvarint( "scr_veh_explosion_radius" );
1364  explosionMinDamage = GetDvarint( "scr_veh_explosion_mindamage" );
1365  explosionMaxDamage = GetDvarint( "scr_veh_explosion_maxdamage" );
1366  self ‪kill_vehicle(attacker);
1367  self RadiusDamage( deathOrigin, explosionRadius, explosionMaxDamage, explosionMinDamage, attacker, "MOD_EXPLOSIVE", GetWeapon( self.vehicletype + "_explosion" ) );
1368  }
1369  }
1370 
1371 
1372  self notify( "transmute" );
1373 
1374 
1375  respawn_vehicle_now = true;
1376 
1377  if ( vehicleWasDestroyed
1378  && GetDvarint( "scr_veh_ondeath_createhusk" ) != 0 )
1379  {
1380  // Spawn burned out husk for players to use as cover
1381 
1382  if ( GetDvarint( "scr_veh_ondeath_usevehicleashusk" ) != 0 )
1383  {
1384  husk = self;
1385  self.is_husk = true;
1386  }
1387  else
1388  {
1389  husk = ‪_spawn_husk( deathOrigin, deathAngles, self.vehmodel );
1390  }
1391 
1392  husk ‪_init_husk( vehicle_name, respawn_parameters );
1393 
1394  if ( GetDvarint( "scr_veh_respawnafterhuskcleanup" ) != 0 )
1395  {
1396  respawn_vehicle_now = false;
1397  }
1398  }
1399 
1400 
1401  if ( !isdefined( self.is_husk ) )
1402  {
1404  }
1405 
1406  if ( GetDvarint( "scr_veh_disablerespawn" ) != 0 ) //The Vehicle Mayhem gamemode handles spawning the vehicles, so it does not need to respawn here
1407  {
1408  respawn_vehicle_now = false;
1409  }
1410 
1411  if ( respawn_vehicle_now )
1412  {
1413  ‪respawn_vehicle( respawn_parameters );
1414  }
1415 }
1416 
1417 
1418 function ‪respawn_vehicle( respawn_parameters )
1419 {
1420  {
1421  minTime = GetDvarint( "scr_veh_respawntimemin" );
1422  maxTime = GetDvarint( "scr_veh_respawntimemax" );
1423  seconds = RandomFloatRange( minTime, maxTime );
1424  wait seconds;
1425  }
1426 
1427 
1428  ‪wait_until_vehicle_position_wont_telefrag( respawn_parameters.origin );
1429 
1430 
1431  if ( !‪manage_vehicles() ) // make sure we don't hit max vehicle limit
1432  {
1433  /#
1434  iprintln("Vehicle can't respawn because MAX_VEHICLES has been reached and none of the vehicles could be cleaned up.");
1435  #/
1436  }
1437  else
1438  {
1439  if ( isdefined( respawn_parameters.destructibledef ) ) // passing undefined argument doesn't make the server happy
1440  {
1441  vehicle = SpawnVehicle(
1442  respawn_parameters.vehicletype,
1443  respawn_parameters.origin,
1444  respawn_parameters.angles,
1445  respawn_parameters.targetname,
1446  respawn_parameters.destructibledef );
1447  }
1448  else
1449  {
1450  vehicle = SpawnVehicle(
1451  respawn_parameters.vehicletype,
1452  respawn_parameters.origin,
1453  respawn_parameters.angles,
1454  respawn_parameters.targetname );
1455  }
1456 
1457  vehicle.vehicletype = respawn_parameters.vehicletype;
1458  vehicle.destructibledef = respawn_parameters.destructibledef;
1459  vehicle.health = respawn_parameters.health;
1460 
1461  vehicle ‪init_vehicle();
1462 
1463  vehicle ‪vehicle_telefrag_griefers_at_position( respawn_parameters.origin );
1464  }
1465 }
1466 
1467 
1469 {
1470  // this is a temporary hack trying to resolve the "!cent->pose.fx.effect"
1471  // crash bug. Basically I think the bug is caused by deleteing the original
1472  // tanks that were in the bsp
1473 
1474  self notify ( "removed" );
1475 
1476  if ( isdefined( self.original_vehicle ) )
1477  {
1478  if ( !isdefined( self.permanentlyRemoved ) )
1479  {
1480  self.permanentlyRemoved = true; // Mark that it has been permanently removed from the world
1481  self thread ‪hide_vehicle(); // threaded because it calls a wait()
1482  }
1483 
1484  return false;
1485  }
1486  else
1487  {
1488  self ‪_delete_entity();
1489  return true;
1490  }
1491 }
1492 
1493 
1495 {
1496  /#
1497  //iprintln("$e" + ( self GetEntNum() ) + " is deleting");
1498  #/
1499 
1500  self Delete();
1501 }
1502 
1503 
1505 {
1506  under_the_world = ( self.origin[0], self.origin[1], self.origin[2] - 10000 );
1507  self.origin = under_the_world;
1508 
1509  wait 0.1;
1510  self Hide();
1511 
1512  self notify( "hidden_permanently" );
1513 }
1514 
1515 
1517 {
1518  maxPreventDistanceFeet = GetDvarint( "scr_veh_disappear_maxpreventdistancefeet" );
1519  maxPreventVisibilityFeet = GetDvarint( "scr_veh_disappear_maxpreventvisibilityfeet" );
1520 
1521  maxPreventDistanceInchesSq = 144 * maxPreventDistanceFeet * maxPreventDistanceFeet;
1522  maxPreventVisibilityInchesSq = 144 * maxPreventVisibilityFeet * maxPreventVisibilityFeet;
1523 
1524 
1525  maxSecondsToWait = GetDvarfloat( "scr_veh_disappear_maxwaittime" );
1526  iterationWaitSeconds = 1.0;
1527 
1528  for ( secondsWaited = 0.0; secondsWaited < maxSecondsToWait; secondsWaited += iterationWaitSeconds )
1529  {
1530  players_s = ‪util::get_all_alive_players_s();
1531 
1532  okToCleanup = true;
1533 
1534  for ( j = 0; j < players_s.a.size && okToCleanup; j++ )
1535  {
1536  player = players_s.a[ j ];
1537  distInchesSq = DistanceSquared( self.origin, player.origin );
1538 
1539  if ( distInchesSq < maxPreventDistanceInchesSq )
1540  {
1541  okToCleanup = false;
1542  }
1543  else if ( distInchesSq < maxPreventVisibilityInchesSq )
1544  {
1545  vehicleVisibilityFromPlayer = self SightConeTrace( player.origin, player, AnglesToForward( player.angles ) );
1546 
1547  if ( vehicleVisibilityFromPlayer > 0 )
1548  {
1549  okToCleanup = false;
1550  }
1551  }
1552  }
1553 
1554  if ( okToCleanup )
1555  {
1556  return;
1557  }
1558 
1559  wait iterationWaitSeconds;
1560  }
1561 }
1562 
1563 
1565 {
1566  maxIterations = GetDvarint( "scr_veh_respawnwait_maxiterations" );
1567  iterationWaitSeconds = GetDvarint( "scr_veh_respawnwait_iterationwaitseconds" );
1568 
1569  for ( i = 0; i < maxIterations; i++ )
1570  {
1571  if ( !‪vehicle_position_will_telefrag( position ) )
1572  {
1573  return;
1574  }
1575 
1576  wait iterationWaitSeconds;
1577  }
1578 }
1579 
1580 
1582 {
1583  players_s = ‪util::get_all_alive_players_s();
1584 
1585  for ( i = 0; i < players_s.a.size; i++ )
1586  {
1587  if ( players_s.a[ i ] ‪player_vehicle_position_will_telefrag( position ) )
1588  {
1589  return true;
1590  }
1591  }
1592 
1593  return false;
1594 }
1595 
1596 
1598 {
1599  attacker = self;
1600  inflictor = self;
1601 
1602  players_s = ‪util::get_all_alive_players_s();
1603 
1604  for ( i = 0; i < players_s.a.size; i++ )
1605  {
1606  player = players_s.a[ i ];
1607 
1608  if ( player ‪player_vehicle_position_will_telefrag( position ) )
1609  {
1610  player DoDamage( 20000, player.origin + ( 0, 0, 1 ), attacker, inflictor, "none" );
1611  }
1612  }
1613 }
1614 
1615 
1617 {
1618  distanceInches = 20 * 12;
1619  minDistInchesSq = distanceInches * distanceInches;
1620 
1621  distInchesSq = DistanceSquared( self.origin, position );
1622 
1623  return distInchesSq < minDistInchesSq;
1624 }
1625 
1626 
1628 {
1629  self endon( "delete" );
1630 
1631  self waittill( "death", attacker ); // "vehicle Delete()" sends death message too!!!
1632 
1633  if ( isdefined( self ) )
1634  {
1635  self ‪vehicle_transmute( attacker );
1636  }
1637 }
1638 
1639 
1641 {
1642  self playSound( "car_explo_large" );
1643 }
1644 
1645 
1647 {
1648  self endon( "delete" );
1649  self endon( "removed" );
1650 
1651  for( ;; )
1652  {
1653  self waittill ( "damage", ‪damage, attacker );
1654 
1655  players = GetPlayers();
1656  for ( i = 0 ; i < players.size ; i++ )
1657  {
1658  if ( !isalive(players[i]) )
1659  continue;
1660 
1661  vehicle = players[i] GetVehicleOccupied();
1662  if ( isdefined( vehicle) && self == vehicle && players[i] ‪player_is_driver() )
1663  {
1664  if (‪damage>0)
1665  {
1666  // ^^^ earthquake() will generate an SRE if scale <= 0
1667  ‪earthquake( ‪damage/400, 1.0, players[i].origin, 512, players[i] );
1668  }
1669 
1670  if ( ‪damage > 100.0 )
1671  {
1672 /#
1673  println( "Playing heavy rumble." );
1674 #/
1675  players[i] PlayRumbleOnEntity( "tank_damage_heavy_mp" );
1676  }
1677  else if ( ‪damage > 10.0 )
1678  {
1679 /#
1680  println( "Playing light rumble." );
1681 #/
1682  players[i] PlayRumbleOnEntity( "tank_damage_light_mp" );
1683  }
1684  }
1685  }
1686 
1687  ‪update_damage_effects(self, attacker);
1688  if ( self.health <= 0 )
1689  {
1690  return;
1691  }
1692  }
1693 }
1694 
1695 
1696 // =====================================================================================
1697 // Burnt-Out Husk Code
1698 
1699 function ‪_spawn_husk( origin, angles, modelname )
1700 {
1701  husk = ‪spawn( "script_model", origin );
1702  husk.angles = angles;
1703  husk SetModel( modelname );
1704 
1705  husk.health = 1;
1706  husk SetCanDamage( false );
1707 
1708  return husk;
1709 }
1710 
1711 
1712 function ‪is_vehicle()
1713 {
1714  // Could check classname=="script_vehicle", but this is a little more general purpose, I think
1715  return isdefined( self.vehicletype );
1716 }
1717 
1718 
1720 {
1721  if ( isdefined( self.vehicletype ) )
1722  {
1723  husk_model = level.veh_husk_models[ self.vehicletype ];
1724 
1725  if ( isdefined( husk_model ) )
1726  {
1727  self SetModel( husk_model );
1728  }
1729  }
1730 }
1731 
1732 
1733 function ‪_init_husk( vehicle_name, respawn_parameters )
1734 {
1735  self ‪swap_to_husk_model();
1736 
1737  if ( isdefined( level.vehicles_husk_effects ) )
1738  {
1739  effects = level.vehicles_husk_effects[ vehicle_name ];
1740  self ‪play_vehicle_effects( effects );
1741  }
1742 
1743  self.respawn_parameters = respawn_parameters;
1744 
1745 
1746  forcePointVariance = GetDvarint( "scr_veh_explosion_husk_forcepointvariance" );
1747  horzVelocityVariance = GetDvarint( "scr_veh_explosion_husk_horzvelocityvariance" );
1748  vertVelocityMin = GetDvarint( "scr_veh_explosion_husk_vertvelocitymin" );
1749  vertVelocityMax = GetDvarint( "scr_veh_explosion_husk_vertvelocitymax" );
1750 
1751 
1752  forcePointX = RandomFloatRange( 0-forcePointVariance, forcePointVariance );
1753  forcePointY = RandomFloatRange( 0-forcePointVariance, forcePointVariance );
1754  forcePoint = ( forcePointX, forcePointY, 0 );
1755 
1756  forcePoint += self.origin;
1757 
1758  initialVelocityX = RandomFloatRange( 0-horzVelocityVariance, horzVelocityVariance );
1759  initialVelocityY = RandomFloatRange( 0-horzVelocityVariance, horzVelocityVariance );
1760  initialVelocityZ = RandomFloatRange( vertVelocityMin, vertVelocityMax );
1761  initialVelocity = ( initialVelocityX, initialVelocityY, initialVelocityZ );
1762 
1763 
1764  if ( self ‪is_vehicle() )
1765  {
1766  self LaunchVehicle( initialVelocity, forcePoint );
1767  }
1768  else
1769  {
1770  self PhysicsLaunch( forcePoint, initialVelocity );
1771  }
1772 
1773 
1774  self thread ‪husk_cleanup_t();
1775 }
1776 
1777 
1779 {
1780  self endon( "death" ); // ent Delete() actually sends the "death" message!!!
1781  self endon( "delete" );
1782  self endon( "hidden_permanently" );
1783 
1784 
1785  respawn_parameters = self.respawn_parameters;
1786 
1787 
1788  self ‪do_dead_cleanup_wait( "Husk Cleanup Test" );
1789 
1791 
1792 
1793  self thread ‪final_husk_cleanup_t( respawn_parameters ); // break off new thread to avoid end-ons
1794 }
1795 
1796 
1797 function ‪final_husk_cleanup_t( respawn_parameters )
1798 {
1799  self ‪husk_do_cleanup(); // causes endons, which is why we broke this off into a new thread
1800 
1801  if ( GetDvarint( "scr_veh_respawnafterhuskcleanup" ) != 0 )
1802  {
1803  if ( GetDvarint( "scr_veh_disablerespawn" ) == 0 ) //The Vehicle Mayhem gamemode handles spawning the vehicles, so it does not need to respawn here
1804  {
1805  ‪respawn_vehicle( respawn_parameters );
1806  }
1807  }
1808 }
1809 
1810 
1811 // Returns true only if the entity is actually deleted, rather than just hidden.
1813 {
1814  // Don't ever let vehicles just blink out. Spawn a VFX
1815  // explosion that doesn't injur any surrounding entities,
1816  // just to mask the blink out, in case players are
1817  // looking in the direction of this vehicle husk.
1818  self ‪_spawn_explosion( self.origin );
1819 
1820 
1821  if ( self ‪is_vehicle() )
1822  {
1823  return self ‪remove_vehicle_from_world();
1824  }
1825  else
1826  {
1827  self ‪_delete_entity();
1828  return true;
1829  }
1830 }
1831 
1832 // =====================================================================================
1833 
1834 
1835 // =====================================================================================
1836 // Explosion Code
1837 
1838 function ‪_spawn_explosion( origin )
1839 {
1840  if ( GetDvarint( "scr_veh_explosion_spawnfx" ) == 0 )
1841  {
1842  return;
1843  }
1844 
1845  if ( isdefined( level.vehicle_explosion_effect ) )
1846  {
1847  forward = ( 0, 0, 1 );
1848 
1849  rot = randomfloat( 360 );
1850  up = ( cos( rot ), sin( rot ), 0 );
1851 
1852  PlayFX( level.vehicle_explosion_effect, origin, forward, up );
1853  }
1854 
1855  thread ‪_play_sound_in_space( "vehicle_explo", origin );
1856 }
1857 
1858 
1859 // NOTE: This function was copied from sab.gsc. Should be centralized somewhere...
1860 function ‪_play_sound_in_space( soundEffectName, origin )
1861 {
1862  org = ‪Spawn( "script_origin", origin );
1863  org.origin = origin;
1864  org PlaySoundWithNotify( soundEffectName, "sounddone" );
1865  org waittill( "sounddone" );
1866  org delete();
1867 }
1868 
1869 // =====================================================================================
1870 
1872 {
1873  self notify( "kill_disconnect_paths_forever" );
1874 }
1875 
1877 {
1878 /* MPAI_PETER_TODO
1879  self endon( "death" );
1880  self endon( "kill_disconnect_paths_forever" );
1881  if ( isdefined( self.script_disconnectpaths ) && !self.script_disconnectpaths )
1882  {
1883  self.dontDisconnectPaths = true;// lets other parts of the script know not to disconnect script
1884  return;
1885  }
1886  wait( randomfloat( 1 ) );
1887  while( isdefined( self ) )
1888  {
1889  if( self getspeed() < 1 )
1890  {
1891  if ( !isdefined( self.dontDisconnectPaths ) )
1892  self disconnectpaths();
1893  self notify( "speed_zero_path_disconnect" );
1894  while( self getspeed() < 1 )
1895  wait .05;
1896  }
1897  self connectpaths();
1898  wait 1;
1899  }
1900  */
1901 }
1902 
1903 function ‪follow_path( node )
1904 {
1905  self endon("death");
1906 
1907  assert( isdefined( node ), "vehicle_path() called without a path" );
1908  self notify( "newpath" );
1909 
1910  // dynamicpaths unique. node isn't defined by info vehicle node calls to this function
1911  if( isdefined( node ) )
1912  {
1913  self.attachedpath = node;
1914  }
1915 
1916  pathstart = self.attachedpath;
1917  self.currentNode = self.attachedpath;
1918 
1919  if( !isdefined( pathstart ) )
1920  {
1921  return;
1922  }
1923 
1924  self AttachPath( pathstart );
1925  self StartPath();
1926 
1927  self endon( "newpath" );
1928 
1929  nextpoint = pathstart;
1930 
1931  while ( isdefined( nextpoint ) )
1932  {
1933  self waittill( "reached_node", nextpoint );
1934 
1935  self.currentNode = nextpoint;
1936 
1937  // the sweet stuff! Pathpoints handled in script as triggers!
1938  nextpoint notify( "trigger", self );
1939 
1940  if ( isdefined( nextpoint.script_noteworthy ) )
1941  {
1942  self notify( nextpoint.script_noteworthy );
1943  self notify( "noteworthy", nextpoint.script_noteworthy, nextpoint );
1944  }
1945 
1946  waittillframeend;
1947  }
1948 }
1949 
1951 {
1952  thread ‪VehicleMainThread();
1953 }
1954 
1956 {
1957  if ( level.disableVehicleSpawners === true )
1958  return;
1959 
1960  //"siegebot";
1961  //"siegebot_boss";
1962  //"quadtank";
1963  //"mechtank";
1964 
1965  //spawn_nodes = getentarray( "veh_spawn_point", "targetname" );
1966  spawn_nodes = ‪struct::get_array( "veh_spawn_point", "targetname" );
1967 
1968  veh_spawner_id = 0; // a unique identifier for gameplay driven fx
1969  for( i = 0; i < spawn_nodes.size; i++ )
1970  {
1971  spawn_node = spawn_nodes[i];
1972 
1973  veh_name = spawn_node.script_noteworthy;
1974  time_interval = int(spawn_node.script_parameters);
1975 
1976  if( !isdefined( veh_name ) )
1977  continue;
1978 
1979  veh_spawner_id++;
1980  thread ‪VehicleSpawnThread( veh_spawner_id, veh_name, spawn_node.origin, spawn_node.angles, time_interval );
1981 
1982  if ( isdefined( level.vehicle_spawner_init ) )
1983  level [[ level.vehicle_spawner_init ]] ( veh_spawner_id, veh_name, spawn_node.origin, spawn_node.angles );
1984 
1986  }
1987 
1988  if ( isdefined( level.vehicle_spawners_init_finished ) )
1989  level thread [[ level.vehicle_spawners_init_finished ]]();
1990 }
1991 
1992 function ‪VehicleSpawnThread( veh_spawner_id, veh_name, origin, angles, time_interval )
1993 {
1994  level endon( "game_ended" );
1995 
1996  veh_spawner = GetEnt( veh_name + "_spawner", "targetname" );
1997  ‪kill_trigger = ‪spawn( "trigger_radius", origin, 0, 60, 180 );
1998 
1999  while( 1 )
2000  {
2001  vehicle = veh_spawner SpawnFromSpawner( veh_name, true, true, true );
2002  if( !isdefined( vehicle ) )
2003  {
2004  wait RandomFloatRange( 1.0, 2.0 );
2005  continue;
2006  }
2007 
2008  if( isdefined( vehicle.archetype ) )
2009  vehicle ASMRequestSubstate( "locomotion@movement" );
2010 
2012 
2013  vehicle.origin = origin;
2014  vehicle.angles = angles;
2015  vehicle.veh_spawner_id = veh_spawner_id;
2016 
2017 
2018  vehicle thread ‪VehicleTeamThread();
2019 
2020  vehicle waittill( "death" );
2021  vehicle ‪vehicle_death::DeleteWhenSafe( 0.25 );
2022 
2023  if ( isdefined( level.vehicle_destroyed ) )
2024  level thread [[ level.vehicle_destroyed ]]( veh_spawner_id );
2025 
2026 
2027  if( isdefined( time_interval ) )
2028  {
2029  level thread ‪PerformVehiclePreSpawn( veh_spawner_id, veh_name, origin, angles, time_interval, ‪kill_trigger );
2030  wait time_interval;
2031  }
2032  }
2033 }
2034 
2035 function ‪PerformVehiclePreSpawn( veh_spawner_id, veh_name, origin, angles, spawn_delay, ‪kill_trigger )
2036 {
2037  fx_prespawn_time = 5.0;
2038  fx_spawn_delay = spawn_delay - fx_prespawn_time;
2039 
2040  wait fx_spawn_delay;
2041 
2042  if ( isdefined( level.vehicle_about_to_spawn ) )
2043  {
2044  level thread [[ level.vehicle_about_to_spawn ]]( veh_spawner_id, veh_name, origin, angles, fx_prespawn_time );
2045  }
2046 
2047  kill_overlap_time = 0.1;
2048 
2049  wait_before_kill = fx_prespawn_time - kill_overlap_time;
2050  wait wait_before_kill;
2051 
2052  kill_duration_ms = kill_overlap_time * 2 * 1000;
2053  level thread ‪kill_any_touching( ‪kill_trigger, kill_duration_ms );
2054 
2055  wait kill_overlap_time;
2056 }
2057 
2058 function ‪kill_any_touching( ‪kill_trigger, kill_duration_ms )
2059 {
2060  kill_expire_time_ms = GetTime() + kill_duration_ms;
2061 
2062  kill_weapon = GetWeapon( "hero_minigun" ); // we like this for the gib settings
2063 
2064  while ( GetTime() <= kill_expire_time_ms )
2065  {
2066  foreach( player in level.players )
2067  {
2068  if ( !isdefined( player ) )
2069  continue;
2070 
2071  if ( player IsTouching( ‪kill_trigger ) )
2072  {
2073  if ( player IsInVehicle() )
2074  {
2075  vehicle = player GetVehicleOccupied();
2076  if ( isdefined( vehicle ) && ( vehicle.is_oob_kill_target === true ) ) // intentionally piggy-backed on is_oob_kill_target
2077  {
2078  ‪destroy_vehicle( vehicle );
2079  continue;
2080  }
2081  }
2082  player DoDamage( player.health + 1, player.origin, ‪kill_trigger, ‪kill_trigger, "none", "MOD_SUICIDE", 0, kill_weapon );
2083  }
2084  }
2085 
2086  potential_victims = GetAIArray();
2087 
2088  if ( isdefined( potential_victims ) )
2089  {
2090  foreach( entity in potential_victims )
2091  {
2092  if ( !isdefined( entity ) )
2093  continue;
2094 
2095  if ( !entity IsTouching( ‪kill_trigger ) )
2096  continue;
2097 
2098  if ( isdefined( entity.health ) && entity.health <= 0 )
2099  continue;
2100 
2101  if ( IsVehicle( entity ) )
2102  ‪destroy_vehicle( entity );
2103  }
2104  }
2105 
2107  }
2108 }
2109 
2110 function ‪destroy_vehicle( vehicle )
2111 {
2112  // need to do this to destroy vehicles
2113 
2114  vehicle DoDamage( vehicle.health + 10000, vehicle.origin, undefined, undefined, "none", "MOD_TRIGGER_HURT" ); // must be MOD_TRIGGER_HURT
2115 }
2116 
2117 
2118 
2120 {
2121  vehicle = self;
2122  vehicle endon( "death" );
2123 
2124  vehicle MakeVehicleUsable();
2125  if( Target_isTarget( vehicle ) )
2126  Target_Remove( vehicle );
2127 
2128  vehicle.noJumping = true;
2129  vehicle.forceDamageFeedback = true;
2130  vehicle.vehkilloccupantsondeath = true;
2131  vehicle DisableAimAssist();
2132 
2133  while( 1 )
2134  {
2135  vehicle setteam( "neutral" );
2136  vehicle.ignoreme = true;
2137  //vehicle SetHighDetail( false );
2138  vehicle ‪clientfield::set( "toggle_lights", ‪CF_TOGGLE_LIGHTS_OFF );
2139  if( Target_isTarget( vehicle ) )
2140  Target_Remove( vehicle );
2141 
2142 
2143  vehicle waittill( "enter_vehicle", player );
2144  player ‪ClearAndCachePerks();
2145  vehicle setteam( player.team );
2146  vehicle.ignoreme = false;
2147  //vehicle SetHighDetail( true );
2148  vehicle ‪clientfield::set( "toggle_lights", ‪CF_TOGGLE_LIGHTS_ON );
2149  vehicle ‪spawning::create_entity_enemy_influencer( "small_vehicle", player.team );
2150  player ‪spawning::enable_influencers( false );
2151  if( !Target_isTarget( vehicle ) )
2152  {
2153  if( isdefined( vehicle.targetOffset ) )
2154  Target_Set( vehicle, vehicle.targetOffset );
2155  else
2156  Target_Set( vehicle, ( 0, 0, 0 ) );
2157  }
2158 
2159  vehicle thread ‪WatchPlayerExitRequestThread( player );
2160 
2161  vehicle waittill( "exit_vehicle", player );
2162 
2163  if( isdefined( player ) )
2164  {
2165  player ‪SetCachedPerks();
2166  player ‪spawning::enable_influencers( true );
2167  }
2168 
2170  }
2171 }
2172 
2174 {
2175  level endon( "game_ended" );
2176  player endon ( "death" );
2177  player endon( "disconnect" );
2178 
2179  vehicle = self;
2180 
2181  vehicle endon( "death" );
2182 
2183  wait 1.5;
2184 
2185  while( true )
2186  {
2187  timeUsed = 0;
2188  while( player UseButtonPressed() )
2189  {
2190  timeUsed += 0.05;
2191  if( timeUsed > 0.25 )
2192  {
2193  player unlink();
2194  return;
2195  }
2197  }
2199  }
2200 }
2201 
2202 // We will cache of the perks on the player. If the player dies, cache is lost but respawned
2204 {
2205  self.perks_before_vehicle = self GetPerks();
2206  self ClearPerks();
2207 }
2208 
2210 {
2211  assert( IsDefined( self.perks_before_vehicle ) );
2212  foreach( perk in self.perks_before_vehicle )
2213  {
2214  self SetPerk( perk );
2215  }
2216 }
2217 
2218 
2219 
‪InitVehicleMap
‪function InitVehicleMap()
Definition: _vehicle.gsc:1950
‪enable_influencers
‪function enable_influencers(enabled)
Definition: _spawning.gsc:449
‪get_default_vehicle_name
‪function get_default_vehicle_name()
Definition: _vehicle.gsc:290
‪vehicle_transmute
‪function vehicle_transmute(attacker)
Definition: _vehicle.gsc:1331
‪vehicle_recycle
‪function vehicle_recycle()
Definition: _vehicle.gsc:1228
‪vehicle_overturn_eject_occupants
‪function vehicle_overturn_eject_occupants()
Definition: _vehicle.gsc:1260
‪cleanup
‪function cleanup(test_name, cleanup_dvar_name, cleanup_func)
Definition: _vehicle.gsc:948
‪vehicle_play_explosion_sound
‪function vehicle_play_explosion_sound()
Definition: _vehicle.gsc:1640
‪register_vehicle
‪function register_vehicle()
Definition: _vehicle.gsc:444
‪createBar
‪function createBar(color, width, height, flashFrac)
Definition: hud_util_shared.gsc:529
‪wait_for_unnoticeable_cleanup_opportunity
‪function wait_for_unnoticeable_cleanup_opportunity()
Definition: _vehicle.gsc:1516
‪manage_vehicles
‪function manage_vehicles()
Definition: _vehicle.gsc:461
‪get_all_alive_players_s
‪function get_all_alive_players_s()
Definition: util_shared.gsc:2865
‪vehicle_abandoned_by_occupants_timeout_t
‪function vehicle_abandoned_by_occupants_timeout_t()
Definition: _vehicle.gsc:821
‪vehicle_should_explode_on_cleanup
‪function vehicle_should_explode_on_cleanup()
Definition: _vehicle.gsc:1222
‪player_is_occupant_invulnerable
‪function player_is_occupant_invulnerable(sMeansOfDeath)
Definition: _vehicle.gsc:1100
‪_play_sound_in_space
‪function _play_sound_in_space(soundEffectName, origin)
Definition: _vehicle.gsc:1860
‪vehicle_damage_t
‪function vehicle_damage_t()
Definition: _vehicle.gsc:1646
‪vehicle_wait_player_enter_t
‪function vehicle_wait_player_enter_t()
Definition: _vehicle.gsc:592
‪do_alive_cleanup_wait
‪function do_alive_cleanup_wait(test_name)
Definition: _vehicle.gsc:875
‪wait_for_vehicle_overturn
‪function wait_for_vehicle_overturn()
Definition: _vehicle.gsc:1235
‪init_original_vehicle
‪function init_original_vehicle()
Definition: _vehicle.gsc:581
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪setPoint
‪function setPoint(point, relativePoint, xOffset, yOffset, moveTime)
Definition: hud_util_shared.gsc:53
‪rumble
‪function rumble()
Definition: exploder_shared.gsc:862
‪QRDrone_force_destroy
‪function QRDrone_force_destroy()
Definition: _qrdrone.gsc:755
‪destroy_vehicle
‪function destroy_vehicle(vehicle)
Definition: _vehicle.gsc:2110
‪DeleteWhenSafe
‪function DeleteWhenSafe(time=4)
Definition: vehicle_death_shared.gsc:1761
‪destroyElem
‪function destroyElem()
Definition: hud_util_shared.gsc:755
‪init_vehicle_threads
‪function init_vehicle_threads()
Definition: _vehicle.gsc:693
‪_init_husk
‪function _init_husk(vehicle_name, respawn_parameters)
Definition: _vehicle.gsc:1733
‪water_killbrush_think
‪function water_killbrush_think()
Definition: _vehicle.gsc:132
‪vehicle_telefrag_griefers_at_position
‪function vehicle_telefrag_griefers_at_position(position)
Definition: _vehicle.gsc:1597
‪play_vehicle_effects
‪function play_vehicle_effects(effects, isDamagedTread)
Definition: _vehicle.gsc:390
‪vehicle_record_initial_values
‪function vehicle_record_initial_values()
Definition: _vehicle.gsc:1194
‪get_vehicle_name_key_for_damage_states
‪function get_vehicle_name_key_for_damage_states(vehicle)
Definition: _vehicle.gsc:296
‪respawn_vehicle
‪function respawn_vehicle(respawn_parameters)
Definition: _vehicle.gsc:1418
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪setParent
‪function setParent(element)
Definition: hud_util_shared.gsc:10
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪player_change_seat_handler_t
‪function player_change_seat_handler_t(vehicle)
Definition: _vehicle.gsc:1140
‪player_wait_exit_vehicle_t
‪function player_wait_exit_vehicle_t()
Definition: _vehicle.gsc:609
‪initialize_vehicle_damage_effects_for_level
‪function initialize_vehicle_damage_effects_for_level()
Definition: _vehicle.gsc:160
‪vehicle_overturn_suicide
‪function vehicle_overturn_suicide()
Definition: _vehicle.gsc:1294
‪WatchPlayerExitRequestThread
‪function WatchPlayerExitRequestThread(player)
Definition: _vehicle.gsc:2173
‪vehicle_wait_tread_damage
‪function vehicle_wait_tread_damage()
Definition: _vehicle.gsc:967
‪player_update_vehicle_hud
‪function player_update_vehicle_hud(show, vehicle)
Definition: _vehicle.gsc:642
‪play_start_stop_sound
‪function play_start_stop_sound(sound_alias, modulation)
Definition: _vehicle.gsc:1044
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪__init__
‪function __init__()
Definition: _vehicle.gsc:21
‪wait_then_cleanup_vehicle
‪function wait_then_cleanup_vehicle(test_name, cleanup_dvar_name)
Definition: _vehicle.gsc:831
‪suicide
‪function suicide()
Definition: _vehicle.gsc:1309
‪remove_vehicle_from_world
‪function remove_vehicle_from_world()
Definition: _vehicle.gsc:1468
‪SetCachedPerks
‪function SetCachedPerks()
Definition: _vehicle.gsc:2209
‪player_vehicle_position_will_telefrag
‪function player_vehicle_position_will_telefrag(position)
Definition: _vehicle.gsc:1616
‪createFontString
‪function createFontString(font, fontScale)
Definition: hud_util_shared.gsc:334
‪updateBar
‪function updateBar(barFrac, rateOfChange)
Definition: hud_util_shared.gsc:294
‪vehicle_abandoned_by_occupants_t
‪function vehicle_abandoned_by_occupants_t()
Definition: _vehicle.gsc:1023
‪husk_do_cleanup
‪function husk_do_cleanup()
Definition: _vehicle.gsc:1812
‪create_entity_enemy_influencer
‪function create_entity_enemy_influencer(name, team)
Definition: _spawning.gsc:310
‪vehicle_eject_all_occupants
‪function vehicle_eject_all_occupants()
Definition: _vehicle.gsc:1279
‪value_with_default
‪function value_with_default(preferred_value, default_value)
Definition: _vehicle.gsc:1320
‪CF_TOGGLE_LIGHTS_OFF
‪#define CF_TOGGLE_LIGHTS_OFF
Definition: shared.gsh:520
‪_delete_entity
‪function _delete_entity()
Definition: _vehicle.gsc:1494
‪vehicle_disconnect_paths
‪function vehicle_disconnect_paths()
Definition: _vehicle.gsc:1876
‪_spawn_husk
‪function _spawn_husk(origin, angles, modelname)
Definition: _vehicle.gsc:1699
‪VehicleSpawnThread
‪function VehicleSpawnThread(veh_spawner_id, veh_name, origin, angles, time_interval)
Definition: _vehicle.gsc:1992
‪get_vehicle_name
‪function get_vehicle_name(vehicle)
Definition: _vehicle.gsc:273
‪remove_influencers
‪function remove_influencers()
Definition: _spawning.gsc:405
‪CF_TOGGLE_LIGHTS_ON
‪#define CF_TOGGLE_LIGHTS_ON
Definition: shared.gsh:519
‪get_random_cleanup_wait_time
‪function get_random_cleanup_wait_time(state)
Definition: _vehicle.gsc:858
‪create_entity_masked_enemy_influencer
‪function create_entity_masked_enemy_influencer(name, team_mask)
Definition: _spawning.gsc:324
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪play_damage_state_effects
‪function play_damage_state_effects(vehicle, start_damage_state_index, end_damage_state_index)
Definition: _vehicle.gsc:367
‪vehicle_abandoned_by_drift_t
‪function vehicle_abandoned_by_drift_t()
Definition: _vehicle.gsc:811
‪husk_cleanup_t
‪function husk_cleanup_t()
Definition: _vehicle.gsc:1778
‪earthquake
‪function earthquake()
Definition: exploder_shared.gsc:850
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪_spawn_explosion
‪function _spawn_explosion(origin)
Definition: _vehicle.gsc:1838
‪kill_any_touching
‪function kill_any_touching(kill_trigger, kill_duration_ms)
Definition: _vehicle.gsc:2058
‪vehicle_ghost_entering_occupants_t
‪function vehicle_ghost_entering_occupants_t()
Definition: _vehicle.gsc:1057
‪build_exhaust
‪function build_exhaust(effect)
Definition: _vehicle.gsc:802
‪vehicle_kill_disconnect_paths_forever
‪function vehicle_kill_disconnect_paths_forever()
Definition: _vehicle.gsc:1871
‪build_quake
‪function build_quake(scale, duration, radius, basetime, randomaditionaltime)
Definition: _vehicle.gsc:778
‪update_damage_effects
‪function update_damage_effects(vehicle, attacker)
Definition: _vehicle.gsc:336
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪PerformVehiclePreSpawn
‪function PerformVehiclePreSpawn(veh_spawner_id, veh_name, origin, angles, spawn_delay, kill_trigger)
Definition: _vehicle.gsc:2035
‪wait_for_vehicle_to_stop_outside_min_radius
‪function wait_for_vehicle_to_stop_outside_min_radius()
Definition: _vehicle.gsc:994
‪player_is_driver
‪function player_is_driver()
Definition: _vehicle.gsc:1114
‪vehicle_position_will_telefrag
‪function vehicle_position_will_telefrag(position)
Definition: _vehicle.gsc:1581
‪ClearAndCachePerks
‪function ClearAndCachePerks()
Definition: _vehicle.gsc:2203
‪final_husk_cleanup_t
‪function final_husk_cleanup_t(respawn_parameters)
Definition: _vehicle.gsc:1797
‪is_vehicle
‪function is_vehicle()
Definition: _vehicle.gsc:1712
‪init_vehicle
‪function init_vehicle()
Definition: _vehicle.gsc:534
‪kill_vehicle
‪function kill_vehicle(attacker)
Definition: _vehicle.gsc:1314
‪vehicle_wait_damage_t
‪function vehicle_wait_damage_t()
Definition: _vehicle.gsc:620
‪wait_until_vehicle_position_wont_telefrag
‪function wait_until_vehicle_position_wont_telefrag(position)
Definition: _vehicle.gsc:1564
‪swap_to_husk_model
‪function swap_to_husk_model()
Definition: _vehicle.gsc:1719
‪VehicleTeamThread
‪function VehicleTeamThread()
Definition: _vehicle.gsc:2119
‪build_template
‪function build_template(type, model, typeoverride)
Definition: _vehicle.gsc:733
‪precache_vehicles
‪function precache_vehicles()
Definition: _vehicle.gsc:438
‪follow_path
‪function follow_path(node)
Definition: _vehicle.gsc:1903
‪do_dead_cleanup_wait
‪function do_dead_cleanup_wait(test_name)
Definition: _vehicle.gsc:933
‪name
‪class GroundFx name
‪vehicle_recycle_spawner_t
‪function vehicle_recycle_spawner_t()
Definition: _vehicle.gsc:1627
‪vehicle_is_tank
‪function vehicle_is_tank()
Definition: _vehicle.gsc:1183
‪build_rumble
‪function build_rumble(rumble, scale, duration, radius, basetime, randomaditionaltime)
Definition: _vehicle.gsc:768
‪initialize_vehicle_damage_state_data
‪function initialize_vehicle_damage_state_data()
Definition: _vehicle.gsc:565
‪hide_vehicle
‪function hide_vehicle()
Definition: _vehicle.gsc:1504
‪VehicleMainThread
‪function VehicleMainThread()
Definition: _vehicle.gsc:1955
‪kill_trigger
‪function kill_trigger(trigger)
Definition: spawner_shared.gsc:345
‪get_vehicle_damage_state_index_from_health_percentage
‪function get_vehicle_damage_state_index_from_health_percentage(vehicle)
Definition: _vehicle.gsc:310
‪wait_until_severely_damaged
‪function wait_until_severely_damaged()
Definition: _vehicle.gsc:842
‪player_leave_vehicle_cleanup_t
‪function player_leave_vehicle_cleanup_t(vehicle)
Definition: _vehicle.gsc:1168
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪init_vehicle_entities
‪function init_vehicle_entities()
Definition: _vehicle.gsc:424