From 63ec69bb108ebdc5ca752c88b7fc06b2c6e9ffee Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:55:41 +0300 Subject: [PATCH] Fix #864 and Rehydratable System Doing Client-Side Spawn (#888) # Description - Resolves #864 by partially reverting #516 - Adds a _net.IsClient check to RehydratableSystem to avoid spawning duplicate entities on client side

Media

https://github.com/user-attachments/assets/e50785a6-b5f7-4484-9097-118bc3a5dfa5

--- # Changelog :cl: - fix: Cyborg recharging stations finally work again. - fix: Rehydratable entities (such as monkey cubes) no longer spawn a second client-side entity when rehydrated. --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: VMSolidus --- .../Components/ActiveChargerComponent.cs | 7 + .../Power/Components/ChargingComponent.cs | 19 --- .../Power/EntitySystems/BatterySystem.cs | 16 -- .../Power/EntitySystems/ChargerSystem.cs | 149 ++++-------------- .../EntitySystems/RehydratableSystem.cs | 5 + 5 files changed, 39 insertions(+), 157 deletions(-) create mode 100644 Content.Server/Power/Components/ActiveChargerComponent.cs delete mode 100644 Content.Server/Power/Components/ChargingComponent.cs diff --git a/Content.Server/Power/Components/ActiveChargerComponent.cs b/Content.Server/Power/Components/ActiveChargerComponent.cs new file mode 100644 index 00000000000..9f75db853d2 --- /dev/null +++ b/Content.Server/Power/Components/ActiveChargerComponent.cs @@ -0,0 +1,7 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Power; + +namespace Content.Server.Power.Components; + +[RegisterComponent] +public sealed partial class ActiveChargerComponent : Component { } diff --git a/Content.Server/Power/Components/ChargingComponent.cs b/Content.Server/Power/Components/ChargingComponent.cs deleted file mode 100644 index db7c14f7082..00000000000 --- a/Content.Server/Power/Components/ChargingComponent.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Power; - -namespace Content.Server.Power.Components -{ - [RegisterComponent] - public sealed partial class ChargingComponent : Component - { - /// - ///References the entity of the charger that is currently powering this battery - /// - public EntityUid ChargerUid; - - /// - ///References the component of the charger that is currently powering this battery - /// - public ChargerComponent ChargerComponent; - } -} diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs index 1c5d83b094d..cbe61f66717 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -21,7 +21,6 @@ public override void Initialize() SubscribeLocalEvent(OnBatteryRejuvenate); SubscribeLocalEvent(CalculateBatteryPrice); SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); SubscribeLocalEvent(PreSync); SubscribeLocalEvent(PostSync); @@ -106,17 +105,6 @@ private void OnEmpPulse(EntityUid uid, BatteryComponent component, ref EmpPulseE UseCharge(uid, args.EnergyConsumption, component); } - // if a disabled battery is put into a recharged, - // allow the recharger to start recharging again after the disable ends - private void OnEmpDisabledRemoved(EntityUid uid, BatteryComponent component, ref EmpDisabledRemoved args) - { - if (!TryComp(uid, out var charging)) - return; - - var ev = new ChargerUpdateStatusEvent(); - RaiseLocalEvent(charging.ChargerUid, ref ev); - } - public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) { if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0) @@ -191,10 +179,6 @@ public bool IsFull(EntityUid uid, BatteryComponent? battery = null) if (!Resolve(uid, ref battery)) return false; - // If the battery is full, remove its charging component. - if (TryComp(uid, out _)) - RemComp(uid); - return battery.CurrentCharge / battery.MaxCharge >= 0.99f; } } diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index ae6b024162e..db16dfa008e 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -1,16 +1,13 @@ using Content.Server.Power.Components; -using Content.Server.Emp; using Content.Server.PowerCell; using Content.Shared.Examine; using Content.Shared.Power; using Content.Shared.PowerCell.Components; -using Content.Shared.Emp; using JetBrains.Annotations; using Robust.Shared.Containers; using System.Diagnostics.CodeAnalysis; using Content.Shared.Storage.Components; using Robust.Server.Containers; -using Content.Shared.Whitelist; namespace Content.Server.Power.EntitySystems; @@ -31,11 +28,6 @@ public override void Initialize() SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnEntityStorageInsertAttempt); SubscribeLocalEvent(OnChargerExamine); - - SubscribeLocalEvent(OnUpdateStatus); - - SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); } private void OnStartup(EntityUid uid, ChargerComponent component, ComponentStartup args) @@ -48,58 +40,21 @@ private void OnChargerExamine(EntityUid uid, ChargerComponent component, Examine args.PushMarkup(Loc.GetString("charger-examine", ("color", "yellow"), ("chargeRate", (int) component.ChargeRate))); } - private void StartChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - bool charge = true; - - if (HasComp(uid)) - charge = false; - else - if (!TryComp(target, out var battery)) - charge = false; - else - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - charge = false; - - // wrap functionality in an if statement instead of returning... - if (charge) - { - var charging = EnsureComp(target); - charging.ChargerUid = uid; - charging.ChargerComponent = component; - } - - // ...so the status always updates (for insertin a power cell) - UpdateStatus(uid, component); - } - - private void StopChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - if (HasComp(target)) - RemComp(target); - UpdateStatus(uid, component); - } - public override void Update(float frameTime) { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var charging)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var charger, out var containerComp)) { - if (!TryComp(charging.ChargerUid, out var chargerComponent)) + if (!_container.TryGetContainer(uid, charger.SlotId, out var container, containerComp)) continue; - if (charging.ChargerComponent.Status == CellChargerStatus.Off || charging.ChargerComponent.Status == CellChargerStatus.Empty) + if (charger.Status == CellChargerStatus.Empty || charger.Status == CellChargerStatus.Charged || container.ContainedEntities.Count == 0) continue; - if (HasComp(charging.ChargerUid)) - continue; - - if (!TryComp(uid, out var battery)) - continue; - - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - StopChargingBattery(charging.ChargerUid, charging.ChargerComponent, uid); - TransferPower(charging.ChargerUid, uid, charging.ChargerComponent, frameTime); + foreach (var contained in container.ContainedEntities) + { + TransferPower(uid, contained, charger, frameTime); + } } } @@ -116,7 +71,7 @@ private void OnInserted(EntityUid uid, ChargerComponent component, EntInsertedIn if (args.Container.ID != component.SlotId) return; - StartChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFromContainerMessage args) @@ -124,7 +79,7 @@ private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFrom if (args.Container.ID != component.SlotId) return; - StopChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } /// @@ -157,11 +112,6 @@ private void OnEntityStorageInsertAttempt(EntityUid uid, ChargerComponent compon args.Cancelled = true; } - private void OnUpdateStatus(EntityUid uid, ChargerComponent component, ref ChargerUpdateStatusEvent args) - { - UpdateStatus(uid, component); - } - private void UpdateStatus(EntityUid uid, ChargerComponent component) { var status = GetStatus(uid, component); @@ -176,6 +126,15 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) component.Status = status; + if (component.Status == CellChargerStatus.Charging) + { + AddComp(uid); + } + else + { + RemComp(uid); + } + switch (component.Status) { case CellChargerStatus.Off: @@ -187,7 +146,7 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Empty, appearance); break; case CellChargerStatus.Charging: - receiver.Load = component.ChargeRate; //does not scale with multiple slotted batteries + receiver.Load = component.ChargeRate; _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Charging, appearance); break; case CellChargerStatus.Charged: @@ -198,42 +157,6 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) throw new ArgumentOutOfRangeException(); } } - - private void OnEmpPulse(EntityUid uid, ChargerComponent component, ref EmpPulseEvent args) - { - // we don't care if we haven't been disabled - if (!args.Disabled) - return; - - // if the recharger is hit by an emp pulse, - // stop recharging contained batteries to save resources - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StopChargingBattery(uid, component, containedEntity); - } - } - - private void OnEmpDisabledRemoved(EntityUid uid, ChargerComponent component, ref EmpDisabledRemoved args) - { - // if an emp disable subsides, - // attempt to start charging all batteries - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StartChargingBattery(uid, component, containedEntity); - } - } private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) { @@ -255,28 +178,13 @@ private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) if (container.ContainedEntities.Count == 0) return CellChargerStatus.Empty; - var statusOut = CellChargerStatus.Off; - - foreach (var containedEntity in container.ContainedEntities) - { - // if none of the slotted items are actually batteries, represent the charger as off - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - // if all batteries are either EMP'd or fully charged, represent the charger as fully charged - statusOut = CellChargerStatus.Charged; - if (HasComp(containedEntity)) - continue; - - if (!HasComp(containedEntity)) - continue; + if (!SearchForBattery(container.ContainedEntities[0], out _, out var heldBattery)) + return CellChargerStatus.Off; - // if we have atleast one battery being charged, represent the charger as charging; - statusOut = CellChargerStatus.Charging; - break; - } + if (Math.Abs(heldBattery.MaxCharge - heldBattery.CurrentCharge) < 0.01) + return CellChargerStatus.Charged; - return statusOut; + return CellChargerStatus.Charging; } private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerComponent component, float frameTime) @@ -293,11 +201,11 @@ private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerCompone if (!SearchForBattery(targetEntity, out var batteryUid, out var heldBattery)) return; - _battery.TrySetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); // Just so the sprite won't be set to 99.99999% visibility if (heldBattery.MaxCharge - heldBattery.CurrentCharge < 0.01) { - _battery.TrySetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); } UpdateStatus(uid, component); @@ -315,6 +223,3 @@ private bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? return true; } } - -[ByRefEvent] -public record struct ChargerUpdateStatusEvent(); \ No newline at end of file diff --git a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs index e260280ae45..44bfb583dd8 100644 --- a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs @@ -1,12 +1,14 @@ using Content.Shared.Chemistry.Components; using Content.Shared.FixedPoint; using Content.Shared.Popups; +using Robust.Shared.Network; using Robust.Shared.Random; namespace Content.Shared.Chemistry.EntitySystems; public sealed class RehydratableSystem : EntitySystem { + [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutions = default!; @@ -31,6 +33,9 @@ private void OnSolutionChange(Entity ent, ref SolutionCon // Try not to make this public if you can help it. private void Expand(Entity ent) { + if (_net.IsClient) + return; // no + var (uid, comp) = ent; var randomMob = _random.Pick(comp.PossibleSpawns);