‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_decoy.gsc
Go to the documentation of this file.
1 #using scripts\codescripts\struct;
2 
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\entityheadicons_shared;
5 #using scripts\shared\system_shared;
6 #using scripts\shared\util_shared;
7 #using scripts\shared\weapons\_weaponobjects;
8 
9 #insert scripts\shared\shared.gsh;
10 
11 #namespace decoy;
12 
13 function ‪init_shared()
14 {
15  level.decoyWeapons = [];
16  level.decoyWeapons["fullauto"] = [];
17  level.decoyWeapons["semiauto"] = [];
18 
19  level.decoyWeapons["fullauto"][level.decoyWeapons["fullauto"].size] = GetWeapon( "ar_accurate" ); // BO2: "uzi"
20 
21  level.decoyWeapons["semiauto"][level.decoyWeapons["semiauto"].size] = GetWeapon( "pistol_standard" ); // BO2: "m1911"
22 
24 }
25 
27 {
28  watcher = self ‪weaponobjects::createUseWeaponObjectWatcher( "nightingale", self.team );
29  watcher.onSpawn =&‪on_spawn;
30  watcher.onDetonateCallback =&‪detonate;
31  watcher.deleteOnDifferentObjectSpawn = false;
32  watcher.headicon = false;
33 }
34 
35 function ‪on_spawn(watcher, owner)
36 {
37  owner endon("disconnect");
38  self endon( "death" );
39 
41 
42  self.initial_velocity = self GetVelocity();
43  ‪delay = 1;
44 
45  wait (‪delay );
46  decoy_time = 30;
47  spawn_time = GetTime();
48 
49  owner AddWeaponStat( self.weapon, "used", 1 );
50 
51  self thread ‪simulate_weapon_fire(owner);
52 
53  while( 1 )
54  {
55  if ( GetTime() > spawn_time + ( decoy_time * 1000 ))
56  {
57  self ‪destroy(watcher,owner);
58  return;
59  }
60 
62  }
63 }
64 
65 function ‪move( owner, count, fire_time, main_dir, max_offset_angle )
66 {
67  self endon( "death" );
68  self endon( "done" );
69 
70  if ( !(self IsOnGround() ) )
71  return;
72 
73  min_speed = 100;
74  max_speed = 200;
75 
76  min_up_speed = 100;
77  max_up_speed = 200;
78 
79  current_main_dir = RandomIntRange(main_dir - max_offset_angle,main_dir + max_offset_angle);
80 
81  avel = ( RandomFloatRange( 800, 1800) * (RandomIntRange( 0, 2 ) * 2 - 1), 0, RandomFloatRange( 580, 940) * (RandomIntRange( 0, 2 ) * 2 - 1));
82 
83  intial_up = RandomFloatRange( min_up_speed, max_up_speed );
84 
85  start_time = GetTime();
86  gravity = GetDvarint( "bg_gravity" );
87 
88 // PrintLn( "start time " + start_time );
89  for ( i = 0; i < 1; i++ )
90  {
91  angles = ( 0,RandomIntRange(current_main_dir - max_offset_angle,current_main_dir + max_offset_angle), 0 );
92  dir = AnglesToForward( angles );
93 
94  dir = VectorScale( dir, RandomFloatRange( min_speed, max_speed ) );
95 
96  deltaTime = ( GetTime() - start_time ) * 0.001;
97 
98  // must manually manage the gravity because of the way the Launch function and the tr interpolater work
99  up = (0,0, (intial_up) - (800 * deltaTime) );
100 
101  self ‪launch( dir + up, avel );
102 
103  wait( fire_time );
104  }
105 // PrintLn( "end time " + GetTime() );
106 }
107 
108 function ‪destroy(watcher,owner)
109 {
110  self notify( "done" );
112 
113  // play deactivated particle effect here
114 }
115 
116 function ‪detonate( attacker, weapon, target )
117 {
118  // NOTE: this isn't being called currently through the watcher system
119  self notify( "done" );
121 }
122 
123 function ‪simulate_weapon_fire( owner )
124 {
125  owner endon("disconnect");
126  self endon( "death" );
127  self endon( "done" );
128 
129  weapon = ‪pick_random_weapon();
130 
131  self thread ‪watch_for_explosion( owner, weapon );
132  self thread ‪track_main_direction();
133 
134  self.max_offset_angle = 30;
135 
136  weapon_class = ‪util::getWeaponClass( weapon );
137 
138  switch ( weapon_class )
139  {
140  case "weapon_cqb":
141  case "weapon_smg":
142  case "weapon_hmg":
143  case "weapon_lmg":
144  case "weapon_assault":
145  ‪simulate_weapon_fire_machine_gun( owner, weapon );
146  break;
147  case "weapon_sniper":
148  ‪simulate_weapon_fire_sniper( owner, weapon );
149  break;
150  case "weapon_pistol":
151  ‪simulate_weapon_fire_pistol( owner, weapon );
152  break;
153  case "weapon_shotgun":
154  ‪simulate_weapon_fire_shotgun( owner, weapon );
155  break;
156 
157  // for weapons like rocket launchers
158  default:
159  ‪simulate_weapon_fire_machine_gun( owner, weapon );
160  break;
161  }
162 
163 }
164 
165 function ‪simulate_weapon_fire_machine_gun( owner, weapon )
166 {
167  if ( weapon.isSemiAuto )
168  {
170  }
171  else
172  {
174  }
175 }
176 
177 
179 {
180  clipSize = weapon.clipSize;
181  fireTime = weapon.fireTime;
182  reloadTime = weapon.reloadTime;
183 
184  burst_spacing_min = 4;
185  burst_spacing_max = 10;
186 
187  while( 1 )
188  {
189  if ( clipSize <= 1 )
190  burst_count = 1;
191  else
192  burst_count = RandomIntRange( 1, clipSize );
193  self thread ‪move( owner, burst_count, fireTime, self.main_dir, self.max_offset_angle );
194  self ‪fire_burst( owner, weapon, fireTime, burst_count, true );
195  ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max);
196  }
197 }
198 
199 function ‪simulate_weapon_fire_pistol( owner, weapon )
200 {
201  clipSize = weapon.clipSize;
202  fireTime = weapon.fireTime;
203  reloadTime = weapon.reloadTime;
204 
205  burst_spacing_min = 0.5;
206  burst_spacing_max = 4;
207 
208  while( 1 )
209  {
210  burst_count = RandomIntRange( 1, clipSize );
211  self thread ‪move( owner, burst_count, fireTime, self.main_dir, self.max_offset_angle );
212  self ‪fire_burst( owner, weapon, fireTime, burst_count, false );
213  ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max);
214  }
215 }
216 
217 function ‪simulate_weapon_fire_shotgun( owner, weapon )
218 {
219  clipSize = weapon.clipSize;
220  fireTime = weapon.fireTime;
221  reloadTime = weapon.reloadTime;
222 
223  if ( clipSize > 2 )
224  clipSize = 2;
225 
226  burst_spacing_min = 0.5;
227  burst_spacing_max = 4;
228 
229  while( 1 )
230  {
231  burst_count = RandomIntRange( 1, clipSize );
232  self thread ‪move( owner, burst_count, fireTime, self.main_dir, self.max_offset_angle );
233  self ‪fire_burst( owner, weapon, fireTime, burst_count, false );
234  ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max);
235  }
236 }
237 
239 {
240  clipSize = weapon.clipSize;
241  fireTime = weapon.fireTime;
242  reloadTime = weapon.reloadTime;
243 
244  if ( clipSize > 30 )
245  clipSize = 30;
246 
247  burst_spacing_min = 2;
248  burst_spacing_max = 6;
249 
250  while( 1 )
251  {
252  burst_count = RandomIntRange( Int(clipSize * 0.6), clipSize );
253  interrupt = false; // RandomIntRange( 0, 2 );
254  self thread ‪move( owner, burst_count, fireTime, self.main_dir, self.max_offset_angle );
255  self ‪fire_burst( owner, weapon, fireTime, burst_count, interrupt );
256 
257  ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max);
258  }
259 }
260 
261 function ‪simulate_weapon_fire_sniper( owner, weapon )
262 {
263  clipSize = weapon.clipSize;
264  fireTime = weapon.fireTime;
265  reloadTime = weapon.reloadTime;
266 
267  if ( clipSize > 2 )
268  clipSize = 2;
269 
270  burst_spacing_min = 3;
271  burst_spacing_max = 5;
272 
273  while( 1 )
274  {
275  burst_count = RandomIntRange( 1, clipSize );
276  self thread ‪move( owner, burst_count, fireTime, self.main_dir, self.max_offset_angle );
277  self ‪fire_burst( owner, weapon, fireTime, burst_count, false );
278  ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max);
279  }
280 }
281 
282 function ‪fire_burst( owner, weapon, fireTime, count, interrupt )
283 {
284  interrupt_shot = count;
285 
286  if ( interrupt )
287  {
288  interrupt_shot = Int( count * RandomFloatRange( 0.6, 0.8 ) );
289  }
290 
291  self FakeFire( owner, self.origin, weapon, interrupt_shot );
292  wait ( fireTime * interrupt_shot );
293 
294  if ( interrupt )
295  {
296  self FakeFire( owner, self.origin, weapon, count - interrupt_shot );
297  wait ( fireTime * (count - interrupt_shot) );
298  }
299 }
300 
301 function ‪finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max)
302 {
304  {
305  ‪play_reload_sounds( weapon, reloadTime );
306  }
307  else
308  {
309  wait ( RandomFloatRange(burst_spacing_min, burst_spacing_max) );
310  }
311 }
312 
313 function ‪play_reload_sounds(weapon, reloadTime)
314 {
315  divy_it_up = (reloadTime - 0.1) / 2;
316  wait (0.1);
317  self PlaySound("fly_assault_reload_npc_mag_out");
318  wait (divy_it_up);
319  self PlaySound("fly_assault_reload_npc_mag_in");
320  wait (divy_it_up);
321 // self PlaySound("fly_assault_reload_npc_charge");
322 // wait (divy_it_up);
323 }
324 
325 function ‪watch_for_explosion( owner, weapon )
326 {
328 
329  owner endon( "disconnect");
330  self endon( "death_before_explode");
331  self waittill("explode", pos);
332  level thread ‪do_explosion( owner, pos, weapon, RandomIntRange( 5, 10 ) );
333 }
334 
336 {
337  self waittill("death");
338  wait(0.1);
339  if ( IsDefined(self) )
340  {
341  self notify("death_before_explode");
342  }
343 }
344 
345 
346 function ‪do_explosion( owner, pos, weapon, count )
347 {
348  min_offset = 100;
349  max_offset = 500;
350 
351  for ( i = 0 ; i < count; i++ )
352  {
353  wait(RandomFloatRange(0.1,0.5));
354  offset = ( RandomFloatRange(min_offset,max_offset)* (RandomIntRange( 0, 2 ) * 2 - 1), RandomFloatRange(min_offset,max_offset)* (RandomIntRange( 0, 2 ) * 2 - 1), 0 );
355  owner FakeFire( owner, pos+offset, weapon, 1 );
356  }
357 }
358 
360 {
361  type = "fullauto";
362 
363  if ( RandomIntRange( 0, 10 ) < 3 )
364  {
365  type = "semiauto";
366  }
367 
368  randomval = RandomIntRange(0,level.decoyWeapons[type].size);
369 
370 /# PrintLn( "Decoy type: " + type + " weapon: " + level.decoyWeapons[type][randomval].name ); #/
371 
372  return level.decoyWeapons[type][randomval];
373 }
374 
376 {
377  if( RandomIntRange(0,5) == 1 )
378  {
379  return true;
380  }
381 
382  return false;
383 }
384 
386 {
387  self endon( "death" );
388  self endon( "done" );
389  self.main_dir = Int(VectorToAngles((self.initial_velocity[0], self.initial_velocity[1], 0 ))[1]);
390 
391  up = (0,0,1);
392  while( 1 )
393  {
394  self waittill( "grenade_bounce", pos, normal );
395 
396  dot = VectorDot( normal, up );
397 
398  // something got in the way thats somewhat vertical
399  if ( dot < 0.5 && dot > -0.5 )
400  {
401  self.main_dir = Int(VectorToAngles((normal[0], normal[1], 0 ))[1]);
402  }
403  }
404 }
‪simulate_weapon_fire_machine_gun_semi_auto
‪function simulate_weapon_fire_machine_gun_semi_auto(owner, weapon)
Definition: _decoy.gsc:178
‪onSpawnUseWeaponObject
‪function onSpawnUseWeaponObject(watcher, owner)
Definition: _weaponobjects.gsc:1597
‪getWeaponClass
‪function getWeaponClass(weapon)
Definition: util_shared.gsc:2676
‪play_reload_sounds
‪function play_reload_sounds(weapon, reloadTime)
Definition: _decoy.gsc:313
‪should_play_reload_sound
‪function should_play_reload_sound()
Definition: _decoy.gsc:375
‪do_explosion
‪function do_explosion(owner, pos, weapon, count)
Definition: _decoy.gsc:346
‪init_shared
‪function init_shared()
Definition: _decoy.gsc:13
‪launch
‪function launch(ent_1, str_tag1, ent_2, str_tag2, str_beam_type)
Definition: beam_shared.csc:11
‪track_main_direction
‪function track_main_direction()
Definition: _decoy.gsc:385
‪create_watcher
‪function create_watcher()
Definition: _decoy.gsc:26
‪simulate_weapon_fire
‪function simulate_weapon_fire(owner)
Definition: _decoy.gsc:123
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪on_spawn
‪function on_spawn(watcher, owner)
Definition: _decoy.gsc:35
‪watch_for_explosion
‪function watch_for_explosion(owner, weapon)
Definition: _decoy.gsc:325
‪finish_while_loop
‪function finish_while_loop(weapon, reloadTime, burst_spacing_min, burst_spacing_max)
Definition: _decoy.gsc:301
‪simulate_weapon_fire_shotgun
‪function simulate_weapon_fire_shotgun(owner, weapon)
Definition: _decoy.gsc:217
‪watch_for_death_before_explosion
‪function watch_for_death_before_explosion()
Definition: _decoy.gsc:335
‪detonate
‪function detonate(attacker, weapon, target)
Definition: _decoy.gsc:116
‪simulate_weapon_fire_machine_gun
‪function simulate_weapon_fire_machine_gun(owner, weapon)
Definition: _decoy.gsc:165
‪simulate_weapon_fire_sniper
‪function simulate_weapon_fire_sniper(owner, weapon)
Definition: _decoy.gsc:261
‪add_weapon_watcher
‪function add_weapon_watcher(callback)
Definition: callbacks_shared.gsc:609
‪pick_random_weapon
‪function pick_random_weapon()
Definition: _decoy.gsc:359
‪setEntityHeadIcon
‪function setEntityHeadIcon(team, owner, offset, objective, constant_size)
Definition: entityheadicons_shared.gsc:43
‪createUseWeaponObjectWatcher
‪function createUseWeaponObjectWatcher(weaponname, ownerTeam)
Definition: _weaponobjects.gsc:1297
‪simulate_weapon_fire_pistol
‪function simulate_weapon_fire_pistol(owner, weapon)
Definition: _decoy.gsc:199
‪simulate_weapon_fire_machine_gun_full_auto
‪function simulate_weapon_fire_machine_gun_full_auto(owner, weapon)
Definition: _decoy.gsc:238
‪destroy
‪function destroy(watcher, owner)
Definition: _decoy.gsc:108
‪move
‪function move(owner, count, fire_time, main_dir, max_offset_angle)
Definition: _decoy.gsc:65
‪fire_burst
‪function fire_burst(owner, weapon, fireTime, count, interrupt)
Definition: _decoy.gsc:282
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265