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