‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_metal_storm.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\clientfield_shared;
4 #using scripts\shared\flag_shared;
5 #using scripts\shared\gameskill_shared;
6 #using scripts\shared\math_shared;
7 #using scripts\shared\statemachine_shared;
8 #using scripts\shared\system_shared;
9 #using scripts\shared\util_shared;
10 #using scripts\shared\vehicle_ai_shared;
11 
12 #insert scripts\shared\shared.gsh;
13 #insert scripts\shared\statemachine.gsh;
14 #insert scripts\shared\version.gsh;
15 
16 #insert scripts\shared\ai\utility.gsh;
17 
18 //#using scripts\sp\_util;
19 #using scripts\shared\vehicle_shared;
20 #using scripts\shared\vehicle_death_shared;
21 
22 #define NUM_DAMAGE_STATES 4
23 #define DAMAGE_STATE_THRESHOLD_PCT_1 0.75
24 #define DAMAGE_STATE_THRESHOLD_PCT_2 0.5
25 #define DAMAGE_STATE_THRESHOLD_PCT_3 0.25
26 #define DAMAGE_STATE_THRESHOLD_PCT_4 0.1
27 
28 #define SCAN_HEIGHT_OFFSET 40
29 
30 #define TURRET_STATE_SCAN_AT_ENEMY 0
31 #define TURRET_STATE_SCAN_FORWARD 1
32 #define TURRET_STATE_SCAN_RIGHT 2
33 #define TURRET_STATE_SCAN_FORWARD2 3
34 #define TURRET_STATE_SCAN_LEFT 4
35 #define NUM_TURRET_STATES 5
36 
37 #define STR_VEHICLETYPE "drone_metalstorm"
38 
39 #precache( "fx", "_t6/destructibles/fx_metalstorm_damagestate00" );
40 #precache( "fx", "_t6/destructibles/fx_metalstorm_damagestate01" );
41 #precache( "fx", "_t6/destructibles/fx_metalstorm_damagestate02" );
42 #precache( "fx", "_t6/destructibles/fx_metalstorm_damagestate03" );
43 #precache( "fx", "_t6/destructibles/fx_metalstorm_damagestate_back01" );
44 #precache( "fx", "_t6/destructibles/fx_metalstorm_death01a" );
45 #precache( "fx", "_t6/impacts/fx_metalstorm_hit01" );
46 #precache( "fx", "_t6/impacts/fx_metalstorm_hit02" );
47 #precache( "fx", "_t6/light/fx_vlight_metalstorm_eye_grn" );
48 #precache( "fx", "_t6/light/fx_vlight_metalstorm_eye_red" );
49 #precache( "fx", "_t6/electrical/fx_elec_sp_emp_stun_metalstorm" );
50 
51 #namespace metal_storm;
52 
53 ‪REGISTER_SYSTEM( "metal_storm", &‪__init__, undefined )
54 
55 
56 function ‪__init__()
57 {
58  ‪clientfield::register( "vehicle", "toggle_gas_freeze", ‪VERSION_SHIP, 1, "int" );
59 
60  vehicle::add_main_callback( "drone_metalstorm",&‪main );
61  vehicle::add_main_callback( "drone_metalstorm_rts",&‪main );
62  vehicle::add_main_callback( "drone_metalstorm_afghan_rts",&‪main );
63  vehicle::add_main_callback( "drone_metalstorm_karma",&‪main );
64  vehicle::add_main_callback( "drone_metalstorm_monsoon",&‪main );
65 
67 
68  level.difficultySettings[ "asd_burst_scale" ][ "easy" ] = 1.15;
69  level.difficultySettings[ "asd_burst_scale" ][ "normal" ] = 1;
70  level.difficultySettings[ "asd_burst_scale" ][ "hardened" ] = 0.85;
71  level.difficultySettings[ "asd_burst_scale" ][ "veteran" ] = 0.7;
72 
73  level.difficultySettings[ "asd_health_boost" ][ "easy" ] = -70;
74  level.difficultySettings[ "asd_health_boost" ][ "normal" ] = 0;
75  level.difficultySettings[ "asd_health_boost" ][ "hardened" ] = 70;
76  level.difficultySettings[ "asd_health_boost" ][ "veteran" ] = 140;
77 }
78 
79 // Metal storm short hand commands!! Use these to give explicit orders
80 
82 {
83  if ( !isdefined( level.fx_damage_effects ) )
84  {
85  level.fx_damage_effects = [];
86  }
87 
88  if ( !isdefined( level.fx_damage_effects[ ‪STR_VEHICLETYPE ] ) )
89  {
90  level.fx_damage_effects[ ‪STR_VEHICLETYPE ] = [];
91  }
92 
93  for ( i = 0; i < ‪NUM_DAMAGE_STATES; i++ )
94  level.fx_damage_effects[ ‪STR_VEHICLETYPE ][i] = "_t6/destructibles/fx_metalstorm_damagestate0" + ( i + 1 );
95 
96  // final explosion fx
97  level._effect[ "metalstorm_busted" ] = "_t6/destructibles/fx_metalstorm_damagestate_back01";
98  level._effect[ "metalstorm_explo" ] = "_t6/destructibles/fx_metalstorm_death01a";
99 
100  level._effect[ "metalstorm_hit" ] = "_t6/impacts/fx_metalstorm_hit01";
101  level._effect[ "metalstorm_hit_back" ] = "_t6/impacts/fx_metalstorm_hit02";
102 
103  level._effect[ "eye_light_friendly" ] = "_t6/light/fx_vlight_metalstorm_eye_grn";
104  level._effect[ "eye_light_enemy" ] = "_t6/light/fx_vlight_metalstorm_eye_red";
105 
106  level._effect[ "metalstorm_stun" ] = "_t6/electrical/fx_elec_sp_emp_stun_metalstorm";
107 }
108 
109 function ‪main()
110 {
111  self thread ‪metalstorm_think();
112  self thread ‪update_damage_states();
113  self thread ‪metalstorm_rocket_recoil();
114  self thread ‪metalstorm_death();
115  /#self thread ‪metalstorm_debug();#/
116  self.overrideVehicleDamage =&‪MetalStormCallback_VehicleDamage;
117 }
118 
120 {
121  self EnableAimAssist();
122  self SetNearGoalNotifyDist( 35 );
123  self SetSpeed( 5, 5, 5 );
124 
125  // Set this on the metal storm to specify the cuttoff distance at which he can see
126  self.turret_state = ‪TURRET_STATE_SCAN_AT_ENEMY;
127  self.turret_on_target = false;
128  self.highlyawareradius = 80;
129 
130  if( !isdefined( self.goalradius ) )
131  {
132  self.goalradius = 600;
133  }
134 
135  if( !isdefined( self.goalpos ) )
136  {
137  self.goalpos = self.origin;
138  }
139 
140  self SetVehGoalPos( self.goalpos, true );
141 
142  self.state_machine = ‪statemachine::create( "metalstormbrain", self );
143  ‪main = self.state_machine ‪statemachine::add_state( "main", undefined,&‪metalstorm_main, undefined );
144  scripted = self.state_machine ‪statemachine::add_state( "scripted", undefined,&‪metalstorm_scripted, undefined );
145 
146  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "enter_vehicle" );
147  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "scripted" );
148  ‪vehicle_ai::add_interrupt_connection( "main", "scripted", "exit_vehicle" );
149  ‪vehicle_ai::add_interrupt_connection( "main", "scripted", "main" );
150  ‪vehicle_ai::add_interrupt_connection( "scripted", "main", "enter_vehicle" );
151 
152  // Set the first state
153  if ( isdefined( self.script_startstate ) )
154  {
155  //removed || self.script_startstate == "idle"- this was breaking all the audio on the metalstorms CDC
156  if( self.script_startstate == "off" )
157  {
158  self ‪metalstorm_off();
159  }
160  else
161  {
162  self.state_machine ‪statemachine::set_state( self.script_startstate );
163  }
164  }
165  else
166  {
167  // Set the first state
169  }
170 
171  self thread ‪metalstorm_set_team( self.team );
172 
173  waittillframeend;
174 
175 // if( self.team == "axis" )
176 // {
177 // self.health += gameskill::getCurrentDifficultySetting( "asd_health_boost" );
178 // }
179 }
180 
182 {
183  if( !IsAlive( self ) )
184  return false;
185 
186  driver = self GetSeatOccupant( 0 );
187  if( isdefined( driver ) )
188  return false;
189 
190  return true;
191 }
192 
194 {
195  self.state_machine ‪statemachine::set_state( "scripted" );
196  self ‪vehicle::lights_off();
197  self LaserOff();
198  self ‪vehicle::toggle_tread_fx( 0 );
199  self ‪vehicle::toggle_sounds( 0 );
201  angles = self GetTagAngles( "tag_flash" );
202  target_vec = self.origin + AnglesToForward( ( 0, angles[1], 0 ) ) * 1000;
203  target_vec = target_vec + ( 0, 0, -700 );
204  self SetTargetOrigin( target_vec );
205  self.off = true;
206  if( !isdefined( self.‪emped ) )
207  {
208  self DisableAimAssist();
209  }
210 }
211 
213 {
214  self ‪vehicle::lights_on();
215  self ‪vehicle::toggle_tread_fx( 1 );
216  self EnableAimAssist();
217  self ‪vehicle::toggle_sounds( 1 );
218  self ‪bootup();
219  self playsound ("veh_metalstorm_boot_up");
221  self.off = undefined;
223 }
224 
225 function ‪bootup()
226 {
227  for( i = 0; i < 6; i++ )
228  {
229  wait 0.1;
231  wait 0.1;
233  }
234 
235  angles = self GetTagAngles( "tag_flash" );
236  target_vec = self.origin + AnglesToForward( ( 0, angles[1], 0 ) ) * 1000;
237  self.turretRotScale = 0.3;
238 
239  driver = self GetSeatOccupant( 0 );
240  if( !isdefined(driver) )
241  {
242  self SetTargetOrigin( target_vec );
243  }
244  wait 1;
245  self.turretRotScale = 1;
246 }
247 
248 function ‪metalstorm_turret_on_vis_target_thread() // Used for grenade watching
249 {
250  self endon( "death" );
251  self endon( "change_state" );
252 
253  self.turret_on_target = false;
254 
255  while( 1 )
256  {
257  self waittill( "turret_on_vistarget" );
258  self.turret_on_target = true;
260  }
261 }
262 
263 
265 {
266  self endon( "death" );
267  self endon( "change_state" );
268  self notify( "turret_on_target_thread" );
269 
270  self endon( "turret_on_target_thread" );
271 
272  self.turret_on_target = false;
273 
274  while( 1 )
275  {
276  self waittill( "turret_on_target" );
277  self.turret_on_target = true;
278  wait 0.5;
279  }
280 }
281 
282 // rotates the turret around until he can see his enemy
283 function ‪metalstorm_turret_scan( scan_forever )
284 {
285  self endon( "death" );
286  self endon( "change_state" );
287 
289 
290  self.turretRotScale = 0.35;
291 
292  while( scan_forever || ( !isdefined( self.enemy ) || !(self VehCanSee( self.enemy )) ) )
293  {
294  if( self.turret_on_target )
295  {
296  self.turret_on_target = false;
297  self.turret_state++;
298  if( self.turret_state >= ‪NUM_TURRET_STATES )
299  self.turret_state = 0;
300  }
301 
302  switch( self.turret_state )
303  {
305  if( isdefined( self.enemy ) )
306  {
307  target_vec = ( self.enemy.origin[0], self.enemy.origin[1], self.origin[2] );
308  break;
309  } // else fall through to FORWARD
310 
312  target_vec = self.origin + AnglesToForward( ( 0, self.angles[1], 0 ) ) * 1000;
313  break;
314 
316  target_vec = self.origin + AnglesToForward( ( 0, self.angles[1] + 90, 0 ) ) * 1000;
317  break;
318 
320  target_vec = self.origin + AnglesToForward( ( 0, self.angles[1], 0 ) ) * 1000;
321  break;
322 
324  target_vec = self.origin + AnglesToForward( ( 0, self.angles[1] - 90, 0 ) ) * 1000;
325  break;
326  }
327 
328  target_vec = target_vec + ( 0, 0, ‪SCAN_HEIGHT_OFFSET );
329  self SetTargetOrigin( target_vec );
330 
331  wait 0.2;
332  }
333 }
334 
335 
336 //TODO T7 - looks like this will need to get updated to support coop
338 {
339  self endon( "death" );
340  self endon( "change_state" );
341 
342  level ‪flag::wait_till( "all_players_connected" );
343 
344  while( 1 )
345  {
346  level.players[0] waittill( "grenade_fire", grenade );
347 
348  if (!IsDefined(grenade))
349  continue;
350 
351  // coming at me?
352  vel_towards_me = VectorDot( grenade GetVelocity(), VectorNormalize( self.origin - grenade.origin) );
353  if( vel_towards_me < 100 || !self VehCanSee( grenade ) )
354  continue;
355 
356  wait 0.15;
357 
358  distSq = 0;
359  if( isdefined( grenade ) )
360  {
361  distSq = DistanceSquared( self.origin, grenade.origin );
362  while( isdefined( grenade ) && ( distSq > 650 * 650 || distSq < 150 * 150 ) )
363  {
364  distSq = DistanceSquared( self.origin, grenade.origin );
366  }
367  }
368 
369  if( !isdefined( grenade ) )
370  continue;
371 
372  // double check that the granade is still coming towards me
373  vel_towards_me = VectorDot( grenade GetVelocity(), VectorNormalize( self.origin - grenade.origin) );
374  if( vel_towards_me < 100 )
375  continue;
376 
377  self SetSpeed( 0 );
378  self.turretRotScale = 2;
379  self SetTurretTargetEnt( grenade );
381 
383 
384  for( i = 0; i < 6; i++ )
385  {
386  self FireWeapon();
387 
388  if( RandomInt( 100 ) > 40 && self.turret_on_target )
389  {
390  if( isdefined( grenade ) )
391  {
392  grenade ResetMissileDetonationTime( 0 );
393  }
394  break;
395  }
396 
397  wait 0.15;
398  }
399 
400  self SetSpeed( 5, 5, 5 );
401  self ClearTurretTarget();
402  }
403 }
404 
406 {
407  self endon( "death" );
408  self endon( "change_state" );
409 
410  cant_see_enemy_count = 0;
411 
412  self thread ‪metalstorm_grenade_watcher();
413 
414  while ( 1 )
415  {
416  enemy_is_tank = false;
417  enemy_is_hind = false;
418  if( isdefined( self.enemy ) && isdefined( self.enemy.vehicletype ) )
419  {
420  enemy_is_tank = self.enemy.vehicletype == "tank_t72_rts" || self.enemy.vehicletype == "drone_claw_rts";
421  enemy_is_hind = self.enemy.vehicletype == "heli_hind_afghan_rts";
422  }
423 
424  if ( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
425  {
426  self.turretRotScale = 1;
427  self SetTurretTargetEnt( self.enemy );
428 
429  if( cant_see_enemy_count >= 2 )
430  {
431  // found enemy, react by changing goal positions
432  self ClearVehGoalPos();
433  self notify( "near_goal" );
434  }
435  cant_see_enemy_count = 0;
436 
437  //C. Ayers: Changing this to play only when locking onto a player
438  if( IsPlayer( self.enemy ) )
439  {
440  self playsound ("wpn_metalstorm_lock_on");
441  }
442  self thread ‪metalstorm_blink_lights();
443  self LaserOn();
444 
445  wait 1.0;
446 
447  if ( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
448  {
449  if( isdefined( self.enemy ) && DistanceSquared( self.origin, self.enemy.origin ) > 800 * 800 || enemy_is_tank )
450  {
451  if( enemy_is_hind ) // setup the missile guidance
452  self SetGunnerTargetEnt( self.enemy, (0,0,-40), 0 );
453 
454  // This is the missile
455  self FireWeapon( 1, self.enemy );
456 
457  self ClearGunnerTarget( 0 );
458  }
459  else
460  {
461  self ‪metalstorm_fire_for_time( RandomFloatRange( 1.5, 2.5 ) );
462  }
463  }
464 
465  self LaserOff();
466 
467  wait RandomFloatRange( 1.2, 2 );// * gameskill::getCurrentDifficultySetting( "asd_burst_scale" );
468  }
469  else
470  {
471  cant_see_enemy_count++;
472 
473  wait 0.5;
474 
475  if( cant_see_enemy_count > 2 )
476  {
477  self ‪metalstorm_turret_scan( false );
478  }
479  else if( cant_see_enemy_count > 1 )
480  {
481  self ClearTargetEntity();
482  }
483  }
484  }
485 }
486 
487 function ‪metalstorm_fire_for_time( totalFireTime )
488 {
489  self endon( "crash_done" );
490  self endon( "death" );
491 
492  weapon = self SeatGetWeapon( 0 );
493  if ( weapon == level.weaponNone )
494  return;
495 
496  fireTime = weapon.fireTime;
497  time = 0;
498 
499  while( time < totalFireTime )
500  {
501  if( isdefined( self.enemy ) && isdefined(self.enemy.attackerAccuracy) && self.enemy.attackerAccuracy == 0 )
502  {
503  self FireWeapon( 0, self.enemy );
504  }
505  else
506  {
507  self FireWeapon();
508  }
509  wait fireTime;
510  time += fireTime;
511  }
512 }
513 
514 function ‪metalstorm_start_ai( state )
515 {
516  self.goalpos = self.origin;
517 
518  if ( !isdefined( state ) )
519  state = "main";
520 
521  self.state_machine ‪statemachine::set_state( state );
522 }
523 
525 {
526  self.state_machine ‪statemachine::set_state( "scripted" );
527 }
528 
530 {
531  while( isdefined( self.‪emped ) )
532  {
533  wait 1;
534  }
535 
536  if (isdefined(self.vMaxAISpeedOverridge))
537  {
538  self SetSpeed( self.vMaxAISpeedOverridge, 5, 5 );
539  }
540  else
541  {
542  self SetSpeed( 5, 5, 5 );
543  self SetVehMaxSpeed( 0 );
544  }
545 
546  self thread ‪metalstorm_movementupdate();
547  self thread ‪metalstorm_weapon_think();
548 }
549 
550 /#
552 {
553  self endon( "death" );
554 
555  while ( 1 )
556  {
557  // no dvar, no debugging
558  if( GetDvarInt( "metalstorm_debug" ) == 0 )
559  {
560  wait( 0.5 );
561  continue;
562  }
563 
564  if ( isdefined( self.goalpos ) )
565  {
566  DebugStar( self.goalpos, 10, ( 1, 0, 0 ) );
567  Circle( self.goalpos, self.goalradius, ( 1, 0, 0 ), false, 10 );
568  }
569 
570  if ( isdefined( self.enemy ) )
571  {
572  Line( self.origin + ( 0, 0, 30 ), self.enemy.origin + ( 0, 0, 30 ), ( 1, 0, 0 ), true, 1 );
573  }
574 
576  }
577 }
578 #/
579 
580 function ‪metalstorm_check_move( position )
581 {
582  results = PhysicsTraceEx( self.origin, position, (-15,-15,-5), (15,15,5), self );
583 
584  if( results["fraction"] == 1 )
585  {
586  return true;
587  }
588 
589  return false;
590 }
591 
593 {
594  self endon( "death" );
595  self endon( "change_state" );
596  self endon( "near_goal" );
597  self endon( "reached_end_node" );
598 
599  wait 1;
600 
601  while( 1 )
602  {
603  if ( isdefined( self.enemy ) && isdefined( self.goal_node ) )
604  {
605  if( distance2dSquared( self.enemy.origin, self.origin ) < 150 * 150 )
606  {
607  self.move_now = true;
608  self notify( "near_goal" );
609  }
610  if( distance2dSquared( self.enemy.origin, self.goal_node.origin ) < 150 * 150 )
611  {
612  self.move_now = true;
613  self notify( "near_goal" );
614  }
615  }
616 
617  if( isdefined( self.goal_node ) )
618  {
619  if( distance2dSquared( self.goal_node.origin, self.goalpos ) > self.goalradius * self.goalradius )
620  {
621  wait 1;
622 
623  self.move_now = true;
624  self notify( "near_goal" );
625  }
626  }
627 
628  wait 0.2;
629  }
630 }
631 
633 {
634  self endon( "death" );
635  self endon( "change_state" );
636 
637  while( time > 0 )
638  {
639  time -= 0.2;
640  wait 0.2;
641 
642  if ( isdefined( self.enemy ) )
643  {
644  if( distance2dSquared( self.enemy.origin, self.origin ) < 150 * 150 )
645  {
646  return;
647  }
648  if ( !isdefined(self.goal_node))
649  return;
650  if( distance2dSquared( self.enemy.origin, self.goal_node.origin ) < 150 * 150 )
651  {
652  return;
653  }
654  }
655  }
656 }
657 
659 {
660  self endon( "death" );
661  self endon( "change_state" );
662 
663  if( distance2dSquared( self.origin, self.goalpos ) > 20 * 20 )
664  self SetVehGoalPos( self.goalpos, true, 2 );
665 
666  wait 0.5;
667 
668  goalfailures = 0;
669 
670  while( 1 )
671  {
673  if( self SetVehGoalPos( goalpos, false, 2 ) )
674  {
675  self thread ‪path_update_interrupt();
676 
677  goalfailures = 0;
678  self ‪util::waittill_any( "near_goal", "reached_end_node" );
679 
680  if( isdefined( self.move_now ) )
681  {
682  self.move_now = undefined;
683  wait 0.1;
684  }
685  else if( isdefined( self.enemy ) && self VehCanSee( self.enemy ) )
686  {
687  if( Abs( AngleClamp180( self.angles[0] ) ) > 6 || Abs( AngleClamp180( self.angles[2] ) ) > 6 )
688  {
689  self SetBrake( 1 );
690  }
691  ‪waittill_enemy_too_close_or_timeout( RandomFloatRange( 3, 4 ) );
692  }
693  else
694  {
695  if( Abs( AngleClamp180( self.angles[0] ) ) > 6 || Abs( AngleClamp180( self.angles[2] ) ) > 6 )
696  {
697  self SetBrake( 1 );
698  }
699  wait 0.5;
700  }
701  self SetBrake( 0 );
702  }
703  else
704  {
705  goalfailures++;
706 
707  offset = ( RandomFloatRange(-70,70), RandomFloatRange(-70,70), 15 );
708  goalpos = self.origin + offset;
709 
710  if( self ‪metalstorm_check_move( goalpos ) )
711  {
712  self SetVehGoalPos( goalpos, false );
713  self waittill( "near_goal" );
714 
715  wait 2;
716  }
717  wait 0.5;
718  }
719  }
720 }
721 
723 {
724  const sweet_spot_dist = 350;
725 
726  origin = self.goalpos;
727 
728  nodes = GetNodesInRadius( self.goalpos, self.goalradius, 0, 128, "Path" );
729 
730  /*
731  nodea = GetNode( "a", "targetname" );
732  nodeb = GetNode( "b", "targetname" );
733 
734  if( isdefined( self.goal_node ) )
735  {
736  if( self.goal_node == nodea )
737  {
738  self.goal_node = nodeb;
739  return nodeb.origin;
740  }
741  else
742  {
743  self.goal_node = nodea;
744  return nodea.origin;
745  }
746  }
747  */
748 
749  if( nodes.size == 0 )
750  {
751  self.goalpos = ( self.goalpos[0], self.goalpos[1], self.origin[2] );
752  nodes = GetNodesInRadius( self.goalpos, self.goalradius + 500, 0, 500, "Path" );
753  }
754 
755  best_node = undefined;
756  best_score = -999999;
757 
758  if ( isdefined( self.enemy ) )
759  {
760  vec_enemy_to_self = VectorNormalize( ‪FLAT_ORIGIN( self.origin ) - ‪FLAT_ORIGIN( self.enemy.origin ) );
761 
762  foreach( node in nodes )
763  {
764  vec_enemy_to_node = ( ‪FLAT_ORIGIN( node.origin ) - ‪FLAT_ORIGIN( self.enemy.origin ) );
765 
766  dist_in_front_of_enemy = VectorDot( vec_enemy_to_node, vec_enemy_to_self );
767  dist_away_from_sweet_line = Abs( dist_in_front_of_enemy - sweet_spot_dist );
768 
769  score = 1 + RandomFloat( .15 );
770 
771  if( dist_away_from_sweet_line > 100 )
772  {
773  score -= ‪math::clamp( dist_away_from_sweet_line / 800, 0, 0.5 );
774  }
775 
776  if( distance2dSquared( node.origin, self.enemy.origin ) > 550 * 550 )
777  {
778  score -= 0.2;
779  }
780 
781  if( distance2dSquared( self.origin, node.origin ) < 120 * 120 )
782  {
783  score -= 0.2;
784  }
785 
786  if( isdefined( node.metal_storm_previous_goal ) )
787  {
788  score -= 0.2;
789  node.metal_storm_previous_goal--;
790  if( node.metal_storm_previous_goal == 0 )
791  {
792  node.metal_storm_previous_goal = undefined;
793  }
794  }
795 
796  //DebugStar( node.origin, 100, ( 1, score, 1 ) );
797  //Print3d( node.origin, "Score: " + score, ( 1, 1, 1 ), 1, 1, 100 );
798 
799  if ( score > best_score )
800  {
801  best_score = score;
802  best_node = node;
803  }
804  }
805  }
806  else
807  {
808  foreach( node in nodes )
809  {
810 
811  score = RandomFloat( 1 );
812 
813  if( distance2dSquared( self.origin, node.origin ) < 100 )
814  {
815  score -= 0.5;
816  }
817 
818  if( isdefined( node.metal_storm_previous_goal ) )
819  {
820  score -= 0.2;
821  node.metal_storm_previous_goal--;
822  if( node.metal_storm_previous_goal == 0 )
823  {
824  node.metal_storm_previous_goal = undefined;
825  }
826  }
827 
828  if( score > best_score )
829  {
830  best_score = score;
831  best_node = node;
832  }
833  }
834  }
835 
836  if( isdefined( best_node ) )
837  {
838  best_node.metal_storm_previous_goal = 3;
839  origin = best_node.origin;
840  self.goal_node = best_node;
841  }
842 
843  return origin;
844 }
845 
846 // self is vehicle
848 {
849  self waittill( "exit_vehicle", player );
850 
851  player.ignoreme = false;
852  player DisableInvulnerability();
853 
854  self thread ‪metalstorm_rocket_recoil();
855  self ShowPart( "tag_pov_hide" );
856  self.goalpos = self.origin;
857 }
858 
860 {
861  self endon( "change_state" );
862 
863  driver = self GetSeatOccupant( 0 );
864  if( isdefined(driver) )
865  {
866  self.turretRotScale = 1;
867  self DisableAimAssist();
868  self HidePart( "tag_pov_hide" );
869  self thread ‪vehicle_death::vehicle_damage_filter( "firestorm_turret" );
870  self thread ‪metalstorm_set_team( driver.team );
871  self SetVehMaxSpeed( (isdefined(self.vMaxSpeedOverridge)?self.vMaxSpeedOverridge:7) );
872  driver EnableInvulnerability();
873  driver.ignoreme = true;
874  self thread ‪metalstorm_player_rocket_recoil( driver );
875  self thread ‪metalstorm_player_bullet_shake( driver );
877  self thread ‪metalstorm_exit_vehicle();
878  self SetBrake( 0 );
879  }
880 
881  self LaserOff();
882  self ClearTargetEntity();
883  self CancelAIMove();
884  self ClearVehGoalPos();
885 }
886 
888 {
889  next_damage_state = 0;
890 
891  max_health = self.healthdefault;
892  if( isdefined( self.health_max ) )
893  {
894  max_health = self.health_max;
895  }
896 
897  health_pct = self.health / max_health;
898 
899  if ( health_pct <= DAMAGE_STATE_THRESHOLD_PCT_1 && health_pct > ‪DAMAGE_STATE_THRESHOLD_PCT_2 )
900  {
901  next_damage_state = 1;
902  }
903  else if ( health_pct <= DAMAGE_STATE_THRESHOLD_PCT_2 && health_pct > ‪DAMAGE_STATE_THRESHOLD_PCT_3 )
904  {
905  next_damage_state = 2;
906  }
907  else if ( health_pct <= DAMAGE_STATE_THRESHOLD_PCT_3 && health_pct > ‪DAMAGE_STATE_THRESHOLD_PCT_4 )
908  {
909  next_damage_state = 3;
910  }
911  else if ( health_pct <= ‪DAMAGE_STATE_THRESHOLD_PCT_4 )
912  {
913  next_damage_state = 4;
914  }
915 
916  if ( next_damage_state != self.current_damage_state )
917  {
918  if ( isdefined( level.fx_damage_effects[ ‪STR_VEHICLETYPE ][ next_damage_state - 1 ] ) )
919  {
921 
922  PlayFXOnTag( level.fx_damage_effects[ ‪STR_VEHICLETYPE ][ next_damage_state - 1 ], ‪fx_ent, "tag_origin" );
923  }
924  else
925  {
926  // This will get rid of the fx ent
928  }
929 
930  self.current_damage_state = next_damage_state;
931  }
932 }
933 
935 {
936  self endon( "death" );
937 
938  self.current_damage_state = 0;
939 
940  if ( !isdefined( level.fx_damage_effects ) || !isdefined( level.fx_damage_effects[ ‪STR_VEHICLETYPE ] ) )
941  return;
942 
943  while ( 1 )
944  {
945  self waittill( "damage", ‪damage, attacker, dir, point, mod, model, modelAttachTag, part );
946 
947  if ( !isdefined( self ) )
948  return;
949 
950  if( mod == "MOD_RIFLE_BULLET" || mod == "MOD_PISTOL_BULLET" || mod == "MOD_MELEE" )
951  {
952  if( part == "tag_control_panel" || part == "tag_body_panel" )
953  {
954  ‪PlayFx( level._effect[ "metalstorm_hit_back" ], point, dir );
955  }
956  else
957  {
958  ‪PlayFx( level._effect[ "metalstorm_hit" ], point, dir );
959  }
960  }
961 
962  // when taking damage let the turret know if it is scanning to look at our enemy
963  // hopefully code will update our enemy
964  self.turret_state = ‪TURRET_STATE_SCAN_AT_ENEMY;
965  self.turretRotScale = 1.0;
966  self.turret_on_target = true;
967 
969  }
970 }
971 
973 {
974  if ( isdefined( self.damage_fx_ent ) )
975  self.damage_fx_ent Delete();
976 
977  self.damage_fx_ent = ‪Spawn( "script_model", ( 0, 0, 0 ) );
978  self.damage_fx_ent SetModel( "tag_origin" );
979  self.damage_fx_ent.origin = self.origin;
980  self.damage_fx_ent.angles = self.angles;
981  self.damage_fx_ent LinkTo( self, "tag_turret", (0,0,0), (0,0,0) );
982 
983  return self.damage_fx_ent;
984 }
985 
987 {
988  if( isdefined( self.damage_fx_ent ) )
989  {
990  self.damage_fx_ent delete();
991  }
992 
993  if( isdefined( self.stun_fx ) )
994  {
995  self.stun_fx delete();
996  }
997 }
998 
999 
1001 {
1002  self endon( "death" );
1003 
1004  self ‪vehicle::lights_off();
1005  wait 0.4;
1006  self ‪vehicle::lights_on();
1007  wait 0.3;
1008  self ‪vehicle::lights_off();
1009  wait 0.4;
1010  self ‪vehicle::lights_on();
1011  wait 0.3;
1012  self ‪vehicle::lights_off();
1013  wait 0.4;
1014  self ‪vehicle::lights_on();
1015  wait 0.3;
1016  self ‪vehicle::lights_off();
1017 }
1018 
1019 function ‪metalstorm_freeze_death( attacker, mod )
1020 {
1021  self endon( "death" );
1022 
1023  level notify( "asd_freezed" );
1024 
1025  // Just give the credit to the player for the freeze kill. Who else is going to be shooting the nitrogen containers.
1026  //level.player util::inc_general_stat( "mechanicalkills" );
1027 
1028  goalDist = RandomFloatRange( 350, 450 );
1029  deathGoal = self.origin + AnglesToForward( self.angles ) * goalDist;
1030  PlayFXOnTag( level._effect[ "freeze_short_circuit" ], self, "tag_origin" );
1031  self SetModel( "veh_t6_drone_tank_freeze" );
1032  self SetVehGoalPos( deathGoal, false );
1033  self thread ‪metalstorm_freeze_blink_lights();
1034  self ‪clientfield::set( "toggle_gas_freeze", 1 );
1035 
1036  self.turretRotScale = 0.3;
1037  self SetSpeed( 1 );
1038 
1039  if( !isdefined( self.stun_fx) )
1040  {
1041  self.stun_fx = ‪Spawn( "script_model", self.origin );
1042  self.stun_fx SetModel( "tag_origin" );
1043  self.stun_fx LinkTo( self, "tag_turret", (0,0,0), (0,0,0) );
1044  PlayFXOnTag( level._effect[ "metalstorm_stun" ], self.stun_fx, "tag_origin" );
1045  }
1046 
1047  wait 1;
1048 
1049  self.turretRotScale = 0.1;
1050  self SetSpeed( 0.5 );
1051  self LaserOff();
1052 
1053  wait 1;
1054 
1055  self.turretRotScale = 0.01;
1056  self SetSpeed( 0.0 );
1057 
1058  wait 1;
1059 
1060  self CancelAIMove();
1061  self ClearVehGoalPos();
1062  self ClearTurretTarget();
1063  //self SetBrake( 1 );
1064 
1065  wait 2;
1066 
1067  if( isdefined( self.stun_fx ) )
1068  {
1069  self.stun_fx delete();
1070  }
1071 }
1072 
1073 // Death
1074 
1076 {
1077  wait 0.1;
1078 
1079  self notify( "nodeath_thread" ); // Kill off the vehicle_death::main thread
1080 
1081  self waittill( "death", attacker, damageFromUnderneath, weapon, point, dir, mod );
1082 
1083  if( isdefined( self.eye_fx_ent ) )
1084  {
1085  self.eye_fx_ent delete();
1086  }
1087 
1088  if( isdefined( self.‪delete_on_death ) )
1089  {
1090  self ‪cleanup_fx_ents();
1091  self delete();
1092  return;
1093  }
1094 
1095  if ( !isdefined( self ) )
1096  {
1097  return;
1098  }
1099 
1101 
1102  self DisableAimAssist();
1103  self ‪vehicle::toggle_sounds( false );
1104  self ‪vehicle::lights_off();
1105  self LaserOff();
1106  self ‪cleanup_fx_ents();
1107  self ‪vehicle::toggle_tread_fx( false );
1108  self ‪vehicle::toggle_exhaust_fx( false );
1109 
1110 
1111  if( isdefined(mod) && mod == "MOD_GAS" && isdefined( level.metalstorm_freeze_death ) )
1112  {
1113  self ‪metalstorm_freeze_death( attacker, mod );
1114  }
1115  else
1116  {
1117  ‪fx_ent = self ‪get_damage_fx_ent();
1118  PlayFXOnTag( level._effect[ "metalstorm_explo" ], ‪fx_ent, "tag_origin" );
1119  self PlaySound( "veh_metalstorm_dying" );
1120 
1121  self ‪metalstorm_crash_movement( attacker );
1122  }
1123 
1124  wait 5;
1125 
1126  //self NotSolid();
1127 
1128  if ( isdefined( self ) )
1129  {
1130  radius = 18;
1131  height = 50;
1132  badplace_box( "", 40, self.origin, radius, "all" );
1133  self freeVehicle();
1134  }
1135 
1136  wait 40;
1137 
1138  if ( isdefined( self ) )
1139  {
1140  self delete();
1141  }
1142 }
1143 
1144 
1145 function ‪death_fx()
1146 {
1147  self ‪vehicle::do_death_fx();
1148  self playsound("veh_metalstorm_sparks");
1149 }
1150 
1151 function ‪metalstorm_crash_movement( attacker )
1152 {
1153  self endon( "crash_done" );
1154  self endon( "death" );
1155 
1156  self CancelAIMove();
1157  self ClearVehGoalPos();
1158 
1159  self.takedamage = 0;
1160 
1161  if( !isdefined( self.off ) )
1162  {
1163  self thread ‪death_turret_rotate();
1164  self.turretRotScale = 1.0;
1165 
1166  self PlaySound( "wpn_turret_alert" );
1167  self thread ‪metalstorm_fire_for_time( RandomFloatRange( 1.5, 4.0 ) );
1168 
1169  self SetSpeed( 7 );
1170 
1171  deathMove = RandomInt( 8 );
1172 
1173  if( deathMove == 0 )
1174  {
1175  goalDist = RandomFloatRange( 350, 450 );
1176  deathGoal = self.origin + AnglesToForward( self.angles ) * goalDist;
1177  }
1178  else if( deathMove == 1 )
1179  {
1180  goalDist = RandomFloatRange( 350, 450 );
1181  deathGoal = self.origin + AnglesToForward( self.angles ) * -goalDist;
1182  }
1183  else if( deathMove <= 4 )
1184  {
1185  self thread ‪spin_crash();
1186  }
1187  else //if( deathMove >= 4 )
1188  {
1189  if( isdefined( attacker ) )
1190  {
1191  deathGoal = attacker.origin;
1192  }
1193  else
1194  {
1195  self thread ‪spin_crash();
1196  }
1197  }
1198 
1199  if( isdefined( deathGoal ) )
1200  {
1201  self SetVehGoalPos( deathGoal, false );
1202  }
1203 
1204  wait 0.5;
1205  self ‪util::waittill_any_timeout( 2.5, "near_goal", "veh_collision" );
1206  }
1207 
1208  if( !isdefined( self ) )
1209  {
1210  return;
1211  }
1212 
1213  self CancelAIMove();
1214  self ClearVehGoalPos();
1215  self ClearTurretTarget();
1216  self SetBrake( 1 );
1217 
1219 
1220  /*if( self.team == "allies" || IsSubStr( self.vehicletype, "karma" ) )//TODO T7 - self.team is undefined
1221  {
1222  self thread vehicle_death::set_death_model( self.deathmodel, self.modelswapdelay );
1223  }
1224  else*/
1225  {
1226  self thread ‪vehicle_death::set_death_model( "veh_t6_drone_tank_alt_dead", self.modelswapdelay );
1227  }
1228 
1229  self ‪death_fx();
1230  self LaunchVehicle( ( RandomFloatRange(-20,20), RandomFloatRange(-20,20), 32 ), (RandomFloatRange(-5,5),RandomFloatRange(-5,5),0), true, false );
1231  self playsound ("exp_metalstorm_vehicle");
1232 
1233  self notify( "crash_done" );
1234 }
1235 
1236 function ‪spin_crash()
1237 {
1238  self endon( "crash_done" );
1239 
1240  turn_rate = 5 + RandomFloatRange( 0, 20 );
1241 
1242  if( RandomInt( 100 ) > 50 )
1243  {
1244  turn_rate *= -1;
1245  }
1246 
1247  count = 0;
1248 
1249  while( isdefined( self ) )
1250  {
1251  deathGoal = self.origin + AnglesToForward( (0, self.angles[1] + turn_rate, 0) ) * 300;
1252  self SetVehGoalPos( deathGoal, false );
1254 
1255  count++;
1256  if( count % 10 == 0 )
1257  {
1258  turn_rate += RandomFloatRange( -10, 10 );
1259  }
1260  }
1261 }
1262 
1263 
1264 // rotates the turret around until he can see his enemy
1266 {
1267  self endon( "crash_done" );
1268  self endon( "death" );
1269 
1270  self.turretRotScale = 1.3;
1271 
1272  while( 1 )
1273  {
1274  pitch = RandomFloatRange( -60, 20 );
1275  target_vec = self.origin + AnglesToForward( ( pitch, RandomFloat( 360 ), 0 ) ) * 1000;
1276 
1277  driver = self GetSeatOccupant( 0 );
1278  if( !isdefined(driver) ) // can't set the target on the player's vehicle
1279  {
1280  self SetTargetOrigin( target_vec );
1281  }
1282 
1283  wait RandomFloatRange( 0.3, 0.6 );
1284 
1285  if( pitch < 0 && RandomInt( 100 ) > 50 )
1286  {
1287  self FireWeapon( 1 );
1288  }
1289  }
1290 }
1291 
1293 {
1294  self endon( "death" );
1295  self notify( "emped" );
1296  self endon( "emped" );
1297 
1298  self.emped = true;
1299  PlaySoundAtPosition( "veh_asd_emp_down", self.origin );
1300  self.turretRotScale = 0.2;
1301  self ‪metalstorm_off();
1302  if( !isdefined( self.stun_fx) )
1303  {
1304  self.stun_fx = ‪Spawn( "script_model", self.origin );
1305  self.stun_fx SetModel( "tag_origin" );
1306  self.stun_fx LinkTo( self, "tag_turret", (0,0,0), (0,0,0) );
1307  PlayFXOnTag( level._effect[ "metalstorm_stun" ], self.stun_fx, "tag_origin" );
1308  }
1309 
1310  wait RandomFloatRange( 4, 8 );
1311 
1312  self.stun_fx delete();
1313 
1314  self.emped = undefined;
1315  self ‪metalstorm_on();
1316  self playsound ("veh_qrdrone_boot_asd");
1317 }
1318 
1319 function ‪MetalStormCallback_VehicleDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName )
1320 {
1321  is_damaged_by_grenade = weapon.weapClass == "grenade";
1322  is_damaged_by_god_rod = weapon.name == "god_rod";
1323  if ( is_damaged_by_grenade || is_damaged_by_god_rod )
1324  {
1325  iDamage = Int( iDamage * 3 );
1326  }
1327 
1328  if( sMeansOfDeath == "MOD_GAS" )
1329  {
1330  iDamage = self.health + 100;
1331  }
1332 
1333  driver = self GetSeatOccupant( 0 );
1334 
1335  if ( weapon.isEmp && sMeansOfDeath != "MOD_IMPACT" )
1336  {
1337  if( !isdefined(driver) )
1338  {
1339  self thread ‪metalstorm_emped();
1340  }
1341  }
1342 
1343  if( isdefined( driver ) )
1344  {
1345  // Lets get some hit indicators
1346  //driver FinishPlayerDamage( eInflictor, eAttacker, 1, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, "none", 0, psOffsetTime );
1347  }
1348 
1349  return iDamage;
1350 }
1351 
1352 
1353 function ‪metalstorm_set_team( team )
1354 {
1355  self.team = team;
1356  if( isdefined( self.vehmodelenemy ) )
1357  {
1358  if( team == "allies" )
1359  {
1360  self SetModel( self.vehmodel );
1361  }
1362  else
1363  {
1364  self SetModel( self.vehmodelenemy );
1365  }
1366  }
1367 
1368  if( !isdefined( self.off ) )
1369  {
1371  }
1372 }
1373 
1375 {
1376  self endon( "death" );
1377 
1378  self ‪vehicle::lights_off();
1379  wait 0.1;
1380  self ‪vehicle::lights_on();
1381  wait 0.1;
1382  self ‪vehicle::lights_off();
1383  wait 0.1;
1384  self ‪vehicle::lights_on();
1385 }
1386 
1388 {
1389  self endon( "death" );
1390  self endon( "recoil_thread" );
1391 
1392  while( 1 )
1393  {
1394  self waittill( "turret_fire" );
1395  angles = self GetTagAngles( "tag_barrel" );
1396  dir = AnglesToForward( angles );
1397  self LaunchVehicle( dir * -5, self.origin + (0,0,30), false );
1398  Earthquake( 0.2, 0.2, player.origin, 200 );
1399  }
1400 }
1401 
1403 {
1404  self notify( "recoil_thread" );
1405  self endon( "recoil_thread" );
1406  self endon( "death" );
1407 
1408  while( 1 )
1409  {
1410  player waittill( "missile_fire" );
1411 
1412  angles = self GetTagAngles( "tag_barrel" );
1413  dir = AnglesToForward( angles );
1414 
1415  self LaunchVehicle( dir * -30, self.origin + (0,0,70), false );
1416  Earthquake( 0.4, 0.3, player.origin, 200 );
1417 
1418  //self SetAnimRestart( %vehicles::o_drone_tank_missile_fire_sp, 1, 0, 0.4 );
1419  }
1420 }
1421 
1423 {
1424  self notify( "recoil_thread" );
1425  self endon( "recoil_thread" );
1426  self endon( "death" );
1427 
1428  while( 1 )
1429  {
1430  self waittill( "missile_fire" );
1431 
1432  angles = self GetTagAngles( "tag_barrel" );
1433  dir = AnglesToForward( angles );
1434 
1435  self LaunchVehicle( dir * -30, self.origin + (0,0,70), false );
1436 
1437  //self SetAnimRestart( %vehicles::o_drone_tank_missile_fire_sp, 1, 0, 0.4 );
1438  }
1439 }
1440 
1442 {
1443  self endon( "exit_vehicle" );
1444  self endon( "death" );
1445 
1446  while( 1 )
1447  {
1448  self waittill( "touch", enemy );
1449 
1450  if( isdefined( enemy ) && IsAI( enemy ) )
1451  {
1452  self playsound( "veh_rts_hit_npc" );
1453  wait 0.3;
1454  }
1455  }
1456 }
‪set_death_model
‪function set_death_model(sModel, fDelay)
Definition: vehicle_death_shared.gsc:258
‪metalstorm_find_new_position
‪function metalstorm_find_new_position()
Definition: _metal_storm.gsc:722
‪add_interrupt_connection
‪function add_interrupt_connection(from_state_name, to_state_name, on_notify, checkfunc)
Definition: statemachine_shared.gsc:90
‪metalstorm_off
‪function metalstorm_off()
Definition: _metal_storm.gsc:193
‪STR_VEHICLETYPE
‪#define STR_VEHICLETYPE
Definition: _metal_storm.gsc:37
‪NUM_DAMAGE_STATES
‪#define NUM_DAMAGE_STATES
Definition: _metal_storm.gsc:22
‪add_state
‪function add_state(name, enter_func, update_func, exit_func, reenter_func)
Definition: statemachine_shared.gsc:59
‪lights_off
‪function lights_off(localClientNum)
Definition: vehicle_shared.csc:652
‪set_state
‪function set_state(name, state_params)
Definition: statemachine_shared.gsc:133
‪metalstorm_freeze_death
‪function metalstorm_freeze_death(attacker, mod)
Definition: _metal_storm.gsc:1019
‪__init__
‪function __init__()
Definition: _metal_storm.gsc:56
‪DAMAGE_STATE_THRESHOLD_PCT_2
‪#define DAMAGE_STATE_THRESHOLD_PCT_2
Definition: _metal_storm.gsc:24
‪vehicle_damage_filter
‪function vehicle_damage_filter(vision_set, heavy_damage_threshold, filterid=0, b_use_player_damage=false)
Definition: vehicle_death_shared.gsc:1392
‪SCAN_HEIGHT_OFFSET
‪#define SCAN_HEIGHT_OFFSET
Definition: _metal_storm.gsc:28
‪toggle_tread_fx
‪function toggle_tread_fx(on)
Definition: vehicle_shared.gsc:3357
‪metalstorm_turret_on_vis_target_thread
‪function metalstorm_turret_on_vis_target_thread()
Definition: _metal_storm.gsc:248
‪metalstorm_turret_scan
‪function metalstorm_turret_scan(scan_forever)
Definition: _metal_storm.gsc:283
‪get_damage_fx_ent
‪function get_damage_fx_ent()
Definition: _metal_storm.gsc:972
‪metalstorm_scripted
‪function metalstorm_scripted()
Definition: _metal_storm.gsc:859
‪fx_ent
‪var fx_ent
Definition: traps_shared.gsc:2008
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪toggle_exhaust_fx
‪function toggle_exhaust_fx(on)
Definition: vehicle_shared.gsc:3335
‪NUM_TURRET_STATES
‪#define NUM_TURRET_STATES
Definition: _metal_storm.gsc:35
‪can_enter_main
‪function can_enter_main()
Definition: _metal_storm.gsc:181
‪TURRET_STATE_SCAN_AT_ENEMY
‪#define TURRET_STATE_SCAN_AT_ENEMY
Definition: _metal_storm.gsc:30
‪spin_crash
‪function spin_crash()
Definition: _metal_storm.gsc:1236
‪metalstorm_crash_movement
‪function metalstorm_crash_movement(attacker)
Definition: _metal_storm.gsc:1151
‪death_cleanup_level_variables
‪function death_cleanup_level_variables()
Definition: vehicle_death_shared.gsc:1144
‪waittill_any_timeout
‪function waittill_any_timeout(n_timeout, string1, string2, string3, string4, string5)
Definition: util_shared.csc:423
‪metalstorm_player_hit_dudes_sound
‪function metalstorm_player_hit_dudes_sound()
Definition: _metal_storm.gsc:1441
‪metalstorm_think
‪function metalstorm_think()
Definition: _metal_storm.gsc:119
‪metalstorm_emped
‪function metalstorm_emped()
Definition: _metal_storm.gsc:1292
‪metalstorm_check_move
‪function metalstorm_check_move(position)
Definition: _metal_storm.gsc:580
‪TURRET_STATE_SCAN_LEFT
‪#define TURRET_STATE_SCAN_LEFT
Definition: _metal_storm.gsc:34
‪MetalStormCallback_VehicleDamage
‪function MetalStormCallback_VehicleDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, modelIndex, partName)
Definition: _metal_storm.gsc:1319
‪metalstorm_player_rocket_recoil
‪function metalstorm_player_rocket_recoil(player)
Definition: _metal_storm.gsc:1402
‪death_radius_damage
‪function death_radius_damage(meansOfDamage="MOD_EXPLOSIVE")
Definition: vehicle_death_shared.gsc:1196
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪metalstorm_update_damage_fx
‪function metalstorm_update_damage_fx()
Definition: _metal_storm.gsc:887
‪TURRET_STATE_SCAN_FORWARD2
‪#define TURRET_STATE_SCAN_FORWARD2
Definition: _metal_storm.gsc:33
‪metalstorm_death
‪function metalstorm_death()
Definition: _metal_storm.gsc:1075
‪update_damage_states
‪function update_damage_states()
Definition: _metal_storm.gsc:934
‪metalstorm_grenade_watcher
‪function metalstorm_grenade_watcher()
Definition: _metal_storm.gsc:337
‪metalstorm_stop_ai
‪function metalstorm_stop_ai()
Definition: _metal_storm.gsc:524
‪DAMAGE_STATE_THRESHOLD_PCT_4
‪#define DAMAGE_STATE_THRESHOLD_PCT_4
Definition: _metal_storm.gsc:26
‪metalstorm_blink_lights
‪function metalstorm_blink_lights()
Definition: _metal_storm.gsc:1374
‪TURRET_STATE_SCAN_FORWARD
‪#define TURRET_STATE_SCAN_FORWARD
Definition: _metal_storm.gsc:31
‪metalstorm_weapon_think
‪function metalstorm_weapon_think()
Definition: _metal_storm.gsc:405
‪death_fx
‪function death_fx()
Definition: _metal_storm.gsc:1145
‪metalstorm_set_team
‪function metalstorm_set_team(team)
Definition: _metal_storm.gsc:1353
‪waittill_any
‪function waittill_any(str_notify1, str_notify2, str_notify3, str_notify4, str_notify5)
Definition: util_shared.csc:375
‪create
‪function create(name, origin, team, shader, alpha, scale)
Definition: objpoints_shared.gsc:32
‪metalstorm_rocket_recoil
‪function metalstorm_rocket_recoil()
Definition: _metal_storm.gsc:1422
‪metalstorm_player_bullet_shake
‪function metalstorm_player_bullet_shake(player)
Definition: _metal_storm.gsc:1387
‪death_turret_rotate
‪function death_turret_rotate()
Definition: _metal_storm.gsc:1265
‪cleanup_fx_ents
‪function cleanup_fx_ents()
Definition: _metal_storm.gsc:986
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪metalstorm_start_ai
‪function metalstorm_start_ai(state)
Definition: _metal_storm.gsc:514
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪waittill_enemy_too_close_or_timeout
‪function waittill_enemy_too_close_or_timeout(time)
Definition: _metal_storm.gsc:632
‪metalstorm_debug
‪function metalstorm_debug()
Definition: _metal_storm.gsc:551
‪bootup
‪function bootup()
Definition: _metal_storm.gsc:225
‪TURRET_STATE_SCAN_RIGHT
‪#define TURRET_STATE_SCAN_RIGHT
Definition: _metal_storm.gsc:32
‪emped
‪function emped(down_time)
Definition: _siegebot.gsc:1359
‪Spawn
‪function Spawn(parent, onDeathCallback)
Definition: _flak_drone.gsc:427
‪DAMAGE_STATE_THRESHOLD_PCT_3
‪#define DAMAGE_STATE_THRESHOLD_PCT_3
Definition: _metal_storm.gsc:25
‪metalstorm_on
‪function metalstorm_on()
Definition: _metal_storm.gsc:212
‪main
‪function main()
Definition: _metal_storm.gsc:109
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪metalstorm_main
‪function metalstorm_main()
Definition: _metal_storm.gsc:529
‪metalstorm_exit_vehicle
‪function metalstorm_exit_vehicle()
Definition: _metal_storm.gsc:847
‪metalstorm_turret_on_target_thread
‪function metalstorm_turret_on_target_thread()
Definition: _metal_storm.gsc:264
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪FLAT_ORIGIN
‪#define FLAT_ORIGIN(__origin)
Definition: shared.gsh:256
‪do_death_fx
‪function do_death_fx()
Definition: vehicle_shared.gsc:2855
‪metalstorm_fire_for_time
‪function metalstorm_fire_for_time(totalFireTime)
Definition: _metal_storm.gsc:487
‪clamp
‪function clamp(val, val_min, val_max)
Definition: math_shared.csc:16
‪toggle_sounds
‪function toggle_sounds(on)
Definition: vehicle_shared.gsc:3379
‪path_update_interrupt
‪function path_update_interrupt()
Definition: _metal_storm.gsc:592
‪precache_damage_fx
‪function precache_damage_fx()
Definition: _metal_storm.gsc:81
‪delete_on_death
‪function delete_on_death(ent)
Definition: util_shared.gsc:1796
‪metalstorm_movementupdate
‪function metalstorm_movementupdate()
Definition: _metal_storm.gsc:658
‪metalstorm_freeze_blink_lights
‪function metalstorm_freeze_blink_lights()
Definition: _metal_storm.gsc:1000
‪lights_on
‪function lights_on(localClientNum, team)
Definition: vehicle_shared.csc:404
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪PlayFx
‪function PlayFx(name)
Definition: _counteruav.gsc:390