From 86f47958497d45c1163ff1746560be77efbba98d Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:28:28 +0100 Subject: [PATCH] Fix rigged power cells exploding early (#41813) * fix riggable * fix --- .../Power/EntitySystems/BatterySystem.API.cs | 8 ++-- .../Power/EntitySystems/RiggableSystem.cs | 23 +++++----- Content.Shared/Power/ChargeEvents.cs | 42 ++++++++++++++++++- .../PredictedBatterySystem.API.cs | 9 ++-- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/Content.Server/Power/EntitySystems/BatterySystem.API.cs b/Content.Server/Power/EntitySystems/BatterySystem.API.cs index 5683e7c133..5995758d3d 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.API.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.API.cs @@ -26,7 +26,7 @@ public sealed partial class BatterySystem TrySetChargeCooldown(ent.Owner); - var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, delta, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref ev); return delta; } @@ -61,21 +61,23 @@ public sealed partial class BatterySystem return; } - var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.CurrentCharge - oldCharge, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref ev); } + public override void SetMaxCharge(Entity ent, float value) { if (!Resolve(ent, ref ent.Comp)) return; var old = ent.Comp.MaxCharge; + var oldCharge = ent.Comp.CurrentCharge; ent.Comp.MaxCharge = Math.Max(value, 0); ent.Comp.CurrentCharge = Math.Min(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); if (MathHelper.CloseTo(ent.Comp.MaxCharge, old)) return; - var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.CurrentCharge - oldCharge, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref ev); } diff --git a/Content.Server/Power/EntitySystems/RiggableSystem.cs b/Content.Server/Power/EntitySystems/RiggableSystem.cs index 3972cf3f86..390e75eeb8 100644 --- a/Content.Server/Power/EntitySystems/RiggableSystem.cs +++ b/Content.Server/Power/EntitySystems/RiggableSystem.cs @@ -86,13 +86,10 @@ public sealed class RiggableSystem : EntitySystem if (!ent.Comp.IsRigged) return; - if (TryComp(ent, out var batteryComponent)) - { - if (batteryComponent.CurrentCharge == 0f) - return; + if (args.Charge == 0f) + return; // No charge to cause an explosion. - Explode(ent, batteryComponent.CurrentCharge); - } + Explode(ent, args.Charge); } // predicted batteries @@ -101,13 +98,13 @@ public sealed class RiggableSystem : EntitySystem if (!ent.Comp.IsRigged) return; - if (TryComp(ent, out var predictedBatteryComponent)) - { - var charge = _predictedBattery.GetCharge((ent.Owner, predictedBatteryComponent)); - if (charge == 0f) - return; + if (args.CurrentCharge == 0f) + return; // No charge to cause an explosion. - Explode(ent, charge); - } + // Don't explode if we are not using any charge. + if (args.CurrentChargeRate == 0f && args.Delta == 0f) + return; + + Explode(ent, args.CurrentCharge); } } diff --git a/Content.Shared/Power/ChargeEvents.cs b/Content.Shared/Power/ChargeEvents.cs index f84b255f12..d6a9c66071 100644 --- a/Content.Shared/Power/ChargeEvents.cs +++ b/Content.Shared/Power/ChargeEvents.cs @@ -8,7 +8,23 @@ namespace Content.Shared.Power; /// Only raised for entities with . /// [ByRefEvent] -public readonly record struct ChargeChangedEvent(float Charge, float MaxCharge); +public readonly record struct ChargeChangedEvent(float Charge, float Delta, float MaxCharge) +{ + /// + /// The new charge of the battery. + /// + public readonly float Charge = Charge; + + /// + /// The amount the charge was changed by. + /// + public readonly float Delta = Delta; + + /// + /// The maximum charge of the battery. + /// + public readonly float MaxCharge = MaxCharge; +} /// /// Raised when a predicted battery's charge or capacity changes (capacity affects relative charge percentage). @@ -18,7 +34,29 @@ public readonly record struct ChargeChangedEvent(float Charge, float MaxCharge); /// Only raised for entities with . /// [ByRefEvent] -public readonly record struct PredictedBatteryChargeChangedEvent(float CurrentCharge, float CurrentChargeRate, TimeSpan CurrentTime, float MaxCharge); +public readonly record struct PredictedBatteryChargeChangedEvent(float CurrentCharge, float Delta, float CurrentChargeRate, float MaxCharge) +{ + /// + /// The new charge of the battery. + /// + public readonly float CurrentCharge = CurrentCharge; + + /// + /// The amount the charge was changed by. + /// This might be 0 if only the charge rate was modified. + /// + public readonly float Delta = Delta; + + /// + /// The new charge rate of the battery. + /// + public readonly float CurrentChargeRate = CurrentChargeRate; + + /// + /// The maximum charge of the battery. + /// + public readonly float MaxCharge = MaxCharge; +} /// /// Raised when a battery changes its state between full, empty, or neither. diff --git a/Content.Shared/Power/EntitySystems/PredictedBatterySystem.API.cs b/Content.Shared/Power/EntitySystems/PredictedBatterySystem.API.cs index e5b509ca31..e1d685daeb 100644 --- a/Content.Shared/Power/EntitySystems/PredictedBatterySystem.API.cs +++ b/Content.Shared/Power/EntitySystems/PredictedBatterySystem.API.cs @@ -36,7 +36,7 @@ public sealed partial class PredictedBatterySystem TrySetChargeCooldown(ent.Owner); - var changedEv = new PredictedBatteryChargeChangedEvent(newValue, ent.Comp.ChargeRate, curTime, ent.Comp.MaxCharge); + var changedEv = new PredictedBatteryChargeChangedEvent(newValue, delta, ent.Comp.ChargeRate, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref changedEv); // Raise events if the battery status changed between full, empty, or neither. @@ -95,7 +95,7 @@ public sealed partial class PredictedBatterySystem ent.Comp.LastUpdate = curTime; Dirty(ent); - var ev = new PredictedBatteryChargeChangedEvent(newValue, ent.Comp.ChargeRate, curTime, ent.Comp.MaxCharge); + var ev = new PredictedBatteryChargeChangedEvent(newValue, delta, ent.Comp.ChargeRate, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref ev); // Raise events if the battery status changed between full, empty, or neither. @@ -115,13 +115,14 @@ public sealed partial class PredictedBatterySystem if (value == ent.Comp.MaxCharge) return; + var oldCharge = GetCharge(ent); ent.Comp.MaxCharge = Math.Max(value, 0); ent.Comp.LastCharge = GetCharge(ent); // This clamps it using the new max. var curTime = _timing.CurTime; ent.Comp.LastUpdate = curTime; Dirty(ent); - var ev = new PredictedBatteryChargeChangedEvent(ent.Comp.LastCharge, ent.Comp.ChargeRate, curTime, ent.Comp.MaxCharge); + var ev = new PredictedBatteryChargeChangedEvent(ent.Comp.LastCharge, ent.Comp.LastCharge - oldCharge, ent.Comp.ChargeRate, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref ev); // Raise events if the battery status changed between full, empty, or neither. @@ -240,7 +241,7 @@ public sealed partial class PredictedBatterySystem Dirty(ent); // Inform other systems about the new rate; - var changedEv = new PredictedBatteryChargeChangedEvent(ent.Comp.LastCharge, ent.Comp.ChargeRate, curTime, ent.Comp.MaxCharge); + var changedEv = new PredictedBatteryChargeChangedEvent(ent.Comp.LastCharge, 0f, ent.Comp.ChargeRate, ent.Comp.MaxCharge); RaiseLocalEvent(ent, ref changedEv); return refreshEv.NewChargeRate; -- 2.52.0