‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
exploder_shared.csc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\fx_shared;
5 #using scripts\shared\sound_shared;
6 #using scripts\shared\system_shared;
7 
8 #insert scripts\shared\shared.gsh;
9 
10 #namespace exploder;
11 
12 ‪REGISTER_SYSTEM( "exploder", &‪__init__, undefined )
13 
14 function ‪__init__()
15 {
16  if( SessionModeIsCampaignGame() )
17  {
19  }
20 }
21 
22 function ‪player_init( clientnum )
23 {
24  //println("*** Init exploders...");
25  script_exploders = [];
26 
27  ents = ‪struct::get_array( "script_brushmodel", "classname" );
28  //println("Client : s_bm " + ents.size);
29 
30  smodels = ‪struct::get_array( "script_model", "classname" );
31  //println("Client : sm " + smodels.size);
32 
33  for( i = 0; i < smodels.size; i++ )
34  {
35  ents[ents.size] = smodels[i];
36  }
37 
38  for( i = 0; i < ents.size; i++ )
39  {
40  if( isdefined( ents[i].script_prefab_exploder ) )
41  {
42  ents[i].script_exploder = ents[i].script_prefab_exploder;
43  }
44  }
45 
46  potentialExploders = ‪struct::get_array( "script_brushmodel", "classname" );
47  //println("Client : Potential exploders from script_brushmodel " + potentialExploders.size);
48 
49  for( i = 0; i < potentialExploders.size; i++ )
50  {
51  if( isdefined( potentialExploders[i].script_prefab_exploder ) )
52  {
53  potentialExploders[i].script_exploder = potentialExploders[i].script_prefab_exploder;
54  }
55 
56  if( isdefined( potentialExploders[i].script_exploder ) )
57  {
58  script_exploders[script_exploders.size] = potentialExploders[i];
59  }
60  }
61 
62  potentialExploders = ‪struct::get_array( "script_model", "classname" );
63  //println("Client : Potential exploders from script_model " + potentialExploders.size);
64 
65  for( i = 0; i < potentialExploders.size; i++ )
66  {
67  if( isdefined( potentialExploders[i].script_prefab_exploder ) )
68  {
69  potentialExploders[i].script_exploder = potentialExploders[i].script_prefab_exploder;
70  }
71 
72  if( isdefined( potentialExploders[i].script_exploder ) )
73  {
74  script_exploders[script_exploders.size] = potentialExploders[i];
75  }
76  }
77 
78  // Also support script_structs to work as exploders
79  for( i = 0; i < level.struct.size; i++ )
80  {
81  if( isdefined( level.struct[i].script_prefab_exploder ) )
82  {
83  level.struct[i].script_exploder = level.struct[i].script_prefab_exploder;
84  }
85 
86  if( isdefined( level.struct[i].script_exploder ) )
87  {
88  script_exploders[script_exploders.size] = level.struct[i];
89  }
90  }
91 
92  if( !isdefined( level.createFXent ) )
93  {
94  level.createFXent = [];
95  }
96 
97  acceptableTargetnames = [];
98  acceptableTargetnames["exploderchunk visible"] = true;
99  acceptableTargetnames["exploderchunk"] = true;
100  acceptableTargetnames["exploder"] = true;
101 
102  exploder_id = 1;
103 
104  for( i = 0; i < script_exploders.size; i++ )
105  {
106  ‪exploder = script_exploders[i];
107  ent = ‪createExploder( ‪exploder.script_fxid );
108  ent.v = [];
109 
110  //if(!isdefined(exploder.origin))
111  //{
112  // println("************** NO EXPLODER ORIGIN." + i);
113  //}
114 
115  ent.v["origin"] = ‪exploder.origin;
116  ent.v["angles"] = ‪exploder.angles;
117  ent.v["delay"] = ‪exploder.script_delay;
118  ent.v["firefx"] = ‪exploder.script_firefx;
119  ent.v["firefxdelay"] = ‪exploder.script_firefxdelay;
120  ent.v["firefxsound"] = ‪exploder.script_firefxsound;
121  ent.v["firefxtimeout"] = ‪exploder.script_firefxtimeout;
122  ent.v["trailfx"] = ‪exploder.script_trailfx;
123  ent.v["trailfxtag"] = ‪exploder.script_trailfxtag;
124  ent.v["trailfxdelay"] = ‪exploder.script_trailfxdelay;
125  ent.v["trailfxsound"] = ‪exploder.script_trailfxsound;
126  ent.v["trailfxtimeout"] = ‪exploder.script_firefxtimeout;
127  ent.v["earthquake"] = ‪exploder.script_earthquake;
128  ent.v["rumble"] = ‪exploder.script_rumble;
129  ent.v["damage"] = ‪exploder.script_damage;
130  ent.v["damage_radius"] = ‪exploder.script_radius;
131  ent.v["repeat"] = ‪exploder.script_repeat;
132  ent.v["delay_min"] = ‪exploder.script_delay_min;
133  ent.v["delay_max"] = ‪exploder.script_delay_max;
134  ent.v["target"] = ‪exploder.target;
135  ent.v["ender"] = ‪exploder.script_ender;
136  ent.v["physics"] = ‪exploder.script_physics;
137  ent.v["type"] = "exploder";
138 // ent.v["worldfx"] = true;
139 
140  if( !isdefined( ‪exploder.script_fxid ) )
141  {
142  ent.v["fxid"] = "No FX";
143  }
144  else
145  {
146  ent.v["fxid"] = ‪exploder.script_fxid;
147  }
148  ent.v["exploder"] = ‪exploder.script_exploder;
149  // assert( isdefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
150 
151  if( !isdefined( ent.v["delay"] ) )
152  {
153  ent.v["delay"] = 0;
154  }
155 
156  // MikeD( 4/14/2008 ): Attempt to use the fxid as the sound reference, this way Sound can add sounds to anything
157  // without the scripter needing to modify the map
158  if( isdefined( ‪exploder.script_sound ) )
159  {
160  ent.v["soundalias"] = ‪exploder.script_sound;
161  }
162  else if( ent.v["fxid"] != "No FX" )
163  {
164  if( isdefined( level.scr_sound ) && isdefined( level.scr_sound[ent.v["fxid"]] ) )
165  {
166  ent.v["soundalias"] = level.scr_sound[ent.v["fxid"]];
167  }
168  }
169 
170  fixup_set = false;
171 
172  if(isdefined(ent.v["target"]))
173  {
174  ent.needs_fixup = exploder_id;
175  exploder_id++;
176  fixup_set = true;
177 
178 /* temp_ent = GetEnt(0, ent.v["target"], "targetname" );
179  * if( isdefined( temp_ent ) )
180  {
181  org = temp_ent.origin;
182  }
183  else */
184  {
185  temp_ent = ‪struct::get( ent.v["target"], "targetname" );
186  if (isdefined(temp_ent) )
187  {
188  org = temp_ent.origin;
189  }
190  }
191 
192  if(isdefined(org))
193  {
194  ent.v["angles"] = VectorToAngles( org - ent.v["origin"] );
195  }
196  //else
197  //{
198  //println("*** Client : Exploder " + exploder.script_fxid + " Failed to find target ");
199  //}
200 
201  if(isdefined(ent.v["angles"]))
202  {
204  }
205  //else
206  //{
207  //println("*** Client " + exploder.script_fxid + " has no angles.");
208  //}
209 
210  }
211 
212 
213  // this basically determines if its a brush/model exploder or not
214  if( (isdefined(‪exploder.classname) && ‪exploder.classname == "script_brushmodel") || isdefined( ‪exploder.model ) )
215  {
216  //if(isdefined(exploder.model))
217  //{
218  //println("*** exploder " + exploder_id + " model " + exploder.model);
219  //}
220  ent.model = ‪exploder;
221  //ent.model.disconnect_paths = exploder.script_disconnectpaths;
222  if(fixup_set == false)
223  {
224  ent.needs_fixup = exploder_id;
225  exploder_id++;
226  }
227  }
228 
229  if( isdefined( ‪exploder.targetname ) && isdefined( acceptableTargetnames[‪exploder.targetname] ) )
230  {
231  ent.v["exploder_type"] = ‪exploder.targetname;
232  }
233  else
234  {
235  ent.v["exploder_type"] = "normal";
236  }
237  }
238 
239  level.createFXexploders = [];
240 
241  for(i = 0; i < level.createFXent.size;i ++ )
242  {
243  ent = level.createFXent[i];
244 
245  if(ent.v["type"] != "exploder")
246  continue;
247 
248  ent.v["exploder_id"] = exploder::getexploderid( ent );
249 
250  if(!isdefined(level.createFXexploders[ent.v["exploder"]]))
251  {
252  level.createFXexploders[ent.v["exploder"]] = [];
253  }
254 
255  level.createFXexploders[ent.v["exploder"]][level.createFXexploders[ent.v["exploder"]].size] = ent;
256 
257  }
258 
259  reportexploderids();
260 
261 
262 // println("*** Client : " + script_exploders.size + " exploders.");
263 }
264 
265 function ‪getExploderId( ent )
266 {
267  if(!isdefined(level._exploder_ids))
268  {
269  level._exploder_ids = [];
270  level._exploder_id = 1;
271  }
272 
273  if(!isdefined(level._exploder_ids[ent.v["exploder"]]))
274  {
275  level._exploder_ids[ent.v["exploder"]] = level._exploder_id;
276  level._exploder_id ++;
277  }
278 
279  return level._exploder_ids[ent.v["exploder"]];
280 }
281 
283 {
284  if(!isdefined(level._exploder_ids))
285  return;
286 
287  keys = GetArrayKeys( level._exploder_ids );
288 
289  //println("Client Exploder dictionary : ");
290  //for( i = 0; i < keys.size; i++ )
291  //{
292  // println(keys[i] + " : " + level._exploder_ids[keys[i]]);
293  //}
294 }
295 
296 //Note: specific client number only supported for radiant based exploders as ID based is now legacy
297 function ‪exploder( exploder_id, n_localclientnumber )
298 {
299  if( IsInt( exploder_id ) )
300  {
301  ‪activate_exploder( exploder_id );
302  }
303  else//This is a radiant exploder
304  {
305  ‪activate_radiant_exploder( exploder_id, n_localclientnumber );
306  }
307 }
308 
309 function ‪activate_exploder( num )
310 {
311  num = int( num );
312 
313  if(isdefined(level.createFXexploders) && isdefined(level.createFXexploders[num]))
314  {
315  for(i = 0; i < level.createFXexploders[num].size; i ++)
316  {
317  level.createFXexploders[num][i] ‪activate_individual_exploder();
318  }
319  }
320 
322  {
323  if(isdefined(level.lightningNormalFunc) && isdefined(level.lightningFlashFunc))
324  {
325  thread ‪fx::lightning(level.lightningNormalFunc, level.lightningFlashFunc);
326  }
327  }
328 
329 }
330 
332 {
333  if(!isdefined(self.v["angles"]))
334  {
335  self.v["angles"] = (0,0,0);
337  }
338 
339  if( isdefined( self.v[ "firefx" ] ) )
340  self thread ‪fire_effect();
341 
342  if( isdefined( self.v[ "fxid" ] ) && self.v[ "fxid" ] != "No FX" )
343  self thread ‪cannon_effect();
344 
345  if( isdefined( self.v[ "earthquake" ] ) )
346  {
347  self thread ‪exploder_earthquake();
348  }
349 }
350 
351 //TODO T7 - update this if other functionality comes online for the new system
352 function ‪activate_radiant_exploder( string, n_localclientnumber )
353 {
354  if( isdefined( n_localclientnumber ) )
355  {
356  PlayRadiantExploder( n_localclientnumber, string );
357  }
358  else
359  {
360  for ( localClientNum = 0; localClientNum < level.localPlayers.size; localClientNum++ )
361  {
362  PlayRadiantExploder( localClientNum, string );
363  }
364  }
365 }
366 
367 //Note: specific client number only supported for radiant based exploders as ID based is now legacy
368 function ‪stop_exploder( exploder_id, n_localclientnumber )
369 {
370  //println("*** Client : Delete exploder " + num);
371  if( IsString( exploder_id ) )
372  {
373  if( isdefined( n_localclientnumber ) )
374  {
375  StopRadiantExploder( n_localclientnumber, exploder_id );
376  }
377  else
378  {
379  for ( localClientNum = 0; localClientNum < level.localPlayers.size; localClientNum++ )
380  {
381  StopRadiantExploder( localClientNum, exploder_id );
382  }
383  }
384  return;
385  }
386 
387  num = int( exploder_id );
388 
389  if(isdefined(level.createFXexploders[exploder_id]))
390  {
391  for(i = 0; i < level.createFXexploders[exploder_id].size; i ++)
392  {
393  ent = level.createFXexploders[exploder_id][i];
394 
395  if( isdefined(ent.loopFX) )
396  {
397  for(j = 0; j < ent.loopFX.size; j ++)
398  {
399  if( isdefined( ent.loopFX[j] ) )
400  {
401  StopFX( j, ent.loopFX[j] );
402  ent.loopFX[j] = undefined;
403  }
404  }
405 
406  ent.loopFX = [];
407  }
408  }
409  }
410 }
411 
412 function ‪kill_exploder( exploder_id )
413 {
414  //println("*** Client : Delete exploder " + num);
415  if( IsString( exploder_id ) )
416  {
417  for ( localClientNum = 0; localClientNum < level.localPlayers.size; localClientNum++ )
418  {
419  KillRadiantExploder( localClientNum, exploder_id );
420  }
421  return;
422  }
423  assertmsg( "unhandled exploder type, only radiant exploders are handled: " + exploder_id );
424 }
425 
427 {
428  if( !isdefined( self.v[ "delay" ] ) )
429  self.v[ "delay" ] = 0;
430 
431  min_delay = self.v[ "delay" ];
432  max_delay = self.v[ "delay" ] + 0.001;// cant randomfloatrange on the same #
433  if( isdefined( self.v[ "delay_min" ] ) )
434  min_delay = self.v[ "delay_min" ];
435 
436  if( isdefined( self.v[ "delay_max" ] ) )
437  max_delay = self.v[ "delay_max" ];
438 
439  if( min_delay > 0 )
440  waitrealtime( randomfloatrange( min_delay, max_delay ) );
441 }
442 
444 {
445  if( !isdefined( self.v[ "soundalias" ] ) || self.v[ "soundalias" ] == "nil" )
446  return;
447 
448  ‪sound::play_in_space( 0, self.v[ "soundalias" ], self.v[ "origin" ] );
449 }
450 
452 {
453  self ‪exploder_delay();
454  eq = level.earthquake[ self.v[ "earthquake" ] ];
455 
456  if(isdefined(eq))
457  {
458  GetLocalPlayers()[0] ‪earthquake( eq[ "magnitude" ], eq[ "duration" ], self.v[ "origin" ], eq[ "radius" ] );
459  }
460 }
461 
463 {
464  if (isdefined(level.lightningExploder))
465  {
466  for(i = 0; i < level.lightningExploder.size; i ++)
467  {
468  if(level.lightningExploder[i] == num)
469  {
470  return true;
471  }
472  }
473  }
474 
475  return false;
476 }
477 
478 function ‪stopLightLoopExploder( exploderIndex )
479 {
480  num = Int(exploderIndex);
481 
482  if(isdefined(level.createFXexploders[num]))
483  {
484  for(i = 0; i < level.createFXexploders[num].size; i ++)
485  {
486  ent = level.createFXexploders[num][i];
487 
488  if ( !isdefined( ent.looperFX ) )
489  {
490  ent.looperFX = [];
491  }
492 
493  for( clientNum = 0; clientNum < level.max_local_clients; clientNum++ )
494  {
495  if( localClientActive( clientNum ) )
496  {
497  if ( isdefined( ent.looperFX[clientNum] ) )
498  {
499  for( looperFXCount = 0; looperFXCount < ent.looperFX[clientNum].size; looperFXCount++ )
500  {
501  deletefx( clientNum, ent.looperFX[clientNum][looperFXCount] );
502  }
503  }
504  }
505 
506  ent.looperFX[clientNum] = [];
507  }
508 
509  ent.looperFX = [];
510  }
511  }
512 }
513 
514 function ‪playLightLoopExploder( exploderIndex )
515 {
516  num = Int(exploderIndex);
517 
518  if(isdefined(level.createFXexploders[num]))
519  {
520  for(i = 0; i < level.createFXexploders[num].size; i ++)
521  {
522  ent = level.createFXexploders[num][i];
523 
524  if ( !isdefined( ent.looperFX ) )
525  {
526  ent.looperFX = [];
527  }
528 
529  for( clientNum = 0; clientNum < level.max_local_clients; clientNum++ )
530  {
531  if( localClientActive( clientNum ) )
532  {
533  if ( !isdefined( ent.looperFX[clientNum] ) )
534  {
535  ent.looperFX[clientNum] = [];
536  }
537  ent.looperFX[clientNum][ent.looperFX[clientNum].size] = ent ‪playExploderFX( clientNum );
538  }
539  }
540  }
541  }
542 }
543 
544 function ‪createExploder( fxid )
545 {
546  ent = ‪fx::create_effect( "exploder", fxid );
547  ent.v[ "delay" ] = 0;
548  ent.v[ "exploder_type" ] = "normal";
549  return ent;
550 }
551 
553 {
554  if( isdefined( self.v[ "repeat" ] ) )
555  {
556  for( i = 0;i < self.v[ "repeat" ];i ++ )
557  {
558  players = getlocalplayers();
559 
560  for(player = 0; player < players.size; player ++)
561  {
562  PlayFX( player, level._effect[ self.v[ "fxid" ] ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
563  }
564 
565  self ‪exploder_delay();
566  }
567  return;
568  }
569 
570  self ‪exploder_delay();
571 
572  players = getlocalplayers();
573 
574  if ( isdefined( self.loopFX ) )
575  {
576  for(i = 0; i < self.loopFX.size; i ++)
577  {
578  StopFX( i, self.loopFX[i] );
579  }
580 
581  self.loopFX = [];
582  }
583 
584  if(!isdefined(self.loopFX))
585  {
586  self.loopFX = [];
587  }
588 
589  if(!isdefined(level._effect[self.v["fxid"]]))
590  {
591  assertmsg("*** Client : Effect " + self.v["fxid"] + " not precached in level_fx.csc.");
592  return;
593  }
594 
595  for(i = 0; i < players.size; i ++)
596  {
597  if( isdefined( self.v["fxid"] ) )
598  {
599  self.loopFX[i] = PlayFX( i , level._effect[ self.v[ "fxid" ] ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
600  }
601  }
602 
603  self ‪exploder_playSound();
604 }
605 
606 function ‪fire_effect()
607 {
608  forward = self.v[ "forward" ];
609  if( !isdefined( forward ) )
610  {
611  forward = anglestoforward( self.v["angles"] );
612  }
613  up = self.v[ "up" ];
614  if( !isdefined( up ) )
615  {
616  up = anglestoup( self.v["angles"] );
617  }
618 
619  //org = undefined;
620 
621  firefxSound = self.v[ "firefxsound" ];
622  origin = self.v[ "origin" ];
623  firefx = self.v[ "firefx" ];
624  ender = self.v[ "ender" ];
625  if( !isdefined( ender ) )
626  ender = "createfx_effectStopper";
627 
628  fireFxDelay = 0.5;
629  if( isdefined( self.v[ "firefxdelay" ] ) )
630  fireFxDelay = self.v[ "firefxdelay" ];
631 
632  self ‪exploder_delay();
633 
634  players = GetLocalPlayers();
635 
636  for(i = 0; i < players.size; i ++)
637  {
638  if( isdefined( firefxSound ) )
639  {
640  level thread ‪sound::loop_fx_sound( i, firefxSound, origin, ender );
641  }
642  playfx( i, level._effect[ firefx ], self.v[ "origin" ], forward, up, 0, self.v[ "primlightfrac" ], self.v[ "lightoriginoffs" ] );
643  }
644 }
645 
646 // self is the exploder entity
647 function ‪playExploderFX( clientNum )
648 {
649  return playfx( clientNum, level._effect[ self.v[ "fxid" ] ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ], 0, self.v[ "primlightfrac" ], self.v[ "lightoriginoffs" ] );
650 }
651 
652 
653 function ‪stop_after_duration( ‪name, duration )
654 {
655  wait( duration );
657 }
658 
659 
660 function ‪exploder_duration( ‪name, duration )
661 {
662  if ( !‪IS_TRUE( duration ) )
663  {
664  return;
665  }
666 
667  ‪exploder( ‪name );
668 
669  level thread ‪stop_after_duration( ‪name, duration );
670 }
671 
‪createExploder
‪function createExploder(fxid)
Definition: exploder_shared.csc:544
‪exploder
‪function exploder(exploder_id, n_localclientnumber)
Definition: exploder_shared.csc:297
‪stop_exploder
‪function stop_exploder(exploder_id, n_localclientnumber)
Definition: exploder_shared.csc:368
‪player_init
‪function player_init(clientnum)
Definition: exploder_shared.csc:22
‪cannon_effect
‪function cannon_effect()
Definition: exploder_shared.csc:552
‪loop_fx_sound
‪function loop_fx_sound(clientNum, alias, origin, ender)
Definition: sound_shared.csc:5
‪play_in_space
‪function play_in_space(localClientNum, alias, origin)
Definition: sound_shared.csc:30
‪stop_after_duration
‪function stop_after_duration(name, duration)
Definition: exploder_shared.csc:653
‪playLightLoopExploder
‪function playLightLoopExploder(exploderIndex)
Definition: exploder_shared.csc:514
‪playExploderFX
‪function playExploderFX(clientNum)
Definition: exploder_shared.csc:647
‪get_array
‪function get_array(kvp_value, kvp_key="targetname")
Definition: struct.csc:34
‪exploder_delay
‪function exploder_delay()
Definition: exploder_shared.csc:426
‪exploder_is_lightning_exploder
‪function exploder_is_lightning_exploder(num)
Definition: exploder_shared.csc:462
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪get
‪function get(kvp_value, kvp_key="targetname")
Definition: struct.csc:13
‪activate_radiant_exploder
‪function activate_radiant_exploder(string, n_localclientnumber)
Definition: exploder_shared.csc:352
‪exploder_playSound
‪function exploder_playSound()
Definition: exploder_shared.csc:443
‪on_localclient_connect
‪function on_localclient_connect(localClientNum)
Definition: ctf.csc:20
‪lightning
‪function lightning(normalFunc, flashFunc)
Definition: fx_shared.csc:182
‪reportExploderIds
‪function reportExploderIds()
Definition: exploder_shared.csc:282
‪create_effect
‪function create_effect(type, fxid)
Definition: fx_shared.csc:104
‪activate_exploder
‪function activate_exploder(num)
Definition: exploder_shared.csc:309
‪getExploderId
‪function getExploderId(ent)
Definition: exploder_shared.csc:265
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪activate_individual_exploder
‪function activate_individual_exploder()
Definition: exploder_shared.csc:331
‪earthquake
‪function earthquake()
Definition: exploder_shared.gsc:850
‪stopLightLoopExploder
‪function stopLightLoopExploder(exploderIndex)
Definition: exploder_shared.csc:478
‪fire_effect
‪function fire_effect()
Definition: exploder_shared.csc:606
‪set_forward_and_up_vectors
‪function set_forward_and_up_vectors()
Definition: fx_shared.csc:134
‪kill_exploder
‪function kill_exploder(exploder_id)
Definition: exploder_shared.csc:412
‪exploder_earthquake
‪function exploder_earthquake()
Definition: exploder_shared.csc:451
‪__init__
‪function __init__()
Definition: exploder_shared.csc:14
‪name
‪class GroundFx name
‪exploder_duration
‪function exploder_duration(name, duration)
Definition: exploder_shared.csc:660