Fixed EMPs and Ion damage. Fixes #4989

This commit is contained in:
Vanessa 2025-12-21 11:32:48 -06:00
parent 8f34b7daf2
commit 19308e6737
6 changed files with 38 additions and 21 deletions

View File

@ -24,6 +24,8 @@ public abstract class SharedEmpSystem : EntitySystem
[Dependency] private readonly SharedPvsOverrideSystem _pvs = default!; // Frontier
[Dependency] private readonly IConfigurationManager _cfg = default!; // Frontier: EMP Blast PVS
private readonly DamageSpecifier? _defaultEmpDamage = new() { DamageDict = new() { { "Ion", 130 } } }; // DeltaV - EMP damage
private HashSet<EntityUid> _entSet = new();
public override void Initialize()
@ -47,13 +49,13 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse. In Joule.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null)
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
{
foreach (var uid in _lookup.GetEntitiesInRange(mapCoordinates, range))
{
TryEmpEffects(uid, energyConsumption, duration, user);
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? _defaultEmpDamage); // DeltaV - Add Ion Damage
}
// TODO: replace with PredictedSpawn once it works with animated sprites
// TODO: replace with PredictedSpawn once it works with animated sprites
if (_net.IsServer)
{
@ -79,13 +81,13 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null)
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
{
_entSet.Clear();
_lookup.GetEntitiesInRange(coordinates, range, _entSet);
foreach (var uid in _entSet)
{
TryEmpEffects(uid, energyConsumption, duration, user);
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? _defaultEmpDamage); // DeltaV - Add Ion Damage
}
// TODO: replace with PredictedSpawn once it works with animated sprites
if (_net.IsServer)
@ -111,14 +113,14 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
/// <returns>If the entity was affected by the EMP.</returns>
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
{
var attemptEv = new EmpAttemptEvent();
RaiseLocalEvent(uid, ref attemptEv);
if (attemptEv.Cancelled)
return false;
return DoEmpEffects(uid, energyConsumption, duration, user);
return DoEmpEffects(uid, energyConsumption, duration, user, damage); // DeltaV - Add Ion Damage
}
/// <summary>
@ -129,9 +131,9 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
/// <returns>If the entity was affected by the EMP.</returns>
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
{
var ev = new EmpPulseEvent(energyConsumption, false, false, duration, user);
var ev = new EmpPulseEvent(energyConsumption, false, false, duration, user, damage); // DeltaV - Add Ion Damage
RaiseLocalEvent(uid, ref ev);
// TODO: replace with PredictedSpawn once it works with animated sprites

View File

@ -1,3 +1,4 @@
using Content.Shared._DV.Silicons;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Emp;
using Content.Shared.PowerCell.Components;
@ -12,6 +13,8 @@ public abstract class SharedPowerCellSystem : EntitySystem
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedSiliconEmpSystem _siliconEmp = default!;
public override void Initialize()
{
@ -77,6 +80,10 @@ public abstract class SharedPowerCellSystem : EntitySystem
private void OnCellEmpAttempt(EntityUid uid, PowerCellComponent component, EmpAttemptEvent args)
{
var parent = Transform(uid).ParentUid;
if (_siliconEmp.ShouldTakeDamageInsteadOfPowerDrain(parent)) // DeltaV - Silicon EMP
return;
// relay the attempt event to the slot so it can cancel it
if (HasComp<PowerCellSlotComponent>(parent))
RaiseLocalEvent(parent, ref args);

View File

@ -32,10 +32,6 @@ public sealed partial class EmpOnTriggerComponent : BaseXOnTriggerComponent
/// <summary>
/// DeltaV - The damage dealt to silicons instead of draining their power cells
/// </summary>
[DataField]
public DamageSpecifier Damage = new() {
DamageDict = new() {
{ "Ion", 130 } // Most EMP sources should pretty much oneshot silicons. This would kill an IPC and completely disable a borg for a minute.
}
};
[DataField, AutoNetworkedField]
public DamageSpecifier? Damage;
}

View File

@ -24,7 +24,7 @@ public sealed class EmpOnTriggerSystem : EntitySystem
if (target == null)
return;
_emp.EmpPulse(Transform(target.Value).Coordinates, ent.Comp.Range, ent.Comp.EnergyConsumption, ent.Comp.DisableDuration, args.User);
_emp.EmpPulse(Transform(target.Value).Coordinates, ent.Comp.Range, ent.Comp.EnergyConsumption, ent.Comp.DisableDuration, args.User, ent.Comp.Damage); // DeltaV - Silicon damage
args.Handled = true;
}
}

View File

@ -8,6 +8,19 @@ public abstract class SharedSiliconEmpSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
/// <summary>
/// If the entity has the <see cref="SiliconEmpComponent"/>, then it should take damage instead of draining its battery.
/// </summary>
/// <param name="entity">The entity to check</param>
/// <returns>true if the entity has <see cref="SiliconEmpComponent"/></returns>
public bool ShouldTakeDamageInsteadOfPowerDrain(Entity<SiliconEmpComponent?> entity)
{
if (!Resolve(entity, ref entity.Comp, false))
return false;
return true;
}
public override void Initialize()
{
base.Initialize();
@ -17,7 +30,9 @@ public abstract class SharedSiliconEmpSystem : EntitySystem
private void OnEmpPulse(Entity<SiliconEmpComponent> ent, ref EmpPulseEvent args)
{
if (args.Damage is not { } damage) return;
_damageable.TryChangeDamage(ent, damage / 2, false); // Damage is divided by 2 because the event is raised twice (once from entity itself, and another is relayed from it's power cell) and I'm too lazy for an actual fix - NoElka | Make EMP not ignore armor.
if (args.Damage is not { } damage)
return;
_damageable.TryChangeDamage(ent, damage, false);
}
}

View File

@ -10,7 +10,4 @@
- type: Tag
tags:
- HideContextMenu
- type: EmitSoundOnSpawn
sound:
path: /Audio/Effects/Lightning/lightningbolt.ogg
- type: AnimationPlayer