‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
vehicle_shared.csc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\clientfield_shared;
4 #using scripts\shared\filter_shared;
5 #using scripts\shared\math_shared;
6 #using scripts\shared\system_shared;
7 #using scripts\shared\util_shared;
8 #using scripts\shared\postfx_shared;
9 #using scripts\shared\vehicleriders_shared;
10 
11 #insert scripts\shared\shared.gsh;
12 #insert scripts\shared\version.gsh;
13 
14 #namespace vehicle;
15 
16 ‪REGISTER_SYSTEM( "vehicle_shared", &‪__init__, undefined )
17 
18 function ‪__init__()
19 {
20  level._customVehicleCBFunc = &‪spawned_callback;
21 
44 
67 
69 
71 
73 
75 }
76 
77 function ‪add_vehicletype_callback( vehicletype, ‪callback )
78 {
79  if ( !isdefined( level.vehicleTypeCallbackArray ) )
80  {
81  level.vehicleTypeCallbackArray = [];
82  }
83 
84  level.vehicleTypeCallbackArray[vehicletype] = ‪callback;
85 }
86 
87 function ‪spawned_callback( localClientNum )
88 {
89  if ( isdefined( self.vehicleridersbundle ) )
90  {
91  ‪set_vehicleriders_bundle( self.vehicleridersbundle );
92  }
93 
94  vehicletype = self.vehicletype;
95  if( isdefined( level.vehicleTypeCallbackArray ) )
96  {
97  if ( isdefined( vehicletype ) && isdefined( level.vehicleTypeCallbackArray[vehicletype] ) )
98  {
99  self thread [[level.vehicleTypeCallbackArray[vehicletype]]]( localClientNum );
100  }
101  else if( isdefined( self.scriptvehicletype ) && isdefined( level.vehicleTypeCallbackArray[self.scriptvehicletype] ) )
102  {
103  self thread [[level.vehicleTypeCallbackArray[self.scriptvehicletype]]]( localClientNum );
104  }
105  }
106 }
107 
108 function ‪rumble( localClientNum )
109 {
110  self endon( "entityshutdown" );
111 
112  if( !isdefined( self.rumbletype ) || ( self.rumbleradius == 0 ) )
113  {
114  return;
115  }
116 
117  // Init undefined variables
118  if( !isdefined( self.rumbleon ) )
119  {
120  self.rumbleon = true;
121  }
122 
123  height = self.rumbleradius * 2;
124  zoffset = -1 * self.rumbleradius;
125 
126  self.player_touching = 0;
127 
128  // This is threaded on each vehicle, per local client - so we only need to be concerned with checking on
129  // client that we've been threaded on.
130 
131  radius_squared = self.rumbleradius * self.rumbleradius;
132 
133  wait 2; // hack to let the getloaclplayers return a valid local player
134 
135  while( 1 )
136  {
137  if( !isdefined( level.localPlayers[localClientNum] ) || ( distancesquared( self.origin, level.localPlayers[localClientNum].origin ) > radius_squared ) || self getspeed() == 0 )
138  {
139  wait( 0.2 );
140  continue;
141  }
142 
143  if( isdefined( self.rumbleon ) && !self.rumbleon )
144  {
145  wait( 0.2 );
146  continue;
147  }
148 
149  self PlayRumbleLoopOnEntity( localClientNum, self.rumbletype );
150 
151  while( isdefined( level.localPlayers[localClientNum] ) && ( distancesquared( self.origin, level.localPlayers[localClientNum].origin ) < radius_squared ) && ( self getspeed() > 0 ) )
152  {
153  self ‪earthquake( self.rumblescale, self.rumbleduration, self.origin, self.rumbleradius ); // scale duration source radius
154  time_to_wait = self.rumblebasetime + randomfloat( self.rumbleadditionaltime );
155  if( time_to_wait <= 0 )
156  {
157  time_to_wait = 0.05;
158  }
159  wait( time_to_wait );
160  }
161 
162  if ( isdefined( level.localPlayers[localClientNum] ) )
163  {
164  self StopRumble( localClientNum, self.rumbletype );
165  }
166 
167  wait 0.05;
168  }
169 }
170 
172 {
173  //PrintLn("****CLIENT:: killing the tread_fx");
174  self notify( "kill_treads_forever" );
175 }
176 
177 function ‪play_exhaust( localClientNum )
178 {
179  if( isdefined(self.csf_no_exhaust) && self.csf_no_exhaust )
180  {
181  return;
182  }
183 
184  if( !isdefined( self.exhaust_fx ) && isdefined( self.exhaustfxname ) )
185  {
186  if( !isdefined( level._effect ) )
187  {
188  level._effect = [];
189  }
190 
191  if ( !isdefined( level._effect[self.exhaustfxname] ) )
192  {
193  level._effect[self.exhaustfxname] = self.exhaustfxname;
194  }
195  self.exhaust_fx = level._effect[self.exhaustfxname];
196  }
197 
198  if( isdefined( self.exhaust_fx ) && isdefined( self.exhaustFxTag1 ) )
199  {
200  if( isalive(self) )
201  {
202  Assert( isdefined( self.exhaustFxTag1 ), self.vehicletype + " vehicle exhaust effect is set, but tag 1 is undefined. Please update the vehicle gdt entry" );
203 
204  self endon( "entityshutdown" );
205 
206  self ‪wait_for_DObj( localClientNum );
207  self.exhaust_id_left = PlayFXOnTag( localClientNum, self.exhaust_fx, self, self.exhaustFxTag1 );
208 
209  if( !isdefined( self.exhaust_id_right ) && IsDefined( self.exhaustFxTag2 ) )
210  {
211  self.exhaust_id_right = PlayFXOnTag( localClientNum, self.exhaust_fx, self, self.exhaustFxTag2 );
212  }
213 
214  self thread ‪kill_exhaust_watcher( localClientNum );
215  }
216  }
217 }
218 
219 function ‪kill_exhaust_watcher( localClientNum )
220 {
221  self waittill( "stop_exhaust_fx" );
222 
223  if ( isdefined( self.exhaust_id_left ) )
224  {
225  StopFX( localClientNum, self.exhaust_id_left );
226  self.exhaust_id_left = undefined;
227  }
228 
229  if ( isdefined( self.exhaust_id_right ) )
230  {
231  StopFX( localClientNum, self.exhaust_id_right );
232  self.exhaust_id_right = undefined;
233  }
234 }
235 
236 function ‪stop_exhaust( localClientNum )
237 {
238  self notify( "stop_exhaust_fx" );
239 }
240 
242 {
243  waittillframeend;
244 
245  self endon( "kill_treads_forever" );
246  self endon( "entityshutdown" );
247 
248  if(!IsDefined(self))
249  {
250  return;
251  }
252 
253  if( isdefined(self.csf_no_tread) && self.csf_no_tread ) //-- set by clientside flag
254  {
255  return;
256  }
257 
258  const maxHeight = 1200;
259  const minHeight = 350;
260 
261  const slowestRepeatWait = 0.2;
262  const fastestRepeatWait = 0.1;
263 
264  if( ‪IS_MIG( self ) ) //-- GLOCKE: added in just for jets for Flash Point
265  {
266  numFramesPerTrace = 1;
267  }
268  else
269  {
270  numFramesPerTrace = 3;
271  }
272  doTraceThisFrame = numFramesPerTrace;
273 
274  const defaultRepeatRate = 1.0;
275  repeatRate = defaultRepeatRate;
276 
277  ‪trace = undefined;
278  d = undefined;
279 
280  trace_ent = self;
281 
282  while( isdefined( self ) )
283  {
284 
285  if( repeatRate <= 0 )
286  {
287  repeatRate = defaultRepeatRate;
288  }
289 
290  if( ‪IS_MIG( self ) ) //-- GLOCKE: added in just for jets for Flash Point
291  {
292  repeatRate = 0.02;
293  }
294 
295  waitrealtime( repeatRate );
296 
297  if( !isdefined( self ) )
298  {
299  return;
300  }
301 
302  doTraceThisFrame-- ;
303 
304  if( doTraceThisFrame <= 0 )
305  {
306  doTraceThisFrame = numFramesPerTrace;
307 
308  ‪trace = tracepoint( trace_ent.origin, trace_ent.origin -( 0, 0, 100000 ) );
309 
310  d = distance( trace_ent.origin, ‪trace["position"] );
311 
312  if( d > minHeight )
313  {
314  repeatRate = ( ( d - minHeight ) / ( maxHeight - minHeight ) ) * ( slowestRepeatWait - fastestRepeatWait ) + fastestRepeatWait;
315  }
316  else
317  {
318  repeatRate = fastestRepeatWait;
319  }
320  }
321 
322  if( isdefined( ‪trace ) )
323  {
324  if( d > maxHeight )
325  {
326  repeatRate = defaultRepeatRate;
327  continue;
328  }
329 
330  if( !isdefined( ‪trace["surfacetype"] ) )
331  {
332  ‪trace["surfacetype"] = "dirt";
333  }
334 
335  }
336 
337 
338  }
339 }
340 
341 function ‪weapon_fired()
342 {
343  self endon( "entityshutdown" );
344 
345  const shock_distance = 400 * 400;
346  const rumble_distance = 500 * 500;
347  while( true )
348  {
349  self waittill( "weapon_fired" );
350 //println( "<<<<<< CSC VEHICLE_WEAPON_FIRED START" );
351 
352  players = level.localPlayers;
353  for( i = 0; i < players.size; i++ )
354  {
355  player_distance = DistanceSquared( self.origin, players[i].origin );
356 //println( "<<<<<< CSC VEHICLE_WEAPON_FIRED PLAYER DISTANCE = " + player_distance );
357 
358  // RUMBLE ------------
359  if( player_distance < rumble_distance )
360  {
361  if( isdefined(self.shootrumble) && self.shootrumble != "" )
362  {
363 //println( "<<<<<< CSC VEHICLE_WEAPON_FIRED RUMBLE " + self.shootrumble );
364  PlayRumbleOnPosition( i, self.shootrumble, self.origin + ( 0, 0, 32 ) );
365  }
366  }
367 
368  // SHOCK -------------
369  if( player_distance < shock_distance )
370  {
371  fraction = player_distance / shock_distance;
372  time = 4 - ( 3 * fraction );
373 
374  if( isdefined( players[i] ) )
375  {
376  if( isdefined(self.shootshock) && self.shootshock != "" )
377  {
378 //println( "<<<<<< CSC VEHICLE_WEAPON_FIRED SHELLSHOCK " + self.shootshock );
379  players[i] ShellShock( i, self.shootshock, time );
380  }
381  }
382  }
383  }
384  }
385 }
386 
387 function ‪wait_for_DObj( localClientNum )
388 {
389  count = 30;
390  while( !self HasDObj( localClientNum ) )
391  {
392  if( count < 0 )
393  {
394  /#
395  IPrintLnBold( "WARNING: Failing to turn on fx lights for vehicle because no DOBJ!" );
396  #/
397  return;
398  }
400  count -= 1;
401  }
402 }
403 
404 function ‪lights_on( localClientNum, team )
405 {
406  self endon( "entityshutdown" );
407 
408  ‪lights_off( localClientNum ); // make sure we kill all of the old fx
409 
410  ‪wait_for_DObj( localClientNum );
411 
412  if( isdefined( self.lightfxnamearray ) )
413  {
414  if( !isdefined( self.light_fx_handles ) )
415  {
416  self.light_fx_handles = [];
417  }
418 
419  for( i = 0; i < self.lightfxnamearray.size; i++ )
420  {
421  self.light_fx_handles[ i ] = PlayFXOnTag( localClientNum, self.lightfxnamearray[i], self, self.lightfxtagarray[i] );
422  SetFXIgnorePause( localClientNum, self.light_fx_handles[ i ], true );
423  if( IsDefined( team ) )
424  {
425  SetFXTeam( localClientNum, self.light_fx_handles[ i ], team );
426  }
427  }
428  }
429 }
430 
431 function ‪addAnimToList( animItem, &listOn, &listOff, playWhenOff, id, maxID )
432 {
433  if ( isdefined( animItem ) && id <= maxID )
434  {
435  if ( playWhenOff === true )
436  {
437  ‪ARRAY_ADD( listOff, animItem );
438  }
439  else
440  {
441  ‪ARRAY_ADD( listOn, animItem );
442  }
443  }
444 }
445 
446 function ‪ambient_anim_toggle( localClientNum, groupID, isOn )
447 {
448  self endon( "entityshutdown" );
449 
450  if( !isdefined( self.scriptbundlesettings ) )
451  {
452  return;
453  }
454 
455  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
456 
457  if ( !isdefined( settings ) )
458  {
459  return;
460  }
461 
462  ‪wait_for_DObj( localClientNum );
463 
464  listOn = [];
465  listOff = [];
466 
467  switch ( groupID )
468  {
469  case 1:
470  ‪addAnimToList( settings.ambient_group1_anim1, listOn, listOff, settings.ambient_group1_off1, 1, settings.ambient_group1_numslots );
471  ‪addAnimToList( settings.ambient_group1_anim2, listOn, listOff, settings.ambient_group1_off2, 2, settings.ambient_group1_numslots );
472  ‪addAnimToList( settings.ambient_group1_anim3, listOn, listOff, settings.ambient_group1_off3, 3, settings.ambient_group1_numslots );
473  ‪addAnimToList( settings.ambient_group1_anim4, listOn, listOff, settings.ambient_group1_off4, 4, settings.ambient_group1_numslots );
474  break;
475  case 2:
476  ‪addAnimToList( settings.ambient_group2_anim1, listOn, listOff, settings.ambient_group2_off1, 1, settings.ambient_group2_numslots );
477  ‪addAnimToList( settings.ambient_group2_anim2, listOn, listOff, settings.ambient_group2_off2, 2, settings.ambient_group2_numslots );
478  ‪addAnimToList( settings.ambient_group2_anim3, listOn, listOff, settings.ambient_group2_off3, 3, settings.ambient_group2_numslots );
479  ‪addAnimToList( settings.ambient_group2_anim4, listOn, listOff, settings.ambient_group2_off4, 4, settings.ambient_group2_numslots );
480  break;
481  case 3:
482  ‪addAnimToList( settings.ambient_group3_anim1, listOn, listOff, settings.ambient_group3_off1, 1, settings.ambient_group3_numslots );
483  ‪addAnimToList( settings.ambient_group3_anim2, listOn, listOff, settings.ambient_group3_off2, 2, settings.ambient_group3_numslots );
484  ‪addAnimToList( settings.ambient_group3_anim3, listOn, listOff, settings.ambient_group3_off3, 3, settings.ambient_group3_numslots );
485  ‪addAnimToList( settings.ambient_group3_anim4, listOn, listOff, settings.ambient_group3_off4, 4, settings.ambient_group3_numslots );
486  break;
487  case 4:
488  ‪addAnimToList( settings.ambient_group4_anim1, listOn, listOff, settings.ambient_group4_off1, 1, settings.ambient_group4_numslots );
489  ‪addAnimToList( settings.ambient_group4_anim2, listOn, listOff, settings.ambient_group4_off2, 2, settings.ambient_group4_numslots );
490  ‪addAnimToList( settings.ambient_group4_anim3, listOn, listOff, settings.ambient_group4_off3, 3, settings.ambient_group4_numslots );
491  ‪addAnimToList( settings.ambient_group4_anim4, listOn, listOff, settings.ambient_group4_off4, 4, settings.ambient_group4_numslots );
492  break;
493  }
494 
495  if ( isOn )
496  {
497  weightOn = 1.0;
498  weightOff = 0.0;
499  }
500  else
501  {
502  weightOn = 0.0;
503  weightOff = 1.0;
504  }
505 
506  for ( i = 0; i < listOn.size; i++ )
507  {
508  self SetAnim( listOn[i], weightOn, 0.2, 1.0 );
509  }
510 
511  for ( i = 0; i < listOff.size; i++ )
512  {
513  self SetAnim( listOff[i], weightOff, 0.2, 1.0 );
514  }
515 }
516 
517 function ‪field_toggle_ambient_anim_handler1( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
518 {
519  self ‪ambient_anim_toggle( localClientNum, 1, newVal );
520 }
521 
522 function ‪field_toggle_ambient_anim_handler2( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
523 {
524  self ‪ambient_anim_toggle( localClientNum, 2, newVal );
525 }
526 
527 function ‪field_toggle_ambient_anim_handler3( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
528 {
529  self ‪ambient_anim_toggle( localClientNum, 3, newVal );
530 }
531 
532 function ‪field_toggle_ambient_anim_handler4( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
533 {
534  self ‪ambient_anim_toggle( localClientNum, 4, newVal );
535 }
536 
537 function ‪lights_group_toggle( localClientNum, id, isOn )
538 {
539  self endon( "entityshutdown" );
540 
541  if( !isdefined( self.scriptbundlesettings ) )
542  {
543  return;
544  }
545 
546  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
547 
548  if ( !isdefined( settings ) || !isdefined( settings.lightgroups_numGroups ) )
549  {
550  return;
551  }
552 
553  ‪wait_for_DObj( localClientNum );
554 
555  groupID = id - 1;
556 
557  // remove old fx
558  if ( isdefined( self.lightfxgroups ) && groupID < self.lightfxgroups.size )
559  {
560  foreach( fx_handle in self.lightfxgroups[ groupID ] )
561  {
562  StopFX( localClientNum, fx_handle );
563  }
564  }
565 
566  if ( !isOn )
567  {
568  return;
569  }
570 
571  // initialize
572  if ( !isdefined( self.lightfxgroups ) )
573  {
574  self.lightfxgroups = [];
575  for ( i = 0; i < settings.lightgroups_numGroups; i++ )
576  {
577  newfxhandlearray = [];
578  ‪ARRAY_ADD( self.lightfxgroups, newfxhandlearray );
579  }
580  }
581 
582  self.lightfxgroups[groupID] = [];
583 
584  fxList = [];
585  tagList = [];
586 
587  switch ( groupID )
588  {
589  case 0:
590  ‪addFxAndTagToLists( settings.lightgroups_1_fx1, settings.lightgroups_1_tag1, fxList, tagList, 1, settings.lightgroups_1_numslots );
591  ‪addFxAndTagToLists( settings.lightgroups_1_fx2, settings.lightgroups_1_tag2, fxList, tagList, 2, settings.lightgroups_1_numslots );
592  ‪addFxAndTagToLists( settings.lightgroups_1_fx3, settings.lightgroups_1_tag3, fxList, tagList, 3, settings.lightgroups_1_numslots );
593  ‪addFxAndTagToLists( settings.lightgroups_1_fx4, settings.lightgroups_1_tag4, fxList, tagList, 4, settings.lightgroups_1_numslots );
594  break;
595  case 1:
596  ‪addFxAndTagToLists( settings.lightgroups_2_fx1, settings.lightgroups_2_tag1, fxList, tagList, 1, settings.lightgroups_2_numslots );
597  ‪addFxAndTagToLists( settings.lightgroups_2_fx2, settings.lightgroups_2_tag2, fxList, tagList, 2, settings.lightgroups_2_numslots );
598  ‪addFxAndTagToLists( settings.lightgroups_2_fx3, settings.lightgroups_2_tag3, fxList, tagList, 3, settings.lightgroups_2_numslots );
599  ‪addFxAndTagToLists( settings.lightgroups_2_fx4, settings.lightgroups_2_tag4, fxList, tagList, 4, settings.lightgroups_2_numslots );
600  break;
601  case 2:
602  ‪addFxAndTagToLists( settings.lightgroups_3_fx1, settings.lightgroups_3_tag1, fxList, tagList, 1, settings.lightgroups_3_numslots );
603  ‪addFxAndTagToLists( settings.lightgroups_3_fx2, settings.lightgroups_3_tag2, fxList, tagList, 2, settings.lightgroups_3_numslots );
604  ‪addFxAndTagToLists( settings.lightgroups_3_fx3, settings.lightgroups_3_tag3, fxList, tagList, 3, settings.lightgroups_3_numslots );
605  ‪addFxAndTagToLists( settings.lightgroups_3_fx4, settings.lightgroups_3_tag4, fxList, tagList, 4, settings.lightgroups_3_numslots );
606  break;
607  case 3:
608  ‪addFxAndTagToLists( settings.lightgroups_4_fx1, settings.lightgroups_4_tag1, fxList, tagList, 1, settings.lightgroups_4_numslots );
609  ‪addFxAndTagToLists( settings.lightgroups_4_fx2, settings.lightgroups_4_tag2, fxList, tagList, 2, settings.lightgroups_4_numslots );
610  ‪addFxAndTagToLists( settings.lightgroups_4_fx3, settings.lightgroups_4_tag3, fxList, tagList, 3, settings.lightgroups_4_numslots );
611  ‪addFxAndTagToLists( settings.lightgroups_4_fx4, settings.lightgroups_4_tag4, fxList, tagList, 4, settings.lightgroups_4_numslots );
612  break;
613  }
614 
615  for ( i = 0; i < fxList.size; i++ )
616  {
617  fx_handle = PlayFXOnTag( localClientNum, fxList[i], self, tagList[i] );
618  ‪ARRAY_ADD( self.lightfxgroups[groupID], fx_handle );
619  }
620 }
621 
622 function ‪field_toggle_lights_group_handler1( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
623 {
624  self ‪lights_group_toggle( localClientNum, 1, newVal );
625 }
626 function ‪field_toggle_lights_group_handler2( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
627 {
628  self ‪lights_group_toggle( localClientNum, 2, newVal );
629 }
630 function ‪field_toggle_lights_group_handler3( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
631 {
632  self ‪lights_group_toggle( localClientNum, 3, newVal );
633 }
634 function ‪field_toggle_lights_group_handler4( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
635 {
636  self ‪lights_group_toggle( localClientNum, 4, newVal );
637 }
638 
639 function ‪delete_alert_lights( localClientNum )
640 {
641  if( isdefined( self.alert_light_fx_handles ) )
642  {
643  for( i = 0; i < self.alert_light_fx_handles.size; i++ )
644  {
645  StopFX( localClientNum, self.alert_light_fx_handles[ i ] );
646  }
647  }
648 
649  self.alert_light_fx_handles = undefined;
650 }
651 
652 function ‪lights_off( localClientNum )
653 {
654  if( isdefined( self.light_fx_handles ) )
655  {
656  for( i = 0; i < self.light_fx_handles.size; i++ )
657  {
658  StopFX( localClientNum, self.light_fx_handles[ i ] );
659  }
660  }
661 
662  self.light_fx_handles = undefined;
663 
664  ‪delete_alert_lights( localClientNum );
665 }
666 
667 function ‪field_toggle_emp( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
668 {
669  self thread ‪toggle_fx_bundle( localClientNum, "emp_base", newVal == 1 );
670 }
671 
672 function ‪field_toggle_burn( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
673 {
674  self thread ‪toggle_fx_bundle( localClientNum, "burn_base", newVal == 1 );
675 }
676 
677 function ‪toggle_fx_bundle( localClientNum, ‪name, turnOn )
678 {
679  if( !isdefined( self.settings ) && isdefined( self.scriptbundlesettings ) )
680  {
681  self.settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
682  }
683 
684  if( !isdefined( self.settings ) )
685  {
686  return;
687  }
688 
689  self endon( "entityshutdown" );
690  self notify( "end_toggle_field_fx_" + ‪name );
691  self endon( "end_toggle_field_fx_" + ‪name );
692  ‪wait_for_DObj( localClientNum );
693 
694  if ( !isdefined( self.fx_handles ) )
695  {
696  self.fx_handles = [];
697  }
698 
699  if ( isdefined( self.fx_handles[ ‪name ] ) )
700  {
701  handle = self.fx_handles[ ‪name ];
702  if ( IsArray( handle ) )
703  {
704  foreach( handleElement in handle )
705  {
706  StopFX( localClientNum, handleElement );
707  }
708  }
709  else
710  {
711  StopFX( localClientNum, handle );
712  }
713  }
714 
715  if( turnOn )
716  {
717  for( i = 1; ; i++ )
718  {
719  fx = GetStructField( self.settings, ‪name + "_fx_" + i );
720  if ( !isdefined( fx ) )
721  {
722  return;
723  }
724  tag = GetStructField( self.settings, ‪name + "_tag_" + i );
725  ‪delay = GetStructField( self.settings, ‪name + "_delay_" + i );
726  self thread ‪delayed_fx_thread( localClientNum, ‪name, fx, tag, ‪delay );
727  }
728  }
729 }
730 
731 function ‪delayed_fx_thread( localClientNum, ‪name, fx, tag, ‪delay )
732 {
733  self endon( "entityshutdown" );
734  self endon( "end_toggle_field_fx_" + ‪name );
735 
736  if ( !isdefined( tag ) )
737  {
738  return;
739  }
740 
741  if ( isdefined( ‪delay ) && ‪delay > 0 )
742  {
743  wait ‪delay;
744  }
745 
746  fx_handle = PlayFxOnTag( localClientNum, fx, self, tag );
747  ‪ARRAY_ADD( self.fx_handles[ ‪name ], fx_handle );
748 }
749 
750 function ‪field_toggle_sounds( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
751 {
752  if( ‪IS_HELICOPTER( self ) )
753  {
754  if(newVal)
755  {
756  self notify( "stop_heli_sounds" );
757  self.should_not_play_sounds = true;
758  }
759  else
760  {
761  self notify( "play_heli_sounds" );
762  self.should_not_play_sounds = false;
763  }
764  }
765 
766  if(newVal)
767  {
768  self disablevehiclesounds();
769  }
770  else
771  {
772  self enablevehiclesounds();
773  }
774 }
775 
776 function ‪field_toggle_dnidamagefx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
777 {
778  if( newVal )
779  {
780  self thread postfx::PlayPostfxBundle( "pstfx_dni_vehicle_dmg" );
781  }
782 }
783 
784 function ‪toggle_flir_postfxbundle( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
785 {
786  player = self;
787  if( newval == oldVal )
788  return;
789 
790  if( !isdefined( player ) || !( player IsLocalPlayer() ) )
791  return;
792 
793  if( newVal == 0 )
794  {
795  player thread ‪postfx::stopPlayingPostfxBundle();
796  ‪update_ui_fullscreen_filter_model( localClientNum, 0 );
797  }
798  else if( newVal == 1 )
799  {
800  if ( player ‪ShouldChangeScreenPostFx( localClientNum ) )
801  {
802  player thread postfx::PlayPostfxBundle( "pstfx_infrared" );
803  ‪update_ui_fullscreen_filter_model( localClientNum, 2 );
804  }
805  }
806  else if( newVal == 2 )
807  {
808  should_change = true;
809 
810 
811  if ( player ‪ShouldChangeScreenPostFx( localClientNum ) )
812  {
813  player thread postfx::PlayPostfxBundle( "pstfx_flir" );
814  ‪update_ui_fullscreen_filter_model( localClientNum, 1 );
815  }
816  }
817 }
818 
819 function ‪ShouldChangeScreenPostFx( localClientNum )
820 {
821  player = self;
822 
823  assert( isdefined( player ) );
824 
825  if ( player GetInKillCam( localClientNum ) )
826  {
827  killCamEntity = player GetKillCamEntity( localClientNum );
828  if ( isdefined( killCamEntity ) && ( killCamEntity != player ) )
829  return false;
830  }
831 
832  return true;
833 }
834 
835 function ‪set_static_postfxbundle( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
836 {
837  player = self;
838  if( newval == oldVal )
839  return;
840 
841  if( !isdefined( player ) || !( player IsLocalPlayer() ) )
842  return;
843 
844  if( newVal == 0 )
845  {
846  player thread ‪postfx::stopPlayingPostfxBundle();
847  }
848  else if( newVal == 1 )
849  {
850  player thread postfx::PlayPostfxBundle( "pstfx_static" );
851  }
852 }
853 
854 function ‪update_ui_fullscreen_filter_model( localClientNum, vision_set_value )
855 {
856  //note: use the VEHICLE_VISION_SET enum to determine values to use
857  controllerModel = GetUIModelForController( localClientNum );
858  model = GetUIModel( controllerModel, "vehicle.fullscreenFilter" );
859  if ( isdefined( model ) )
860  {
861  SetUIModelValue( model, vision_set_value );
862  }
863 }
864 
865 function ‪field_toggle_treadfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
866 {
867 
868  if( ‪IS_HELICOPTER( self ) || ‪IS_PLANE( self ) )
869  {
870  /#PrintLn("****CLIENT:: Vehicle Flag Plane");#/
871 
872  if(newVal)
873  {
874  if(isdefined(bNewEnt) && bNewEnt)
875  {
876  self.csf_no_tread = true;
877  }
878  else
879  {
880  self ‪kill_treads_forever();
881  }
882  }
883  else // Flag being cleared.
884  {
885  if(isdefined(self.csf_no_tread))
886  {
887  self.csf_no_tread = false;
888  }
889  self ‪kill_treads_forever();
890  self thread ‪aircraft_dustkick();
891  }
892  }
893  else // Non-helicopter version...
894  {
895  if(newVal)
896  {
897  /#PrintLn("****CLIENT:: Vehicle Flag Tread FX Set");#/
898  if(isdefined(bNewEnt) && bNewEnt)
899  {
900  /#PrintLn("****CLIENT:: TreadFX NewEnt: " + self GetEntityNumber());#/
901  self.csf_no_tread = true;
902  }
903  else
904  {
905  /#PrintLn("****CLIENT:: TreadFX OldEnt" + self GetEntityNumber());#/
906  self ‪kill_treads_forever();
907  }
908  }
909  else // Flag being cleared.
910  {
911  /#PrintLn("****CLIENT:: Vehicle Flag Tread FX Clear");#/
912  if(isdefined(self.csf_no_tread))
913  {
914  self.csf_no_tread = false;
915  }
916  self ‪kill_treads_forever();
917  }
918  }
919 }
920 
921 function ‪field_use_engine_damage_sounds( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
922 {
923  if( ‪IS_HELICOPTER( self ) )
924  {
925  switch ( newVal )
926  {
927  case 0:
928  {
929  self.engine_damage_low = false;
930  self.engine_damage_high = false;
931  } break;
932  case 1: // Low
933  {
934  self.engine_damage_low = true;
935  self.engine_damage_high = false;
936  } break;
937  case 1: // High
938  {
939  self.engine_damage_low = false;
940  self.engine_damage_high = true;
941  } break;
942  }
943  //TODO T7 - bring this over from SP if we need it
944  //self helicopter_sounds::update_helicopter_sounds();
945  }
946 }
947 
948 function ‪field_do_deathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
949 {
950  self endon( "entityshutdown" );
951 
952  if ( newVal == 2 ) // EMP specific death
953  {
954  self ‪field_do_empdeathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump );
955  }
956  else
957  {
958  self ‪field_do_standarddeathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump );
959  }
960 }
961 
962 function ‪field_do_standarddeathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
963 {
964  if( newVal && !bInitialSnap )
965  {
966  ‪wait_for_DObj( localClientNum );
967 
968  if( isdefined( self.deathfxname ) )
969  {
970  if ( isdefined( self.deathfxtag ) && self.deathfxtag != "" )
971  {
972  handle = PlayFXOnTag( localClientNum, self.deathfxname, self, self.deathfxtag );
973  }
974  else
975  {
976  handle = PlayFX( localClientNum, self.deathfxname, self.origin );
977  }
978  SetFXIgnorePause( localClientNum, handle, true );
979  }
980 
981  self PlaySound( localClientNum, self.deathfxsound );
982 
983  if ( isdefined( self.deathquakescale ) && self.deathquakescale > 0 )
984  {
985  self Earthquake( self.deathquakescale, self.deathquakeduration, self.origin, self.deathquakeradius );
986  }
987  }
988 }
989 
990 function ‪field_do_empdeathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
991 {
992  if( !isdefined( self.settings ) && isdefined( self.scriptbundlesettings ) )
993  {
994  self.settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
995  }
996 
997  if( !isdefined( self.settings ) )
998  {
999  self ‪field_do_standarddeathfx( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump );
1000  return;
1001  }
1002 
1003  if( newVal && !bInitialSnap )
1004  {
1005  ‪wait_for_DObj( localClientNum );
1006 
1007  s = self.settings;
1008 
1009  if( isdefined( s.emp_death_fx_1 ) )
1010  {
1011  if ( isdefined( s.emp_death_tag_1 ) && s.emp_death_tag_1 != "" )
1012  {
1013  handle = PlayFXOnTag( localClientNum, s.emp_death_fx_1, self, s.emp_death_tag_1 );
1014  }
1015  else
1016  {
1017  handle = PlayFX( localClientNum, s.emp_death_tag_1, self.origin );
1018  }
1019  SetFXIgnorePause( localClientNum, handle, true );
1020  }
1021 
1022  self PlaySound( localClientNum, s.emp_death_sound_1 );
1023 
1024  // TODO: perhaps we want to make emp death quake settings
1025  if ( isdefined( self.deathquakescale ) && self.deathquakescale > 0 )
1026  {
1027  self Earthquake( self.deathquakescale * 0.25, self.deathquakeduration * 2.0, self.origin, self.deathquakeradius );
1028  }
1029  }
1030 }
1031 
1032 function ‪field_update_alert_level( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1033 {
1034  ‪vehicle::delete_alert_lights( localClientNum );
1035 
1036  if( !isdefined( self.scriptbundlesettings ) )
1037  {
1038  return;
1039  }
1040 
1041  if( !isdefined( self.alert_light_fx_handles ) )
1042  {
1043  self.alert_light_fx_handles = [];
1044  }
1045 
1046  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
1047 
1048  switch( newVal )
1049  {
1050  case 0:
1051  break;
1052  case 1:
1053  if( isdefined( settings.unawarelightfx1 ) )
1054  {
1055  self.alert_light_fx_handles[ 0 ] = PlayFXOnTag( localClientNum, settings.unawarelightfx1, self, settings.lighttag1 );
1056  }
1057  break;
1058  case 2:
1059  if( isdefined( settings.alertlightfx1 ) )
1060  {
1061  self.alert_light_fx_handles[ 0 ] = PlayFXOnTag( localClientNum, settings.alertlightfx1, self, settings.lighttag1 );
1062  }
1063  break;
1064  case 3:
1065  if( isdefined( settings.combatlightfx1 ) )
1066  {
1067  self.alert_light_fx_handles[ 0 ] = PlayFXOnTag( localClientNum, settings.combatlightfx1, self, settings.lighttag1 );
1068  }
1069  break;
1070  }
1071 
1072 }
1073 
1074 function ‪field_toggle_exhaustfx_handler( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1075 {
1076  if(newVal)
1077  {
1078  if(isdefined(bNewEnt) && bNewEnt)
1079  {
1080  self.csf_no_exhaust = true;
1081  }
1082  else
1083  {
1084  self ‪stop_exhaust( localClientNum );
1085  }
1086  }
1087  else
1088  {
1089  if(isdefined(self.csf_no_exhaust))
1090  {
1091  self.csf_no_exhaust = false;
1092  }
1093  self ‪stop_exhaust( localClientNum );
1094 
1095  self ‪play_exhaust( localClientNum );
1096  }
1097 }
1098 
1099 function ‪control_lights_groups( localClientNum, on )
1100 {
1101  if( !isdefined( self.scriptbundlesettings ) )
1102  {
1103  return;
1104  }
1105 
1106  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
1107 
1108  if ( !isdefined( settings ) || !isdefined( settings.lightgroups_numGroups ) )
1109  {
1110  return;
1111  }
1112 
1113  if ( settings.lightgroups_numGroups >= 1 && settings.lightgroups_1_always_on !== true )
1114  {
1115  ‪lights_group_toggle( localClientNum, 1, on );
1116  }
1117  if ( settings.lightgroups_numGroups >= 2 && settings.lightgroups_2_always_on !== true )
1118  {
1119  ‪lights_group_toggle( localClientNum, 2, on );
1120  }
1121  if ( settings.lightgroups_numGroups >= 3 && settings.lightgroups_3_always_on !== true )
1122  {
1123  ‪lights_group_toggle( localClientNum, 3, on );
1124  }
1125  if ( settings.lightgroups_numGroups >= 4 && settings.lightgroups_4_always_on !== true )
1126  {
1127  ‪lights_group_toggle( localClientNum, 4, on );
1128  }
1129 }
1130 
1131 function ‪field_toggle_lights_handler( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1132 {
1133  //lights:
1134  //0 - turn on normal
1135  //1 - turn off
1136  //2 - override to allied color
1137  //3 - override to axis color
1138 
1139  if( newVal == 1 )
1140  {
1141  self ‪lights_off( localClientNum );
1142  }
1143  else // Flag being cleared.
1144  {
1145  if( newVal == 2 )
1146  {
1147  self ‪lights_on( localClientNum, "allies" );
1148  }
1149  else if( newVal == 3 )
1150  {
1151  self ‪lights_on( localClientNum, "axis" );
1152  }
1153  else
1154  {
1155  self ‪lights_on( localClientNum );
1156  }
1157  }
1158 
1159  ‪control_lights_groups( localClientNum, newVal != 1 );
1160 }
1161 
1162 function ‪field_toggle_lockon_handler( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1163 {
1164  //TODO T7 - work with code to get this back if needed
1165  /*if(newVal)
1166  {
1167  self SetVehicleLockedOn( true );
1168  }
1169  else
1170  {
1171  self SetVehicleLockedOn( false );
1172  }*/
1173 }
1174 
1175 function ‪addFxAndTagToLists( fx, tag, &fxList, &tagList, id, maxID )
1176 {
1177  if ( isdefined( fx ) && isdefined( tag ) && id <= maxID )
1178  {
1179  ‪ARRAY_ADD( fxList, fx );
1180  ‪ARRAY_ADD( tagList, tag );
1181  }
1182 }
1183 
1184 function ‪field_update_damage_state( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1185 {
1186  if( !isdefined( self.scriptbundlesettings ) )
1187  {
1188  return;
1189  }
1190 
1191  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
1192 
1193  if ( isdefined( self.damage_state_fx_handles ) )
1194  {
1195  foreach( fx_handle in self.damage_state_fx_handles )
1196  {
1197  StopFX( localClientNum, fx_handle );
1198  }
1199  }
1200 
1201  self.damage_state_fx_handles = [];
1202 
1203  fxList = [];
1204  tagList = [];
1205  sound = undefined;
1206 
1207  switch( newVal )
1208  {
1209  case 0:
1210  break;
1211  case 1:
1212  ‪addFxAndTagToLists( settings.damagestate_lv1_fx1, settings.damagestate_lv1_tag1, fxList, tagList, 1, settings.damagestate_lv1_numslots );
1213  ‪addFxAndTagToLists( settings.damagestate_lv1_fx2, settings.damagestate_lv1_tag2, fxList, tagList, 2, settings.damagestate_lv1_numslots );
1214  ‪addFxAndTagToLists( settings.damagestate_lv1_fx3, settings.damagestate_lv1_tag3, fxList, tagList, 3, settings.damagestate_lv1_numslots );
1215  ‪addFxAndTagToLists( settings.damagestate_lv1_fx4, settings.damagestate_lv1_tag4, fxList, tagList, 4, settings.damagestate_lv1_numslots );
1216  sound = settings.damagestate_lv1_sound;
1217  break;
1218  case 2:
1219  ‪addFxAndTagToLists( settings.damagestate_lv2_fx1, settings.damagestate_lv2_tag1, fxList, tagList, 1, settings.damagestate_lv2_numslots );
1220  ‪addFxAndTagToLists( settings.damagestate_lv2_fx2, settings.damagestate_lv2_tag2, fxList, tagList, 2, settings.damagestate_lv2_numslots );
1221  ‪addFxAndTagToLists( settings.damagestate_lv2_fx3, settings.damagestate_lv2_tag3, fxList, tagList, 3, settings.damagestate_lv2_numslots );
1222  ‪addFxAndTagToLists( settings.damagestate_lv2_fx4, settings.damagestate_lv2_tag4, fxList, tagList, 4, settings.damagestate_lv2_numslots );
1223  sound = settings.damagestate_lv2_sound;
1224  break;
1225  case 3:
1226  ‪addFxAndTagToLists( settings.damagestate_lv3_fx1, settings.damagestate_lv3_tag1, fxList, tagList, 1, settings.damagestate_lv3_numslots );
1227  ‪addFxAndTagToLists( settings.damagestate_lv3_fx2, settings.damagestate_lv3_tag2, fxList, tagList, 2, settings.damagestate_lv3_numslots );
1228  ‪addFxAndTagToLists( settings.damagestate_lv3_fx3, settings.damagestate_lv3_tag3, fxList, tagList, 3, settings.damagestate_lv3_numslots );
1229  ‪addFxAndTagToLists( settings.damagestate_lv3_fx4, settings.damagestate_lv3_tag4, fxList, tagList, 4, settings.damagestate_lv3_numslots );
1230  sound = settings.damagestate_lv3_sound;
1231  break;
1232  case 4:
1233  ‪addFxAndTagToLists( settings.damagestate_lv4_fx1, settings.damagestate_lv4_tag1, fxList, tagList, 1, settings.damagestate_lv4_numslots );
1234  ‪addFxAndTagToLists( settings.damagestate_lv4_fx2, settings.damagestate_lv4_tag2, fxList, tagList, 2, settings.damagestate_lv4_numslots );
1235  ‪addFxAndTagToLists( settings.damagestate_lv4_fx3, settings.damagestate_lv4_tag3, fxList, tagList, 3, settings.damagestate_lv4_numslots );
1236  ‪addFxAndTagToLists( settings.damagestate_lv4_fx4, settings.damagestate_lv4_tag4, fxList, tagList, 4, settings.damagestate_lv4_numslots );
1237  sound = settings.damagestate_lv4_sound;
1238  break;
1239  case 5:
1240  ‪addFxAndTagToLists( settings.damagestate_lv5_fx1, settings.damagestate_lv5_tag1, fxList, tagList, 1, settings.damagestate_lv5_numslots );
1241  ‪addFxAndTagToLists( settings.damagestate_lv5_fx2, settings.damagestate_lv5_tag2, fxList, tagList, 2, settings.damagestate_lv5_numslots );
1242  ‪addFxAndTagToLists( settings.damagestate_lv5_fx3, settings.damagestate_lv5_tag3, fxList, tagList, 3, settings.damagestate_lv5_numslots );
1243  ‪addFxAndTagToLists( settings.damagestate_lv5_fx4, settings.damagestate_lv5_tag4, fxList, tagList, 4, settings.damagestate_lv5_numslots );
1244  sound = settings.damagestate_lv5_sound;
1245  break;
1246  case 6:
1247  ‪addFxAndTagToLists( settings.damagestate_lv6_fx1, settings.damagestate_lv6_tag1, fxList, tagList, 1, settings.damagestate_lv6_numslots );
1248  ‪addFxAndTagToLists( settings.damagestate_lv6_fx2, settings.damagestate_lv6_tag2, fxList, tagList, 2, settings.damagestate_lv6_numslots );
1249  ‪addFxAndTagToLists( settings.damagestate_lv6_fx3, settings.damagestate_lv6_tag3, fxList, tagList, 3, settings.damagestate_lv6_numslots );
1250  ‪addFxAndTagToLists( settings.damagestate_lv6_fx4, settings.damagestate_lv6_tag4, fxList, tagList, 4, settings.damagestate_lv6_numslots );
1251  sound = settings.damagestate_lv6_sound;
1252  break;
1253  }
1254 
1255  for( i = 0; i < fxList.size; i++ )
1256  {
1257  fx_handle = PlayFXOnTag( localClientNum, fxList[i], self, tagList[i] );
1258  ‪ARRAY_ADD( self.damage_state_fx_handles, fx_handle );
1259  }
1260 
1261  if ( isdefined( self ) && isdefined( sound ) )
1262  {
1263  self PlaySound( localClientNum, sound );
1264  }
1265 }
1266 
1267 function ‪field_death_spawn_dynents( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1268 {
1269  if( !isdefined( self.scriptbundlesettings ) )
1270  {
1271  return;
1272  }
1273 
1274  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
1275 
1276  if( localClientNum == 0 ) // dynents are shared between clients
1277  {
1278  velocity = self GetVelocity();
1279 
1280  numDynents = ‪VAL( settings.death_dynent_count, 0 );
1281  for( i = 0; i < numDynents; i++ )
1282  {
1283  model = GetStructField( settings, "death_dynmodel" + i );
1284 
1285  if( !isdefined( model ) )
1286  continue;
1287 
1288  gibpart = GetStructField( settings, "death_dynent_gib" + i );
1289  if ( self.gibbed === true && gibpart === true )
1290  continue;
1291 
1292  pitch = ‪VAL( GetStructField( settings, "death_dynent_force_pitch" + i ), 0 );
1293  yaw = ‪VAL( GetStructField( settings, "death_dynent_force_yaw" + i ), 0 );
1294  angles = ( RandomFloatRange( pitch - 15, pitch + 15 ), RandomFloatRange( yaw - 20, yaw + 20 ), RandomFloatRange( -20, 20 ) );
1295  direction = AnglesToForward( self.angles + angles );
1296 
1297  minscale = ‪VAL( GetStructField( settings, "death_dynent_force_minscale" + i ), 0 );
1298  maxscale = ‪VAL( GetStructField( settings, "death_dynent_force_maxscale" + i ), 0 );
1299 
1300  force = direction * RandomFloatRange( minscale, maxscale );
1301 
1302  offset = ( ‪VAL( GetStructField( settings, "death_dynent_offsetX" + i ), 0 ),
1303  ‪VAL( GetStructField( settings, "death_dynent_offsetY" + i ), 0 ),
1304  ‪VAL( GetStructField( settings, "death_dynent_offsetZ" + i ), 0 ) );
1305 
1306  switch( newVal )
1307  {
1308  case 0: // no FX
1309  break;
1310  case 1:
1311  fx = GetStructField( settings, "death_dynent_fx" + i );
1312  break;
1313  case 2: // EMP FX
1314  fx = GetStructField( settings, "death_dynent_elec_fx" + i );
1315  break;
1316  case 3: // Burn FX
1317  fx = GetStructField( settings, "death_dynent_fire_fx" + i );
1318  break;
1319  }
1320 
1321  offset = RotatePoint( offset, self.angles );
1322 
1323  if ( newVal > 1 && isdefined( fx ) )
1324  {
1325  dynent = CreateDynEntAndLaunch( localClientNum, model, self.origin + offset, self.angles, (0,0,0), velocity * 0.8, fx );
1326  }
1327  else if ( newVal == 1 && isdefined( fx ) )
1328  {
1329  dynent = CreateDynEntAndLaunch( localClientNum, model, self.origin + offset, self.angles, (0,0,0), velocity * 0.8, fx );
1330  }
1331  else
1332  {
1333  dynent = CreateDynEntAndLaunch( localClientNum, model, self.origin + offset, self.angles, (0,0,0), velocity * 0.8 );
1334  }
1335 
1336  if ( isdefined( dynent ) )
1337  {
1338  hitOffset = ( randomFloatRange( -5, 5 ), randomFloatRange( -5, 5 ), randomFloatRange( -5, 5 ) );
1339  LaunchDynent( dynent, force, hitOffset );
1340  }
1341  }
1342  }
1343 }
1344 
1345 function ‪field_gib_spawn_dynents( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
1346 {
1347  if( !isdefined( self.scriptbundlesettings ) )
1348  {
1349  return;
1350  }
1351 
1352  settings = ‪struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
1353 
1354  if( localClientNum == 0 ) // dynents are shared between clients
1355  {
1356  velocity = self GetVelocity();
1357 
1358  numDynents = 2;
1359  for( i = 0; i < numDynents; i++ )
1360  {
1361  model = GetStructField( settings, "servo_gib_model" + i );
1362 
1363  if( !isdefined( model ) )
1364  {
1365  return;
1366  }
1367 
1368  self.gibbed = true; // prevent gibbed death part from spawning on death
1369 
1370  origin = self.origin;
1371  angles = self.angles;
1372  hidetag = GetStructField( settings, "servo_gib_tag" + i );
1373  if ( isdefined( hidetag ) )
1374  {
1375  origin = self GetTagOrigin( hidetag );
1376  angles = self GetTagAngles( hidetag );
1377  }
1378 
1379  pitch = ‪VAL( GetStructField( settings, "servo_gib_force_pitch" + i ), 0 );
1380  yaw = ‪VAL( GetStructField( settings, "servo_gib_force_yaw" + i ), 0 );
1381  relative_angles = ( RandomFloatRange( pitch - 5, pitch + 5 ), RandomFloatRange( yaw - 5, yaw + 5 ), RandomFloatRange( -5, 5 ) );
1382  direction = AnglesToForward( angles + relative_angles );
1383 
1384  minscale = ‪VAL( GetStructField( settings, "servo_gib_force_minscale" + i ), 0 );
1385  maxscale = ‪VAL( GetStructField( settings, "servo_gib_force_maxscale" + i ), 0 );
1386 
1387  force = direction * RandomFloatRange( minscale, maxscale );
1388 
1389  offset = ( ‪VAL( GetStructField( settings, "servo_gib_offsetX" + i ), 0 ),
1390  ‪VAL( GetStructField( settings, "servo_gib_offsetY" + i ), 0 ),
1391  ‪VAL( GetStructField( settings, "servo_gib_offsetZ" + i ), 0 ) );
1392 
1393  fx = GetStructField( settings, "servo_gib_fx" + i );
1394 
1395  offset = RotatePoint( offset, angles );
1396 
1397  if ( isdefined( fx ) )
1398  {
1399  dynent = CreateDynEntAndLaunch( localClientNum, model, origin + offset, angles, (0,0,0), velocity * 0.8, fx );
1400  }
1401  else
1402  {
1403  dynent = CreateDynEntAndLaunch( localClientNum, model, origin + offset, angles, (0,0,0), velocity * 0.8 );
1404  }
1405 
1406  if ( isdefined( dynent ) )
1407  {
1408  hitOffset = ( randomFloatRange( -5, 5 ), randomFloatRange( -5, 5 ), randomFloatRange( -5, 5 ) );
1409  LaunchDynent( dynent, force, hitOffset );
1410  }
1411  }
1412  }
1413 }
1414 
1415 //-----------------------------------------------------------------------------
1416 //
1417 // Generic Full-Screen Damage Filter System
1418 //
1419 //-----------------------------------------------------------------------------
1420 
1421 #define MIN_FILTER_INTENSITY 0.5
1422 #define MAX_FILTER_INTENSITY 1
1423 #define FILTER_FADE_IN_TIME 0.1
1424 #define FILTER_FADE_OUT_TIME 0.33
1425 #define FILTER_FADE_IN_RATE MIN_FILTER_INTENSITY / FILTER_FADE_IN_TIME
1426 #define FILTER_FADE_OUT_RATE MAX_FILTER_INTENSITY / FILTER_FADE_OUT_TIME
1427 #define FILTER_DT 0.016667
1428 
1429 // yuck
1430 function autoexec ‪build_damage_filter_list()
1431 {
1432  if ( !isdefined( level.vehicle_damage_filters ) )
1433  {
1434  level.vehicle_damage_filters = [];
1435  }
1436 
1437  level.vehicle_damage_filters[ 0 ] = "generic_filter_vehicle_damage";
1438  level.vehicle_damage_filters[ 1 ] = "generic_filter_sam_damage";
1439  level.vehicle_damage_filters[ 2 ] = "generic_filter_f35_damage";
1440  level.vehicle_damage_filters[ 3 ] = "generic_filter_vehicle_damage_sonar";
1441  level.vehicle_damage_filters[ 4 ] = "generic_filter_rts_vehicle_damage";
1442 }
1443 
1444 function ‪init_damage_filter( materialid )
1445 {
1446  level.localPlayers[0].damage_filter_intensity = 0;
1447 
1448  materialname = level.vehicle_damage_filters[ materialid ];
1449 
1450  ‪filter::init_filter_vehicle_damage( level.localPlayers[0], materialname );
1451  ‪filter::enable_filter_vehicle_damage( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, materialname );
1454 }
1455 
1456 function ‪damage_filter_enable( localClientNum, materialid )
1457 {
1458  ‪filter::enable_filter_vehicle_damage( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.vehicle_damage_filters[ materialid ] );
1459 
1460  level.localPlayers[0].damage_filter_intensity = 0;
1461  ‪filter::set_filter_vehicle_damage_amount( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.localPlayers[0].damage_filter_intensity );
1462 }
1463 
1464 function ‪damage_filter_disable( localClientNum )
1465 {
1466  level notify( "damage_filter_off" );
1467 
1468  level.localPlayers[0].damage_filter_intensity = 0;
1469  ‪filter::set_filter_vehicle_damage_amount( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.localPlayers[0].damage_filter_intensity );
1470 
1472 
1473 }
1474 
1475 function ‪damage_filter_off( localClientNum )
1476 {
1477  level endon( "damage_filter" );
1478  level endon( "damage_filter_off" );
1479  level endon( "damage_filter_heavy" );
1480 
1481  if(!isdefined(level.localPlayers[0].damage_filter_intensity ))
1482  return;
1483 
1484  while ( level.localPlayers[0].damage_filter_intensity > 0 )
1485  {
1486  level.localPlayers[0].damage_filter_intensity -= ‪FILTER_FADE_OUT_RATE * ‪FILTER_DT;
1487  if ( level.localPlayers[0].damage_filter_intensity < 0 )
1488  level.localPlayers[0].damage_filter_intensity = 0;
1489 
1490  ‪filter::set_filter_vehicle_damage_amount( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.localPlayers[0].damage_filter_intensity );
1491 
1492  wait( ‪FILTER_DT );
1493  }
1494 }
1495 
1496 function ‪damage_filter_light( localClientNum )
1497 {
1498  level endon( "damage_filter_off" );
1499  level endon( "damage_filter_heavy" );
1500 
1501  level notify( "damage_filter" );
1502 
1503  while ( level.localPlayers[0].damage_filter_intensity < ‪MIN_FILTER_INTENSITY )
1504  {
1505  level.localPlayers[0].damage_filter_intensity += ‪FILTER_FADE_IN_RATE * ‪FILTER_DT;
1506  if ( level.localPlayers[0].damage_filter_intensity > ‪MIN_FILTER_INTENSITY )
1507  level.localPlayers[0].damage_filter_intensity = ‪MIN_FILTER_INTENSITY;
1508 
1509  ‪filter::set_filter_vehicle_damage_amount( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.localPlayers[0].damage_filter_intensity );
1510 
1511  wait( ‪FILTER_DT );
1512  }
1513 }
1514 
1515 function ‪damage_filter_heavy( localClientNum )
1516 {
1517  level endon( "damage_filter_off" );
1518 
1519  level notify( "damage_filter_heavy" );
1520 
1521  while ( level.localPlayers[0].damage_filter_intensity < ‪MAX_FILTER_INTENSITY )
1522  {
1523  level.localPlayers[0].damage_filter_intensity += ‪FILTER_FADE_IN_RATE * ‪FILTER_DT;
1524  if ( level.localPlayers[0].damage_filter_intensity > ‪MAX_FILTER_INTENSITY )
1525  level.localPlayers[0].damage_filter_intensity = ‪MAX_FILTER_INTENSITY;
1526 
1527  ‪filter::set_filter_vehicle_damage_amount( level.localPlayers[0], ‪FILTER_INDEX_VEHICLE, level.localPlayers[0].damage_filter_intensity );
1528 
1529  wait( ‪FILTER_DT );
1530  }
1531 }
1532 
‪field_gib_spawn_dynents
‪function field_gib_spawn_dynents(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1345
‪damage_filter_light
‪function damage_filter_light(localClientNum)
Definition: vehicle_shared.csc:1496
‪callback
‪function callback(event, localclientnum, params)
Definition: callbacks_shared.csc:13
‪__init__
‪function __init__()
Definition: vehicle_shared.csc:18
‪lights_off
‪function lights_off(localClientNum)
Definition: vehicle_shared.csc:652
‪enable_filter_vehicle_damage
‪function enable_filter_vehicle_damage(player, filterid, materialname)
Definition: filter_shared.csc:386
‪kill_exhaust_watcher
‪function kill_exhaust_watcher(localClientNum)
Definition: vehicle_shared.csc:219
‪delayed_fx_thread
‪function delayed_fx_thread(localClientNum, name, fx, tag, delay)
Definition: vehicle_shared.csc:731
‪set_vehicleriders_bundle
‪function set_vehicleriders_bundle(str_bundlename)
Definition: vehicleriders_shared.csc:107
‪field_toggle_sounds
‪function field_toggle_sounds(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:750
‪field_toggle_lights_handler
‪function field_toggle_lights_handler(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1131
‪field_toggle_lights_group_handler4
‪function field_toggle_lights_group_handler4(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:634
‪disable_filter_vehicle_damage
‪function disable_filter_vehicle_damage(player, filterid)
Definition: filter_shared.csc:395
‪field_toggle_dnidamagefx
‪function field_toggle_dnidamagefx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:776
‪delete_alert_lights
‪function delete_alert_lights(localClientNum)
Definition: vehicle_shared.csc:639
‪damage_filter_enable
‪function damage_filter_enable(localClientNum, materialid)
Definition: vehicle_shared.csc:1456
‪IS_HELICOPTER
‪#define IS_HELICOPTER(__e)
Definition: shared.gsh:351
‪field_do_deathfx
‪function field_do_deathfx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:948
‪set_filter_vehicle_sun_position
‪function set_filter_vehicle_sun_position(player, filterid, x, y)
Definition: filter_shared.csc:380
‪addFxAndTagToLists
‪function addFxAndTagToLists(fx, tag, &fxList, &tagList, id, maxID)
Definition: vehicle_shared.csc:1175
‪update_ui_fullscreen_filter_model
‪function update_ui_fullscreen_filter_model(localClientNum, vision_set_value)
Definition: vehicle_shared.csc:854
‪set_filter_vehicle_damage_amount
‪function set_filter_vehicle_damage_amount(player, filterid, amount)
Definition: filter_shared.csc:375
‪control_lights_groups
‪function control_lights_groups(localClientNum, on)
Definition: vehicle_shared.csc:1099
‪field_death_spawn_dynents
‪function field_death_spawn_dynents(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1267
‪ShouldChangeScreenPostFx
‪function ShouldChangeScreenPostFx(localClientNum)
Definition: vehicle_shared.csc:819
‪CF_CALLBACK_ZERO_ON_NEW_ENT
‪#define CF_CALLBACK_ZERO_ON_NEW_ENT
Definition: version.gsh:103
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪field_toggle_ambient_anim_handler2
‪function field_toggle_ambient_anim_handler2(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:522
‪VAL
‪#define VAL(__var, __default)
Definition: shared.gsh:272
‪IS_MIG
‪#define IS_MIG(__e)
Definition: shared.gsh:365
‪field_do_empdeathfx
‪function field_do_empdeathfx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:990
‪field_toggle_exhaustfx_handler
‪function field_toggle_exhaustfx_handler(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1074
‪wait_for_DObj
‪function wait_for_DObj(localClientNum)
Definition: vehicle_shared.csc:387
‪MIN_FILTER_INTENSITY
‪#define MIN_FILTER_INTENSITY
Definition: vehicle_shared.csc:1421
‪trace
‪function trace(from, to, target)
Definition: grapple.gsc:369
‪kill_treads_forever
‪function kill_treads_forever()
Definition: vehicle_shared.csc:171
‪damage_filter_off
‪function damage_filter_off(localClientNum)
Definition: vehicle_shared.csc:1475
‪field_use_lighting_ent
‪function field_use_lighting_ent(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: util_shared.csc:1104
‪field_toggle_lockon_handler
‪function field_toggle_lockon_handler(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1162
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪toggle_flir_postfxbundle
‪function toggle_flir_postfxbundle(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:784
‪stop_exhaust
‪function stop_exhaust(localClientNum)
Definition: vehicle_shared.csc:236
‪lights_group_toggle
‪function lights_group_toggle(localClientNum, id, isOn)
Definition: vehicle_shared.csc:537
‪set_static_postfxbundle
‪function set_static_postfxbundle(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:835
‪FILTER_INDEX_VEHICLE
‪#define FILTER_INDEX_VEHICLE
Definition: shared.gsh:486
‪field_set_lighting_ent
‪function field_set_lighting_ent(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: util_shared.csc:1099
‪field_toggle_lights_group_handler3
‪function field_toggle_lights_group_handler3(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:630
‪damage_filter_disable
‪function damage_filter_disable(localClientNum)
Definition: vehicle_shared.csc:1464
‪field_toggle_lights_group_handler2
‪function field_toggle_lights_group_handler2(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:626
‪field_toggle_burn
‪function field_toggle_burn(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:672
‪field_update_damage_state
‪function field_update_damage_state(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1184
‪CF_HOST_ONLY
‪#define CF_HOST_ONLY
Definition: version.gsh:102
‪field_toggle_ambient_anim_handler4
‪function field_toggle_ambient_anim_handler4(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:532
‪ambient_anim_toggle
‪function ambient_anim_toggle(localClientNum, groupID, isOn)
Definition: vehicle_shared.csc:446
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪rumble
‪function rumble(localClientNum)
Definition: vehicle_shared.csc:108
‪init_filter_vehicle_damage
‪function init_filter_vehicle_damage(player, materialname)
Definition: filter_shared.csc:367
‪FILTER_DT
‪#define FILTER_DT
Definition: vehicle_shared.csc:1427
‪aircraft_dustkick
‪function aircraft_dustkick()
Definition: vehicle_shared.csc:241
‪FILTER_FADE_OUT_RATE
‪#define FILTER_FADE_OUT_RATE
Definition: vehicle_shared.csc:1426
‪field_use_engine_damage_sounds
‪function field_use_engine_damage_sounds(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:921
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪field_toggle_lights_group_handler1
‪function field_toggle_lights_group_handler1(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:622
‪init_damage_filter
‪function init_damage_filter(materialid)
Definition: vehicle_shared.csc:1444
‪earthquake
‪function earthquake()
Definition: exploder_shared.gsc:850
‪stopPlayingPostfxBundle
‪function stopPlayingPostfxBundle()
Definition: postfx_shared.csc:241
‪field_toggle_emp
‪function field_toggle_emp(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:667
‪spawned_callback
‪function spawned_callback(localClientNum)
Definition: vehicle_shared.csc:87
‪add_vehicletype_callback
‪function add_vehicletype_callback(vehicletype, callback)
Definition: vehicle_shared.csc:77
‪MAX_FILTER_INTENSITY
‪#define MAX_FILTER_INTENSITY
Definition: vehicle_shared.csc:1422
‪toggle_fx_bundle
‪function toggle_fx_bundle(localClientNum, name, turnOn)
Definition: vehicle_shared.csc:677
‪weapon_fired
‪function weapon_fired()
Definition: vehicle_shared.csc:341
‪field_toggle_ambient_anim_handler1
‪function field_toggle_ambient_anim_handler1(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:517
‪addAnimToList
‪function addAnimToList(animItem, &listOn, &listOff, playWhenOff, id, maxID)
Definition: vehicle_shared.csc:431
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪get_script_bundle
‪function get_script_bundle(str_type, str_name)
Definition: struct.csc:45
‪FILTER_FADE_IN_RATE
‪#define FILTER_FADE_IN_RATE
Definition: vehicle_shared.csc:1425
‪play_exhaust
‪function play_exhaust(localClientNum)
Definition: vehicle_shared.csc:177
‪field_update_alert_level
‪function field_update_alert_level(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:1032
‪IS_PLANE
‪#define IS_PLANE(__e)
Definition: shared.gsh:350
‪field_toggle_treadfx
‪function field_toggle_treadfx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:865
‪name
‪class GroundFx name
‪WAIT_CLIENT_FRAME
‪#define WAIT_CLIENT_FRAME
Definition: shared.gsh:266
‪lights_on
‪function lights_on(localClientNum, team)
Definition: vehicle_shared.csc:404
‪damage_filter_heavy
‪function damage_filter_heavy(localClientNum)
Definition: vehicle_shared.csc:1515
‪field_do_standarddeathfx
‪function field_do_standarddeathfx(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:962
‪build_damage_filter_list
‪function autoexec build_damage_filter_list()
Definition: vehicle_shared.csc:1430
‪field_toggle_ambient_anim_handler3
‪function field_toggle_ambient_anim_handler3(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: vehicle_shared.csc:527