‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_ambient.csc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\shared\sound_shared;
7 
8 #insert scripts\shared\shared.gsh;
9 
10 #namespace ambient;
11 
12 ‪REGISTER_SYSTEM( "ambient", &‪__init__, undefined )
13 
14 function ‪__init__()
15 {
17 }
18 
19 function ‪on_player_connect( localclientnum )
20 {
21  thread ‪ceiling_fans_init( localclientnum );
22  thread ‪clocks_init( localclientnum );
23  thread ‪spin_anemometers( localclientnum );
24  if ( isdefined( level._levelSpecificAmbient ) )
25  {
26  thread [[level._levelSpecificAmbient]]( localClientNum );
27  }
28 }
29 
30 // setup a script_struct to play scripted Flak88 tracers FX
31 function ‪setup_point_fx(point, fx_id)
32 {
33  if(isdefined(point.script_fxid))
34  {
35  fx_id = point.script_fxid;
36  }
37 
38  point.fx_id = fx_id;
39 
40  if(isdefined(point.angles))
41  {
42  point.forward = anglesToForward(point.angles);
43  point.up = anglesToUp(point.angles);
44  }
45  else
46  {
47  point.angles = (0, 0, 0);
48  point.forward = (0, 0, 0);
49  point.up = (0, 0, 0);
50  }
51 
52  if(point.targetname == "flak_fire_fx")
53  {
54  level thread ‪ambient_flak_think(point);
55  }
56 
57  if(point.targetname == "fake_fire_fx")
58  {
59  level thread ‪ambient_fakefire_think(point);
60  }
61 }
62 
63 // rotate the Flak88 tracers FX
64 function ‪ambient_flak_think(point)
65 {
66  amount = undefined;
67  speed = undefined;
68  night = false;
69 
70  min_delay = 0.4;
71  max_delay = 4;
72 
73  min_burst_time = 1;
74  max_burst_time = 3;
75 
76  point.is_firing = false;
77  level thread ‪ambient_flak_rotate(point);
78  level thread ‪ambient_flak_flash(point, min_burst_time, max_burst_time);
79 
80  for(;;)
81  {
82  ‪timer = randomFloatRange(min_burst_time, max_burst_time);
83  while(‪timer > 0)
84  {
85  point.is_firing = true;
86  playFX(0, level._effect[point.fx_id], point.origin, point.forward, point.up);
87  thread ‪sound::play_in_space(0, "wpn_triple25_fire", point.origin);
88  wait(0.2);
89 
90  ‪timer -= 0.2;
91  }
92 
93  point.is_firing = false;
94  wait(randomFloatRange(min_delay, max_delay));
95  }
96 }
97 
98 // This mimics the rotation of the FX, but without using an ent (or client-ent)
99 // Updates the forward and up vectors which are used above
100 function ‪ambient_flak_rotate(point)
101 {
102  min_pitch = 30;
103  max_pitch = 80;
104 
105  if(isdefined(point.angles))
106  {
107  pointangles = point.angles;
108  }
109  else
110  {
111  pointangles = (0, 0, 0);
112  }
113 
114  for(;;)
115  {
116  time = randomFloatRange(0.5, 2);
117  steps = time * 10;
118 
119  random_angle = (randomIntRange(min_pitch, max_pitch) * -1, randomInt(360), 0);
120 
121  forward = anglesToForward(random_angle);
122  up = anglesToUp(random_angle);
123 
124  diff_forward = (forward - point.forward) / steps;
125  diff_up = (up - point.up) / steps;
126 
127  for(i = 0; i < steps; i++)
128  {
129  point.forward += diff_forward;
130  point.up += diff_up;
131 
132  wait(0.1);
133  }
134 
135  point.forward = forward;
136  point.up = up;
137  }
138 }
139 
140 // This gives a random chance to play a cloud flash
141 // or flak burst FX for the ambient Flak
142 function ‪ambient_flak_flash(point, min_burst_time, max_burst_time)
143 {
144  min_dist = 5000;
145  max_dist = 6500;
146 
147  if(isdefined(point.script_mindist))
148  {
149  min_dist = point.script_mindist;
150  }
151 
152  if(isdefined(point.script_maxdist))
153  {
154  max_dist = point.script_maxdist;
155  }
156 
157  min_burst_time = 0.25;
158  max_burst_time = 1;
159 
160  fxpos = undefined;
161 
162  while(1)
163  {
164  if( !point.is_firing )
165  {
166  wait( 0.25 );
167  continue;
168  }
169 
170  fxpos = point.origin + VectorScale(point.forward, randomIntRange(min_dist, max_dist));
171 
172  playFX(0, level._effect["flak_burst_single"], fxpos);
173 
174  if(isdefined(level.timeofday) && (level.timeofday == "evening" || level.timeofday == "night"))
175  {
176  playFX(0, level._effect["flak_cloudflash_night"], fxpos);
177  }
178 
179  wait randomFloatRange(min_burst_time, max_burst_time);
180  }
181 }
182 
183 
184 
185 // *******************************************************************************************************
186 // Ambient Weapon Muzzleflashes
187 //
188 // point = a script_struct in the map
189 // This is used to play the ambient fake fire fx and sound
191 {
192  fireSound = undefined;
193  weapType = undefined;
194 
195  burstMin = undefined;
196  burstMax = undefined;
197  betweenShotsMin = undefined;
198  betweenShotsMax = undefined;
199  reloadTimeMin = undefined;
200  reloadTimeMax = undefined;
201  soundChance = undefined;
202 
203  if(!isdefined(point.weaponinfo))
204  {
205  point.weaponinfo = "axis_turret";
206  }
207 
208  // determine what type of weapon the script_struct is faking
209  switch(point.weaponinfo)
210  {
211  case "allies_assault":
212 
213  if(isdefined(level.allies_team) && (level.allies_team == "marines"))
214  {
215  fireSound = "weap_bar_fire";
216  }
217  else
218  {
219  fireSound = "weap_dp28_fire_plr";
220  }
221 
222  burstMin = 16;
223  burstMax = 24;
224  betweenShotsMin = 0.05;
225  betweenShotsMax = 0.08;
226  reloadTimeMin = 4;
227  reloadTimeMax = 7;
228  soundChance = 75;
229  weapType = "assault";
230  break;
231 
232  case "axis_assault":
233 
234  if(isdefined(level.axis_team) && (level.axis_team == "german"))
235  {
236  fireSound = "weap_mp44_fire";
237  }
238  else
239  {
240  fireSound = "weap_type99_fire";
241  }
242 
243  burstMin = 16;
244  burstMax = 24;
245  betweenShotsMin = 0.05;
246  betweenShotsMax = 0.08;
247  reloadTimeMin = 4;
248  reloadTimeMax = 7;
249  soundChance = 75;
250  weapType = "assault";
251  break;
252 
253  case "allies_rifle":
254 
255  if(isdefined(level.allies_team) && (level.allies_team == "marines"))
256  {
257  fireSound = "weap_m1garand_fire";
258  }
259  else
260  {
261  fireSound = "weap_mosinnagant_fire";
262  }
263 
264  burstMin = 1;
265  burstMax = 3;
266  betweenShotsMin = 0.8;
267  betweenShotsMax = 1.3;
268  reloadTimeMin = 3;
269  reloadTimeMax = 6;
270  soundChance = 95;
271  weapType = "rifle";
272  break;
273 
274  case "axis_rifle":
275 
276  if(isdefined(level.axis_team) && (level.axis_team == "german"))
277  {
278  fireSound = "weap_kar98k_fire";
279  }
280  else
281  {
282  fireSound = "weap_arisaka_fire";
283  }
284 
285  burstMin = 1;
286  burstMax = 3;
287  betweenShotsMin = 0.8;
288  betweenShotsMax = 1.3;
289  reloadTimeMin = 3;
290  reloadTimeMax = 6;
291  soundChance = 95;
292  weapType = "rifle";
293  break;
294 
295  case "allies_smg":
296 
297  if(isdefined(level.allies_team) && (level.allies_team == "marines"))
298  {
299  fireSound = "weap_thompson_fire";
300  }
301  else
302  {
303  fireSound = "weap_ppsh_fire";
304  }
305 
306  burstMin = 14;
307  burstMax = 28;
308  betweenShotsMin = 0.08;
309  betweenShotsMax = 0.12;
310  reloadTimeMin = 2;
311  reloadTimeMax = 5;
312  soundChance = 75;
313  weapType = "smg";
314  break;
315 
316  case "axis_smg":
317 
318  if(isdefined(level.axis_team) && (level.axis_team == "german"))
319  {
320  fireSound = "weap_mp40_fire";
321  }
322  else
323  {
324  fireSound = "weap_type100_fire";
325  }
326 
327  burstMin = 14;
328  burstMax = 28;
329  betweenShotsMin = 0.08;
330  betweenShotsMax = 0.12;
331  reloadTimeMin = 2;
332  reloadTimeMax = 5;
333  soundChance = 75;
334  weapType = "smg";
335  break;
336 
337  case "allies_turret":
338 
339  if(isdefined(level.allies_team) && (level.allies_team == "marines"))
340  {
341  fireSound = "weap_30cal_fire";
342  }
343  else
344  {
345  fireSound = "weap_dp28_fire_plr";
346  }
347 
348  burstMin = 60;
349  burstMax = 90;
350  betweenShotsMin = 0.05;
351  betweenShotsMax = 0.08;
352  reloadTimeMin = 3;
353  reloadTimeMax = 6;
354  soundChance = 95;
355  weapType = "turret";
356  break;
357 
358  case "axis_turret":
359 
360  if(isdefined(level.axis_team) && (level.axis_team == "german"))
361  {
362  fireSound = "weap_bar_fire"; //update this if the sound changes
363  }
364  else
365  {
366  fireSound = "weap_type92_fire";
367  }
368 
369  burstMin = 60;
370  burstMax = 90;
371  betweenShotsMin = 0.05;
372  betweenShotsMax = 0.08;
373  reloadTimeMin = 3;
374  reloadTimeMax = 6;
375  soundChance = 95;
376  weapType = "turret";
377  break;
378 
379  default:
380  ASSERTMSG("Ambient Fakefire: Weapon Info '" + point.weaponinfo + "' is not recognized.");
381  }
382 
383  while(1)
384  {
385  // burst fire
386  burst = randomIntRange(burstMin, burstMax);
387 
388  for(i = 0; i < burst; i++)
389  {
390  traceDist = 10000;
391 
392  target = point.origin + VectorScale(anglesToForward(point.angles + (-3 + randomInt(6), -5 + randomInt(10), 0)), traceDist);
393 
394  // -- not using real weaponsettings
395  if ( randomInt(100) <= 20 )
396  {
397  bulletTracer(point.origin, target);
398  }
399 
400  playFX(0, level._effect[point.fx_id], point.origin, point.forward);
401 
402  // snyder steez - reduce popcorn effect
403 // if(randomInt(100) <= soundChance)
404 // {
405 // thread sound::play_in_space(0, fireSound, point.origin);
406 // }
407 
408  wait (randomFloatRange(betweenShotsMin, betweenShotsMax));
409  }
410 
411  wait (randomFloatRange(reloadTimeMin, reloadTimeMax));
412  }
413 }
414 
415 function ‪ceiling_fans_init(clientNum)
416 {
417  // grab all of the ceiling fans and make them spin
418  fan_array = GetEntArray(clientNum, "ceiling_fan", "targetname");
419  if( isdefined(fan_array) )
420  {
421  /# println("**********fan array is defined, size: " + fan_array.size); #/
422  array::thread_all( fan_array,&‪spin_fan );
423  }
424 }
425 
426 function ‪spin_fan() // self == fan from the array
427 {
428  self endon("entityshutdown");
429 
430  //println("**********fan running");
431  // get the speed from the fan, if no speed then make it random
432  if ( !isdefined ( self.speed ) )
433  {
434  self.speed = RandomIntRange(1, 100);
435  self.speed = (self.speed % 10) + 1;
436  }
437  if ( self.speed < 1 )
438  {
439  self.speed = RandomIntRange(1, 100);
440  self.speed = (self.speed % 10) + 1;
441  }
442 
443  // see if they want it to wobble
444  do_wobble = false;
445  wobble = self.script_noteworthy;
446  if( isdefined(wobble) )
447  {
448  if( wobble == "wobble" )
449  {
450  do_wobble = true;
451  self.wobble_speed = self.speed * 0.5;
452  }
453  }
454 
455  //println("**********fan speed: " + self.speed);
456  //println("**********fan wobble: " + do_wobble);
457 
458  while(true)
459  {
460  if( !do_wobble )
461  {
462  self RotateYaw(180, self.speed);
463  self waittill("rotatedone");
464  }
465  else
466  {
467  self RotateYaw(340, self.speed);
468  self waittill("rotatedone");
469  self RotateYaw(20, self.wobble_speed);
470  self waittill("rotatedone");
471  }
472  }
473 }
474 
475 
476 function ‪clocks_init(clientNum)
477 {
478  // the format should be an array (hour, min, sec), military time
479  // if we pass in a 1 then we'll get GMT 0 London time, else we get the local time on the kit
480  curr_time = GetSystemTime();
481 
482  // put the hands in the right place
483  hours = curr_time[0];
484  if( hours > 12 )
485  {
486  hours -= 12;
487  }
488  if( hours == 0 )
489  {
490  hours = 12;
491  }
492  minutes = curr_time[1];
493  seconds = curr_time[2];
494 
495  // set the starting time
496  // hoping that all of the hands start pointing straight up at 12
497  // each hour is 30 degrees of rotation ...
498  // it should also rotate a little bit each time the minute hand moves
499  // the math is 30 degrees of rotations in 3600 seconds (1 hour)
500  hour_hand = GetEntArray(clientNum, "hour_hand", "targetname");
501  hour_values = [];
502  hour_values["hand_time"] = hours;
503  hour_values["rotate"] = 30;
504  hour_values["rotate_bit"] = 30 / 3600;
505  // we need to do the first rotation based on the beginning time, if we don't do this the time will look like it's off a little bit
506  hour_values["first_rotate"] = ((minutes * 60) + seconds) * hour_values["rotate_bit"];
507 
508  // each minute is 6 degrees of rotation ...
509  // it should also rotate a little bit each time the second hand moves
510  // the math is 6 degrees of rotations in 60 seconds (1 minute)
511  minute_hand = GetEntArray(clientNum, "minute_hand", "targetname");
512  minute_values = [];
513  minute_values["hand_time"] = minutes;
514  minute_values["rotate"] = 6;
515  minute_values["rotate_bit"] = 6 / 60;
516  // we need to do the first rotation based on the beginning time, if we don't do this the time will look like it's off a little bit
517  minute_values["first_rotate"] = seconds * minute_values["rotate_bit"];
518 
519  // each second is 6 degrees of rotation
520  second_hand = GetEntArray(clientNum, "second_hand", "targetname");
521  second_values = [];
522  second_values["hand_time"] = seconds;
523  second_values["rotate"] = 6;
524  second_values["rotate_bit"] = 6;
525 
526  hour_hand_array = GetEntArray(clientNum, "hour_hand", "targetname");
527  if( isdefined(hour_hand_array) )
528  {
529  /# println("**********hour_hand_array is defined, size: " + hour_hand_array.size); #/
530  array::thread_all( hour_hand_array,&‪clock_run, hour_values );
531  }
532  minute_hand_array = GetEntArray(clientNum, "minute_hand", "targetname");
533  if( isdefined(minute_hand_array) )
534  {
535  /# println("**********minute_hand_array is defined, size: " + minute_hand_array.size); #/
536  array::thread_all( minute_hand_array,&‪clock_run, minute_values );
537  }
538  second_hand_array = GetEntArray(clientNum, "second_hand", "targetname");
539  if( isdefined(second_hand_array) )
540  {
541  /# println("**********second_hand_array is defined, size: " + second_hand_array.size); #/
542  array::thread_all( second_hand_array,&‪clock_run, second_values );
543  }
544 
545 }
546 
547 function ‪clock_run(time_values) // self == either hour hand, minute hand, or second hand
548 {
549  self endon("entityshutdown");
550 
551  // hour hands will have script_noteworthy = time zone if they want a different time zone
552  if( isdefined(self.script_noteworthy) )
553  {
554  hour = time_values["hand_time"];
555  curr_time = GetSystemTime(1);
556 
557  switch( ToLower(self.script_noteworthy) )
558  {
559  case "honolulu": // GMT -10
560  hour = curr_time[0] - 10;
561  break;
562  case "alaska": // GMT -9
563  hour = curr_time[0] - 9;
564  break;
565  case "los angeles": // GMT -8
566  hour = curr_time[0] - 8;
567  break;
568  case "denver": // GMT -7
569  hour = curr_time[0] - 7;
570  break;
571  case "chicago": // GMT -6
572  hour = curr_time[0] - 6;
573  break;
574  case "new york": // GMT -5
575  hour = curr_time[0] - 5;
576  break;
577  case "halifax": // GMT -4
578  hour = curr_time[0] - 4;
579  break;
580  case "greenland": // GMT -3
581  hour = curr_time[0] - 3;
582  break;
583  case "london": // GMT 0
584  hour = curr_time[0];
585  break;
586  case "paris": // GMT +1
587  hour = curr_time[0] + 1;
588  break;
589  case "helsinki": // GMT +2
590  hour = curr_time[0] + 2;
591  break;
592  case "moscow": // GMT +3
593  hour = curr_time[0] + 3;
594  break;
595  case "vietnam": // GMT +7
596  hour = curr_time[0] + 7;
597  break;
598  case "china": // GMT +8
599  hour = curr_time[0] + 8;
600  break;
601  }
602 
603  if( hour < 1 )
604  {
605  hour += 12;
606  }
607  if( hour > 12 )
608  {
609  hour -= 12;
610  }
611  time_values["hand_time"] = hour;
612  }
613 
614  self RotatePitch(time_values["hand_time"] * time_values["rotate"], 0.05);
615  self waittill("rotatedone");
616 
617  if( isdefined(time_values["first_rotate"]) )
618  {
619  self RotatePitch(time_values["first_rotate"], 0.05);
620  self waittill("rotatedone");
621  }
622 
623  prev_time = GetSystemTime();
624 
625  while(true)
626  {
627  curr_time = GetSystemTime();
628  if( prev_time != curr_time )
629  {
630  self RotatePitch(time_values["rotate_bit"], 0.05);
631 
632  prev_time = curr_time;
633  }
634 
635  wait(1.0);
636  }
637 }
638 
639 //Makes it so anemometers will spin whenever builders drop them into their map
640 function ‪spin_anemometers( clientNum )
641 {
642  spoon_spinners = GetEntArray(clientNum, "spinner1","targetname");
643  flat_spinners = GetEntArray( clientNum, "spinner2","targetname");
644 
645  if( isdefined( spoon_spinners ))
646  {
647  /# println("**********spoon_spinners is defined, size: " + spoon_spinners.size); #/
648  array::thread_all( spoon_spinners,&‪spoon_spin_func);
649  }
650 
651  if( isdefined( flat_spinners ))
652  {
653  /# println("**********flat_spinners is defined, size: " + flat_spinners.size); #/
654  array::thread_all( flat_spinners,&‪arrow_spin_func);
655  }
656 
657 }
658 
659 //Self is the "spoon" like script model within the anemometer
661 {
662  self endon( "entityshutdown" );
663 
664  if(isdefined( self.script_float))
665  {
666  model_speed = self.script_float;
667  }
668  else
669  {
670  model_speed = 2;
671  }
672 
673  while(1)
674  {
675  speed = RandomFloatRange( model_speed * .6, model_speed);
676  self RotateYaw( 1200, speed);
677  self waittill ("rotatedone");
678  }
679 }
680 
681 //Self is the "arrow" like script model within the anemometer
683 {
684  self endon( "entityshutdown" );
685 
686  if(isdefined( self.script_int))
687  {
688  model_direction_change = self.script_int;
689  }
690  else
691  {
692  model_direction_change = 25;
693  }
694 
695  if(isdefined( self.script_float))
696  {
697  model_speed = self.script_float;
698  }
699  else
700  {
701  model_speed = .8;
702  }
703 
704  while(1)
705  {
706  direction_change = model_direction_change + RandomIntRange(-11, 11);
707  speed_change = RandomFloatRange(model_speed * .3, model_speed);
708 
709  self RotateYaw( direction_change, speed_change);
710  self waittill ("rotatedone");
711  self RotateYaw( (direction_change * -1), speed_change);
712  self waittill ("rotatedone");
713  }
714 }
‪setup_point_fx
‪function setup_point_fx(point, fx_id)
Definition: _ambient.csc:31
‪on_player_connect
‪function on_player_connect(localclientnum)
Definition: _ambient.csc:19
‪timer
‪function timer(n_time, str_endon, x, y, height)
Definition: lui_shared.gsc:163
‪spin_fan
‪function spin_fan()
Definition: _ambient.csc:426
‪play_in_space
‪function play_in_space(localClientNum, alias, origin)
Definition: sound_shared.csc:30
‪spoon_spin_func
‪function spoon_spin_func()
Definition: _ambient.csc:660
‪ceiling_fans_init
‪function ceiling_fans_init(clientNum)
Definition: _ambient.csc:415
‪on_localclient_connect
‪function on_localclient_connect(localClientNum)
Definition: ctf.csc:20
‪ambient_flak_rotate
‪function ambient_flak_rotate(point)
Definition: _ambient.csc:100
‪spin_anemometers
‪function spin_anemometers(clientNum)
Definition: _ambient.csc:640
‪clocks_init
‪function clocks_init(clientNum)
Definition: _ambient.csc:476
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪arrow_spin_func
‪function arrow_spin_func()
Definition: _ambient.csc:682
‪__init__
‪function __init__()
Definition: _ambient.csc:14
‪ambient_flak_flash
‪function ambient_flak_flash(point, min_burst_time, max_burst_time)
Definition: _ambient.csc:142
‪ambient_flak_think
‪function ambient_flak_think(point)
Definition: _ambient.csc:64
‪clock_run
‪function clock_run(time_values)
Definition: _ambient.csc:547
‪ambient_fakefire_think
‪function ambient_fakefire_think(point)
Definition: _ambient.csc:190