diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/superbar')
-rw-r--r-- | Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut | 167 | ||||
-rw-r--r-- | Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut | 417 |
2 files changed, 584 insertions, 0 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut b/Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut new file mode 100644 index 00000000..7e622432 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/superbar/orbitalstrike.nut @@ -0,0 +1,167 @@ +untyped + +global function Orbitalstrike_Init + +global function OrbitalStrike +global function CalculateStrikeDelay + +const STRIKE_MODEL = $"models/containers/can_red_soda.mdl" +const ROCKET_START_HEIGHT = 6000 +const LASER_START_HEIGHT = 1000 // TODO: Make this taller after making the trace go through sky +const LASER_TIME_LENGTH = 7 // Must match charge length in the weapon +const LASER_DAMAGE = 300 +const LASER_DAMAGE_RADIUS = 300 +const SPAWN_DELAY = 0.2 + +table file = +{ + impactEffectTable = null +} + + +function Orbitalstrike_Init() +{ + PrecacheParticleSystem( $"ar_rocket_strike_small_friend" ) + PrecacheParticleSystem( $"ar_rocket_strike_small_foe" ) + PrecacheParticleSystem( $"ar_rocket_strike_large_friend" ) + PrecacheParticleSystem( $"ar_rocket_strike_large_foe" ) + PrecacheParticleSystem( $"wpn_orbital_beam" ) + + //if ( IsServer() ) + // file.impactEffectTable <- PrecacheImpactEffectTable( GetWeaponInfoFileKeyField_Global( "mp_projectile_orbital_strike", "impact_effect_table" ) ) + #if SERVER + file.impactEffectTable = PrecacheImpactEffectTable( "orbital_strike" ) + #endif + + + + RegisterSignal( "TargetDesignated" ) + RegisterSignal( "BeginLaser" ) + RegisterSignal( "MoveLaser" ) + RegisterSignal( "FreezeLaser" ) + RegisterSignal( "EndLaser" ) +} + + +function CalculateStrikeDelay( index, stepCount, duration ) +{ + local lastStepDelay = 0 + if ( index ) + { + local stepFrac = (index - 1) / stepCount.tofloat() + stepFrac = 1 - (1 - stepFrac) * (1 - stepFrac) + lastStepDelay = stepFrac * (duration) + } + + local stepFrac = index / stepCount.tofloat() + stepFrac = 1 - (1 - stepFrac) * (1 - stepFrac) + return (stepFrac * (duration)) - lastStepDelay +} + + +function OrbitalStrike( entity player, vector targetPos, numRockets = 12, float radius = 256.0, float totalTime = 3.0, extraStartDelay = null ) +{ + int team = player.GetTeam() + CreateNoSpawnArea( TEAM_INVALID, TEAM_INVALID, targetPos, totalTime, radius ) + + if ( extraStartDelay != null ) + wait extraStartDelay + + // Trace down from max z height until we hit something so we know where rockets should land + // This makes calling in orbital strike indoors land on the roof like it should, not indoors + //local downStartPos = Vector( targetPos.x, targetPos.y, 16384 ) + //TraceResults downResult = TraceLine( downStartPos, targetPos, null, (TRACE_MASK_NPCSOLID_BRUSHONLY|TRACE_MASK_WATER), TRACE_COLLISION_GROUP_NONE ) + //DebugDrawLine( downStartPos+ Vector(0,10,0), targetPos + Vector(0,10,0), 255, 255, 255, true, 60 ) + + /* + while ( true ) // retrace because we hit a sky brush from outside the level, not the ground + { + if ( !downResult.hitSky ) + break + printt( "Hit sky" ) + downStartPos = downResult.endPos + downStartPos.z -= 5 + downResult = TraceLine( downStartPos, targetPos, null, (TRACE_MASK_NPCSOLID_BRUSHONLY|TRACE_MASK_WATER), TRACE_COLLISION_GROUP_NONE ) + DebugDrawLine( downStartPos, downResult.endPos, 0, 255, 0, true, 60.0 ) + DebugDrawLine( downStartPos + Vector(10,0,0), targetPos + Vector(10,0,0), 255, 255, 0, true, 60.0 ) + } + */ + + /* + local upEndPos = targetPos + Vector( 0, 0, ROCKET_START_HEIGHT ) + TraceResults upResult = TraceLine( downResult.endPos, upEndPos, null, (TRACE_MASK_NPCSOLID_BRUSHONLY|TRACE_MASK_WATER), TRACE_COLLISION_GROUP_NONE ) + local spawnPos = upResult.endPos + + local rocketPos + local min = radius * -1 + local max = radius + local rocket + */ + + vector rocketOrigin = GetRocketSpawnOrigin( targetPos ) + + entity rocket = SpawnRocket( rocketOrigin, Vector( 90, 0, 0 ), player, team ) // First rocket hits center target + EmitSoundOnEntity( rocket, "weapon_titanmortar_fire" ) + EmitSoundOnEntity( rocket, "weapon_titanmortar_projectile" ) + + for ( int i = 1; i < numRockets; i++ ) + { + wait CalculateStrikeDelay( i, numRockets, totalTime ) + + vector offset = Normalize( Vector( RandomFloatRange( -1.0, 1.0 ), RandomFloatRange( -1.0, 1.0 ), 0 ) ) + vector rocketPos = rocketOrigin + ( offset * RandomFloat( radius ) ) + + entity rocket = SpawnRocket( rocketPos, Vector( 90, 0, 0 ), player, team ) + EmitSoundOnEntity( rocket, "weapon_titanmortar_fire" ) + EmitSoundOnEntity( rocket, "weapon_titanmortar_projectile" ) + } +} + +vector function GetRocketSpawnOrigin( vector point ) +{ + vector skyPos = GetSkyOriginAbovePoint( point ) + TraceResults traceResult = TraceLine( skyPos, point, null, (TRACE_MASK_SHOT), TRACE_COLLISION_GROUP_NONE ) + vector rocketOrigin = traceResult.endPos + rocketOrigin.z += 6000 + if ( rocketOrigin.z > skyPos.z - 1 ) + rocketOrigin.z = skyPos.z - 1 + return rocketOrigin +} + +vector function GetSkyOriginAbovePoint( vector point ) +{ + vector skyOrigin = Vector( point.x, point.y, MAX_WORLD_COORD ) + vector traceFromPos = Vector( point.x, point.y, point.z ) + + while ( true ) + { + TraceResults traceResult = TraceLine( traceFromPos, skyOrigin, null, (TRACE_MASK_SHOT), TRACE_COLLISION_GROUP_NONE ) + + if ( traceResult.hitSky ) + { + skyOrigin = traceResult.endPos + break + } + + traceFromPos = traceResult.endPos + traceFromPos.z += 1 + } + + return skyOrigin +} + +entity function SpawnRocket( vector spawnPos, vector spawnAng, entity owner, int team ) +{ + entity rocket = CreateEntity( "rpg_missile" ) + rocket.SetOrigin( spawnPos ) + rocket.SetAngles( spawnAng ) + rocket.SetOwner( owner ) + SetTeam( rocket, team ) + rocket.SetModel( $"models/weapons/bullets/projectile_rocket.mdl" ) + rocket.SetImpactEffectTable( file.impactEffectTable ) + rocket.SetWeaponClassName( "mp_titanweapon_orbital_strike" ) + rocket.kv.damageSourceId = eDamageSourceId.mp_titanweapon_orbital_strike + DispatchSpawn( rocket ) + + return rocket +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut b/Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut new file mode 100644 index 00000000..6bbb3e89 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/superbar/smokescreen.nut @@ -0,0 +1,417 @@ + +global function Smokescreen_Init +global function Smokescreen +global function IsOriginTouchingSmokescreen +global function IsRayTouchingSmokescreen + +#if DEV +const bool SMOKESCREEN_DEBUG = false +#endif + +global struct SmokescreenStruct +{ + vector origin + vector angles + bool fxUseWeaponOrProjectileAngles = false + + float lifetime = 5.0 + int ownerTeam = TEAM_ANY + + asset smokescreenFX = FX_ELECTRIC_SMOKESCREEN + float fxXYRadius = 230.0 // single fx xy radius used to create nospawn area and block traces + float fxZRadius = 170.0 // single fx z radius used to create nospawn area and block traces + string deploySound1p = SFX_SMOKE_DEPLOY_1P + string deploySound3p = SFX_SMOKE_DEPLOY_3P + string stopSound1p = "" + string stopSound3p = "" + int damageSource = eDamageSourceId.mp_titanability_smoke + + bool blockLOS = true + bool shouldHibernate = true + + bool isElectric = true + entity attacker + entity inflictor + entity weaponOrProjectile + float damageDelay = 2.0 + float damageInnerRadius = 320.0 + float damageOuterRadius = 350.0 + float dangerousAreaRadius = -1.0 + int dpsPilot = 30 + int dpsTitan = 2200 + + array<vector> fxOffsets +} + +struct SmokescreenFXStruct +{ + vector center // center of all fx positions + vector mins // approx mins of all fx relative to center + vector maxs // approx maxs of all fx relative to center + float radius // approx radius of all fx relative to center + array<vector> fxWorldPositions + int ownerTeam = TEAM_ANY +} + +struct +{ + array<SmokescreenFXStruct> allSmokescreenFX + table<entity, float> nextSmokeSoundTime +} file + +void function Smokescreen_Init() +{ + PrecacheParticleSystem( FX_ELECTRIC_SMOKESCREEN ) + PrecacheParticleSystem( FX_ELECTRIC_SMOKESCREEN_BURN ) + #if MP + PrecacheParticleSystem( FX_ELECTRIC_SMOKESCREEN_HEAL ) + #endif + PrecacheParticleSystem( FX_GRENADE_SMOKESCREEN ) + + PrecacheSprite( $"sprites/physbeam.vmt" ) + PrecacheSprite( $"sprites/glow01.vmt" ) + +#if SERVER + AddDamageCallbackSourceID( eDamageSourceId.mp_titanability_smoke, TitanElectricSmoke_DamagedPlayerOrNPC ) + AddDamageCallbackSourceID( eDamageSourceId.mp_weapon_grenade_electric_smoke, GrenadeElectricSmoke_DamagedPlayerOrNPC ) +#endif +} + +void function Smokescreen( SmokescreenStruct smokescreen ) +{ + SmokescreenFXStruct fxInfo = Smokescreen_CalculateFXStruct( smokescreen ) + file.allSmokescreenFX.append( fxInfo ) + + array<entity> thermiteBurns = GetActiveThermiteBurnsWithinRadius( fxInfo.center, fxInfo.radius ) + foreach ( thermiteBurn in thermiteBurns ) + { + entity owner = thermiteBurn.GetOwner() + + if ( IsValid( owner ) && owner.GetTeam() != smokescreen.ownerTeam ) + thermiteBurn.Destroy() + } + + entity traceBlocker + + if ( smokescreen.blockLOS ) + traceBlocker = Smokescreen_CreateTraceBlockerVol( smokescreen, fxInfo ) + +#if DEV + if ( SMOKESCREEN_DEBUG ) + DebugDrawCircle( fxInfo.center, <0,0,0>, fxInfo.radius + 240.0, 255, 255, 0, true, smokescreen.lifetime ) +#endif + CreateNoSpawnArea( TEAM_ANY, TEAM_ANY, fxInfo.center, smokescreen.lifetime, fxInfo.radius + 240.0 ) + + if ( IsValid( smokescreen.attacker ) && smokescreen.attacker.IsPlayer() ) + { + EmitSoundAtPositionExceptToPlayer( TEAM_ANY, fxInfo.center, smokescreen.attacker, smokescreen.deploySound3p ) + EmitSoundAtPositionOnlyToPlayer( TEAM_ANY, fxInfo.center, smokescreen.attacker, smokescreen.deploySound1p) + } + else + { + EmitSoundAtPosition( TEAM_ANY, fxInfo.center, smokescreen.deploySound3p ) + } + + array<entity> fxEntities = SmokescreenFX( smokescreen, fxInfo ) + if ( smokescreen.isElectric ) + thread SmokescreenAffectsEntitiesInArea( smokescreen, fxInfo ) + //thread CreateSmokeSightTrigger( fxInfo.center, smokescreen.ownerTeam, smokescreen.lifetime ) // disabling for now, this should use the calculated radius if reenabled + + thread DestroySmokescreen( smokescreen, smokescreen.lifetime, fxInfo, traceBlocker, fxEntities ) +} + +SmokescreenFXStruct function Smokescreen_CalculateFXStruct( SmokescreenStruct smokescreen ) +{ + SmokescreenFXStruct fxInfo + + foreach ( i, position in smokescreen.fxOffsets ) + { + //mins + if ( i == 0 || position.x < fxInfo.mins.x ) + fxInfo.mins = <position.x, fxInfo.mins.y, fxInfo.mins.z> + + if ( i == 0 || position.y < fxInfo.mins.y ) + fxInfo.mins = <fxInfo.mins.x, position.y, fxInfo.mins.z> + + if ( i == 0 || position.z < fxInfo.mins.z ) + fxInfo.mins = <fxInfo.mins.x, fxInfo.mins.y, position.z> + + // maxs + if ( i == 0 || position.x > fxInfo.maxs.x ) + fxInfo.maxs = <position.x, fxInfo.maxs.y, fxInfo.maxs.z> + + if ( i == 0 || position.y > fxInfo.maxs.y ) + fxInfo.maxs = <fxInfo.maxs.x, position.y, fxInfo.maxs.z> + + if ( i == 0 || position.z > fxInfo.maxs.z ) + fxInfo.maxs = <fxInfo.maxs.x, fxInfo.maxs.y, position.z> + } + + vector offsetCenter = fxInfo.mins + ( fxInfo.maxs - fxInfo.mins ) * 0.5 + + float xyRadius = smokescreen.fxXYRadius * 0.7071 + float zRadius = smokescreen.fxZRadius * 0.7071 + + fxInfo.mins = <fxInfo.mins.x - xyRadius, fxInfo.mins.y - xyRadius, fxInfo.mins.z - zRadius> - offsetCenter + fxInfo.maxs = <fxInfo.maxs.x + xyRadius, fxInfo.maxs.y + xyRadius, fxInfo.maxs.z + zRadius> - offsetCenter + + float radiusSqr + float singleFXRadius = max( smokescreen.fxXYRadius, smokescreen.fxZRadius ) + + vector forward = AnglesToForward( smokescreen.angles ) + vector right = AnglesToRight( smokescreen.angles ) + vector up = AnglesToUp( smokescreen.angles ) + + foreach ( i, position in smokescreen.fxOffsets ) + { + float distanceSqr = DistanceSqr( position, offsetCenter ) + + if ( radiusSqr < distanceSqr ) + radiusSqr = distanceSqr + + fxInfo.fxWorldPositions.append( smokescreen.origin + ( position.x * forward ) + ( position.y * right ) + ( position.z * up ) ) + } + + fxInfo.center = smokescreen.origin + ( offsetCenter.x * forward ) + ( offsetCenter.y * right ) + ( offsetCenter.z * up ) + fxInfo.radius = sqrt( radiusSqr ) + singleFXRadius + fxInfo.ownerTeam = smokescreen.ownerTeam + + return fxInfo +} + +void function SmokescreenAffectsEntitiesInArea( SmokescreenStruct smokescreen, SmokescreenFXStruct fxInfo ) +{ + float startTime = Time() + float tickRate = 0.1 + + float dpsPilot = smokescreen.dpsPilot * tickRate + float dpsTitan = smokescreen.dpsTitan * tickRate + Assert( dpsPilot || dpsTitan > 0, "Electric smokescreen with 0 damage created" ) + + entity aiDangerTarget = CreateEntity( "info_target" ) + DispatchSpawn( aiDangerTarget ) + aiDangerTarget.SetOrigin( fxInfo.center ) + SetTeam( aiDangerTarget, smokescreen.ownerTeam ) + + float dangerousAreaRadius = smokescreen.damageOuterRadius + if ( smokescreen.dangerousAreaRadius != -1.0 ) + dangerousAreaRadius = smokescreen.dangerousAreaRadius + + AI_CreateDangerousArea_Static( aiDangerTarget, smokescreen.weaponOrProjectile, dangerousAreaRadius, TEAM_INVALID, true, true, fxInfo.center ) + + OnThreadEnd( + function () : ( aiDangerTarget ) + { + aiDangerTarget.Destroy() + } + ) + + wait smokescreen.damageDelay + + while ( Time() - startTime <= smokescreen.lifetime ) + { +#if DEV + if ( SMOKESCREEN_DEBUG ) + { + DebugDrawCircle( fxInfo.center, <0,0,0>, smokescreen.damageInnerRadius, 255, 0, 0, true, tickRate ) + DebugDrawCircle( fxInfo.center, <0,0,0>, smokescreen.damageOuterRadius, 255, 0, 0, true, tickRate ) + } +#endif + + RadiusDamage( + fxInfo.center, // center + smokescreen.attacker, // attacker + smokescreen.inflictor, // inflictor + dpsPilot, // damage + dpsTitan, // damageHeavyArmor + smokescreen.damageInnerRadius, // innerRadius + smokescreen.damageOuterRadius, // outerRadius + SF_ENVEXPLOSION_MASK_BRUSHONLY, // flags + 0.0, // distanceFromAttacker + 0.0, // explosionForce + DF_ELECTRICAL | DF_NO_HITBEEP, // scriptDamageFlags + smokescreen.damageSource ) // scriptDamageSourceIdentifier + + wait tickRate + } +} + +entity function Smokescreen_CreateTraceBlockerVol( SmokescreenStruct smokescreen, SmokescreenFXStruct fxInfo ) +{ + entity traceBlockerVol = CreateEntity( "trace_volume" ) + traceBlockerVol.kv.targetname = UniqueString( "smokescreen_traceblocker_vol" ) + traceBlockerVol.kv.origin = fxInfo.center + traceBlockerVol.kv.angles = smokescreen.angles + DispatchSpawn( traceBlockerVol ) + traceBlockerVol.SetBox( fxInfo.mins * 0.9, fxInfo.maxs * 0.9 ) + +#if DEV + if ( SMOKESCREEN_DEBUG ) + DrawAngledBox( fxInfo.center, smokescreen.angles, fxInfo.mins, fxInfo.maxs, 255, 0, 0, true, smokescreen.lifetime - 0.6 ) +#endif + + return traceBlockerVol +} + +array<entity> function SmokescreenFX( SmokescreenStruct smokescreen, SmokescreenFXStruct fxInfo ) +{ + array<entity> fxEntities + + foreach ( position in fxInfo.fxWorldPositions ) + { +#if DEV + if ( SMOKESCREEN_DEBUG ) + DebugDrawCircle( position, <0.0, 0.0, 0.0>, smokescreen.fxXYRadius, 0, 0, 255, true, smokescreen.lifetime ) +#endif + int fxID = GetParticleSystemIndex( smokescreen.smokescreenFX ) + vector angles = smokescreen.fxUseWeaponOrProjectileAngles ? smokescreen.weaponOrProjectile.GetAngles() : <0.0, 0.0, 0.0> + entity fxEnt = StartParticleEffectInWorld_ReturnEntity( fxID, position, angles ) + float fxLife = smokescreen.lifetime + + EffectSetControlPointVector( fxEnt, 1, <fxLife, 0.0, 0.0> ) + + if ( !smokescreen.shouldHibernate ) + fxEnt.DisableHibernation() + + fxEntities.append( fxEnt ) + } + + return fxEntities +} + +void function DestroySmokescreen( SmokescreenStruct smokescreen, float lifetime, SmokescreenFXStruct fxInfo, entity traceBlocker, array<entity> fxEntities ) +{ + float timeToWait = 0.0 + + timeToWait = max( lifetime - 0.5, 0.0 ) + + wait( timeToWait ) + if ( IsValid( traceBlocker ) ) + traceBlocker.Destroy() + file.allSmokescreenFX.fastremovebyvalue( fxInfo ) + + StopSoundAtPosition( fxInfo.center, smokescreen.deploySound1p ) + StopSoundAtPosition( fxInfo.center, smokescreen.deploySound3p ) + + if ( IsValid( smokescreen.attacker ) && smokescreen.attacker.IsPlayer() ) + { + if ( smokescreen.stopSound3p != "" ) + EmitSoundAtPositionExceptToPlayer( TEAM_ANY, fxInfo.center, smokescreen.attacker, smokescreen.stopSound3p ) + + if ( smokescreen.stopSound1p != "" ) + EmitSoundAtPositionOnlyToPlayer( TEAM_ANY, fxInfo.center, smokescreen.attacker, smokescreen.stopSound1p) + } + else + { + if ( smokescreen.stopSound3p != "" ) + EmitSoundAtPosition( TEAM_ANY, fxInfo.center, smokescreen.stopSound3p ) + } + + timeToWait = max( ( lifetime + 0.1 ) - timeToWait, 0.0 ) + wait( timeToWait ) + + foreach ( fxEnt in fxEntities ) + { + if ( IsValid( fxEnt ) ) + fxEnt.Destroy() + } +} + +bool function IsOriginTouchingSmokescreen( vector origin, int teamToIgnore = TEAM_UNASSIGNED ) +{ + foreach ( fxInfo in file.allSmokescreenFX ) + { + if ( teamToIgnore == fxInfo.ownerTeam ) + continue + + if ( DistanceSqr( origin, fxInfo.center ) < fxInfo.radius * fxInfo.radius ) + return true + } + + return false +} + +bool function IsRayTouchingSmokescreen( vector rayStart, vector rayEnd, int teamToIgnore = TEAM_UNASSIGNED ) +{ + foreach ( fxInfo in file.allSmokescreenFX ) + { + if ( teamToIgnore == fxInfo.ownerTeam ) + continue + + if ( IntersectRayWithSphere( rayStart, rayEnd, fxInfo.center, fxInfo.radius ).result ) + return true + } + + return false +} + +#if SERVER +void function TitanElectricSmoke_DamagedPlayerOrNPC( entity ent, var damageInfo ) +{ + if ( !IsAlive( ent ) ) + return + + entity attacker = DamageInfo_GetAttacker( damageInfo ) + + if ( ent.GetTeam() == attacker.GetTeam() ) + { + DamageInfo_SetDamage( damageInfo, 0 ) + return + } + + PlayDamageSounds( ent, attacker, ELECTRIC_SMOKESCREEN_SFX_DAMAGE_TITAN_1P, ELECTRIC_SMOKESCREEN_SFX_DAMAGE_TITAN_3P, ELECTRIC_SMOKESCREEN_SFX_DAMAGE_PILOT_1P, ELECTRIC_SMOKESCREEN_SFX_DAMAGE_PILOT_3P ) +} + +void function GrenadeElectricSmoke_DamagedPlayerOrNPC( entity ent, var damageInfo ) +{ + if ( !IsAlive( ent ) ) + return + + entity attacker = DamageInfo_GetAttacker( damageInfo ) + + PlayDamageSounds( ent, attacker, ELECTRIC_SMOKE_GRENADE_SFX_DAMAGE_TITAN_1P, ELECTRIC_SMOKE_GRENADE_SFX_DAMAGE_TITAN_3P, ELECTRIC_SMOKE_GRENADE_SFX_DAMAGE_PILOT_1P, ELECTRIC_SMOKE_GRENADE_SFX_DAMAGE_PILOT_3P ) +} + +void function PlayDamageSounds( entity ent, entity attacker, string titan1P_SFX, string titan3P_SFX, string pilot1P_SFX, string pilot3P_SFX ) +{ + float currentTime = Time() + + if ( !( ent in file.nextSmokeSoundTime ) ) + { + if ( ent.IsPlayer() ) + file.nextSmokeSoundTime[ ent ] <- currentTime + else + file.nextSmokeSoundTime[ ent ] <- currentTime + RandomFloat( 0.5 ) + } + + if ( file.nextSmokeSoundTime[ ent ] <= currentTime ) + { + if ( ent.IsPlayer() ) + { + if ( ent.IsTitan() ) + { + EmitSoundOnEntityExceptToPlayer( ent, ent, titan3P_SFX ) + EmitSoundOnEntityOnlyToPlayer( ent, ent, titan1P_SFX ) + file.nextSmokeSoundTime[ ent ] = currentTime + RandomFloatRange( 0.75, 1.25 ) + } + else + { + EmitSoundOnEntityExceptToPlayer( ent, ent, pilot3P_SFX ) + EmitSoundOnEntityOnlyToPlayer( ent, ent, pilot1P_SFX ) + } + + if ( IsValid( attacker ) && attacker.IsPlayer() ) + EmitSoundOnEntityOnlyToPlayer( attacker, attacker, "Player.Hitbeep" ) + } + else + { + if ( ent.IsTitan() ) + EmitSoundOnEntity( ent, titan3P_SFX ) + else if ( IsHumanSized( ent ) ) + EmitSoundOnEntity( ent, pilot3P_SFX ) + } + + file.nextSmokeSoundTime[ ent ] = currentTime + RandomFloatRange( 0.75, 1.25 ) + } +} +#endif
\ No newline at end of file |