From: 0x6273 <0x40@keemail.me> Date: Mon, 27 Nov 2023 21:54:51 +0000 (+0100) Subject: Anomaly Synchronizer fixes (#21883) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=5aa3c55e5e1e623c5791d7f053ab67193a286013;p=space-station-14.git Anomaly Synchronizer fixes (#21883) - Show if an anomaly is attached when examining - Add verb for attaching anomaly - Add popup messages for when you try to attach when machine isn't powered, or when no anomaly is in range. - Use anomaly threshold values from anomaly comp, instead of hardcoded **and incorrect** values - Use Entity - Formatting fixes and other misc code cleanup --- diff --git a/Content.Server/Anomaly/AnomalySynchronizerSystem.cs b/Content.Server/Anomaly/AnomalySynchronizerSystem.cs index 59c1aa8565..7b42b9d890 100644 --- a/Content.Server/Anomaly/AnomalySynchronizerSystem.cs +++ b/Content.Server/Anomaly/AnomalySynchronizerSystem.cs @@ -1,11 +1,14 @@ +using System.Linq; using Content.Server.Anomaly.Components; using Content.Server.DeviceLinking.Systems; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Shared.Anomaly.Components; +using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; using Robust.Shared.Audio.Systems; +using Content.Shared.Verbs; namespace Content.Server.Anomaly; @@ -22,86 +25,129 @@ public sealed partial class AnomalySynchronizerSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly PowerReceiverSystem _power = default!; + private const float AttachRange = 0.15f; // The radius of one tile. It must not be set higher, otherwise the anomaly can be moved from tile to tile. + public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInteractHand); SubscribeLocalEvent(OnPowerChanged); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent>(OnGetInteractionVerbs); SubscribeLocalEvent(OnAnomalyPulse); SubscribeLocalEvent(OnAnomalySeverityChanged); SubscribeLocalEvent(OnAnomalyStabilityChanged); } - private void OnPowerChanged(EntityUid uid, AnomalySynchronizerComponent component, ref PowerChangedEvent args) + /// + /// If powered, try to attach a nearby anomaly. + /// + public bool TryAttachNearbyAnomaly(Entity ent, EntityUid? user = null) + { + if (!_power.IsPowered(ent)) + { + if (user is not null) + _popup.PopupEntity(Loc.GetString("base-computer-ui-component-not-powered", ("machine", ent)), ent, user.Value); + + return false; + } + + var coords = _transform.GetMapCoordinates(ent); + var anomaly = _entityLookup.GetEntitiesInRange(coords, AttachRange).FirstOrDefault(); + + if (anomaly.Owner is {Valid: false}) // no anomaly in range + { + if (user is not null) + _popup.PopupEntity(Loc.GetString("anomaly-sync-no-anomaly"), ent, user.Value); + + return false; + } + + ConnectToAnomaly(ent, anomaly); + return true; + } + + private void OnPowerChanged(Entity ent, ref PowerChangedEvent args) { if (args.Powered) return; - if (!TryComp(component.ConnectedAnomaly, out var anomaly)) + if (!TryComp(ent.Comp.ConnectedAnomaly, out var anomaly)) return; - _anomaly.DoAnomalyPulse(component.ConnectedAnomaly.Value, anomaly); - DisconneсtFromAnomaly(uid, component, anomaly); + _anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly); + DisconneсtFromAnomaly(ent, anomaly); } - private void OnInteractHand(EntityUid uid, AnomalySynchronizerComponent component, InteractHandEvent args) + private void OnExamined(Entity ent, ref ExaminedEvent args) { - if (!_power.IsPowered(uid)) - return; + args.PushMarkup(Loc.GetString(ent.Comp.ConnectedAnomaly.HasValue ? "anomaly-sync-examine-connected" : "anomaly-sync-examine-not-connected")); + } - foreach (var entity in _entityLookup.GetEntitiesInRange(uid, 0.15f)) //is the radius of one tile. It must not be set higher, otherwise the anomaly can be moved from tile to tile - { - if (!TryComp(entity, out var anomaly)) - continue; + private void OnGetInteractionVerbs(Entity ent, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands is null || ent.Comp.ConnectedAnomaly.HasValue) + return; + var user = args.User; + args.Verbs.Add(new() { + Act = () => + { + TryAttachNearbyAnomaly(ent, user); + }, + Message = Loc.GetString("anomaly-sync-connect-verb-message", ("machine", ent)), + Text = Loc.GetString("anomaly-sync-connect-verb-text"), + }); + } - ConnectToAnomaly(uid, component, entity, anomaly); - break; - } + private void OnInteractHand(Entity ent, ref InteractHandEvent args) + { + TryAttachNearbyAnomaly(ent, args.User); } - private void ConnectToAnomaly(EntityUid uid, AnomalySynchronizerComponent component, EntityUid auid, AnomalyComponent anomaly) + private void ConnectToAnomaly(Entity ent, Entity anomaly) { - if (component.ConnectedAnomaly == auid) + if (ent.Comp.ConnectedAnomaly == anomaly) return; - component.ConnectedAnomaly = auid; + ent.Comp.ConnectedAnomaly = anomaly; //move the anomaly to the center of the synchronizer, for aesthetics. - var targetXform = _transform.GetWorldPosition(uid); - _transform.SetWorldPosition(auid, targetXform); + var targetXform = _transform.GetWorldPosition(ent); + _transform.SetWorldPosition(anomaly, targetXform); - _anomaly.DoAnomalyPulse(component.ConnectedAnomaly.Value, anomaly); - _popup.PopupEntity(Loc.GetString("anomaly-sync-connected"), uid, PopupType.Medium); - _audio.PlayPvs(component.ConnectedSound, uid); + _anomaly.DoAnomalyPulse(anomaly, anomaly); + _popup.PopupEntity(Loc.GetString("anomaly-sync-connected"), ent, PopupType.Medium); + _audio.PlayPvs(ent.Comp.ConnectedSound, ent); } //TO DO: disconnection from the anomaly should also be triggered if the anomaly is far away from the synchronizer. //Currently only bluespace anomaly can do this, but for some reason it is the only one that cannot be connected to the synchronizer. - private void DisconneсtFromAnomaly(EntityUid uid, AnomalySynchronizerComponent component, AnomalyComponent anomaly) + private void DisconneсtFromAnomaly(Entity ent, AnomalyComponent anomaly) { - if (component.ConnectedAnomaly == null) + if (ent.Comp.ConnectedAnomaly == null) return; - _anomaly.DoAnomalyPulse(component.ConnectedAnomaly.Value, anomaly); - _popup.PopupEntity(Loc.GetString("anomaly-sync-disconnected"), uid, PopupType.Large); - _audio.PlayPvs(component.ConnectedSound, uid); + _anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly); + _popup.PopupEntity(Loc.GetString("anomaly-sync-disconnected"), ent, PopupType.Large); + _audio.PlayPvs(ent.Comp.ConnectedSound, ent); - component.ConnectedAnomaly = default!; + ent.Comp.ConnectedAnomaly = null; } private void OnAnomalyPulse(ref AnomalyPulseEvent args) { var query = EntityQueryEnumerator(); - while (query.MoveNext(out var ent, out var component)) + while (query.MoveNext(out var uid, out var component)) { if (args.Anomaly != component.ConnectedAnomaly) continue; - if (!_power.IsPowered(ent)) + + if (!_power.IsPowered(uid)) continue; - _signal.InvokePort(ent, component.PulsePort); + _signal.InvokePort(uid, component.PulsePort); } } @@ -112,8 +158,10 @@ public sealed partial class AnomalySynchronizerSystem : EntitySystem { if (args.Anomaly != component.ConnectedAnomaly) continue; + if (!_power.IsPowered(ent)) continue; + //The superscritical port is invoked not at the AnomalySupercriticalEvent, //but at the moment the growth animation starts. Otherwise, there is no point in this port. //ATTENTION! the console command supercriticalanomaly does not work here, @@ -122,21 +170,25 @@ public sealed partial class AnomalySynchronizerSystem : EntitySystem _signal.InvokePort(ent, component.SupercritPort); } } + private void OnAnomalyStabilityChanged(ref AnomalyStabilityChangedEvent args) { + Entity anomaly = (args.Anomaly, Comp(args.Anomaly)); + var query = EntityQueryEnumerator(); while (query.MoveNext(out var ent, out var component)) { - if (args.Anomaly != component.ConnectedAnomaly) + if (component.ConnectedAnomaly != anomaly) continue; - if (TryComp(ent, out var apcPower) && !apcPower.Powered) + + if (!_power.IsPowered(ent)) continue; - if (args.Stability < 0.25f) //I couldn't find where these values are stored, so I hardcoded them. Tell me where these variables are stored and I'll fix it + if (args.Stability < anomaly.Comp.DecayThreshold) { _signal.InvokePort(ent, component.DecayingPort); } - else if (args.Stability > 0.5f) //I couldn't find where these values are stored, so I hardcoded them. Tell me where these variables are stored and I'll fix it + else if (args.Stability > anomaly.Comp.GrowthThreshold) { _signal.InvokePort(ent, component.GrowingPort); } diff --git a/Resources/Locale/en-US/anomaly/anomaly.ftl b/Resources/Locale/en-US/anomaly/anomaly.ftl index 83b992ce23..8452725e5e 100644 --- a/Resources/Locale/en-US/anomaly/anomaly.ftl +++ b/Resources/Locale/en-US/anomaly/anomaly.ftl @@ -27,6 +27,11 @@ anomaly-scanner-pulse-timer = Time until next pulse: [color=gray]{$time}[/color] anomaly-sync-connected = Anomaly successfully attached anomaly-sync-disconnected = The connection to the anomaly has been lost! +anomaly-sync-no-anomaly = No anomaly in range. +anomaly-sync-examine-connected = It is [color=darkgreen]attached[/color] to an anomaly. +anomaly-sync-examine-not-connected = It is [color=darkred]not attached[/color] to an anomaly. +anomaly-sync-connect-verb-text = Attach anomaly +anomaly-sync-connect-verb-message = Attach a nearby anomaly to {THE($machine)}. anomaly-generator-ui-title = Anomaly Generator anomaly-generator-fuel-display = Fuel: