‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
All Data Structures Files Functions Variables Macros
aat_shared.gsc
Go to the documentation of this file.
1 // AAT stands for Alternative Ammunition Types
2 
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\damagefeedback_shared;
7 #using scripts\shared\spawner_shared;
8 #using scripts\shared\system_shared;
9 #using scripts\shared\util_shared;
10 #using scripts\zm\_zm;
11 
12 #insert scripts\shared\aat_shared.gsh;
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\version.gsh;
15 
16 #namespace aat;
17 
18 ‪REGISTER_SYSTEM_EX( "aat", &‪__init__, &‪__main__, undefined )
19 
20 function private ‪__init__()
21 {
22  if ( !‪IS_TRUE( level.aat_in_use ) )
23  {
24  return;
25  }
26 
27  level.aat_initializing = true;
28 
29  level.aat = [];
30 
31  // Add "none" for HUD elements
32  level.aat[ ‪AAT_RESERVED_NAME ] = SpawnStruct();
33  level.aat[ ‪AAT_RESERVED_NAME ].name = ‪AAT_RESERVED_NAME;
34 
35  level.aat_reroll = [];
36 
38 
39  spawners = GetSpawnerArray();
40  foreach ( spawner in spawners )
41  {
43  }
44 
45  level.aat_exemptions = [];
46 
48 
50 }
51 
52 function ‪__main__()
53 {
54  if ( !‪IS_TRUE( level.aat_in_use ) )
55  {
56  return;
57  }
58 
60 }
61 
62 function private ‪on_player_connect()
63 {
64  self.aat = [];
65 
66  self.aat_cooldown_start = [];
67 
68  keys = GetArrayKeys( level.aat );
69  foreach ( key in keys )
70  {
71  self.aat_cooldown_start[key] = 0;
72  }
73 
74  self thread ‪watch_weapon_changes();
75 }
76 
77 
78 // self = ai or vehicle actor
80 {
81  self.aat_cooldown_start = [];
82 
83  keys = GetArrayKeys( level.aat );
84  foreach ( key in keys )
85  {
86  self.aat_cooldown_start[key] = 0;
87  }
88 }
89 
90 // Returns damage for vehicle_damage_override function
91 // self = vehicle actor
92 function private ‪aat_vehicle_damage_monitor( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
93 {
94  willBeKilled = ( self.health - iDamage ) <= 0;
95 
96  if ( ‪IS_TRUE( level.aat_in_use ) )
97  {
98  self thread ‪aat_response( willBeKilled, eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, vSurfaceNormal );
99  }
100 
101  return iDamage;
102 }
103 
104 function ‪get_nonalternate_weapon( weapon )
105 {
106  if ( IsDefined( weapon ) && weapon.isAltMode )
107  {
108  return weapon.altWeapon;
109  }
110 
111  return weapon;
112 }
113 
114 // Called from _zm.gsc
115 // self = ai actor
116 function ‪aat_response( ‪death, inflictor, attacker, ‪damage, flags, mod, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType )
117 {
118  if ( !IsPlayer( attacker ) )
119  {
120  return;
121  }
122 
123  if ( mod != "MOD_PISTOL_BULLET" && mod != "MOD_RIFLE_BULLET" && mod != "MOD_GRENADE" && mod != "MOD_PROJECTILE" && mod != "MOD_EXPLOSIVE" && mod != "MOD_IMPACT" )
124  {
125  return;
126  }
127 
128  weapon = ‪get_nonalternate_weapon( weapon );
129 
130  ‪name = attacker.aat[weapon];
131  if ( !IsDefined( ‪name ) )
132  {
133  return;
134  }
135 
136  if ( ‪death && !level.aat[‪name].occurs_on_death )
137  {
138  return;
139  }
140 
141  if ( !isdefined( self.archetype ) )
142  {
143  return;
144  }
145 
146  // if self's archetype is registered in immune_trigger, AAT check is completely bypassed
147  if ( ‪IS_TRUE( level.aat[‪name].immune_trigger[ self.archetype ] ) )
148  {
149  return;
150  }
151 
152  now = GetTime() / 1000;
153  if ( now <= self.aat_cooldown_start[‪name] + level.aat[‪name].cooldown_time_entity )
154  {
155  return;
156  }
157 
158  if ( now <= attacker.aat_cooldown_start[‪name] + level.aat[‪name].cooldown_time_attacker )
159  {
160  return;
161  }
162 
163  if ( now <= level.aat[‪name].cooldown_time_global_start + level.aat[‪name].cooldown_time_global )
164  {
165  return;
166  }
167 
168  if ( isdefined( level.aat[‪name].validation_func ) )
169  {
170  if ( !self [[level.aat[‪name].validation_func]]() )
171  {
172  return;
173  }
174  }
175 
176  success = false;
177  reroll_icon = undefined;
178  percentage = level.aat[‪name].percentage;
179 
180 
181  if ( percentage >= RandomFloat( 1 ) )
182  {
183  success = true;
184  }
185 
186  if ( !success )
187  {
188  keys = GetArrayKeys( level.aat_reroll );
189  keys = array::randomize( keys );// randomize the keys so players don't assume one reroll is better than another just because of registration order
190  foreach ( key in keys )
191  {
192  if ( attacker [[level.aat_reroll[key].active_func]]() )
193  {
194  for ( i = 0; i < level.aat_reroll[key].count; i++ )
195  {
196  if ( percentage >= RandomFloat( 1 ) )
197  {
198  success = true;
199  reroll_icon = level.aat_reroll[key].damage_feedback_icon;
200 
201  break;
202  }
203  }
204  }
205 
206  if ( success )
207  {
208  break;
209  }
210  }
211  }
212 
213  if ( !success )
214  {
215  return;
216  }
217 
218  level.aat[‪name].cooldown_time_global_start = now;
219  attacker.aat_cooldown_start[‪name] = now;
220 
221  self thread [[level.aat[‪name].result_func]]( ‪death, attacker, mod, weapon );
222  attacker thread ‪damagefeedback::update_override( level.aat[‪name].damage_feedback_icon, level.aat[‪name].damage_feedback_sound, reroll_icon );
223 }
224 
243 function register( ‪name, percentage, cooldown_time_entity, cooldown_time_attacker, cooldown_time_global, occurs_on_death, result_func, damage_feedback_icon, damage_feedback_sound, validation_func )
244 {
245  assert( ‪IS_TRUE( level.aat_initializing ), "All info registration in the AAT system must occur during the first frame while the system is initializing" );
246 
247  assert( IsDefined( ‪name ), "aat::register(): name must be defined" );
248  assert( ‪AAT_RESERVED_NAME != ‪name, "aat::register(): name cannot be '" + ‪AAT_RESERVED_NAME + "', that name is reserved as an internal sentinel value" );
249  assert( !IsDefined( level.aat[‪name] ), "aat::register(): AAT '" + ‪name + "' has already been registered" );
250 
251  assert( IsDefined( percentage ), "aat::register(): AAT '" + ‪name + "': percentage must be defined" );
252  assert( 0 <= percentage && 1 > percentage, "aat::register(): AAT '" + ‪name + "': percentage must be a value greater than or equal to 0 and less than 1" );
253 
254  assert( IsDefined( cooldown_time_entity ), "aat::register(): AAT '" + ‪name + "': cooldown_time_entity must be defined" );
255  assert( 0 <= cooldown_time_entity, "aat::register(): AAT '" + ‪name + "': cooldown_time_entity must be a value greater than or equal to 0" );
256 
257  assert( IsDefined( cooldown_time_entity ), "aat::register(): AAT '" + ‪name + "': cooldown_time_attacker must be defined" );
258  assert( 0 <= cooldown_time_entity, "aat::register(): AAT '" + ‪name + "': cooldown_time_attacker must be a value greater than or equal to 0" );
259 
260  assert( IsDefined( cooldown_time_global ), "aat::register(): AAT '" + ‪name + "': cooldown_time_global must be defined" );
261  assert( 0 <= cooldown_time_global, "aat::register(): AAT '" + ‪name + "': cooldown_time_global must be a value greater than or equal to 0" );
262 
263  assert( IsDefined( occurs_on_death ), "aat::register(): AAT '" + ‪name + "': occurs_on_death must be defined" );
264 
265  assert( IsDefined( result_func ), "aat::register(): AAT '" + ‪name + "': result_func must be defined" );
266 
267  assert( IsDefined( damage_feedback_icon ), "aat::register(): AAT '" + ‪name + "': damage_feedback_icon must be defined" );
268  assert( IsString( damage_feedback_icon ), "aat::register(): AAT '" + ‪name + "': damage_feedback_icon must be a string" );
269 
270  assert( IsDefined( damage_feedback_sound ), "aat::register(): AAT '" + ‪name + "': damage_feedback_sound must be defined" );
271  assert( IsString( damage_feedback_sound ), "aat::register(): AAT '" + ‪name + "': damage_feedback_sound must be a string" );
272 
273  level.aat[‪name] = SpawnStruct();
274 
275  level.aat[ ‪name ].name = ‪name;
276  level.aat[ ‪name ].hash_id = HashString(‪name);
277  level.aat[ ‪name ].percentage = percentage;
278  level.aat[ ‪name ].cooldown_time_entity = cooldown_time_entity;
279  level.aat[ ‪name ].cooldown_time_attacker = cooldown_time_attacker;
280  level.aat[ ‪name ].cooldown_time_global = cooldown_time_global;
281  level.aat[ ‪name ].cooldown_time_global_start = 0;
282  level.aat[ ‪name ].occurs_on_death = occurs_on_death;
283  level.aat[ ‪name ].result_func = result_func;
284  level.aat[ ‪name ].damage_feedback_icon = damage_feedback_icon;
285  level.aat[ ‪name ].damage_feedback_sound = damage_feedback_sound;
286  level.aat[ ‪name ].validation_func = validation_func;
287  level.aat[ ‪name ].immune_trigger = [];
288  level.aat[ ‪name ].immune_result_direct = [];
289  level.aat[ ‪name ].immune_result_indirect = [];
290 }
291 
305 function ‪register_immunity( ‪name, archetype, immune_trigger, immune_result_direct, immune_result_indirect )
306 {
307  // Waits for AAT's to complete initialization, then begin immunity registration
308  while ( level.aat_initializing !== false )
309  {
310  wait ‪SERVER_FRAME;
311  }
312 
313  // ASSERTS
314  assert( isdefined( ‪name ), "aat::register(): name must be defined" );
315  assert( isdefined( archetype ), "aat::register(): archetype must be defined" );
316  assert( isdefined( immune_trigger ), "aat::register(): immune_trigger must be defined" );
317  assert( isdefined( immune_result_direct ), "aat::register(): immune_result_direct must be defined" );
318  assert( isdefined( immune_result_indirect ), "aat::register(): immune_result_indirect must be defined" );
319 
320  if ( !isdefined( level.aat[ ‪name ].immune_trigger ) )
321  {
322  level.aat[ ‪name ].immune_trigger = [];
323  }
324 
325  if ( !isdefined( level.aat[‪name].immune_result_direct ) )
326  {
327  level.aat[ ‪name ].immune_result_direct = [];
328  }
329 
330  if ( !isdefined( level.aat[‪name].immune_result_indirect ) )
331  {
332  level.aat[ ‪name ].immune_result_indirect = [];
333  }
334 
335  level.aat[ ‪name ].immune_trigger[ archetype ] = immune_trigger;
336  level.aat[ ‪name ].immune_result_direct[ archetype ] = immune_result_direct;
337  level.aat[ ‪name ].immune_result_indirect[ archetype ] = immune_result_indirect;
338 }
339 
341 {
342  /#println( "AAT server registrations:" );#/
343 
344  if ( level.aat.size > 1 )
345  {
346  array::alphabetize( level.aat );
347 
348  i = 0;
349  foreach ( aat in level.aat )
350  {
351 
352  aat.clientfield_index = i;
353  i++;
354 
355  /#println( " " + aat.name );#/
356  }
357 
358  n_bits = GetMinBitCountForNum( level.aat.size - 1 );
360  }
361 
362  level.aat_initializing = false;
363 }
364 
365 // Initializes weapon exemptions
366 function ‪register_aat_exemption( weapon )
367 {
368  weapon = ‪get_nonalternate_weapon( weapon );
369 
370  level.aat_exemptions[ weapon ] = true;
371 }
372 
373 // Checks if weapon is exempt from gaining an AAT. Exemptions defined in array level.aat_exemptions
374 function ‪is_exempt_weapon( weapon )
375 {
376  weapon = ‪get_nonalternate_weapon( weapon );
377 
378  return isdefined( level.aat_exemptions[ weapon ] );
379 }
380 
393 function ‪register_reroll( ‪name, count, active_func, damage_feedback_icon )
394 {
395  assert( IsDefined( ‪name ), "aat::register_reroll (): name must be defined" );
396  assert( ‪AAT_RESERVED_NAME != ‪name, "aat::register_reroll(): name cannot be '" + ‪AAT_RESERVED_NAME + "', that name is reserved as an internal sentinel value" );
397  assert( !IsDefined( level.aat[‪name] ), "aat::register_reroll(): AAT Reroll'" + ‪name + "' has already been registered" );
398 
399  assert( IsDefined( count ), "aat::register_reroll(): AAT Reroll '" + ‪name + "': count must be defined" );
400  assert( 0 < count, "aat::register_reroll(): AAT Reroll '" + ‪name + "': count must be greater than 0" );
401 
402  assert( IsDefined( active_func ), "aat::register_reroll(): AAT Reroll '" + ‪name + "': active_func must be defined" );
403 
404  assert( IsDefined( damage_feedback_icon ), "aat::register_reroll(): AAT Reroll '" + ‪name + "': damage_feedback_icon must be defined" );
405  assert( IsString( damage_feedback_icon ), "aat::register_reroll(): AAT Reroll '" + ‪name + "': damage_feedback_icon must be a string" );
406 
407  level.aat_reroll[‪name] = SpawnStruct();
408 
409  level.aat_reroll[‪name].name = ‪name;
410  level.aat_reroll[‪name].count = count;
411  level.aat_reroll[‪name].active_func = active_func;
412  level.aat_reroll[‪name].damage_feedback_icon = damage_feedback_icon;
413 }
414 
415 function ‪getAATOnWeapon(weapon) //self == player
416 {
417  weapon = ‪get_nonalternate_weapon( weapon );
418 
419  if ( weapon == level.weaponNone
420  || !‪IS_TRUE( level.aat_in_use )
421  || ‪is_exempt_weapon( weapon )
422  || (!isDefined(self.aat) || !isDefined(self.aat[weapon]))
423  || !isDefined( level.aat[self.aat[weapon]])
424  )
425  {
426  return undefined;
427  }
428 
429  return level.aat[self.aat[weapon]];
430 }
431 
432 
443 function ‪acquire( weapon, ‪name )
444 {
445  if ( !‪IS_TRUE( level.aat_in_use ) )
446  {
447  return;
448  }
449 
450  assert( IsDefined( weapon ), "aat::acquire(): weapon must be defined" );
451  assert( weapon != level.weaponNone, "aat::acquire(): weapon must not be level.weaponNone" );
452 
453  weapon = ‪get_nonalternate_weapon( weapon );
454 
455  if ( ‪is_exempt_weapon( weapon ) )
456  {
457  return;
458  }
459 
460  if ( IsDefined( ‪name ) )
461  {
462  assert( ‪AAT_RESERVED_NAME != ‪name, "aat::acquire(): name cannot be '" + ‪AAT_RESERVED_NAME + "', that name is reserved as an internal sentinel value" );
463  assert( IsDefined( level.aat[‪name] ), "aat::acquire(): AAT '" + ‪name + "' was never registered" );
464 
465  self.aat[weapon] = ‪name;
466  }
467  else
468  {
469  keys = GetArrayKeys( level.aat );
470 
471  ArrayRemoveValue( keys, ‪AAT_RESERVED_NAME );
472 
473  // If weapon has AAT, remove current AAT from possible rerolls
474  if ( IsDefined( self.aat[ weapon ] ) )
475  {
476  ArrayRemoveValue( keys, self.aat[ weapon ] );
477  }
478 
479  rand = RandomInt( keys.size );
480  self.aat[weapon] = keys[rand];
481  }
482 
483  if ( weapon == self GetCurrentWeapon() )
484  {
485  self ‪clientfield::set_to_player( ‪AAT_CLIENTFIELD_NAME, level.aat[self.aat[weapon]].clientfield_index );
486  }
487 }
488 
489 
499 function ‪remove( weapon )
500 {
501  if ( !‪IS_TRUE( level.aat_in_use ) )
502  {
503  return;
504  }
505 
506  assert( IsDefined( weapon ), "aat::remove(): weapon must be defined" );
507  assert( weapon != level.weaponNone, "aat::remove(): weapon must not be level.weaponNone" );
508 
509  weapon = ‪get_nonalternate_weapon( weapon );
510 
511  self.aat[weapon] = undefined;
512 }
513 
514 // Monitors weapon changes to detect AAT names, then sends the names to the clientside for HUD changes
516 {
517  self endon( "disconnect" );
518  self endon( "entityshutdown" );
519 
520  while ( isdefined( self ) )
521  {
522  self waittill( "weapon_change", weapon );
523 
524  weapon = ‪get_nonalternate_weapon( weapon );
525 
527  if ( IsDefined( self.aat[weapon] ) )
528  {
529  ‪name = self.aat[weapon];
530  }
531 
532  self ‪clientfield::set_to_player( ‪AAT_CLIENTFIELD_NAME, level.aat[‪name].clientfield_index );
533  }
534 }
535 
‪__main__
‪function __main__()
Definition: aat_shared.gsc:52
‪AAT_CLIENTFIELD_NAME
‪#define AAT_CLIENTFIELD_NAME
Definition: aat_shared.gsh:5
‪register_vehicle_damage_callback
‪function register_vehicle_damage_callback(func)
Definition: _zm.gsc:5597
‪death
‪function death(localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
Definition: _ai_tank.csc:134
‪on_finalize_initialization
‪function on_finalize_initialization(func, obj)
Definition: callbacks_shared.csc:203
‪register_zombie_damage_override_callback
‪function register_zombie_damage_override_callback(func)
Definition: _zm.gsc:5865
‪register_reroll
‪function register_reroll(name, count, active_func, damage_feedback_icon)
Definition: aat_shared.gsc:393
‪aat_cooldown_init
‪function aat_cooldown_init()
Definition: aat_shared.gsc:79
‪__init__
‪function private __init__()
Definition: aat_shared.gsc:20
‪set_to_player
‪function set_to_player(str_field_name, n_value)
Definition: clientfield_shared.gsc:58
‪aat_response
‪function aat_response(death, inflictor, attacker, damage, flags, mod, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType)
Definition: aat_shared.gsc:116
‪acquire
‪function acquire(weapon, name)
Definition: aat_shared.gsc:443
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪finalize_clientfields
‪function finalize_clientfields()
Definition: aat_shared.gsc:340
‪remove
‪function remove(weapon)
Definition: aat_shared.gsc:499
‪on_player_connect
‪function private on_player_connect()
Definition: aat_shared.gsc:62
‪IS_TRUE
‪#define IS_TRUE(__a)
Definition: shared.gsh:251
‪is_exempt_weapon
‪function is_exempt_weapon(weapon)
Definition: aat_shared.gsc:374
‪getAATOnWeapon
‪function getAATOnWeapon(weapon)
Definition: aat_shared.gsc:415
‪register_immunity
‪function register_immunity(name, archetype, immune_trigger, immune_result_direct, immune_result_indirect)
Definition: aat_shared.gsc:305
‪damage
‪function damage(trap)
Definition: _zm_trap_electric.gsc:116
‪get_nonalternate_weapon
‪function get_nonalternate_weapon(weapon)
Definition: aat_shared.gsc:104
‪update_override
‪function update_override(icon, sound, additional_icon)
Definition: damagefeedback_shared.gsc:327
‪REGISTER_SYSTEM_EX
‪#define REGISTER_SYSTEM_EX(__sys, __func_init_preload, __func_init_postload, __reqs)
Definition: shared.gsh:209
‪SERVER_FRAME
‪#define SERVER_FRAME
Definition: shared.gsh:264
‪watch_weapon_changes
‪function watch_weapon_changes()
Definition: aat_shared.gsc:515
‪register_aat_exemption
‪function register_aat_exemption(weapon)
Definition: aat_shared.gsc:366
‪aat_vehicle_damage_monitor
‪function private aat_vehicle_damage_monitor(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal)
Definition: aat_shared.gsc:92
‪register
‪function register(name, percentage, cooldown_time_entity, cooldown_time_attacker, cooldown_time_global, occurs_on_death, result_func, damage_feedback_icon, damage_feedback_sound, validation_func)
Definition: aat_shared.gsc:243
‪AAT_RESERVED_NAME
‪#define AAT_RESERVED_NAME
Definition: aat_shared.gsh:4
‪on_connect
‪function on_connect()
Definition: _arena.gsc:20
‪add_spawn_function
‪function add_spawn_function(spawn_func, param1, param2, param3, param4, param5)
Definition: spawner_shared.gsc:3252
‪name
‪class GroundFx name