Files
WeaponFireCallback/mod/scripts/vscripts/weaponFireCallbacks.gnut
T
2023-08-18 19:19:42 +02:00

149 lines
5.6 KiB
Plaintext

untyped
globalize_all_functions
struct {
table < entity, array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > > weaponCallbacks
table < string, array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > > weaponClassCallbacks
table < string, array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > > ownerClassCallbacks
bool clearThreadRunning = false // Only used on client
} file
void function WeaponFireCallbacks_AddCallbackOnWeaponFired( entity weapon, void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) callback )
{
if ( !IsValid( weapon ) )
return
if ( weapon in file.weaponCallbacks )
file.weaponCallbacks[weapon].append( callback )
else
file.weaponCallbacks[weapon] <- [callback]
#if SERVER
AddEntityDestroyedCallback( weapon, WeaponFireCallbacks_HandleWeaponDestroyed )
#else
// Per-entity destroyed callbacks don't exist on client. Client needs to clear invalid keys periodically.
if ( !file.clearThreadRunning )
thread ClearInvalidWeaponsThread()
#endif
}
void function WeaponFireCallbacks_AddCallbackOnWeaponClassFired( string weaponClass, void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) callback )
{
if ( weaponClass in file.weaponClassCallbacks )
file.weaponClassCallbacks[weaponClass].append( callback )
else
file.weaponClassCallbacks[weaponClass] <- [callback]
}
void function WeaponFireCallbacks_RemoveCallbackOnWeaponClassFired( string weaponClass, void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) callback )
{
if ( weaponClass in file.weaponClassCallbacks )
{
file.weaponClassCallbacks[weaponClass].fastremovebyvalue( callback )
if ( file.weaponClassCallbacks[weaponClass].len() == 0 )
delete file.weaponClassCallbacks[weaponClass]
}
}
void function WeaponFireCallbacks_AddCallbackOnOwnerClassFired( string ownerClass, void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) callback )
{
if ( ownerClass in file.ownerClassCallbacks )
file.ownerClassCallbacks[ownerClass].append( callback )
else
file.ownerClassCallbacks[ownerClass] <- [callback]
}
void function WeaponFireCallbacks_RemoveCallbackOnOwnerClassFired( string ownerClass, void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) callback )
{
if ( ownerClass in file.ownerClassCallbacks )
{
file.ownerClassCallbacks[ownerClass].fastremovebyvalue( callback )
if ( file.ownerClassCallbacks[ownerClass].len() == 0 )
delete file.ownerClassCallbacks[ownerClass]
}
}
function WeaponFireCallbacks_HandleWeaponDestroyed( weapon )
{
entity w = expect entity( weapon )
if ( w in file.weaponCallbacks )
delete file.weaponCallbacks[w]
}
#if CLIENT
void function ClearInvalidWeaponsThread()
{
file.clearThreadRunning = true
while( file.weaponCallbacks.len() > 0 )
{
array< entity > invalidList = []
foreach( key, callback in file.weaponCallbacks )
{
if ( !IsValid( key ) )
invalidList.append( key )
}
foreach( w in invalidList )
delete file.weaponCallbacks[w]
wait 1.0 // Some arbitrary number that isn't WaitFrame(), don't need to run this very often
}
file.clearThreadRunning = false
}
#endif
void function WeaponFireCallbacks_OnWeaponFired( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed )
{
if ( weapon in file.weaponCallbacks )
{
array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > callbacks = file.weaponCallbacks[weapon]
foreach ( callback in callbacks )
callback( weapon, attackParams, ammoUsed )
}
string weaponClass = weapon.GetWeaponClassName()
if ( weaponClass in file.weaponClassCallbacks )
{
array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > callbacks = file.weaponClassCallbacks[weaponClass]
foreach ( callback in callbacks )
callback( weapon, attackParams, ammoUsed )
}
entity owner = weapon.GetWeaponOwner()
if ( !IsValid( owner ) )
return
string ownerClass = owner.GetClassName()
if ( ownerClass in file.ownerClassCallbacks )
{
array< void functionref( entity weapon, WeaponPrimaryAttackParams attackParams, var ammoUsed ) > callbacks = file.ownerClassCallbacks[ownerClass]
foreach ( callback in callbacks )
callback( weapon, attackParams, ammoUsed )
}
}
var function WeaponFireCallbacks_OnWeaponPrimaryAttack( entity weapon, WeaponPrimaryAttackParams attackParams )
{
weapon.EmitWeaponNpcSound( LOUD_WEAPON_AI_SOUND_RADIUS_MP, 0.2 )
var result = weapon.FireWeaponBullet( attackParams.pos, attackParams.dir, 1, weapon.GetWeaponDamageFlags() )
if ( result == 0 )
return 0
WeaponFireCallbacks_OnWeaponFired( weapon, attackParams, result )
return result
}
#if SERVER
var function WeaponFireCallbacks_OnWeaponNpcPrimaryAttack( entity weapon, WeaponPrimaryAttackParams attackParams )
{
weapon.EmitWeaponNpcSound( LOUD_WEAPON_AI_SOUND_RADIUS_MP, 0.2 )
var result = weapon.FireWeaponBullet( attackParams.pos, attackParams.dir, 1, weapon.GetWeaponDamageFlags() )
if ( result == 0 )
return 0
WeaponFireCallbacks_OnWeaponFired( weapon, attackParams, result )
return result
}
#endif