diff --git a/Content.Server/GameObjects/Components/Power/BatteryComponent.cs b/Content.Server/GameObjects/Components/Power/BatteryComponent.cs index 887f9420f0..5235cf69fe 100644 --- a/Content.Server/GameObjects/Components/Power/BatteryComponent.cs +++ b/Content.Server/GameObjects/Components/Power/BatteryComponent.cs @@ -53,7 +53,7 @@ namespace Content.Server.GameObjects.Components.Power /// /// If sufficient charge is avaiable on the battery, use it. Otherwise, don't. /// - public bool TryUseCharge(float chargeToUse) + public virtual bool TryUseCharge(float chargeToUse) { if (chargeToUse >= CurrentCharge) { @@ -66,7 +66,7 @@ namespace Content.Server.GameObjects.Components.Power } } - public float UseCharge(float toDeduct) + public virtual float UseCharge(float toDeduct) { var chargeChangedBy = Math.Min(CurrentCharge, toDeduct); CurrentCharge -= chargeChangedBy; diff --git a/Content.Server/GameObjects/Components/Power/PowerCellComponent.cs b/Content.Server/GameObjects/Components/Power/PowerCellComponent.cs index 8a16a7c7da..61c321c497 100644 --- a/Content.Server/GameObjects/Components/Power/PowerCellComponent.cs +++ b/Content.Server/GameObjects/Components/Power/PowerCellComponent.cs @@ -1,4 +1,7 @@ -using Content.Shared.GameObjects.Components.Power; +using System; +using Content.Server.Explosions; +using Content.Server.GameObjects.Components.Chemistry; +using Content.Shared.GameObjects.Components.Power; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Utility; using Robust.Server.GameObjects; @@ -8,6 +11,8 @@ using Robust.Shared.Serialization; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; +#nullable enable + namespace Content.Server.GameObjects.Components.Power { /// @@ -16,13 +21,15 @@ namespace Content.Server.GameObjects.Components.Power /// [RegisterComponent] [ComponentReference(typeof(BatteryComponent))] - public class PowerCellComponent : BatteryComponent, IExamine + public class PowerCellComponent : BatteryComponent, IExamine, ISolutionChange { public override string Name => "PowerCell"; [ViewVariables] public PowerCellSize CellSize => _cellSize; private PowerCellSize _cellSize = PowerCellSize.Small; + [ViewVariables] public bool IsRigged { get; private set; } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); @@ -42,9 +49,41 @@ namespace Content.Server.GameObjects.Components.Power UpdateVisuals(); } + public override bool TryUseCharge(float chargeToUse) + { + if (IsRigged) + { + Explode(); + return false; + } + + return base.TryUseCharge(chargeToUse); + } + + public override float UseCharge(float toDeduct) + { + if (IsRigged) + { + Explode(); + return 0; + } + + return base.UseCharge(toDeduct); + } + + private void Explode() + { + var heavy = (int) Math.Ceiling(Math.Sqrt(CurrentCharge) / 60); + var light = (int) Math.Ceiling(Math.Sqrt(CurrentCharge) / 30); + + CurrentCharge = 0; + Owner.SpawnExplosion(0, heavy, light, light*2); + Owner.Delete(); + } + private void UpdateVisuals() { - if (Owner.TryGetComponent(out AppearanceComponent appearance)) + if (Owner.TryGetComponent(out AppearanceComponent? appearance)) { appearance.SetData(PowerCellVisuals.ChargeLevel, GetLevel(CurrentCharge / MaxCharge)); } @@ -57,11 +96,18 @@ namespace Content.Server.GameObjects.Components.Power void IExamine.Examine(FormattedMessage message, bool inDetailsRange) { - if(inDetailsRange) + if (inDetailsRange) { message.AddMarkup(Loc.GetString($"The charge indicator reads {CurrentCharge / MaxCharge * 100:F0} %.")); } } + + void ISolutionChange.SolutionChanged(SolutionChangeEventArgs eventArgs) + { + IsRigged = Owner.TryGetComponent(out SolutionContainerComponent? solution) + && solution.Solution.ContainsReagent("chem.Phoron", out var phoron) + && phoron >= 5; + } } public enum PowerCellSize diff --git a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs index c6a7d7a178..eecee54097 100644 --- a/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs +++ b/Content.Server/GameObjects/Components/Weapon/Ranged/Barrels/ServerBatteryBarrelComponent.cs @@ -169,7 +169,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels // Multiply the entity's damage / whatever by the percentage of charge the shot has. IEntity entity; var chargeChange = Math.Min(capacitor.CurrentCharge, _baseFireCost); - capacitor.UseCharge(chargeChange); + if (capacitor.UseCharge(chargeChange) < _lowerChargeLimit) + { + // Handling of funny exploding cells. + return null; + } var energyRatio = chargeChange / _baseFireCost; if (_ammoContainer.ContainedEntity != null) diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index d94314de03..02af2ec187 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -15,6 +15,10 @@ - type: PowerCell - type: Sprite netsync: false + - type: SolutionContainer + maxVol: 5 + caps: AddTo, RemoveFrom + - type: entity id: PowerCellSmallBase