‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
traps_shared.gsc
Go to the documentation of this file.
1 /*
2  * Created by ScriptDevelop.
3  * User: hschmitt
4  * Date: 11/20/2013
5  * Time: 3:22 PM
6  *
7  * To change this template use Tools | Options | Coding | Edit Standard Headers.
8  */
9 
10 #insert scripts\shared\shared.gsh;
11 
12 #using scripts\codescripts\struct;
13 
14 #using scripts\shared\array_shared;
15 #using scripts\shared\callbacks_shared;
16 #using scripts\shared\flag_shared;
17 #using scripts\shared\math_shared;
18 #using scripts\shared\spawner_shared;
19 #using scripts\shared\system_shared;
20 #using scripts\shared\trigger_shared;
21 #using scripts\shared\util_shared;
22 
23 
24 #define ALERT_NONE 0
25 #define ALERT_SCANNING 1
26 #define ALERT_SEE 2
27 
28 #namespace traps;
29 
30 #precache( "fx", "_t6/_prototype/fx_pro_temp_searchlight" );
31 #precache( "fx", "_t6/_prototype/fx_pro_temp_searchlight_grn" );
32 #precache( "fx", "_t6/_prototype/fx_pro_temp_searchlight_red" );
33 #precache( "fx", "_t6/_prototype/fx_pro_temp_searchlight_ylw" );
34 #precache( "fx", "_t6/_prototype/fx_pro_temp_explosion_md" );
35 #precache( "fx", "weapon/fx_muz_sm_gas_flash_3p" );
36 #precache( "fx", "_t6/_prototype/fx_pro_temp_light_blink_red" );
37 #precache( "fx", "_t6/_prototype/fx_pro_temp_sparks_elec_disabled" );
38 #precache( "fx", "_t6/_prototype/fx_pro_temp_steam_cooldown" );
39 #precache( "fx", "_t6/_prototype/fx_pro_temp_laser_beam_deathray" );
40 #precache( "fx", "_t6/_prototype/fx_pro_temp_laser_trail_deathray" );
41 
42 ‪REGISTER_SYSTEM( "traps", &‪__init__, undefined )
43 
44 function ‪__init__()
45 {
47 
48  // custom fx
49  level._effect["camera_light_fx"] = "_t6/_prototype/fx_pro_temp_searchlight"; // generic searchlight
50  level._effect["camera_light_fx_grn"] = "_t6/_prototype/fx_pro_temp_searchlight_grn"; // security not alerted, player not in sight of this camera
51  level._effect["camera_light_fx_red"] = "_t6/_prototype/fx_pro_temp_searchlight_red"; // player sighted by camera
52  level._effect["camera_light_fx_ylw"] = "_t6/_prototype/fx_pro_temp_searchlight_ylw"; // security alerted, but player not in sight of this camera
53  level._effect["temp_explosion_md"] = "_t6/_prototype/fx_pro_temp_explosion_md"; // generic explosion
54  level._effect["railturret_muzzle_flash"] = "weapon/fx_muz_sm_gas_flash_3p"; // muzzle flash for rail turret
55  level._effect["security_light_red"] = "_t6/_prototype/fx_pro_temp_light_blink_red"; // blinks red when security in an area is alerted
56  level._effect["electrical_sparks"] = "_t6/_prototype/fx_pro_temp_sparks_elec_disabled"; // death effect for cameras (damage effect for turrets?)
57  level._effect["steam_cooldown"] = "_t6/_prototype/fx_pro_temp_steam_cooldown"; // cooldown effect for turrets
58  // deathray fx
59  level._effect["deathray_beam"] = "_t6/_prototype/fx_pro_temp_laser_beam_deathray";
60  level._effect["deathray_trail"] = "_t6/_prototype/fx_pro_temp_laser_trail_deathray";
61 
62  level thread ‪setup_all_traps();
63 }
64 
66 {
67  level ‪flag::wait_till( "all_players_connected" );
68 
69  // create all security systems (security systems will then spawn any associated traps)
70  level.prototype_secsystems = [];
71 
72  a_secsystem_structs = ‪struct::get_array( "area_security", "targetname" );
73  foreach( secsystem_struct in a_secsystem_structs )
74  {
75  Assert( isdefined( secsystem_struct.script_noteworthy ), "secsystem_struct.script_noteworthy not found" );
76 
77  str_secsystem_name = secsystem_struct.script_noteworthy;
78 
79  o_secsystem = new ‪cSecuritySystem();
80  [[ o_secsystem ]]->setup_secsystem( secsystem_struct );
81  ‪ARRAY_ADD( level.prototype_secsystems, o_secsystem );
82  }
83 }
84 
85 function ‪precache_all()
86 {
87 
88 }
89 
90 //*****************************************************************************
91 // SECURITY SYSTEM OBJECT
92 //
93 // -handles security states for an area
94 // -security detectors, alert consequences, and interaction points are associated to a security system via script_noteworthy
95 // -to create a security system in the level, make a struct with the targetname "area_security", and a unique script_noteworthy
96 //
97 //*****************************************************************************
98 
100 {
101  // security stats
102  var ‪e_secsystem; // security system struct
103  var ‪str_secsystem_name; // name for the security area (script_noteworthy from the struct)
104  var ‪n_alert_level; // 0 - no alert, 1 - scanning area, 2 - high alert
105  var ‪n_alert_cooldown; // set number of seconds until security cools down
106  var ‪n_alert_remaining_cooldown; // seconds remaining on current cooldown
107  var ‪v_player_last_known_pos; // the last place the player was when detected by any security device (camera or turret scan, tripwire, pressure plate, etc.)
108  var ‪n_security_node_count; // number of security nodes
109  var ‪n_detector_count; // number of detectors (tripwires, cameras, active turrets, active robots)
110  var ‪b_secsystem_can_reactivate; // whether the security system can recover after a cooldown (gets set to false if the system has been disabled via panel, destroying security nodes, etc.
111 
112  // security assets
113  var ‪a_SecurityDoors; // security doors associated with the area
114  var ‪a_SecurityCrushers; // security crushers associated with the area
115  var ‪a_SecurityBlockers; // security blockers associated with the area
116  var ‪a_LaserTripwires; // laser tripwire objects associated with the area
117  var ‪a_Cameras; // security camera objects associated with the area
118  var ‪a_RailTurrets; // rail turrets associated with the area
119  var ‪a_SpiderBots; // spider bots - cling to wall in a radius around their spawner
120  var ‪a_Quadrotors; // security quadrotors
121  var ‪a_SecurityLights; // toggleable lights to convey security alert state
122  var ‪a_SecurityNodes; // security node brushmodels - destroy all to deactivate security (if there are no security nodes associated with the script_noteworthy, this doesn't apply)
123  var ‪a_SecurityPanels; // security panel triggers - use to deactivate security
124  var ‪a_SecurityReversePanels; // security reverse panels - use to reverse specific security elements' behavior
125 
127  {
128  ‪n_alert_level = 0; // 0 - no alert
129  ‪n_alert_cooldown = 10;
133  self ‪flag::init( "secsystem_on" );
134  self ‪flag::init( "turrets_spawned" );
135  }
136 
138  {
139  }
140 
141  function ‪setup_secsystem( secsystem )
142  {
143  Assert( isdefined( secsystem ), "cSecuritySystem->setup_secsystem - secsystem doesn't exist - error in calling function" );
144  ‪e_secsystem = secsystem;
145  ‪str_secsystem_name = ‪e_secsystem.script_noteworthy;
146 
147  if ( isdefined( ‪e_secsystem.script_int ) )
148  {
149  ‪n_alert_cooldown = ‪e_secsystem.script_int;
150 
151  // cooldown of 0 means that the security system is a once-off
152  if ( ‪n_alert_cooldown == 0 )
153  {
155  }
156  }
157 
158  // set active flag
159  self ‪flag::set( "secsystem_on" );
160 
161  // setup detectors
162  ‪a_LaserTripwires = ‪setup_in_array( "laser_tripwire" );
163  ‪a_Cameras = ‪setup_in_array( "security_camera" );
164  // setup consequences
165  ‪a_SecurityDoors = ‪setup_in_array( "security_door" );
166  ‪a_SecurityCrushers = ‪setup_in_array( "security_crusher" );
167  ‪a_SecurityLights = ‪setup_in_array( "security_light" );
168  ‪a_SecurityBlockers = ‪setup_in_array( "security_blocker" );
169  // setup interactables
170  ‪a_SecurityPanels = ‪setup_in_array( "security_shutdown_panel" );
171  ‪a_SecurityReversePanels = ‪setup_in_array( "security_reverse_panel" );
172  ‪a_SecurityNodes = ‪setup_in_array( "security_node" );
173 
174  // option to start security system on
175  if ( isdefined( ‪e_secsystem.script_string ) )
176  {
177  if ( ‪e_secsystem.script_string == "start" )
178  {
180  }
181  }
182  else // ordinary security response thread
183  {
184  self thread ‪respond_to_alert_level();
185  }
186  }
187 
188  function ‪setup_in_array( str_targetname )
189  {
190  a_OutputArray = [];
191  a_things = GetEntArray( str_targetname, "targetname" );
192  // get struct if not using ents
193  if ( a_things.size == 0 )
194  {
195  a_things = ‪struct::get_array( str_targetname, "targetname" );
196  }
197 
198  foreach ( thing in a_things )
199  {
200  if ( !isdefined( thing.script_noteworthy ) )
201  {
202  continue;
203  }
204 
205  if ( thing.script_noteworthy != ‪str_secsystem_name )
206  {
207  continue;
208  }
209 
210  o_Thing = ‪new_object_of_type( str_targetname );
211  thread [[ o_Thing ]]->setup( thing, self );
212  ‪ARRAY_ADD( a_OutputArray, o_Thing );
213  // increase security node count if applicable
214  if ( str_targetname == "security_node" )
215  {
217  }
218  if ( ( str_targetname == "laser_tripwire" ) || ( str_targetname == "security_camera" ) )
219  {
221  }
222  }
223 
224  return a_OutputArray;
225  }
226 
227  function ‪new_object_of_type( str_targetname )
228  {
229  switch( str_targetname )
230  {
231  case "security_door":
232  return new ‪cSecurityDoor();
233  case "security_crusher":
234  return new cSecurityCrusher();
235  case "security_shutdown_panel":
236  return new cSecurityShutdownPanel();
237  case "security_reverse_panel":
238  return new ‪cSecurityReversePanel();
239  case "security_node":
240  return new cSecurityNode();
241  case "laser_tripwire":
242  return new cLaserTripwire();
243  case "security_camera":
244  return new cSecurityCamera();
245  case "security_light":
246  return new ‪cSecurityLight();
247  case "security_blocker":
248  return new cSecurityBlocker();
249  }
250  }
251 
252  // reverse all blockers
254  {
255  foreach( o_blocker in ‪a_SecurityBlockers )
256  {
257  [[ o_blocker ]]->reverse();
258  }
259  }
260 
261  // call this whenever the player is detected
263  {
264  player = level.players[0];
265  ‪v_player_last_known_pos = player.origin;
266  }
267 
269  {
271  if ( ‪n_detector_count < 1 )
272  {
274  }
275  }
276 
278  {
280  if ( ‪n_security_node_count < 1 )
281  {
283  ‪deactivate_spawned(); // if we continue this, find a better way of handling security system state, differentiating between cooldown and deactivation, and cleanly handling deactivation of spawned patrolling entities post-cooldown
284  }
285  }
286 
288  {
289  return ‪n_alert_level;
290  }
291 
292  function ‪set_alert_level( n_target_alert_level )
293  {
294  if ( !isdefined( n_target_alert_level ) )
295  {
296  n_target_alert_level = ‪n_alert_level + 1;
297  }
298 
299  // clamp min/max
300  if ( n_target_alert_level < 0 )
301  {
302  return;
303  }
304  else if ( n_target_alert_level > 2 )
305  {
306  return;
307  }
308  else
309  {
310  // reset cooldown
311  if ( n_target_alert_level > 0 )
312  {
314  }
315 
316  // set alert level (do this after setting cooldown so we don't fall straight through)
317  ‪n_alert_level = n_target_alert_level;
318  }
319 
320  }
321 
323  {
324  while ( true )
325  {
326  while ( ‪n_alert_level == 0 )
327  {
329  }
330 
331  ‪raise_alert();
332  }
333  }
334 
335  function ‪raise_alert()
336  {
337  self endon( "cooldown" );
338 
340 
341  // wait until cooldown is expended
342  while ( ‪n_alert_remaining_cooldown > 0 )
343  {
344  wait 1;
346  }
347 
349 
350  ‪set_alert_level( ‪ALERT_NONE ); // reset alert level
351  }
352 
354  {
356 
357  if ( !self ‪flag::get( "turrets_spawned" ) )
358  {
359  self ‪flag::set( "turrets_spawned" );
361  }
362 
363  // activate consequences
365  }
366 
368  {
369  PlaySoundAtPosition( "vox_inter_security_reset_0", level.players[0].origin ); // "security reset" VO - play over intercom
370 
371  // deactivate consequences
373 
374  // reactivate tripped detectors
376  }
377 
379  {
380  ‪set_alert_level( ‪ALERT_NONE ); // reset alert level
381  self ‪flag::clear( "secsystem_on" );
382  self notify( "cooldown" ); // end any existing alert-cooldown sequence
383 
384  PlaySoundAtPosition( "vox_inter_security_deactivated_0", level.players[0].origin ); // "security deactivated" VO - play over intercom
385 
388 
390  }
391 
393  {
397  }
398 
400  {
404  }
405 
407  {
410  }
411 
413  {
415  }
416 
418  {
420  {
423  }
424  }
425 
426  // functions for activating / deactivating / reactivating all in an array
427  function ‪activate_all_in_array( a_things )
428  {
429  foreach( o_thing in a_things )
430  {
431  [[ o_thing ]]->activate();
432  }
433  }
434 
435  function ‪deactivate_all_in_array( a_things )
436  {
437  if ( !isdefined( a_things ) )
438  {
439  return;
440  }
441 
442  foreach( o_thing in a_things )
443  {
444  [[ o_thing ]]->deactivate();
445  }
446  }
447 
448  function ‪reactivate_all_in_array( a_things )
449  {
450  foreach( o_thing in a_things )
451  {
452  [[ o_thing ]]->reactivate();
453  }
454  }
455 
456  function ‪set_security_lights( b_lights_on )
457  {
458  light_intensity = 0;
459 
460  if ( b_lights_on )
461  {
462  light_intensity = 1;
463  }
464 
465  foreach( light in ‪a_SecurityLights )
466  {
467  // server-side light functions deprecated
468  }
469  }
470 
471  function ‪spawn_turrets()
472  {
473  ‪a_RailTurrets = [];
474  a_railturret_structs = ‪struct::get_array( "railturret_spawn", "targetname" );
475 
476  foreach( railturret_struct in a_railturret_structs )
477  {
478  if ( !isdefined( railturret_struct.script_noteworthy ) )
479  {
480  /# PrintLn( "railturret_struct.script_noteworthy not found" ); #/
481  continue;
482  }
483 
484  if ( railturret_struct.script_noteworthy != ‪str_secsystem_name )
485  {
486  continue;
487  }
488 
489  if ( isdefined( railturret_struct.script_string ) && ( railturret_struct.script_string == "rocket" ) )
490  {
491  o_railturret = new cMissileTurret();
492  [[ o_railturret ]]->spawn_at_struct( railturret_struct, self );
493  ‪ARRAY_ADD( ‪a_RailTurrets, o_railturret );
494  }
495  else
496  {
497  o_railturret = new ‪cRailTurret();
498  [[ o_railturret ]]->spawn_at_struct( railturret_struct, self );
499  ‪ARRAY_ADD( ‪a_RailTurrets, o_railturret );
500  }
501 
502 
503 
504  // turret counts as a potential detector (can sight the player to bring you out of cooldown)
506  }
507  }
508 
509 }
510 
511 //
512 // Laser Tripwires
513 //
514 // For each laser tripwire, place a trigger volume and a script_brushmodel for the visible beam.
515 //
516 // The trigger volume needs:
517 //
518 // � targetname �laser_tripwire�
519 // � target = the targetname of the visible beam script_brushmodel(s), so we know which ones to turn off when triggered
520 // � script_noteworthy = whatever name you put in for the security system
521 // � Laser tripwires can move back and forth; set the script_vector kvp to set their movement displacement, and script_int to set the amount of time it takes
522 // � If a laser tripwire uses a trigger_multiple, it will reactivate after the security system cools down; otherwise, it will be a one-off
523 //
524 class cLaserTripwire
525 {
526  var ‪t_laser; // trigger for the laser field
527  var ‪m_o_secsystem; // associated security system object
528  var ‪e_visible_laser; // script brushmodel representing the laser
529  var ‪b_visible_laser_exists; // whether we are using a visual laser or a script_origin brushmodel
530  var ‪b_laser_can_reactivate; // whether laser can reactivate on security system cooldown; is decided by whether the trigger is a trigger_multiple or not
531  var ‪b_camera_shake; // whether to play a camera shake upon activation
532  // movement [optional]
535  var ‪n_laser_movement_duration; // time it takes for the laser to move to its duration and back
536 
538  {
539  self ‪flag::init( "laser_on" );
540  ‪b_camera_shake = false;
543  ‪n_laser_movement_duration = 10; // default timing - overridden by .script_int on the trigger
544  }
545 
547  {
548  }
549 
550  function ‪setup( trigger, secsystem )
551  {
552  self ‪flag::set( "laser_on" );
553  ‪t_laser = trigger;
554  ‪m_o_secsystem = secsystem;
555 
556  if ( isdefined( ‪t_laser.target ) )
557  {
558  ‪e_visible_laser = GetEnt( ‪t_laser.target, "targetname" );
559  ‪e_visible_laser playloopsound( "evt_laser_loop", 1 );
561  }
562  else // still need the right type of entity to be able to move the laser
563  {
564  ‪e_visible_laser = ‪util::spawn_model( "script_origin", ‪t_laser.origin, ‪t_laser.angles );
565  ‪e_visible_laser Hide();
567  }
568 
569  if( isdefined( ‪t_laser.script_vector ) )
570  {
571  self thread ‪laser_movement();
572  }
573 
574  if( isdefined( ‪t_laser.script_string ) )
575  {
576  if ( ‪t_laser.script_string == "shake" )
577  {
578  ‪b_camera_shake = true;
579  }
580  }
581 
582  if( ‪t_laser.classname == "trigger_multiple" )
583  {
585  }
586 
587  self thread ‪laser_awareness();
588  }
589 
591  {
592  do
593  {
594  ‪t_laser waittill( "trigger", e_other );
595  if ( self ‪flag::get( "laser_on" ) )
596  {
597  self ‪flag::clear( "laser_on" );
598 
599  // optional camera shake, if script_string was set to "shake" (use for triggering pressure plates)
600  if( ‪b_camera_shake )
601  {
602  Earthquake( 1, 2, level.players[0].origin, 64 );
603  }
604 
605  // only play VO and sfx if this is a visible trigger
607  {
608  PlaySoundAtPosition( "vox_inter_laser_tripped_0", level.players[0].origin );
609  ‪e_visible_laser stoploopsound( .1 );
610  PlaySoundAtPosition( "evt_laser_tripped", ‪e_visible_laser.origin );
611  ‪hide_laser();
612  }
613 
614  // alert security system object
615  [[ ‪m_o_secsystem ]]->set_alert_level( ‪ALERT_SCANNING );
616 
617  // laser resets when the security alert level returns to 0
618  self ‪flag::wait_till( "laser_on" );
619  }
620  }
621  while( ‪b_laser_can_reactivate );
622  }
623 
624  function ‪laser_movement()
625  {
626  ‪v_laser_origin = ‪t_laser.origin;
628  if ( isdefined( ‪t_laser.script_float ) )
629  {
631  }
632  else if ( isdefined( ‪t_laser.script_int ) )
633  {
635  }
636 
637  ‪t_laser EnableLinkTo();
638  ‪t_laser LinkTo( ‪e_visible_laser );
639 
640  while( true )
641  {
646  }
647  }
648 
649  function ‪deactivate()
650  {
651  self ‪flag::clear( "laser_on" );
652  ‪hide_laser();
653  }
654 
655  function ‪activate()
656  {
657  self ‪flag::set( "laser_on" );
658  ‪show_laser();
659  }
660 
661  function ‪reactivate()
662  {
664  {
665  ‪activate();
666  }
667  }
668 
669  function ‪show_laser()
670  {
672  {
673  ‪e_visible_laser Show();
674  }
675  }
676 
677  function ‪hide_laser()
678  {
680  {
681  ‪e_visible_laser Hide();
682  }
683  }
684 
685 }
686 
687 
688 // generic security mover class
689 // right now this is for simple things that define a script_vector to move along a set displacement
690 // potential children of this are things like doors, crushers, retractable bridges and dynamic cover
692 {
693  var ‪e_mover; // script_brushmodel for the mover
694  var ‪m_o_secsystem; // associated security system object
695  var ‪e_mover_broken; // broken variant of script_brushmodel, if needed
696  var ‪e_rotation_origin; // script_origin spawned to be the rotation point, if script_linkto is defined
697  // movement
698  var ‪v_startpos; // start position vector
699  var ‪v_endpos; // end position vector
700  var ‪v_startangles; // start position angles (used if b_is_rotator is true)
701  var ‪v_endangles; // end position angles (used if b_is_rotator is true)
702  var ‪n_delay_before_movement; // delay before movement
703  var ‪n_movement_duration; // how long the mover takes to go from v_startpos to v_endpos
704  var ‪n_resttime; // how long the mover rests at its destinations
705  // pathing
706  var ‪a_pathstructs; // array of path structs, if defined by setting .target kvp
707  var ‪n_total_path_dist; // total distance from v_startpos to the end of the path
708  var ‪n_current_path_index; // which struct in a_pathstructs will the mover encounter next, if moving forwards along the path?
709  // other
710  var ‪b_is_rotator; // whether to interpret movement as rotation along script_vector angles
711  var ‪b_is_breakable; // whether to allow the mover to be destroyed by explosive weapons
712  var ‪b_is_broken; // use to make sure we don't try to move a broken wall
713 
715  {
716  ‪n_resttime = 1;
720  ‪b_is_rotator = false;
721  ‪b_is_breakable = false;
722  ‪b_is_broken = false;
723  }
724 
726  {
727  }
728 
729  function ‪setup_mover( mover )
730  {
731  Assert( isdefined( mover ), "cSecurityMover->setup_mover() - valid mover not passed in, error in calling function" );
732  ‪e_mover = mover;
733  ‪v_startpos = ‪e_mover.origin;
734  ‪v_startangles = ‪e_mover.angles;
735 
736  if ( isdefined( ‪e_mover.script_string ) )
737  {
738  if ( IsSubStr( ‪e_mover.script_string, "platform" ) ) // is the mover a platform? (needed for pushers and bridges)
739  {
740  ‪e_mover SetMovingPlatformEnabled( true );
741  }
742 
743  if ( IsSubStr( ‪e_mover.script_string, "rotator" ) )
744  {
745  ‪b_is_rotator = true;
746  }
747 
748  if ( IsSubStr( ‪e_mover.script_string, "breakable" ) )
749  {
750  ‪b_is_breakable = true;
751  }
752  }
753 
754  // delay before beginning initial movement?
755  if ( isdefined( ‪e_mover.script_delay ) )
756  {
757  ‪n_delay_before_movement = ‪e_mover.script_delay;
758  }
759 
760  // get movement duration
761  if ( isdefined( ‪e_mover.script_float ) )
762  {
763  ‪n_movement_duration = ‪e_mover.script_float;
764  }
765  else if ( isdefined( ‪e_mover.script_int ) )
766  {
767  ‪n_movement_duration = ‪e_mover.script_int;
768  }
769  Assert( isdefined( ‪n_movement_duration ), "cSecurityMover->setup_mover() - n_movement_duration not defined, set script_float or script_int on the script_brushmodel in the map" );
770 
771  // if target kvp is defined, load the path
772  if ( isdefined( ‪e_mover.target ) )
773  {
775  }
776  else if ( isdefined( ‪e_mover.script_vector ) ) // else if script_vector is defined, set the endpos
777  {
778  if ( ‪b_is_rotator )
779  {
780  if ( isdefined( ‪e_mover.script_linkto ) )
781  {
782  // find the rotation origin, and linkto
783  e_rotation_struct = ‪struct::get( ‪e_mover.script_linkto, "script_linkname" );
784  ‪e_rotation_origin = ‪util::spawn_model( "script_origin", e_rotation_struct.origin, e_rotation_struct.angles );
785  ‪e_rotation_origin Hide();
786  // everything attaches to the e_rotation_origin
788  ‪v_startangles = ‪e_rotation_origin.angles; // get a different v_startangles before calculating v_endangles below
789  }
790 
791  ‪v_endangles = ‪v_startangles + ‪e_mover.script_vector;
792  }
793  else
794  {
795  ‪v_endpos = ‪v_startpos + ‪e_mover.script_vector;
796  }
797  }
798  else
799  {
800  AssertMsg( "cSecurityMover->setup_mover() - neither script_vector, nor target is defined" );
801  }
802 
803  if ( ‪b_is_breakable )
804  {
805  if ( isdefined( ‪e_mover.target ) )
806  {
807  ‪e_mover_broken = GetEnt( ‪e_mover.target, "targetname" );
808  Assert( isdefined( ‪e_mover_broken ), "cBreakableWalls->setup_breakable_wall - wall_broken does not exist; targetname should be: " + ‪e_mover.target );
809 
810  if ( isdefined( ‪e_mover_broken ) )
811  {
812  ‪e_mover_broken LinkTo( ‪e_mover );
813  ‪e_mover_broken Hide();
814  ‪e_mover_broken SetPlayerCollision( false );
815  }
816  }
817 
818  ‪e_mover.health = 10000;
819  ‪e_mover SetCanDamage( true );
820  self thread ‪breakable_wall_damage_watcher();
821  }
822  }
823 
824  // wall breaks only due to explosive damage
826  {
827  while( true )
828  {
829  ‪e_mover waittill( "damage", ‪damage, attacker, direction_vec, point, type, modelName, tagName, partName, weapon, iDFlags );
830  // wall breaks only due to explosive damage
831  if ( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" || type == "MOD_EXPLOSIVE" || type == "MOD_EXPLOSIVE_SPLASH" || type == "MOD_PROJECTILE" || type == "MOD_PROJECTILE_SPLASH" )
832  {
833  ‪break_wall();
834  }
835  else
836  {
837  // restore health; so we don't chip away at it with a different weapon
838  ‪e_mover.health = 10000;
839  }
840  }
841  }
842 
843  // effects of breaking wall
844  function ‪break_wall()
845  {
846  self notify( "stop_moving" );
847  ‪b_is_broken = true;
848 
849  // stop any previous movement
850  ‪e_mover MoveTo( ‪e_mover.origin, 0.05 );
852 
853  ‪e_mover Delete();
854  if ( isdefined( ‪e_mover_broken ) )
855  {
856  ‪e_mover_broken Show();
857  ‪e_mover_broken SetPlayerCollision( true );
858  }
859  }
860 
861  function ‪move_to_endpos()
862  {
863  self endon( "stop_moving" );
864 
865  if ( ‪b_is_broken )
866  {
868  return;
869  }
870 
871  if ( isdefined( ‪e_mover.target ) ) // follow path, if path is defined
872  {
874  }
875  else if ( ‪b_is_rotator )
876  {
877  if ( isdefined( ‪e_rotation_origin ) )
878  {
880  ‪timed_effects( true ); // play sounds and screen shake at appropriate times
881  }
882  else
883  {
885  ‪timed_effects( true ); // play sounds and screen shake at appropriate times
886  }
887  }
888  else
889  {
891  ‪timed_effects( true ); // play sounds and screen shake at appropriate times
892  }
893  }
894 
896  {
897  self endon( "stop_moving" );
898 
899  if ( ‪b_is_broken )
900  {
902  return;
903  }
904 
905  if ( isdefined( ‪e_mover.target ) ) // follow path, if path is defined
906  {
908  }
909  else if ( ‪b_is_rotator )
910  {
911  if ( isdefined( ‪e_rotation_origin ) )
912  {
914  ‪timed_effects( false ); // play sounds and screen shake at appropriate times
915  }
916  else
917  {
919  ‪timed_effects( false ); // play sounds at appropriate times; no screen shake
920  }
921  }
922  else
923  {
925  ‪timed_effects( false ); // play sounds at appropriate times; no screen shake
926  ‪e_mover.origin = ‪v_startpos;
927  }
928  }
929 
931  {
932  s_nextstruct = ‪struct::get( ‪e_mover.target, "targetname" );
933  v_current_position = ‪v_startpos;
934 
935  while ( isdefined( s_nextstruct ) )
936  {
937  // add to cumulative distance
938  ‪n_total_path_dist += Distance( v_current_position, s_nextstruct.origin );
939  v_current_position = s_nextstruct.origin;
940  // save struct in array
941  ‪ARRAY_ADD( ‪a_pathstructs, s_nextstruct );
942 
943  if ( !isdefined( s_nextstruct.target ) )
944  {
945  return;
946  }
947  s_nextstruct = ‪struct::get( s_nextstruct.target, "targetname" );
948  }
949  }
950 
951  // starts the mover moving along a trail of structs, or continues movement when stopped
953  {
954  self notify( "move_forward_along_path" );
955  self endon( "move_forward_along_path" );
956  self endon( "move_backward_along_path" );
957  self endon( "stop_moving" );
958 
959  ‪start_sounds();
960 
961  // slide to next node
962  while( ‪n_current_path_index <= ( ‪a_pathstructs.size - 1 ) )
963  {
964  s_nextstruct = ‪a_pathstructs[ ‪n_current_path_index ];
965  Assert( isdefined( s_nextstruct ), "cSecurityMover->move_along_path() s_nextstruct not defined" );
966  n_dist = Distance( ‪e_mover.origin, s_nextstruct.origin );
967  n_duration = ( n_dist / ‪n_total_path_dist ) * ‪n_movement_duration; // scale duration by the ratio between the length of this leg of the path, and the cumulative length of the path
968  // safety catch for n_duration
969  if ( n_duration <= 0 )
970  {
971  n_duration = 0.05;
972  }
973  ‪e_mover MoveTo( s_nextstruct.origin, n_duration );
974  wait n_duration; // reach the destination
975  ‪n_current_path_index++; // try the next path index
976  }
977 
978  ‪stop_sounds();
979  }
980 
982  {
983  self notify( "move_backward_along_path" );
984  self endon( "move_backward_along_path" );
985  self endon( "move_forward_along_path" );
986  self endon( "stop_moving" );
987 
988  ‪start_sounds();
989 
990  // slide to previous node
991  while( ‪n_current_path_index > 0 )
992  {
993  s_nextstruct = ‪a_pathstructs[ ‪n_current_path_index - 1 ]; // slide to previous node
994  Assert( isdefined( s_nextstruct ), "cSecurityMover->move_along_path() s_nextstruct not defined" );
995  n_dist = Distance( ‪e_mover.origin, s_nextstruct.origin );
996  n_duration = ( n_dist / ‪n_total_path_dist ) * ‪n_movement_duration; // scale duration by the ratio between the length of this leg of the path, and the cumulative length of the path
997  // safety catch for n_duration
998  if ( n_duration <= 0 )
999  {
1000  n_duration = 0.05;
1001  }
1002  ‪e_mover MoveTo( s_nextstruct.origin, n_duration );
1003  wait n_duration; // reach the destination
1004  ‪n_current_path_index--; // try the next path index
1005  }
1006  // slide to v_startpos
1007  n_dist = Distance( ‪e_mover.origin, ‪v_startpos );
1008  n_duration = ( n_dist / ‪n_total_path_dist ) * ‪n_movement_duration; // scale duration by the ratio between the length of this leg of the path, and the cumulative length of the path
1009  // safety catch for n_duration
1010  if ( n_duration <= 0 )
1011  {
1012  n_duration = 0.05;
1013  }
1014  ‪e_mover MoveTo( ‪v_startpos, n_duration );
1015  wait n_duration; // reach the destination
1016 
1017  ‪stop_sounds();
1018  }
1019 
1020  function ‪start_sounds()
1021  {
1022  // start sounds
1023  ‪e_mover stoploopsound( .25 ); // safety catch if we interrupted previous movement
1024  ‪e_mover playsound( "evt_door_close_start" );
1025  ‪e_mover playloopsound( "evt_door_move", .25 );
1026  }
1027 
1028  function ‪stop_sounds()
1029  {
1030  // stop sounds
1031  ‪e_mover stoploopsound( .25 );
1032  ‪e_mover playsound( "evt_door_open_stop" );
1033  }
1034 
1035  function ‪timed_effects( b_play_screen_shake )
1036  {
1037  self endon( "stop_moving" );
1038 
1039  ‪start_sounds();
1041  if ( b_play_screen_shake )
1042  {
1043  Earthquake( 0.3, 1, ‪e_mover.origin, 256 ); // screen shake for when mover hits its endpoint (may want to make this a conditional effect on a kvp later)
1044  }
1045  ‪stop_sounds();
1046  }
1047 }
1048 
1049 // mover that rises into place as you approach within a radius of it, retracting as you retreat from the radius
1050 class cSecurityBlocker : ‪cSecurityMover
1051 {
1052  var ‪n_inner_radius; // radius at which the blocker is fully moved to its script_vector
1053  var ‪n_outer_radius; // radius within which the blocker moves at all; amount that blocker moves is linearly scaled between inner and outer radii
1054  var ‪b_reversed; // whether to reverse blocker behavior (have it at full extend when the player is outside of n_outer_radius, scale to fully retracted once player reaches n_inner_radius)
1055 
1056  function ‪setup( blocker, secsystem )
1057  {
1058  ‪m_o_secsystem = secsystem;
1059  self ‪flag::init( "locking_down" );
1060  ‪setup_mover( blocker );
1061 
1062  Assert( isdefined( blocker.radius ), "cSecurityBlocker->setup() - .radius kvp on blocker not defined" );
1063 
1064  ‪n_inner_radius = blocker.radius;
1066  ‪b_reversed = false;
1067 
1068  self thread ‪blocker_control_thread();
1069  }
1070 
1071  function ‪reverse()
1072  {
1074  }
1075 
1077  {
1078  Assert( isdefined( e_mover ), "cSecurityBlocker->blocker_control_thread() - e_mover not defined" );
1079 
1080  while ( true )
1081  {
1082  if ( [[ ‪m_o_secsystem ]]->get_alert_level() == ‪ALERT_SCANNING )
1083  {
1084  n_player_dist = Distance( level.player.origin, e_mover.origin );
1085 
1086  if ( n_player_dist < ‪n_outer_radius )
1087  {
1088  if ( n_player_dist <= ‪n_inner_radius )
1089  {
1090  if ( ‪b_reversed )
1091  {
1092  e_mover.origin = ‪v_startpos;
1093  }
1094  else
1095  {
1096  e_mover.origin = ‪v_endpos;
1097  }
1098  }
1099  else
1100  {
1101  // move_amount - player's proximity between the inner and outer radii, on a 0-1 scale
1102  move_amount = 1 - ( ( n_player_dist - ‪n_inner_radius ) / ( ‪n_outer_radius - ‪n_inner_radius ) );
1103 
1104  if ( ‪b_reversed )
1105  {
1106  e_mover.origin = LerpVector( v_endpos, v_startpos, move_amount );
1107  }
1108  else
1109  {
1110  e_mover.origin = LerpVector( v_startpos, v_endpos, move_amount );
1111  }
1112  }
1113  }
1114  else
1115  {
1116  if ( ‪b_reversed )
1117  {
1118  e_mover.origin = ‪v_endpos;
1119  }
1120  else
1121  {
1122  e_mover.origin = ‪v_startpos;
1123  }
1124  }
1125  }
1127  }
1128  }
1129 
1130 }
1131 
1132 // DOOR activates on security alert, moves along script_vector, taking script_int seconds - if deactivated, it pauses and then returns to starting position (reopening door)
1134 {
1135  var ‪b_lockingdown; // whether door is currently locking/locked down
1136 
1137  function ‪setup( door, secsystem )
1138  {
1139  ‪m_o_secsystem = secsystem;
1140  self ‪flag::init( "locking_down" );
1141  ‪setup_mover( door );
1142  self thread ‪door_control_thread();
1143  }
1144 
1146  {
1147  self endon( "stop_moving" );
1148 
1149  while( true )
1150  {
1151  self ‪flag::wait_till( "locking_down" );
1152  wait ‪n_delay_before_movement; // starting delay
1153  self thread ‪cSecurityMover::move_to_endpos(); // thread this so we can interrupt the closing movement if we want
1154  self ‪flag::wait_till_clear( "locking_down" );
1156  }
1157  }
1158 
1159  function ‪activate()
1160  {
1161  ‪close_door();
1162  }
1163 
1164  function ‪deactivate()
1165  {
1166  ‪open_door();
1167  }
1168 
1169  function ‪close_door()
1170  {
1171  self ‪flag::set( "locking_down" );
1172  }
1173 
1174  function ‪open_door()
1175  {
1176  self ‪flag::clear( "locking_down" );
1177  }
1178 }
1179 
1180 // CRUSHER activates on security alert, moves along script_vector, taking script_int seconds, then returns the same way - does this repeatedly until deactivated, in which case it pauses and then returns to starting position
1181 class cSecurityCrusher : ‪cSecurityMover
1182 {
1184 
1185  function ‪setup( crusher, secsystem )
1186  {
1187  ‪m_o_secsystem = secsystem;
1188  ‪setup_mover( crusher );
1189  ‪b_crusher_is_active = false;
1190  self thread ‪watch_for_player_touch();
1191  }
1192 
1194  {
1195  self endon( "stop_moving" );
1196 
1197  while ( true )
1198  {
1199  e_mover waittill( "touch", player );
1200  if ( ‪b_crusher_is_active )
1201  {
1202  player DoDamage( player.health, player.origin );
1203  }
1204  }
1205  }
1206 
1208  {
1209  self endon( "stop_moving" );
1210  self endon( "deactivate" );
1211  self notify( "activate" );
1212 
1213  wait ‪n_delay_before_movement; // starting delay
1214 
1215  ‪b_crusher_is_active = true; // crusher can now do damage
1216 
1217  while( true )
1218  {
1221  }
1222  }
1223 
1224  // crusher retracts - during this time, the crusher doesn't do damage
1225  function ‪retract()
1226  {
1227  self endon( "activate" );
1228  self notify( "deactivate" );
1229 
1230  if ( !isdefined( e_mover ) )
1231  {
1232  return;
1233  }
1234 
1235  ‪b_crusher_is_active = false; // turn off damage
1236 
1237  // scale time to return to starting pos by the current distance between the crusher and its starting pos
1238  n_distance_scale = Distance( e_mover.origin, v_startpos ) / Distance( v_endpos, v_startpos );
1239  n_adjusted_movement_duration = n_distance_scale * ‪n_movement_duration;
1240  if ( n_adjusted_movement_duration <= 0 )
1241  {
1242  /# IPrintLn( "cSecurityCrusher->retract() - n_adjustment_movement_duration is zero or less" ); #/
1243  e_mover.origin = ‪v_startpos;
1244  }
1245  else
1246  {
1247  e_mover MoveTo( v_startpos, n_adjusted_movement_duration );
1248  }
1249  e_mover stoploopsound( .25 );
1250  }
1251 
1252  function ‪activate()
1253  {
1254  self thread ‪looping_movement();
1255  }
1256 
1257  function ‪deactivate()
1258  {
1259  self thread ‪retract();
1260  }
1261 }
1262 
1263 // security light class for playing a red-blinking security light effect on a struct whenever the associated security system is alerted
1265 {
1266  var ‪m_e_securitylight; // struct
1267  var ‪m_o_secsystem; // associated security system object
1268  var ‪fx_ent; // fx entity to play the effect on
1269 
1271  {
1272  }
1273 
1275  {
1276  }
1277 
1278  function ‪setup( securitylight, secsystem )
1279  {
1280  Assert( isdefined( securitylight ), "cSecurityLight->setup() - securitynode not defined, error in the calling function" );
1281  Assert( isdefined( secsystem ), "cSecurityLight->setup() - secsystem not defined, error in the calling function" );
1282  ‪m_o_secsystem = secsystem;
1283  ‪m_e_securitylight = securitylight;
1284  }
1285 
1286  function ‪activate()
1287  {
1288  ‪fx_ent = ‪util::spawn_model( "script_origin", ‪m_e_securitylight.origin, ‪m_e_securitylight.angles );
1289  ‪fx_ent Hide();
1290  if ( isdefined( ‪fx_ent ) )
1291  {
1292  PlayFXOnTag( level._effect["security_light_red"], ‪fx_ent, "tag_origin" );
1293  }
1294  }
1295 
1296  function ‪deactivate()
1297  {
1298  if ( isdefined( ‪fx_ent ) )
1299  {
1300  ‪fx_ent Delete();
1301  }
1302  }
1303 }
1304 
1305 // security node class for controlling security level via destructible script_brushmodels
1306 class cSecurityNode
1307 {
1308  var ‪m_e_securitynode; // script_brushmodel
1309  var ‪e_linkto_target; // entity that m_e_securitynode will be linked to
1310  var ‪m_o_secsystem; // associated security system object
1311  var ‪n_health; // hp
1312 
1313  ‪constructor()
1314  {
1315  ‪n_health = 10;
1316  }
1317 
1318  ‪destructor()
1319  {
1320  }
1321 
1322  function ‪setup( securitynode, secsystem )
1323  {
1324  Assert( isdefined( securitynode ), "cSecurityNode->setup_securitynode() - securitynode not defined, error in the calling function" );
1325  Assert( isdefined( secsystem ), "cSecurityNode->setup_securitynode() - secsystem not defined, error in the calling function" );
1326  ‪m_o_secsystem = secsystem;
1327  ‪m_e_securitynode = securitynode;
1328 
1329  // attach security node to a mover?
1330  if ( isdefined( ‪m_e_securitynode.target ) )
1331  {
1332  ‪e_linkto_target = GetEnt( ‪m_e_securitynode.target, "targetname" );
1334  }
1335  else if ( isdefined( ‪m_e_securitynode.script_linkto ) )
1336  {
1337  ‪e_linkto_target = GetEnt( ‪m_e_securitynode.script_linkto, "script_linkname" );
1339  }
1340 
1341  // set security node health in map?
1342  if ( isdefined( ‪m_e_securitynode.script_int ) )
1343  {
1344  ‪n_health = ‪m_e_securitynode.script_int;
1345  }
1347  ‪m_e_securitynode SetCanDamage( true );
1348 
1349  self thread ‪watch_securitynode_death();
1350  }
1351 
1353  {
1354  ‪m_e_securitynode waittill( "death" );
1355  // play effect
1356  PlayFX( level._effect["temp_explosion_md"], ‪m_e_securitynode.origin );
1357  ‪m_e_securitynode Hide();
1358  ‪m_e_securitynode SetPlayerCollision( false );
1359  [[ ‪m_o_secsystem ]]->decrement_security_node_count();
1360  }
1361 }
1362 
1363 // generic security panel class so we can have different consequences for using panels (shutdown security, cooldown security, shut off specific subsystem, etc.)
1365 {
1366  var ‪t_panel; // use_trigger to activate the panel
1367  var ‪m_o_secsystem; // parent security system
1368 
1370  {
1371  }
1374  {
1375  }
1376 
1377  function ‪setup( trigger, secsystem )
1378  {
1379  Assert( isdefined( trigger ), "cSecurityPanel->setup_securitypanel - trigger not defined, error in calling function" );
1380  Assert( isdefined( secsystem ), "cSecurityPanel->setup_securitypanel - secsystem not defined, error in calling function" );
1381  ‪t_panel = trigger;
1382  ‪m_o_secsystem = secsystem;
1383  }
1384 
1386  {
1387  ‪t_panel waittill( "trigger", e_other );
1388  }
1389 
1390  function ‪deactivate()
1391  {
1392  ‪t_panel TriggerEnable( false );
1393  }
1394 
1396  {
1397  }
1398 }
1399 
1400 // security shutdown panel - deactivates the security system when used
1401 class cSecurityShutdownPanel : ‪cSecurityPanel
1402 {
1403  function ‪setup( trigger, secsystem )
1404  {
1405  ‪cSecurityPanel::setup( trigger, secsystem );
1406  ‪watch_security_panel_trigger(); // blocking call - waits for security panel to be activated
1407  ‪security_panel_consequences(); // results of the player using the security panel
1408  }
1409 
1411  {
1412  [[ ‪m_o_secsystem ]]->deactivate_security_system();
1413  ‪t_panel TriggerEnable( false );
1414  }
1415 }
1416 
1417 // security reverse panel - reverses the effects of certain security elements (blockers to start with)
1419 {
1420  function ‪setup( trigger, secsystem )
1421  {
1422  ‪cSecurityPanel::setup( trigger, secsystem );
1423  ‪watch_security_panel_trigger(); // blocking call - waits for security panel to be activated
1424  ‪security_panel_consequences(); // results of the player using the security panel
1425  }
1426 
1428  {
1429  [[ ‪m_o_secsystem ]]->reverse_blockers();
1430  ‪t_panel TriggerEnable( false );
1431  }
1432 }
1433 
1434 // Missile Turret
1435 //
1436 // missile-firing variant of the rail turret
1437 //
1438 // the rail turret fires when the player is within view and the turret is finished with its cooldown
1439 // the rail turret, while firing, attempts to track the player (and if it loses sight of the player, watches the player's last known location)
1440 // the missile turret commits to firing when the player has been within its view frustrum for a specified duration
1441 // the missile turret, once it commits to firing, locks down its position/orientation, plays a laser sight, waits n_pause_before_attack, then fires
1442 class cMissileTurret : ‪cRailTurret
1443 {
1444  ‪constructor()
1445  {
1446  w_weapon = GetWeapon( "ai_tank_drone_rocket" );
1447  n_pause_before_attack = 3;
1448  n_pause_between_shots = 5;
1449  n_shoot_duration = 5000;
1450  n_shoot_cooldown = 5;
1451  n_shoot_revtime = 3;
1452  n_turn_speed = 1.0;
1453  ‪n_health = 1000;
1454  b_track_while_attacking = false;
1455  }
1456 
1457  ‪destructor()
1458  {
1459  }
1460 
1461  function ‪spawn_at_struct( str_struct, secsystem )
1462  {
1463  Assert( isdefined( str_struct ), "cMissileTurret->spawn_at_struct() str_struct not defined" );
1464  Assert( isdefined( secsystem ), "cMissileTurret->spawn_at_struct() secsystem not defined" );
1465 
1466  ‪m_o_secsystem = secsystem;
1467 
1468  // "turret_acquired_target" flag is set when the turret locks onto a target
1469  self ‪flag::init( "turret_acquired_target" );
1470  self ‪flag::init( "turret_moving_along_path" );
1471 
1472  self ‪flag::init( "turret_ready_to_fire" );
1473  self ‪flag::set( "turret_ready_to_fire" );
1474 
1475  // spawn model
1476  e_railturret = ‪util::spawn_model( "t6_wpn_turret_cic_world", str_struct.origin, str_struct.angles );
1477 
1478  e_railturret_snd1 = ‪spawn( "script_origin", str_struct.origin );
1479  e_railturret_snd1 linkto( e_railturret );
1480  e_railturret_snd2 = ‪spawn( "script_origin", str_struct.origin );
1481  e_railturret_snd2 linkto( e_railturret );
1482 
1483  // setup model to take damage
1484  b_turret_alive = true; // b_turret_alive = the turret has not been destroyed
1485  e_railturret.health = ‪n_health;
1486  e_railturret SetCanDamage( true );
1489 
1490  // set turret to target player (will set e_target to player)
1491  player = level.players[0];
1492  self ‪cRailTurret::set_combat_target( player );
1493 
1494  // stats
1495  n_speed = 128;
1496  b_turret_active = true;
1497 
1498  // turret ai
1499  self thread ‪cRailTurret::turret_awareness();
1500  self thread ‪turret_behavior();
1501  s_nextdest = ‪struct::get( str_struct.target, "targetname" );
1502  self thread ‪turret_movement_behavior();
1503  self thread ‪cRailTurret::face_player();
1504  }
1505 
1507  {
1508  do
1509  {
1510  self ‪flag::wait_till( "turret_acquired_target" );
1512  }
1513  while( b_turret_active && b_turret_alive );
1514  }
1515 
1517  {
1518  self thread ‪cRailTurret::move_along_path();
1519 
1520  while( b_turret_active && b_turret_alive )
1521  {
1522  if ( self ‪flag::get( "turret_acquired_target" ) && ( self ‪flag::get( "turret_moving_along_path" ) ) )
1523  {
1524  PlaySoundAtPosition( "vox_turr_target_sighted_0", e_railturret.origin ); // "target sighted" VO
1525  PlaySoundAtPosition( "evt_turret_target", e_railturret.origin );
1526  self thread ‪cRailTurret::stop_moving();
1527  wait 5;
1528  }
1529  else if ( !self ‪flag::get( "turret_moving_along_path" ) )
1530  {
1531  self thread ‪cRailTurret::move_along_path();
1532  }
1533  wait 0.01;
1534  }
1535  }
1536 
1537 }
1538 
1539 // Rail Turret Spawners
1540 // For each place you want a rail turret to spawn when security alerts, place a struct with these values:
1541 // � targetname �railturret_spawn�
1542 // � target = the targetname of the first struct in a chain describing the path you want the railturret to follow (ideally, create a loop of structs, each one targeting the next)
1543 // � script_noteworthy = whatever name you put in for the security system
1544 //
1546 {
1547  var ‪e_railturret; // model
1548  var ‪m_o_secsystem; // associated security system object
1549  var ‪n_health; // hp
1550  var ‪fx_ent; // play fx on this
1551  // combat
1552  var ‪b_turret_alive; // whether turret is alive or not (turret has not been destroyed)
1553  var ‪b_turret_active; // is the turret active or not (allows spawned turrets to be shutdown by security system or emps, hacking, etc.)
1555  var ‪w_weapon; // weapon used by the turret
1556  var ‪n_pause_before_attack; // once a target is sighted, the turret waits this many seconds before attacking
1557  var ‪n_pause_between_shots; // while firing, the turret waits this many seconds between shots
1558  var ‪n_shoot_duration; // shoot duration in ms
1559  var ‪n_shoot_cooldown; // cooldown time between attacks in seconds
1560  var ‪n_shoot_revtime; // turret revving up time in seconds
1561  var ‪b_track_while_attacking; // whether turret should continue to track its target while attacking (if false, turret stays locked in position once it starts to attack)
1562  var ‪n_turn_speed; // speed of turning in place
1563  var ‪n_stop_on_track_dist; // if the player is closer to the railturret than this distance, the railturret will stop moving
1564  // pathing
1567  var ‪n_speed; // current speed of pathing
1569  // rail turret either follows a struct path or attaches to an ent
1570  var ‪s_nextdest; // next struct on the track for the rail turret to move towards
1571  var ‪e_gimbal; // script_origin for the turret to attach to (allows it to rotate independently while following the movement of an attachment entity)
1572  var ‪e_attachpoint; // entity for the rail turret's gimbal to attach to
1573 
1576 
1578  {
1579  ‪w_weapon = GetWeapon( "kard" );
1581  ‪n_pause_between_shots = 0.25;
1582  ‪n_shoot_duration = 5000;
1583  ‪n_shoot_cooldown = 2;
1584  ‪n_shoot_revtime = 1;
1585  ‪n_turn_speed = 5.0;
1586  ‪n_health = 1000;
1589  }
1590 
1592  {
1593  }
1594 
1595  function ‪spawn_at_struct( str_struct, secsystem )
1596  {
1597  Assert( isdefined( str_struct ), "cRailTurret->spawn_at_struct() str_struct not defined" );
1598  Assert( isdefined( secsystem ), "cRailTurret->spawn_at_struct() secsystem not defined" );
1599 
1600  ‪m_o_secsystem = secsystem;
1601 
1602  // "turret_acquired_target" flag is set when the turret locks onto a target
1603  self ‪flag::init( "turret_acquired_target" );
1604  self ‪flag::init( "turret_moving_along_path" );
1605 
1606  self ‪flag::init( "turret_ready_to_fire" );
1607  self ‪flag::set( "turret_ready_to_fire" );
1608 
1609  // spawn model
1610  ‪e_railturret = ‪util::spawn_model( "t6_wpn_turret_cic_world", str_struct.origin, str_struct.angles );
1611 
1612  ‪e_railturret_snd1 = ‪spawn( "script_origin", str_struct.origin );
1614  ‪e_railturret_snd2 = ‪spawn( "script_origin", str_struct.origin );
1616  ‪e_railturret playsound( "evt_turret_spawn" );
1617 
1618  // setup model to take damage
1619  ‪b_turret_alive = true;
1620  ‪e_railturret.health = ‪n_health;
1621  ‪e_railturret SetCanDamage( true );
1622  self thread ‪thread_watch_for_damage();
1623  self thread ‪thread_watch_for_death();
1624 
1625  // set turret to target player (will set e_target to player)
1626  player = level.players[0];
1627  ‪set_combat_target( player );
1628  ‪e_railturret LaserOn(); // TODO: see if we can get this working
1629 
1630  // stats
1631  ‪n_speed = 128;
1632  ‪b_turret_active = true;
1633 
1634  // turret ai
1635  self thread ‪turret_awareness();
1636  self thread ‪turret_behavior();
1637  if ( isdefined( str_struct.script_linkto ) )
1638  {
1639  ‪e_attachpoint = GetEnt( str_struct.script_linkto, "script_linkname" );
1640  }
1641  else if ( isdefined( str_struct.target ) )
1642  {
1643  ‪s_nextdest = ‪struct::get( str_struct.target, "targetname" );
1644  }
1645  self thread ‪turret_movement_behavior();
1646  self thread ‪face_player();
1647  self thread ‪laser_sight_loop();
1648  }
1649 
1651  {
1652  ‪e_railturret endon( "death" );
1653 
1654  while ( true )
1655  {
1656  ‪e_railturret waittill( "damage", iDamage, sAttacker, vDirection, vPoint );
1657  // play effect
1658  PlayFX( level._effect["electrical_sparks"], vPoint );
1660  }
1661  }
1662 
1664  {
1665  ‪e_railturret waittill( "death" );
1666 
1667  // play effect
1668  PlayFX( level._effect["temp_explosion_md"], ‪e_railturret.origin );
1669  ‪e_railturret_snd1 stoploopsound( .1 );
1670  ‪e_railturret_snd2 stoploopsound( .1 );
1671  ‪e_railturret playsound( "evt_turret_explode" );
1672 
1674  }
1675 
1676  function ‪deactivate()
1677  {
1679  }
1680 
1682  {
1683  // stop at current location (override previous MoveTo)
1684  ‪e_railturret MoveTo( ‪e_railturret.origin, 0.05 );
1685  ‪e_railturret RotatePitch( 90, 1 ); // face down
1686  ‪b_turret_alive = false;
1687  ‪b_turret_active = false;
1688 
1689  //e_railturret Delete(); // don't need this anymore, as we're only spawning turret once per rail
1690 
1691  [[ ‪m_o_secsystem ]]->decrement_detector_count();
1692  }
1693 
1694  function ‪warp_to_struct( str_struct )
1695  {
1696  Assert( isdefined( str_struct ), "cRailTurret->warp_to_struct() str_struct not defined" );
1697 
1698  ‪e_railturret.origin = str_struct.origin;
1699  }
1700 
1702  {
1703  // move the turret along the path of structs, if defined
1704  if ( isdefined( ‪s_nextdest ) )
1705  {
1706  self thread ‪move_along_path();
1707  }
1708  else if ( isdefined( ‪e_attachpoint ) ) // attach to the mover
1709  {
1710  //Assert( isdefined( e_attachpoint ), "cRailTurret->turret_movement_behavior - e_attachpoint is not defined" );
1711  self thread ‪follow_mover();
1712  return; // no further movement behavior
1713  }
1714 
1716  {
1717  // stop to attack target
1718  if ( ( self ‪flag::get( "turret_acquired_target" ) ) && ( Distance( ‪e_railturret.origin, ‪e_target.origin ) < ‪n_stop_on_track_dist ) && ( self ‪flag::get( "turret_moving_along_path" ) ) )
1719  {
1720  PlaySoundAtPosition( "vox_turr_target_sighted_0", ‪e_railturret.origin ); // "target sighted" VO
1721  PlaySoundAtPosition( "evt_turret_target", ‪e_railturret.origin );
1722  self thread ‪stop_moving();
1723  wait 5;
1724  }
1725  // resume movement
1726  else if ( ( !self ‪flag::get( "turret_moving_along_path" ) ) && ( isdefined( ‪s_nextdest ) ) ) // added check for is s_nextdest is defined, so we don't try to restart turret movement if it wasn't spawned on a path
1727  {
1728  self thread ‪move_along_path();
1729  }
1730  wait 0.01;
1731  }
1732  }
1733 
1734  // follow the targeted mover at a fixed offset; doing this instead of LinkTo() because LinkTo() stomps on the turret's angle control
1735  function ‪follow_mover()
1736  {
1737  // TODO: spawn a script_origin and use LinkTo between that and e_attachpoint, then keep the turret's origin at the script_origin
1738  ‪e_gimbal = ‪util::spawn_model( "script_origin", ‪e_railturret.origin, ‪e_railturret.angles );
1739  ‪e_gimbal LinkTo( ‪e_attachpoint );
1740  ‪e_gimbal Hide();
1741 
1742  v_offset = ‪e_railturret.origin - ‪e_gimbal.origin;
1743 
1744  while ( isdefined( ‪e_railturret ) )
1745  {
1746  ‪e_railturret.origin = ‪e_gimbal.origin + v_offset;
1748  }
1749  }
1750 
1751  // starts the turret moving along a trail of structs, or continues movement when stopped
1753  {
1754  self notify( "move_along_path" );
1755  self endon( "move_along_path" );
1756  self endon( "stop_moving" );
1757  ‪e_railturret endon( "death" );
1758 
1759  self ‪flag::set( "turret_moving_along_path" );
1760  ‪e_railturret_snd1 playloopsound( "evt_turret_move", .25 );
1761 
1762  // slide to next node
1764  {
1765  Assert( isdefined( ‪s_nextdest ), "cRailTurret->move_along_path() s_nextdest not defined" );
1766  ‪n_dist = Distance( ‪e_railturret.origin, ‪s_nextdest.origin );
1768  // safety catch for n_duration
1769  if ( ‪n_duration <= 0 )
1770  {
1771  ‪n_duration = 0.05;
1772  }
1773  ‪e_railturret MoveTo( ‪s_nextdest.origin, ‪n_duration );
1774  wait ‪n_duration + 1; // pause at end
1775  // let us stop at the end of a path if there is no continuation
1776  if( !isdefined( ‪s_nextdest.target ) )
1777  {
1778  return;
1779  }
1780  // else get the next struct in the path
1781  str_nextstruct = ‪s_nextdest.target;
1782  ‪s_nextdest = ‪struct::get( str_nextstruct, "targetname" );
1783  }
1784  }
1785 
1786  // call move_along_path() again to continue path movement
1787  function ‪stop_moving()
1788  {
1789  self notify( "stop_moving" );
1790  self endon( "stop_moving" );
1791  self endon( "move_along_path" );
1792 
1793  self ‪flag::clear( "turret_moving_along_path" );
1794 
1795  ‪e_railturret_snd1 stoploopsound( .1 );
1796 
1797  // will override MoveTo on move_along_path()
1798  ‪e_railturret MoveTo( ‪e_railturret.origin, 0.05 );
1799  }
1800 
1801 
1802  // function to continuously check for various types of valid targets, including the player
1804  {
1805  do
1806  {
1808  wait 0.1;
1809  }
1811  }
1812 
1813  // sets/clears "turret_acquired_target" flag
1815  {
1816  b_seeplayer = false;
1817 
1818  if ( isdefined( ‪e_railturret ) && isdefined( ‪e_target ) )
1819  {
1820  //b_seeplayer = player SightConeTrace( e_railturret.origin, e_railturret, AnglesToForward( scan_angles ), 30 );
1821  b_seeplayer = BulletTracePassed( ‪e_railturret.origin, ‪e_target.origin + (0, 0, 60), true, undefined );
1822  }
1823 
1824  if ( b_seeplayer )
1825  {
1826 // IPrintLn( "TURRET ACQUIRED TARGET" );
1827  self ‪flag::set( "turret_acquired_target" );
1828  }
1829  else
1830  {
1831 // IPrintLn( "TURRET LOST TARGET" );
1832  self ‪flag::clear( "turret_acquired_target" );
1833  }
1834  }
1835 
1836  // if security is alerted, the turret will attempt to turn and face the player's last known location
1837  function ‪face_player()
1838  {
1839  player = level.players[0];
1840  ‪set_combat_target( player );
1841 
1843  {
1844  target_yaw = ‪get_yaw_to_combat_target();
1845  //yaw = AngleLerp( e_railturret.angles[1], yaw, 0.5 );
1846  if ( isdefined( target_yaw ) )
1847  {
1848  turret_yaw = ‪e_railturret.angles[1];
1849  yaw_diff = turret_yaw - target_yaw;
1850  //IPrintLn( "yaw diff: " + yaw_diff );
1851 
1852  // prevent overcorrection while turning to face player
1853  yaw_to_add = Min( Abs( yaw_diff ), ‪n_turn_speed );
1854 
1855  // turn the correct direction
1856  if ( yaw_diff > 0 )
1857  {
1858  ‪e_railturret.angles -= ( 0, yaw_to_add, 0 );
1859  }
1860  else
1861  {
1862  ‪e_railturret.angles += ( 0, yaw_to_add, 0 );
1863  }
1864 
1865  if( yaw_diff == 0 )
1866  {
1867  ‪e_railturret_snd2 stoploopsound( .1 );
1868  }
1869  else
1870  {
1871  ‪e_railturret_snd2 playloopsound( "evt_turret_turn", .25 );
1872  }
1873  }
1875  }
1876  }
1877 
1879  {
1880  do
1881  {
1882  self ‪flag::wait_till( "turret_acquired_target" );
1884  }
1886  }
1887 
1889  {
1890  player = level.players[0];
1891  ‪set_combat_target( player );
1892  }
1893 
1894  function ‪set_combat_target( target )
1895  {
1896  Assert( isdefined( target ), "cRailTurret->set_combat_target() target not defined" );
1897  ‪e_target = target;
1898  }
1899 
1901  {
1902  Assert( isdefined( ‪e_target ), "cRailTurret->get_yaw_to_combat_target() e_target not defined" );
1903  Assert( isdefined( ‪e_railturret ), "cRailTurret->get_yaw_to_combat_target() e_railturret not defined" );
1904 
1905  v_diff = ‪e_target.origin - ‪e_railturret.origin;
1906  x = v_diff[0];
1907  y = v_diff[1];
1908 
1909  if ( x != 0 )
1910  {
1911  n_slope = y / x;
1912  yaw = ATan( n_slope );
1913  if ( x < 0 )
1914  {
1915  yaw += 180;
1916  }
1917  }
1918 
1919  return yaw;
1920  }
1921 
1923  {
1924  ‪e_railturret endon( "death" );
1925 
1927  {
1928  // get firing angle
1929  v_fx_pos = ‪e_railturret GetTagOrigin( "TAG_FLASH" );
1930  v_accurate_firing_angle = VectorNormalize( ( ‪e_target.origin + (0, 0, 60) ) - ‪e_railturret.origin );
1931  v_turret_yaw = AnglesToForward( ‪e_railturret.angles );
1932  v_turret_firing_angle = ( v_accurate_firing_angle[0], v_turret_yaw[1], v_accurate_firing_angle[2] );
1933  // play beam effect during rev up
1934  PlayFX( level._effect["deathray_beam"], v_fx_pos, v_turret_firing_angle );
1935  PlayFX( level._effect["deathray_trail"], v_fx_pos, v_turret_firing_angle );
1936  wait 0.2;
1937  }
1938  }
1939 
1941  {
1942  ‪e_railturret endon( "death" );
1943 
1944  Assert( isdefined( ‪e_target ), "cRailTurret->fire_at_target() e_target not defined" );
1945  Assert( isdefined( ‪e_railturret ), "cRailTurret->fire_at_target() e_railturret not defined" );
1946 
1947  PlaySoundAtPosition( "vox_turr_spin_up_0", ‪e_railturret.origin );
1948  wait ‪n_shoot_revtime;
1949  PlaySoundAtPosition( "vox_turr_fire_0", ‪e_railturret.origin );
1950 
1951  curr_time = GetTime();
1952  time_started_shooting = curr_time;
1953 
1954  while ( curr_time < ( time_started_shooting + ‪n_shoot_duration ) )
1955  {
1956  // get firing angle
1957  v_fx_pos = ‪e_railturret GetTagOrigin( "TAG_FLASH" );
1958  v_accurate_firing_angle = VectorNormalize( ( ‪e_target.origin + (0, 0, 60) ) - ‪e_railturret.origin );
1959  v_turret_yaw = AnglesToForward( ‪e_railturret.angles );
1960  v_turret_firing_angle = ( v_accurate_firing_angle[0], v_turret_yaw[1], v_accurate_firing_angle[2] );
1961 
1962  turret_firing_offset = ( v_turret_firing_angle * 100 );
1963  MagicBullet( ‪w_weapon, v_fx_pos, v_fx_pos + turret_firing_offset );
1964  PlayFX( level._effect["railturret_muzzle_flash"], v_fx_pos, v_turret_firing_angle );
1965 
1967  curr_time = GetTime();
1968  }
1969 
1970  PlaySoundAtPosition( "vox_turr_cool_0", ‪e_railturret.origin );
1971  self thread ‪play_cooldown_fx();
1972  wait ‪n_shoot_cooldown;
1973  self notify( "stop_cooldown_fx" );
1974  }
1975 
1977  {
1978  self endon( "stop_cooldown_fx" );
1979 
1980  // spawn ent to play effect off of
1981  ‪fx_ent = ‪util::spawn_model( "script_origin", ‪e_railturret.origin, ‪e_railturret.angles );
1982  ‪fx_ent Hide();
1983 
1984  while( true )
1985  {
1986  PlayFX( level._effect["steam_cooldown"], ‪fx_ent.origin );
1987  wait 0.5;
1988  }
1989  }
1990 
1991 }
1992 
1993 //
1994 // Security cameras can now be spawned off of structs. These are super easy to set up.
1995 //
1996 // 1. Targetname on the struct is �security_camera�
1997 // 2. Script_noteworthy on the struct matches the local security system
1998 // 3. Script_int sets the total number of seconds that the camera takes to scan 90 degrees in both directions and return to starting position (including one second pauses at each extreme)
1999 //
2000 class cSecurityCamera
2001 {
2002  // id
2003  var ‪m_o_secsystem; // associated security system object
2004  // camera ents
2005  var ‪e_camera; // camera model
2006  var ‪e_camera_mount; // camera mount to wall
2008  var ‪fx_ent; // spotlight cone effect attached to the camera
2009  // camera frustrum
2010  var ‪t_frustrum; // frustrum trigger
2011  var ‪e_frustrum; // visual frustrum
2012  // camera scanangle
2013  var ‪n_scanangle_left; // how far to rotate left from starting angle
2014  var ‪n_scanangle_right; // how far to rotate right from starting angle
2015  // camera stats
2016  var ‪n_scantime; // how long the camera takes to perform a complete left+right scan and return to starting angle
2017  var ‪n_scanpausetime; // how long the camera pauses at each rotational extreme
2018  var ‪n_viewrange; // how far away the camera can see
2019  var ‪n_spotlighttype; // which spotlight should currently be playing
2020  // camera control
2021  var ‪b_active; // the camera is active (will see and respond to entities of interest)
2022  var ‪b_scanning; // the camera is scanning left and right (servos running)
2023  var ‪b_scandir_right; // keep track of scan direction
2024  var ‪b_start_scanyaw; // starting yaw
2025  var ‪b_max_scanyaw; // max yaw
2026  var ‪b_min_scanyaw; // min yaw
2027  // misc
2028  var ‪n_camerapitch; // how pitched down the camera is
2029  var ‪e_target; // the entity that the camera is currently following
2030 
2031  ‪constructor()
2032  {
2033  /# PrintLn( "cSecurityCam->constructor()" ); #/
2034  ‪n_scanangle_left = 90;
2035  ‪n_scanangle_right = 90;
2036  ‪n_scantime = 4;
2037  ‪n_scanpausetime = 1;
2038  ‪n_viewrange = 384;
2039  ‪b_scanning = false;
2040  ‪b_scandir_right = true;
2041  ‪n_camerapitch = 20;
2042  ‪b_active = true;
2043  ‪n_spotlighttype = 0;
2044  self ‪flag::init( "camera_on" );
2045  }
2046 
2047  ‪destructor()
2048  {
2049  /# PrintLn( "cSecurityCam->destructor()" ); #/
2050  }
2051 
2052  function ‪setup( str_struct, secsystem )
2053  {
2054  Assert( isdefined( str_struct ), "cSecurityCam->setup() str_struct not defined" );
2055  Assert( isdefined( secsystem ), "cSecurityCam->setup() secsystem not defined" );
2056  ‪m_o_secsystem = secsystem;
2057 
2058  // spawn model
2059  ‪e_camera = ‪util::spawn_model( "p_int_security_camera", str_struct.origin, str_struct.angles );
2060  ‪e_camera_mount = ‪util::spawn_model( "p6_security_camera_mount", str_struct.origin, str_struct.angles );
2061  ‪e_camera_sound = ‪spawn( "script_origin", str_struct.origin );
2062 
2063  self ‪flag::set( "camera_on" );
2064  ‪e_camera.health = 10;
2065  ‪e_camera SetCanDamage( true );
2066  self thread ‪camera_death_watcher();
2067 
2068  // orient model so that it matches the angle of the struct visually in-editor
2069  ‪e_camera.angles = ( ‪e_camera.angles[0], ‪e_camera.angles[1] + 90, ‪e_camera.angles[2] );
2070 
2071  // angle downwards
2072  ‪e_camera.angles = ( ‪e_camera.angles[0], ‪e_camera.angles[1], ‪e_camera.angles[2] + ‪n_camerapitch );
2073  // calculate relative yaws for min and max rotation
2074  ‪b_start_scanyaw = ‪e_camera.angles[1];
2077 
2078  Assert( isdefined( str_struct.script_noteworthy ), "cSecurityCamera->spawn_at_struct() - script_noteworthy not defined!" );
2079 
2080  // get timing off of struct
2081  if ( isdefined( str_struct.script_int ) )
2082  {
2083  ‪n_scantime = str_struct.script_int;
2084  }
2085 
2086  // get detect distance on xy-plane off of radius
2087  if ( isdefined( str_struct.radius ) )
2088  {
2089  ‪n_viewrange = str_struct.radius;
2090  }
2091 
2092 
2093  // activate camera
2094  self thread ‪camera_awareness();
2095 
2096  // start camera scanning
2097  self thread ‪camera_scan();
2098 
2099  // turn on camera light fx
2100  ‪n_spotlighttype = 2; // green
2101  self thread ‪camera_spotlight_controller();
2102  }
2103 
2105  {
2106  curr_spotlighttype = 0;
2107 
2108  while( ‪b_active )
2109  {
2110  if ( curr_spotlighttype != ‪n_spotlighttype )
2111  {
2112  curr_spotlighttype = ‪n_spotlighttype;
2113  self thread ‪activate_camera_light( curr_spotlighttype );
2114  self thread ‪camera_debug( curr_spotlighttype );
2115  }
2117  }
2118  }
2119 
2120  // play a spotlight effect off the camera
2121  // light_type selects type of spotlight: 1 - white, 2 - green, 3 - red, 4 - yellow
2122  function ‪activate_camera_light( light_type )
2123  {
2124  // reset by deleting any previously existing spotlight effect
2125  if ( isdefined( ‪fx_ent ) )
2126  {
2127  ‪fx_ent Delete();
2128  }
2129 
2130  // spawn ent to play effect off of
2131  ‪fx_ent = ‪util::spawn_model( "script_origin", ‪e_camera.origin, ‪e_camera.angles );
2132  ‪fx_ent Hide();
2133 
2134  // play appropriate effect
2135  if ( isdefined( ‪fx_ent ) )
2136  {
2137  ‪fx_ent LinkTo( ‪e_camera, "tag_origin", (0,0,0), (0,-90,20) );
2138 
2139  switch( light_type )
2140  {
2141  case 1:
2142  camera_light_fx = PlayFXOnTag( level._effect["camera_light_fx"], ‪fx_ent, "tag_origin" );
2143  break;
2144  case 2:
2145  camera_light_fx = PlayFXOnTag( level._effect["camera_light_fx_grn"], ‪fx_ent, "tag_origin" );
2146  break;
2147  case 3:
2148  camera_light_fx = PlayFXOnTag( level._effect["camera_light_fx_red"], ‪fx_ent, "tag_origin" );
2149  break;
2150  case 4:
2151  camera_light_fx = PlayFXOnTag( level._effect["camera_light_fx_ylw"], ‪fx_ent, "tag_origin" );
2152  break;
2153  }
2154  }
2155  }
2156 
2157  function ‪camera_debug( light_type )
2158  {
2159  }
2160 
2161  function ‪camera_scan()
2162  {
2163  /# PrintLn( "cSecurityCam->camera_scan()" ); #/
2164  Assert( isdefined( ‪e_camera ), "cSecurityCam->camera_scan() e_camera not defined" );
2165 
2166  ‪b_scanning = true;
2167 
2168  // remove pauses at each end from total scan time, then weight the time for each half of the scan according to the relative amount of angle (so speed of rotation stays the same)
2169  // calculating this here so that we can specify the length of the total scan period to time out movement across the space, instead of guessing at speed
2172  n_scan_rotationpersecond = ‪n_scanangle_left / n_scanlefttime; // rotation per second
2173  n_scan_rotationperframe = n_scan_rotationpersecond / 20; // rotation per 0.05 second frame
2174 
2175  // scan loop
2176  while ( true )
2177  {
2178  if( ‪b_scanning ) // let us start/stop scanning on any frame
2179  {
2180  cam_angles = ‪e_camera.angles;
2181  yaw = cam_angles[1];
2182 
2183  if ( ‪b_scandir_right ) // which direction are we currently scanning?
2184  {
2185  if ( yaw < ‪b_max_scanyaw )
2186  {
2187  ‪e_camera.angles = cam_angles + ( 0, n_scan_rotationperframe, 0 );
2188  ‪e_camera_sound playloopsound( "evt_camera_move", .5 );
2189  }
2190  else
2191  {
2192  ‪b_scandir_right = false;
2193  ‪e_camera_sound stoploopsound( .05 );
2194  ‪e_camera playsound( "evt_camera_move_stop" );
2195  }
2196  }
2197  else
2198  {
2199  if ( yaw > ‪b_min_scanyaw )
2200  {
2201  ‪e_camera.angles = cam_angles - ( 0, n_scan_rotationperframe, 0 );
2202  ‪e_camera_sound playloopsound( "evt_camera_move", .5 );
2203  }
2204  else
2205  {
2206  ‪b_scandir_right = true;
2207  ‪e_camera_sound stoploopsound( .05 );
2208  ‪e_camera playsound( "evt_camera_move_stop" );
2209  }
2210  }
2211  }
2212 
2214  }
2215  ‪e_camera stoploopsound( .05 );
2216  }
2217 
2219  {
2220  ‪e_camera waittill( "death" );
2221  ‪deactivate();
2222 
2223  ‪e_camera_sound stoploopsound( .05 ); // stop scanning noise
2224 
2225  // play death fx
2226  ‪fx_ent = ‪util::spawn_model( "script_origin", ‪e_camera.origin, ‪e_camera.angles );
2227  ‪fx_ent Hide();
2228  if ( isdefined( ‪fx_ent ) )
2229  {
2230  PlayFXOnTag( level._effect["electrical_sparks"], ‪fx_ent, "tag_origin" );
2231  }
2232  }
2233 
2235  {
2236  // need player ref on hand
2237  player = level.players[0];
2238 
2239  // trigger things based on awareness of player or distraction objects (things the player can throw, hologram, etc.)
2240  while ( true )
2241  {
2242  if ( ‪b_active ) // if the camera is currently looking for targets
2243  {
2244  // if the player is within the camera's view, set off an alert
2245  scan_angles = ( ‪e_camera.angles[0], ‪e_camera.angles[1] - 90, ‪e_camera.angles[2] ); // need to turn 90 degrees because of the coordinates of the camera model
2246 // IPrintLn( scan_angles );
2247  b_cansee = player SightConeTrace( ‪e_camera.origin, ‪e_camera_mount, AnglesToForward( scan_angles ), 30 );
2248  if ( b_cansee == 1 )
2249  {
2250  v_camera_xy_origin = ( ‪e_camera.origin[0], ‪e_camera.origin[1], 0 );
2251  v_player_xy_origin = ( player.origin[0], player.origin[1], 0 );
2252 
2253  if ( Distance( v_camera_xy_origin, v_player_xy_origin ) < ‪n_viewrange )
2254  {
2255  PlaySoundAtPosition( "vox_turr_target_camera_0", ‪e_camera.origin ); // "target on camera" VO - play from camera
2256  PlaySoundAtPosition( "evt_camera_target", ‪e_camera.origin );
2257  ‪n_spotlighttype = 3;
2258  [[ ‪m_o_secsystem ]]->set_alert_level( ‪ALERT_SCANNING );
2259  ‪e_target = player;
2260  yaw = ‪get_yaw_to_target();
2261  if ( isdefined( yaw ) && ( ‪b_min_scanyaw < yaw < ‪b_max_scanyaw ) )
2262  {
2263  cam_angles = ‪e_camera.angles;
2264  ‪e_camera.angles = ( cam_angles[0], yaw + 90, cam_angles[2] );
2265  }
2266  }
2267  }
2268  else
2269  {
2270  if ( [[ ‪m_o_secsystem ]]->get_alert_level() == ‪ALERT_SCANNING )
2271  {
2272  ‪n_spotlighttype = 4;
2273  }
2274  else
2275  {
2276  ‪n_spotlighttype = 2;
2277  }
2278  }
2279  }
2281  }
2282  }
2283 
2285  {
2286  Assert( isdefined( ‪e_target ), "cSecurityCamera->get_yaw_to_target() e_target not defined" );
2287  Assert( isdefined( ‪e_camera ), "cSecurityCamera->get_yaw_to_target() e_camera not defined" );
2288 
2289  v_diff = ‪e_target.origin - ‪e_camera.origin;
2290  x = v_diff[0];
2291  y = v_diff[1];
2292 
2293  if ( x != 0 )
2294  {
2295  n_slope = y / x;
2296  yaw = ATan( n_slope );
2297  if ( x < 0 )
2298  {
2299  yaw += 180;
2300  }
2301  }
2302 
2303  return yaw;
2304  }
2305 
2306  function ‪deactivate()
2307  {
2308  if ( !self ‪flag::get( "camera_on" ) )
2309  {
2310  return;
2311  }
2312 
2313  self ‪flag::clear( "camera_on" );
2314  ‪b_scanning = false; // stop scanning
2315  ‪b_active = false; // stop caring whether player is in front
2316  ‪e_camera RotateRoll( 90 - ‪n_camerapitch, 1 ); // rotate the rest of the way to pointing straight down
2317  // kill the camera light effect
2318  ‪fx_ent Delete();
2319  }
2320 
2321  function ‪reactivate()
2322  {
2323  // don't reactivate if already active
2324  if ( self ‪flag::get( "camera_on" ) )
2325  {
2326  return;
2327  }
2328 
2329  self ‪flag::set( "camera_on" );
2330  ‪e_camera RotateRoll( -(90 - ‪n_camerapitch) , 1 ); // rotate back to n_camerapitch
2331  wait 1; // wait for camera to rise again before reactivating
2332  ‪b_scanning = true; // continue scanning
2333  ‪b_active = true; // detect player
2334  ‪n_spotlighttype = 2;
2335  }
2336 }
‪cSecuritySystem::a_Cameras
‪var a_Cameras
Definition: traps_shared.gsc:117
‪cSecurityPanel::security_panel_consequences
‪function security_panel_consequences()
Definition: traps_shared.gsc:1395
‪cRailTurret::n_shoot_revtime
‪var n_shoot_revtime
Definition: traps_shared.gsc:1560
‪cSecurityMover::v_startpos
‪var v_startpos
Definition: traps_shared.gsc:698
‪cSecuritySystem::a_SecurityNodes
‪var a_SecurityNodes
Definition: traps_shared.gsc:122
‪cSecurityLight::deactivate
‪function deactivate()
Definition: traps_shared.gsc:1296
‪cRailTurret::v_dest
‪var v_dest
Definition: traps_shared.gsc:1566
‪b_start_scanyaw
‪var b_start_scanyaw
Definition: traps_shared.gsc:2024
‪activate
‪function activate()
Definition: traps_shared.gsc:655
‪cSecuritySystem::deactivate_security_system
‪function deactivate_security_system()
Definition: traps_shared.gsc:378
‪cSecuritySystem::reactivate_all_in_array
‪function reactivate_all_in_array(a_things)
Definition: traps_shared.gsc:448
‪b_reversed
‪var b_reversed
Definition: traps_shared.gsc:1054
‪show_laser
‪function show_laser()
Definition: traps_shared.gsc:669
‪t_laser
‪class cSecuritySystem t_laser
‪cSecuritySystem::n_detector_count
‪var n_detector_count
Definition: traps_shared.gsc:109
‪cSecurityMover::setup_mover
‪function setup_mover(mover)
Definition: traps_shared.gsc:729
‪cSecurityDoor::close_door
‪function close_door()
Definition: traps_shared.gsc:1169
‪cSecuritySystem::setup_secsystem
‪function setup_secsystem(secsystem)
Definition: traps_shared.gsc:141
‪precache_all
‪function precache_all()
Definition: traps_shared.gsc:85
‪cSecuritySystem::a_SpiderBots
‪var a_SpiderBots
Definition: traps_shared.gsc:119
‪e_target
‪var e_target
Definition: traps_shared.gsc:2029
‪n_viewrange
‪var n_viewrange
Definition: traps_shared.gsc:2018
‪blocker_control_thread
‪function blocker_control_thread()
Definition: traps_shared.gsc:1076
‪cSecuritySystem::get_alert_level
‪function get_alert_level()
Definition: traps_shared.gsc:287
‪n_health
‪var n_health
Definition: traps_shared.gsc:1311
‪cSecuritySystem::deactivate_spawned
‪function deactivate_spawned()
Definition: traps_shared.gsc:412
‪cRailTurret::warp_to_struct
‪function warp_to_struct(str_struct)
Definition: traps_shared.gsc:1694
‪cSecuritySystem::set_alert_level
‪function set_alert_level(n_target_alert_level)
Definition: traps_shared.gsc:292
‪e_linkto_target
‪var e_linkto_target
Definition: traps_shared.gsc:1309
‪n_outer_radius
‪var n_outer_radius
Definition: traps_shared.gsc:1053
‪cSecuritySystem::a_LaserTripwires
‪var a_LaserTripwires
Definition: traps_shared.gsc:116
‪cSecurityMover::v_endpos
‪var v_endpos
Definition: traps_shared.gsc:699
‪b_camera_shake
‪var b_camera_shake
Definition: traps_shared.gsc:531
‪cSecurityMover::start_sounds
‪function start_sounds()
Definition: traps_shared.gsc:1020
‪retract
‪function retract()
Definition: traps_shared.gsc:1225
‪cSecurityPanel::t_panel
‪var t_panel
Definition: traps_shared.gsc:1366
‪cSecurityDoor::b_lockingdown
‪var b_lockingdown
Definition: traps_shared.gsc:1135
‪e_visible_laser
‪var e_visible_laser
Definition: traps_shared.gsc:528
‪cSecurityMover::e_rotation_origin
‪var e_rotation_origin
Definition: traps_shared.gsc:696
‪cRailTurret::deactivation_effects
‪function deactivation_effects()
Definition: traps_shared.gsc:1681
‪camera_awareness
‪function camera_awareness()
Definition: traps_shared.gsc:2234
‪clear
‪function clear(str_flag)
Definition: flag_shared.csc:130
‪camera_spotlight_controller
‪function camera_spotlight_controller()
Definition: traps_shared.gsc:2104
‪cRailTurret::e_railturret_snd1
‪var e_railturret_snd1
Definition: traps_shared.gsc:1574
‪cSecuritySystem::v_player_last_known_pos
‪var v_player_last_known_pos
Definition: traps_shared.gsc:107
‪cSecuritySystem::a_RailTurrets
‪var a_RailTurrets
Definition: traps_shared.gsc:118
‪cRailTurret::constructor
‪constructor()
Definition: traps_shared.gsc:1577
‪fx_ent
‪var fx_ent
Definition: traps_shared.gsc:2008
‪cSecurityLight::activate
‪function activate()
Definition: traps_shared.gsc:1286
‪cRailTurret::e_attachpoint
‪var e_attachpoint
Definition: traps_shared.gsc:1572
‪cSecurityReversePanel
Definition: traps_shared.gsc:1418
‪cSecuritySystem::reverse_blockers
‪function reverse_blockers()
Definition: traps_shared.gsc:253
‪n_camerapitch
‪var n_camerapitch
Definition: traps_shared.gsc:2028
‪cSecurityReversePanel::setup
‪function setup(trigger, secsystem)
Definition: traps_shared.gsc:1420
‪cRailTurret::get_yaw_to_combat_target
‪function get_yaw_to_combat_target()
Definition: traps_shared.gsc:1900
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪cRailTurret::follow_mover
‪function follow_mover()
Definition: traps_shared.gsc:1735
‪cSecurityLight
Definition: traps_shared.gsc:1264
‪cRailTurret::deactivate
‪function deactivate()
Definition: traps_shared.gsc:1676
‪cSecurityMover::move_to_startpos
‪function move_to_startpos()
Definition: traps_shared.gsc:895
‪cRailTurret::laser_sight_loop
‪function laser_sight_loop()
Definition: traps_shared.gsc:1922
‪cSecurityLight::destructor
‪destructor()
Definition: traps_shared.gsc:1274
‪cSecurityDoor::activate
‪function activate()
Definition: traps_shared.gsc:1159
‪b_active
‪var b_active
Definition: traps_shared.gsc:2021
‪cSecurityMover::m_o_secsystem
‪var m_o_secsystem
Definition: traps_shared.gsc:694
‪cSecurityDoor::open_door
‪function open_door()
Definition: traps_shared.gsc:1174
‪cSecurityMover::destructor
‪destructor()
Definition: traps_shared.gsc:725
‪ALERT_SCANNING
‪#define ALERT_SCANNING
Definition: traps_shared.gsc:25
‪cRailTurret::destructor
‪destructor()
Definition: traps_shared.gsc:1591
‪cRailTurret::spawn_at_struct
‪function spawn_at_struct(str_struct, secsystem)
Definition: traps_shared.gsc:1595
‪cRailTurret::fire_at_target
‪function fire_at_target()
Definition: traps_shared.gsc:1940
‪destructor
‪destructor()
Definition: traps_shared.gsc:546
‪hide_laser
‪function hide_laser()
Definition: traps_shared.gsc:677
‪cRailTurret::play_cooldown_fx
‪function play_cooldown_fx()
Definition: traps_shared.gsc:1976
‪cSecurityDoor::door_control_thread
‪function door_control_thread()
Definition: traps_shared.gsc:1145
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪camera_debug
‪function camera_debug(light_type)
Definition: traps_shared.gsc:2157
‪cSecurityLight::m_o_secsystem
‪var m_o_secsystem
Definition: traps_shared.gsc:1267
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪m_o_secsystem
‪var m_o_secsystem
Definition: traps_shared.gsc:527
‪cSecuritySystem::activate_consequences
‪function activate_consequences()
Definition: traps_shared.gsc:392
‪cRailTurret::b_track_while_attacking
‪var b_track_while_attacking
Definition: traps_shared.gsc:1561
‪camera_death_watcher
‪function camera_death_watcher()
Definition: traps_shared.gsc:2218
‪reverse
‪function reverse()
Definition: traps_shared.gsc:1071
‪cSecuritySystem::deactivate_all_in_array
‪function deactivate_all_in_array(a_things)
Definition: traps_shared.gsc:435
‪cSecurityMover::n_total_path_dist
‪var n_total_path_dist
Definition: traps_shared.gsc:707
‪cSecuritySystem::deactivate_detectors
‪function deactivate_detectors()
Definition: traps_shared.gsc:406
‪b_min_scanyaw
‪var b_min_scanyaw
Definition: traps_shared.gsc:2026
‪cRailTurret::thread_watch_for_damage
‪function thread_watch_for_damage()
Definition: traps_shared.gsc:1650
‪cRailTurret
Definition: traps_shared.gsc:1545
‪cSecurityMover
Definition: traps_shared.gsc:691
‪spawn_model
‪function spawn_model(n_client, str_model, origin=(0, 0, 0), angles=(0, 0, 0))
Definition: util_shared.csc:92
‪n_spotlighttype
‪var n_spotlighttype
Definition: traps_shared.gsc:2019
‪n_scantime
‪var n_scantime
Definition: traps_shared.gsc:2016
‪cSecurityMover::move_backward_along_path
‪function move_backward_along_path()
Definition: traps_shared.gsc:981
‪cRailTurret::turret_awareness
‪function turret_awareness()
Definition: traps_shared.gsc:1803
‪laser_movement
‪function laser_movement()
Definition: traps_shared.gsc:624
‪cRailTurret::set_combat_target_as_player
‪function set_combat_target_as_player()
Definition: traps_shared.gsc:1888
‪cSecuritySystem::a_Quadrotors
‪var a_Quadrotors
Definition: traps_shared.gsc:120
‪cRailTurret::n_shoot_cooldown
‪var n_shoot_cooldown
Definition: traps_shared.gsc:1559
‪cSecuritySystem::activate_all_in_array
‪function activate_all_in_array(a_things)
Definition: traps_shared.gsc:427
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪cSecuritySystem::respond_to_alert_level
‪function respond_to_alert_level()
Definition: traps_shared.gsc:322
‪cSecuritySystem::b_secsystem_can_reactivate
‪var b_secsystem_can_reactivate
Definition: traps_shared.gsc:110
‪cSecuritySystem::set_security_lights
‪function set_security_lights(b_lights_on)
Definition: traps_shared.gsc:456
‪cSecuritySystem::decrement_security_node_count
‪function decrement_security_node_count()
Definition: traps_shared.gsc:277
‪cRailTurret::w_weapon
‪var w_weapon
Definition: traps_shared.gsc:1555
‪cSecurityMover::break_wall
‪function break_wall()
Definition: traps_shared.gsc:844
‪cSecurityPanel
Definition: traps_shared.gsc:1364
‪cRailTurret::thread_watch_for_death
‪function thread_watch_for_death()
Definition: traps_shared.gsc:1663
‪cSecurityLight::fx_ent
‪var fx_ent
Definition: traps_shared.gsc:1268
‪cRailTurret::n_pause_between_shots
‪var n_pause_between_shots
Definition: traps_shared.gsc:1557
‪cSecurityReversePanel::security_panel_consequences
‪function security_panel_consequences()
Definition: traps_shared.gsc:1427
‪cSecurityMover::b_is_rotator
‪var b_is_rotator
Definition: traps_shared.gsc:710
‪cRailTurret::n_health
‪var n_health
Definition: traps_shared.gsc:1549
‪cRailTurret::check_for_target
‪function check_for_target()
Definition: traps_shared.gsc:1814
‪cSecuritySystem::alert_security_system
‪function alert_security_system()
Definition: traps_shared.gsc:353
‪cSecuritySystem::setup_in_array
‪function setup_in_array(str_targetname)
Definition: traps_shared.gsc:188
‪cSecuritySystem::constructor
‪constructor()
Definition: traps_shared.gsc:126
‪cSecuritySystem::spawn_turrets
‪function spawn_turrets()
Definition: traps_shared.gsc:471
‪cSecurityMover::v_endangles
‪var v_endangles
Definition: traps_shared.gsc:701
‪cRailTurret::n_duration
‪var n_duration
Definition: traps_shared.gsc:1568
‪t_frustrum
‪var t_frustrum
Definition: traps_shared.gsc:2010
‪cSecurityMover::n_movement_duration
‪var n_movement_duration
Definition: traps_shared.gsc:703
‪watch_securitynode_death
‪function watch_securitynode_death()
Definition: traps_shared.gsc:1352
‪e_frustrum
‪var e_frustrum
Definition: traps_shared.gsc:2011
‪cSecuritySystem::n_alert_remaining_cooldown
‪var n_alert_remaining_cooldown
Definition: traps_shared.gsc:106
‪cRailTurret::b_turret_active
‪var b_turret_active
Definition: traps_shared.gsc:1553
‪cSecurityLight::m_e_securitylight
‪var m_e_securitylight
Definition: traps_shared.gsc:1266
‪cSecurityPanel::m_o_secsystem
‪var m_o_secsystem
Definition: traps_shared.gsc:1367
‪cRailTurret::n_speed
‪var n_speed
Definition: traps_shared.gsc:1567
‪cSecurityMover::timed_effects
‪function timed_effects(b_play_screen_shake)
Definition: traps_shared.gsc:1035
‪e_camera
‪var e_camera
Definition: traps_shared.gsc:2005
‪cSecurityMover::n_current_path_index
‪var n_current_path_index
Definition: traps_shared.gsc:708
‪cSecuritySystem::a_SecurityLights
‪var a_SecurityLights
Definition: traps_shared.gsc:121
‪n_scanangle_left
‪var n_scanangle_left
Definition: traps_shared.gsc:2013
‪cRailTurret::s_nextdest
‪var s_nextdest
Definition: traps_shared.gsc:1570
‪deactivate
‪function deactivate()
Definition: traps_shared.gsc:649
‪ARRAY_ADD
‪#define ARRAY_ADD(__array, __item)
Definition: shared.gsh:304
‪b_scandir_right
‪var b_scandir_right
Definition: traps_shared.gsc:2023
‪ALERT_NONE
‪#define ALERT_NONE
Definition: traps_shared.gsc:24
‪b_laser_can_reactivate
‪var b_laser_can_reactivate
Definition: traps_shared.gsc:530
‪cRailTurret::n_shoot_duration
‪var n_shoot_duration
Definition: traps_shared.gsc:1558
‪cSecurityMover::load_pathstructs
‪function load_pathstructs()
Definition: traps_shared.gsc:930
‪laser_awareness
‪function laser_awareness()
Definition: traps_shared.gsc:590
‪cSecurityDoor::setup
‪function setup(door, secsystem)
Definition: traps_shared.gsc:1137
‪n_scanpausetime
‪var n_scanpausetime
Definition: traps_shared.gsc:2017
‪cSecurityPanel::constructor
‪constructor()
Definition: traps_shared.gsc:1369
‪wait_till
‪function wait_till(str_flag)
Definition: flag_shared.csc:189
‪v_laser_destination
‪var v_laser_destination
Definition: traps_shared.gsc:534
‪cSecuritySystem::reactivate_detectors
‪function reactivate_detectors()
Definition: traps_shared.gsc:417
‪cSecuritySystem::reset_security_system
‪function reset_security_system()
Definition: traps_shared.gsc:367
‪cSecurityMover::stop_sounds
‪function stop_sounds()
Definition: traps_shared.gsc:1028
‪cSecurityPanel::deactivate
‪function deactivate()
Definition: traps_shared.gsc:1390
‪cSecurityMover::v_startangles
‪var v_startangles
Definition: traps_shared.gsc:700
‪cSecurityMover::e_mover
‪var e_mover
Definition: traps_shared.gsc:693
‪__init__
‪function __init__()
Definition: traps_shared.gsc:44
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪cSecurityMover::n_delay_before_movement
‪var n_delay_before_movement
Definition: traps_shared.gsc:702
‪get_yaw_to_target
‪function get_yaw_to_target()
Definition: traps_shared.gsc:2284
‪cSecurityDoor::deactivate
‪function deactivate()
Definition: traps_shared.gsc:1164
‪camera_scan
‪function camera_scan()
Definition: traps_shared.gsc:2161
‪cRailTurret::fx_ent
‪var fx_ent
Definition: traps_shared.gsc:1550
‪cSecuritySystem::a_SecurityReversePanels
‪var a_SecurityReversePanels
Definition: traps_shared.gsc:124
‪b_crusher_is_active
‪cSecurityDoor b_crusher_is_active
‪cSecurityDoor
Definition: traps_shared.gsc:1133
‪cRailTurret::turret_behavior
‪function turret_behavior()
Definition: traps_shared.gsc:1878
‪cSecuritySystem::set_player_last_known_pos
‪function set_player_last_known_pos()
Definition: traps_shared.gsc:262
‪cSecurityMover::a_pathstructs
‪var a_pathstructs
Definition: traps_shared.gsc:706
‪cRailTurret::n_dist
‪var n_dist
Definition: traps_shared.gsc:1565
‪cSecurityMover::b_is_broken
‪var b_is_broken
Definition: traps_shared.gsc:712
‪cSecurityMover::e_mover_broken
‪var e_mover_broken
Definition: traps_shared.gsc:695
‪e_camera_mount
‪var e_camera_mount
Definition: traps_shared.gsc:2006
‪cSecurityPanel::destructor
‪destructor()
Definition: traps_shared.gsc:1373
‪cRailTurret::e_target
‪var e_target
Definition: traps_shared.gsc:1554
‪init
‪function init()
Definition: struct.csc:1
‪cSecurityMover::constructor
‪constructor()
Definition: traps_shared.gsc:714
‪cRailTurret::m_o_secsystem
‪var m_o_secsystem
Definition: traps_shared.gsc:1548
‪watch_for_player_touch
‪function watch_for_player_touch()
Definition: traps_shared.gsc:1193
‪cRailTurret::n_pause_before_attack
‪var n_pause_before_attack
Definition: traps_shared.gsc:1556
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪b_scanning
‪var b_scanning
Definition: traps_shared.gsc:2022
‪cSecuritySystem::n_alert_level
‪var n_alert_level
Definition: traps_shared.gsc:104
‪cRailTurret::n_turn_speed
‪var n_turn_speed
Definition: traps_shared.gsc:1562
‪cSecurityMover::move_forward_along_path
‪function move_forward_along_path()
Definition: traps_shared.gsc:952
‪cRailTurret::stop_moving
‪function stop_moving()
Definition: traps_shared.gsc:1787
‪cRailTurret::set_combat_target
‪function set_combat_target(target)
Definition: traps_shared.gsc:1894
‪v_laser_origin
‪var v_laser_origin
Definition: traps_shared.gsc:533
‪t_panel
‪var t_panel
Definition: traps_shared.gsc:1353
‪cSecuritySystem::a_SecurityBlockers
‪var a_SecurityBlockers
Definition: traps_shared.gsc:115
‪cSecuritySystem::n_alert_cooldown
‪var n_alert_cooldown
Definition: traps_shared.gsc:105
‪cRailTurret::e_railturret_snd2
‪var e_railturret_snd2
Definition: traps_shared.gsc:1575
‪reactivate
‪function reactivate()
Definition: traps_shared.gsc:661
‪n_scanangle_right
‪var n_scanangle_right
Definition: traps_shared.gsc:2014
‪b_max_scanyaw
‪var b_max_scanyaw
Definition: traps_shared.gsc:2025
‪setup
‪function setup(trigger, secsystem)
Definition: traps_shared.gsc:550
‪b_visible_laser_exists
‪var b_visible_laser_exists
Definition: traps_shared.gsc:529
‪cSecuritySystem::decrement_detector_count
‪function decrement_detector_count()
Definition: traps_shared.gsc:268
‪cSecuritySystem::raise_alert
‪function raise_alert()
Definition: traps_shared.gsc:335
‪looping_movement
‪function looping_movement()
Definition: traps_shared.gsc:1207
‪cSecuritySystem::e_secsystem
‪var e_secsystem
Definition: traps_shared.gsc:102
‪cSecuritySystem::a_SecurityCrushers
‪var a_SecurityCrushers
Definition: traps_shared.gsc:114
‪activate_camera_light
‪function activate_camera_light(light_type)
Definition: traps_shared.gsc:2122
‪cSecuritySystem::new_object_of_type
‪function new_object_of_type(str_targetname)
Definition: traps_shared.gsc:227
‪cSecurityMover::n_resttime
‪var n_resttime
Definition: traps_shared.gsc:704
‪cSecurityMover::move_to_endpos
‪function move_to_endpos()
Definition: traps_shared.gsc:861
‪cSecuritySystem::a_SecurityDoors
‪var a_SecurityDoors
Definition: traps_shared.gsc:113
‪cSecuritySystem
Definition: traps_shared.gsc:99
‪wait_till_clear
‪function wait_till_clear(str_flag)
Definition: flag_shared.csc:248
‪cSecuritySystem::destructor
‪destructor()
Definition: traps_shared.gsc:137
‪cRailTurret::move_along_path
‪function move_along_path()
Definition: traps_shared.gsc:1752
‪m_e_securitynode
‪class cSecurityLight m_e_securitynode
‪cSecuritySystem::deactivate_consequences
‪function deactivate_consequences()
Definition: traps_shared.gsc:399
‪cRailTurret::n_stop_on_track_dist
‪var n_stop_on_track_dist
Definition: traps_shared.gsc:1563
‪cSecurityLight::setup
‪function setup(securitylight, secsystem)
Definition: traps_shared.gsc:1278
‪constructor
‪constructor()
Definition: traps_shared.gsc:537
‪cRailTurret::e_railturret
‪var e_railturret
Definition: traps_shared.gsc:1547
‪setup_all_traps
‪function setup_all_traps()
Definition: traps_shared.gsc:65
‪cRailTurret::turret_movement_behavior
‪function turret_movement_behavior()
Definition: traps_shared.gsc:1701
‪cSecurityLight::constructor
‪constructor()
Definition: traps_shared.gsc:1270
‪n_laser_movement_duration
‪var n_laser_movement_duration
Definition: traps_shared.gsc:535
‪e_camera_sound
‪var e_camera_sound
Definition: traps_shared.gsc:2007
‪cSecuritySystem::n_security_node_count
‪var n_security_node_count
Definition: traps_shared.gsc:108
‪cSecurityMover::breakable_wall_damage_watcher
‪function breakable_wall_damage_watcher()
Definition: traps_shared.gsc:825
‪cSecuritySystem::a_SecurityPanels
‪var a_SecurityPanels
Definition: traps_shared.gsc:123
‪cRailTurret::face_player
‪function face_player()
Definition: traps_shared.gsc:1837
‪cSecuritySystem::str_secsystem_name
‪var str_secsystem_name
Definition: traps_shared.gsc:103
‪cSecurityMover::b_is_breakable
‪var b_is_breakable
Definition: traps_shared.gsc:711
‪cRailTurret::b_turret_alive
‪var b_turret_alive
Definition: traps_shared.gsc:1552
‪cSecurityPanel::watch_security_panel_trigger
‪function watch_security_panel_trigger()
Definition: traps_shared.gsc:1385
‪cRailTurret::e_gimbal
‪var e_gimbal
Definition: traps_shared.gsc:1571
‪n_inner_radius
‪class cSecurityMover n_inner_radius
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪cSecurityPanel::setup
‪function setup(trigger, secsystem)
Definition: traps_shared.gsc:1377