using Content.Server.Explosion.EntitySystems; using Content.Server.Power.EntitySystems; using Content.Server.Radio; using Content.Server.SurveillanceCamera; using Content.Shared.Emp; using Content.Shared.Examine; using Robust.Shared.Map; namespace Content.Server.Emp; public sealed class EmpSystem : SharedEmpSystem { [Dependency] private readonly EntityLookupSystem _lookup = default!; public const string EmpPulseEffectPrototype = "EffectEmpPulse"; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnUnpaused); SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(HandleEmpTrigger); SubscribeLocalEvent(OnRadioSendAttempt); SubscribeLocalEvent(OnRadioReceiveAttempt); SubscribeLocalEvent(OnApcToggleMainBreaker); SubscribeLocalEvent(OnCameraSetActive); } public void EmpPulse(MapCoordinates coordinates, float range, float energyConsumption, float duration) { foreach (var uid in _lookup.GetEntitiesInRange(coordinates, range)) { var ev = new EmpPulseEvent(energyConsumption, false, false); RaiseLocalEvent(uid, ref ev); if (ev.Affected) { Spawn(EmpDisabledEffectPrototype, Transform(uid).Coordinates); } if (ev.Disabled) { var disabled = EnsureComp(uid); disabled.DisabledUntil = Timing.CurTime + TimeSpan.FromSeconds(duration); } } Spawn(EmpPulseEffectPrototype, coordinates); } public override void Update(float frameTime) { base.Update(frameTime); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp)) { if (comp.DisabledUntil < Timing.CurTime) { RemComp(uid); var ev = new EmpDisabledRemoved(); RaiseLocalEvent(uid, ref ev); } } } private void OnUnpaused(EntityUid uid, EmpDisabledComponent component, ref EntityUnpausedEvent args) { component.DisabledUntil += args.PausedTime; component.TargetTime += args.PausedTime; } private void OnExamine(EntityUid uid, EmpDisabledComponent component, ExaminedEvent args) { args.PushMarkup(Loc.GetString("emp-disabled-comp-on-examine")); } private void HandleEmpTrigger(EntityUid uid, EmpOnTriggerComponent comp, TriggerEvent args) { EmpPulse(Transform(uid).MapPosition, comp.Range, comp.EnergyConsumption, comp.DisableDuration); args.Handled = true; } private void OnRadioSendAttempt(EntityUid uid, EmpDisabledComponent component, ref RadioSendAttemptEvent args) { args.Cancelled = true; } private void OnRadioReceiveAttempt(EntityUid uid, EmpDisabledComponent component, ref RadioReceiveAttemptEvent args) { args.Cancelled = true; } private void OnApcToggleMainBreaker(EntityUid uid, EmpDisabledComponent component, ref ApcToggleMainBreakerAttemptEvent args) { args.Cancelled = true; } private void OnCameraSetActive(EntityUid uid, EmpDisabledComponent component, ref SurveillanceCameraSetActiveAttemptEvent args) { args.Cancelled = true; } } [ByRefEvent] public record struct EmpPulseEvent(float EnergyConsumption, bool Affected, bool Disabled); [ByRefEvent] public record struct EmpDisabledRemoved();