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;
12 #insert scripts\shared\aat_shared.gsh;
13 #insert scripts\shared\shared.gsh;
14 #insert scripts\shared\version.gsh;
27 level.aat_initializing =
true;
35 level.aat_reroll = [];
39 spawners = GetSpawnerArray();
40 foreach ( spawner
in spawners )
45 level.aat_exemptions = [];
66 self.aat_cooldown_start = [];
68 keys = GetArrayKeys( level.aat );
69 foreach ( key
in keys )
71 self.aat_cooldown_start[key] = 0;
81 self.aat_cooldown_start = [];
83 keys = GetArrayKeys( level.aat );
84 foreach ( key
in keys )
86 self.aat_cooldown_start[key] = 0;
92 function private aat_vehicle_damage_monitor( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, vDamageOrigin, psOffsetTime, damageFromUnderneath, modelIndex, partName, vSurfaceNormal )
94 willBeKilled = (
self.health - iDamage ) <= 0;
98 self thread
aat_response( willBeKilled, eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime, damageFromUnderneath, vSurfaceNormal );
106 if ( IsDefined( weapon ) && weapon.isAltMode )
108 return weapon.altWeapon;
116 function aat_response(
death, inflictor, attacker,
damage, flags, mod, weapon, vpoint, vdir, sHitLoc, psOffsetTime, boneIndex, surfaceType )
118 if ( !IsPlayer( attacker ) )
123 if ( mod !=
"MOD_PISTOL_BULLET" && mod !=
"MOD_RIFLE_BULLET" && mod !=
"MOD_GRENADE" && mod !=
"MOD_PROJECTILE" && mod !=
"MOD_EXPLOSIVE" && mod !=
"MOD_IMPACT" )
130 name = attacker.aat[weapon];
131 if ( !IsDefined(
name ) )
141 if ( !isdefined(
self.archetype ) )
147 if (
IS_TRUE( level.aat[
name].immune_trigger[
self.archetype ] ) )
152 now = GetTime() / 1000;
153 if ( now <=
self.aat_cooldown_start[
name] + level.aat[
name].cooldown_time_entity )
158 if ( now <= attacker.aat_cooldown_start[
name] + level.aat[
name].cooldown_time_attacker )
163 if ( now <= level.aat[
name].cooldown_time_global_start + level.aat[
name].cooldown_time_global )
168 if ( isdefined( level.aat[
name].validation_func ) )
170 if ( !
self [[level.aat[
name].validation_func]]() )
177 reroll_icon = undefined;
178 percentage = level.aat[
name].percentage;
181 if ( percentage >= RandomFloat( 1 ) )
188 keys = GetArrayKeys( level.aat_reroll );
189 keys = array::randomize( keys );
190 foreach ( key
in keys )
192 if ( attacker [[level.aat_reroll[key].active_func]]() )
194 for ( i = 0; i < level.aat_reroll[key].count; i++ )
196 if ( percentage >= RandomFloat( 1 ) )
199 reroll_icon = level.aat_reroll[key].damage_feedback_icon;
218 level.aat[
name].cooldown_time_global_start = now;
219 attacker.aat_cooldown_start[
name] = now;
221 self thread [[level.aat[
name].result_func]](
death, attacker, mod, weapon );
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 )
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" );
247 assert( IsDefined(
name ),
"aat::register(): name must be defined" );
249 assert( !IsDefined( level.aat[
name] ),
"aat::register(): AAT '" +
name +
"' has already been registered" );
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" );
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" );
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" );
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" );
263 assert( IsDefined( occurs_on_death ),
"aat::register(): AAT '" +
name +
"': occurs_on_death must be defined" );
265 assert( IsDefined( result_func ),
"aat::register(): AAT '" +
name +
"': result_func must be defined" );
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" );
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" );
273 level.aat[
name] = SpawnStruct();
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 = [];
308 while ( level.aat_initializing !==
false )
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" );
320 if ( !isdefined( level.aat[
name ].immune_trigger ) )
322 level.aat[
name ].immune_trigger = [];
325 if ( !isdefined( level.aat[
name].immune_result_direct ) )
327 level.aat[
name ].immune_result_direct = [];
330 if ( !isdefined( level.aat[
name].immune_result_indirect ) )
332 level.aat[
name ].immune_result_indirect = [];
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;
342 /#println(
"AAT server registrations:" );#/
344 if ( level.aat.size > 1 )
346 array::alphabetize( level.aat );
349 foreach ( aat
in level.aat )
352 aat.clientfield_index = i;
355 /#println(
" " + aat.name );#/
358 n_bits = GetMinBitCountForNum( level.aat.size - 1 );
362 level.aat_initializing =
false;
370 level.aat_exemptions[ weapon ] =
true;
378 return isdefined( level.aat_exemptions[ weapon ] );
395 assert( IsDefined(
name ),
"aat::register_reroll (): name must be defined" );
397 assert( !IsDefined( level.aat[
name] ),
"aat::register_reroll(): AAT Reroll'" +
name +
"' has already been registered" );
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" );
402 assert( IsDefined( active_func ),
"aat::register_reroll(): AAT Reroll '" +
name +
"': active_func must be defined" );
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" );
407 level.aat_reroll[
name] = SpawnStruct();
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;
419 if ( weapon == level.weaponNone
422 || (!isDefined(
self.aat) || !isDefined(
self.aat[weapon]))
423 || !isDefined( level.aat[
self.aat[weapon]])
429 return level.aat[
self.aat[weapon]];
445 if ( !
IS_TRUE( level.aat_in_use ) )
450 assert( IsDefined( weapon ),
"aat::acquire(): weapon must be defined" );
451 assert( weapon != level.weaponNone,
"aat::acquire(): weapon must not be level.weaponNone" );
460 if ( IsDefined(
name ) )
463 assert( IsDefined( level.aat[
name] ),
"aat::acquire(): AAT '" +
name +
"' was never registered" );
465 self.aat[weapon] =
name;
469 keys = GetArrayKeys( level.aat );
474 if ( IsDefined(
self.aat[ weapon ] ) )
476 ArrayRemoveValue( keys,
self.aat[ weapon ] );
479 rand = RandomInt( keys.size );
480 self.aat[weapon] = keys[rand];
483 if ( weapon ==
self GetCurrentWeapon() )
501 if ( !
IS_TRUE( level.aat_in_use ) )
506 assert( IsDefined( weapon ),
"aat::remove(): weapon must be defined" );
507 assert( weapon != level.weaponNone,
"aat::remove(): weapon must not be level.weaponNone" );
511 self.aat[weapon] = undefined;
517 self endon(
"disconnect" );
518 self endon(
"entityshutdown" );
520 while ( isdefined(
self ) )
522 self waittill(
"weapon_change", weapon );
527 if ( IsDefined(
self.aat[weapon] ) )
529 name =
self.aat[weapon];