using Content.Server.Pinpointer; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.Radio.Components; using Content.Shared.Construction; using Content.Shared.Destructible; using Content.Shared.Lock; using Content.Shared.Power.EntitySystems; using Robust.Shared.Utility; namespace Content.Server.Radio.EntitySystems; /// /// System for sending radio notification upon entity becoming /// non-functioning - unpowered / deconstructed / destroyed. /// public sealed partial class NotifyOnNonFunctioningSystem : EntitySystem { [Dependency] private RadioSystem _radio = default!; [Dependency] private NavMapSystem _navMap = default!; [Dependency] private PowerStateSystem _powerState = default!; /// Notify on entity destruction. [SubscribeLocalEvent] private void OnDestruction(Entity ent, ref DestructionEventArgs args) { if (ent.Comp.LocDestroyed.HasValue) AlertRadioIfWasWorking(ent, ent.Comp.LocDestroyed); } /// Notify on deconstruction. [SubscribeLocalEvent] private void OnDeconstructed(Entity ent, ref MachineDeconstructedEvent args) { if (ent.Comp.LocDeconstructed.HasValue) AlertRadioIfWasWorking(ent, ent.Comp.LocDeconstructed); } /// Notify on unlocking already locked entity. [SubscribeLocalEvent] private void OnLockToggled(Entity ent, ref LockToggledEvent args) { if (args.Locked || !ent.Comp.LocUnlocked.HasValue) return; AlertRadioIfWasWorking(ent, ent.Comp.LocUnlocked); } /// Notify on turning off. [SubscribeLocalEvent] private void OnIsWorkingChanges(Entity ent, ref PowerStateChanged args) { // deleted entity is working change should be handled during other events if (args.IsWorking || !ent.Comp.LocTurnedOff.HasValue || TerminatingOrDeleted(ent)) return; AlertRadio(ent, ent.Comp.LocTurnedOff); } /// Notify on unanchoring. [SubscribeLocalEvent] private void OnAnchorStateChanged(Entity ent, ref AnchorStateChangedEvent args) { if (args.Anchored || !ent.Comp.LocUnanchored.HasValue || TerminatingOrDeleted(ent)) return; AlertRadioIfWasWorking(ent, ent.Comp.LocUnanchored); } [SubscribeLocalEvent] private void ReceivedChanged(Entity ent, ref PowerConsumerReceivedChanged args) { if (!ent.Comp.LocUnpowered.HasValue ||!_powerState.GetWorkingState(ent.Owner)) return; if (args.ReceivedPower < args.DrawRate) AlertRadioIfWasWorking(ent, ent.Comp.LocUnpowered, true); } private void AlertRadioIfWasWorking(Entity ent, string locString, bool ignorePower = false) { if (!_powerState.GetWorkingState(ent.Owner)) return; AlertRadio(ent, locString, ignorePower); } private void AlertRadio(Entity ent, string locString, bool ignorePower = false) { if (ent.Comp.RequirePowered && !ignorePower) { if (TryComp(ent, out var apc) && !apc.Powered) return; if (TryComp(ent, out var consumer) && consumer.DrawRate > consumer.ReceivedPower) return; } var locationInfo = FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString(ent.Owner)); var message = Loc.GetString(locString, ("location", locationInfo)); _radio.SendRadioMessage(ent.Owner, message, ent.Comp.RadioChannel, ent.Owner); } }