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