diff --git a/Content.Server/Power/Components/BatteryComponent.cs b/Content.Server/Power/Components/BatteryComponent.cs index f9cd0201ca..7581e9af9b 100644 --- a/Content.Server/Power/Components/BatteryComponent.cs +++ b/Content.Server/Power/Components/BatteryComponent.cs @@ -10,6 +10,7 @@ namespace Content.Server.Power.Components public class BatteryComponent : Component { [Dependency] private readonly IEntityManager _entMan = default!; + public string SolutionName = "battery"; /// /// Maximum charge of the battery in joules (ie. watt seconds) diff --git a/Content.Server/Power/Components/RiggableComponent.cs b/Content.Server/Power/Components/RiggableComponent.cs new file mode 100644 index 0000000000..0983989670 --- /dev/null +++ b/Content.Server/Power/Components/RiggableComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Server.Power.Components; + +[RegisterComponent] +public sealed class RiggableComponent : Component +{ + public const string SolutionName = "battery"; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("isRigged")] + public bool IsRigged; +} diff --git a/Content.Server/Power/EntitySystems/RiggableSystem.cs b/Content.Server/Power/EntitySystems/RiggableSystem.cs new file mode 100644 index 0000000000..9d988f00b9 --- /dev/null +++ b/Content.Server/Power/EntitySystems/RiggableSystem.cs @@ -0,0 +1,81 @@ +using Content.Server.Administration.Logs; +using Content.Server.Chemistry.EntitySystems; +using Content.Server.Explosion.EntitySystems; +using Content.Server.Kitchen.Components; +using Content.Server.Power.Components; +using Content.Server.Stunnable.Components; +using Content.Shared.Database; +using Content.Shared.Rejuvenate; + +namespace Content.Server.Power.EntitySystems; + +/// +/// Handles sabotaged/rigged objects +/// +public sealed class RiggableSystem : EntitySystem +{ + [Dependency] private readonly SolutionContainerSystem _solutionsSystem = default!; + [Dependency] private readonly ExplosionSystem _explosionSystem = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnRejuvenate); + SubscribeLocalEvent(OnMicrowaved); + SubscribeLocalEvent(OnSolutionChanged); + } + + private void OnRejuvenate(EntityUid uid, RiggableComponent component, RejuvenateEvent args) + { + component.IsRigged = false; + } + + private void OnMicrowaved(EntityUid uid, RiggableComponent component, BeingMicrowavedEvent args) + { + if (TryComp(uid, out var batteryComponent)) + { + if (batteryComponent.CurrentCharge == 0) + return; + } + + args.Handled = true; + + // What the fuck are you doing??? + Explode(uid, batteryComponent, args.User); + } + + private void OnSolutionChanged(EntityUid uid, RiggableComponent component, SolutionChangedEvent args) + { + if (TryComp(uid, out var battery)) + { + IsRigged(uid, args); + } + + if (component.IsRigged) + { + _adminLogger.Add(LogType.Explosion, LogImpact.Medium, $"{ToPrettyString(uid)} has been rigged up to explode when used."); + } + } + + public void IsRigged(EntityUid uid, SolutionChangedEvent args) + { + if (TryComp(uid, out var riggableComp)) + { + riggableComp.IsRigged = _solutionsSystem.TryGetSolution(uid, RiggableComponent.SolutionName, out var solution) + && solution.TryGetReagent("Plasma", out var plasma) + && plasma >= 5; + } + } + + public void Explode(EntityUid uid, BatteryComponent? battery = null, EntityUid? cause = null) + { + if (!Resolve(uid, ref battery)) + return; + + var radius = MathF.Min(5, MathF.Sqrt(battery.CurrentCharge) / 9); + + _explosionSystem.TriggerExplosive(uid, radius: radius, user:cause); + QueueDel(uid); + } +} diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index 2ba103a05b..f239af4bdc 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -14,7 +14,6 @@ using Content.Server.Power.EntitySystems; using Content.Server.UserInterface; using Content.Shared.Containers.ItemSlots; using Content.Shared.Popups; -using Content.Shared.Rejuvenate; using Robust.Shared.Timing; namespace Content.Server.PowerCell; @@ -34,14 +33,13 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; [Dependency] private readonly SharedAppearanceSystem _sharedAppearanceSystem = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly RiggableSystem _riggableSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnChargeChanged); - SubscribeLocalEvent(OnSolutionChange); - SubscribeLocalEvent(OnRejuvenate); SubscribeLocalEvent(OnCellExamined); SubscribeLocalEvent(OnUnpaused); @@ -51,13 +49,6 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem // funny SubscribeLocalEvent(OnCellSlotExamined); SubscribeLocalEvent(OnSlotMicrowaved); - - SubscribeLocalEvent(OnMicrowaved); - } - - private void OnRejuvenate(EntityUid uid, PowerCellComponent component, RejuvenateEvent args) - { - component.IsRigged = false; } private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args) @@ -71,22 +62,11 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem RaiseLocalEvent(slot.Item.Value, args); } - private void OnMicrowaved(EntityUid uid, BatteryComponent component, BeingMicrowavedEvent args) - { - if (component.CurrentCharge == 0) - return; - - args.Handled = true; - - // What the fuck are you doing??? - Explode(uid, component, args.User); - } - private void OnChargeChanged(EntityUid uid, PowerCellComponent component, ref ChargeChangedEvent args) { - if (component.IsRigged) + if (TryComp(uid, out var rig) && rig.IsRigged) { - Explode(uid, cause: null); + _riggableSystem.Explode(uid, cause: null); return; } @@ -112,17 +92,6 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem RaiseLocalEvent(uid, ref ev); } - private void Explode(EntityUid uid, BatteryComponent? battery = null, EntityUid? cause = null) - { - if (!Resolve(uid, ref battery)) - return; - - var radius = MathF.Min(5, MathF.Sqrt(battery.CurrentCharge) / 9); - - _explosionSystem.TriggerExplosive(uid, radius: radius, user:cause); - QueueDel(uid); - } - #region Activatable /// @@ -258,18 +227,6 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem return false; } - private void OnSolutionChange(EntityUid uid, PowerCellComponent component, SolutionChangedEvent args) - { - component.IsRigged = _solutionsSystem.TryGetSolution(uid, PowerCellComponent.SolutionName, out var solution) - && solution.TryGetReagent("Plasma", out var plasma) - && plasma >= 5; - - if (component.IsRigged) - { - _adminLogger.Add(LogType.Explosion, LogImpact.Medium, $"Power cell {ToPrettyString(uid)} has been rigged up to explode when used."); - } - } - private void OnCellExamined(EntityUid uid, PowerCellComponent component, ExaminedEvent args) { if (TryComp(uid, out var battery)) diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index 97faac5b28..f32ba611af 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -1,4 +1,6 @@ +using Content.Server.Chemistry.EntitySystems; using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; using Content.Server.Power.Events; using Content.Server.Stunnable.Components; using Content.Shared.Audio; @@ -10,7 +12,6 @@ using Content.Shared.Item; using Content.Shared.Popups; using Content.Shared.Toggleable; using Content.Shared.Weapons.Melee.Events; -using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Player; @@ -20,6 +21,7 @@ namespace Content.Server.Stunnable.Systems { [Dependency] private readonly SharedItemSystem _item = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly RiggableSystem _riggableSystem = default!; public override void Initialize() { @@ -27,6 +29,7 @@ namespace Content.Server.Stunnable.Systems SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnStaminaHitAttempt); SubscribeLocalEvent(OnGetMeleeDamage); } @@ -100,17 +103,25 @@ namespace Content.Server.Stunnable.Systems private void TurnOn(EntityUid uid, StunbatonComponent comp, EntityUid user) { + if (comp.Activated) return; var playerFilter = Filter.Pvs(comp.Owner, entityManager: EntityManager); if (!TryComp(comp.Owner, out var battery) || battery.CurrentCharge < comp.EnergyPerUse) { + SoundSystem.Play(comp.TurnOnFailSound.GetSound(), playerFilter, comp.Owner, AudioHelpers.WithVariation(0.25f)); user.PopupMessage(Loc.GetString("stunbaton-component-low-charge")); return; } + if (TryComp(uid, out var rig) && rig.IsRigged) + { + _riggableSystem.Explode(uid, battery, user); + } + + if (EntityManager.TryGetComponent(comp.Owner, out var appearance) && EntityManager.TryGetComponent(comp.Owner, out var item)) { @@ -122,6 +133,16 @@ namespace Content.Server.Stunnable.Systems comp.Activated = true; } + // https://github.com/space-wizards/space-station-14/pull/17288#discussion_r1241213341 + private void OnSolutionChange(EntityUid uid, StunbatonComponent component, SolutionChangedEvent args) + { + // Explode if baton is activated and rigged. + if (TryComp(uid, out var riggable)) + if (TryComp(uid, out var battery)) + if (component.Activated && riggable.IsRigged) + _riggableSystem.Explode(uid, battery); + } + private void SendPowerPulse(EntityUid target, EntityUid? user, EntityUid used) { RaiseLocalEvent(target, new PowerPulseEvent() diff --git a/Content.Shared/PowerCell/Components/PowerCellComponent.cs b/Content.Shared/PowerCell/Components/PowerCellComponent.cs index 3f353c1352..52e89fed02 100644 --- a/Content.Shared/PowerCell/Components/PowerCellComponent.cs +++ b/Content.Shared/PowerCell/Components/PowerCellComponent.cs @@ -11,12 +11,7 @@ namespace Content.Shared.PowerCell; [RegisterComponent] public sealed class PowerCellComponent : Component { - public const string SolutionName = "powerCell"; public const int PowerCellVisualsLevels = 2; - - // Not networked to clients - [ViewVariables(VVAccess.ReadWrite)] - public bool IsRigged { get; set; } } [Serializable, NetSerializable] diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index 28ebbb8d5c..8ea097e479 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -14,12 +14,12 @@ sprite: Objects/Power/power_cells.rsi - type: SolutionContainerManager solutions: - powerCell: + battery: maxVol: 5 - type: InjectableSolution - solution: powerCell + solution: battery - type: DrawableSolution - solution: powerCell + solution: battery - type: Extractable juiceSolution: reagents: @@ -30,6 +30,7 @@ - DroneUsable - type: Appearance - type: PowerCellVisuals + - type: Riggable - type: entity name: potato battery diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index cce3002e14..2ac431b873 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -43,6 +43,19 @@ False: {state: stunbaton_off} - type: StaticPrice price: 100 + - type: Riggable + - type: SolutionContainerManager + solutions: + battery: + maxVol: 5 + - type: InjectableSolution + solution: battery + - type: DrawableSolution + solution: battery + - type: Explosive + explosionType: Default + intensitySlope: 1.5 + maxIntensity: 200 - type: entity name: flash