From 7b590122b652096528ec69921924b3db22b27f6a Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:17:10 +0000 Subject: [PATCH] fire extinguisher using item toggle (#29906) * move SprayAttemptEvent to shared * add SolutionTransferredEvent * replace FireExtinguisher with SpraySafety * update fire extinguisher yml * invert visuals * always handle event in solution transfer, it makes popups * instantly fill it * untroll --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Extinguisher/FireExtinguisherComponent.cs | 7 - .../Extinguisher/FireExtinguisherComponent.cs | 10 -- .../Extinguisher/FireExtinguisherSystem.cs | 139 ------------------ .../Fluids/EntitySystems/SpraySystem.cs | 16 +- .../EntitySystems/SolutionTransferSystem.cs | 16 +- .../SharedFireExtinguisherComponent.cs | 25 ---- .../Fluids/Components/SpraySafetyComponent.cs | 24 +++ Content.Shared/Fluids/Events.cs | 12 ++ Content.Shared/Fluids/SpraySafetySystem.cs | 44 ++++++ .../Objects/Misc/fire_extinguisher.yml | 34 +++-- 10 files changed, 118 insertions(+), 209 deletions(-) delete mode 100644 Content.Client/Extinguisher/FireExtinguisherComponent.cs delete mode 100644 Content.Server/Extinguisher/FireExtinguisherComponent.cs delete mode 100644 Content.Server/Extinguisher/FireExtinguisherSystem.cs delete mode 100644 Content.Shared/Extinguisher/SharedFireExtinguisherComponent.cs create mode 100644 Content.Shared/Fluids/Components/SpraySafetyComponent.cs create mode 100644 Content.Shared/Fluids/SpraySafetySystem.cs diff --git a/Content.Client/Extinguisher/FireExtinguisherComponent.cs b/Content.Client/Extinguisher/FireExtinguisherComponent.cs deleted file mode 100644 index 324b05a93d..0000000000 --- a/Content.Client/Extinguisher/FireExtinguisherComponent.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Content.Shared.Extinguisher; -using Robust.Shared.GameStates; - -namespace Content.Client.Extinguisher; - -[RegisterComponent] -public sealed partial class FireExtinguisherComponent : SharedFireExtinguisherComponent; diff --git a/Content.Server/Extinguisher/FireExtinguisherComponent.cs b/Content.Server/Extinguisher/FireExtinguisherComponent.cs deleted file mode 100644 index 991fc76c62..0000000000 --- a/Content.Server/Extinguisher/FireExtinguisherComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Content.Shared.Extinguisher; -using Robust.Shared.GameStates; - -namespace Content.Server.Extinguisher; - -[RegisterComponent] -[Access(typeof(FireExtinguisherSystem))] -public sealed partial class FireExtinguisherComponent : SharedFireExtinguisherComponent -{ -} diff --git a/Content.Server/Extinguisher/FireExtinguisherSystem.cs b/Content.Server/Extinguisher/FireExtinguisherSystem.cs deleted file mode 100644 index b33a1af157..0000000000 --- a/Content.Server/Extinguisher/FireExtinguisherSystem.cs +++ /dev/null @@ -1,139 +0,0 @@ -using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Fluids.EntitySystems; -using Content.Server.Popups; -using Content.Shared.Chemistry.Components; -using Content.Shared.Extinguisher; -using Content.Shared.FixedPoint; -using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; -using Content.Shared.Verbs; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; - -namespace Content.Server.Extinguisher; - -public sealed class FireExtinguisherSystem : EntitySystem -{ - [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnFireExtinguisherInit); - SubscribeLocalEvent(OnUseInHand); - SubscribeLocalEvent(OnAfterInteract); - SubscribeLocalEvent>(OnGetInteractionVerbs); - SubscribeLocalEvent(OnSprayAttempt); - } - - private void OnFireExtinguisherInit(Entity entity, ref ComponentInit args) - { - if (entity.Comp.HasSafety) - { - UpdateAppearance((entity.Owner, entity.Comp)); - } - } - - private void OnUseInHand(Entity entity, ref UseInHandEvent args) - { - if (args.Handled) - return; - - ToggleSafety((entity.Owner, entity.Comp), args.User); - - args.Handled = true; - } - - private void OnAfterInteract(Entity entity, ref AfterInteractEvent args) - { - if (args.Target == null || !args.CanReach) - { - return; - } - - if (args.Handled) - return; - - if (entity.Comp.HasSafety && entity.Comp.Safety) - { - _popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-safety-on-message"), entity.Owner, args.User); - return; - } - - if (args.Target is not { Valid: true } target || - !_solutionContainerSystem.TryGetDrainableSolution(target, out var targetSoln, out var targetSolution) || - !_solutionContainerSystem.TryGetRefillableSolution(entity.Owner, out var containerSoln, out var containerSolution)) - { - return; - } - - args.Handled = true; - - // TODO: why is this copy paste shit here just have fire extinguisher cancel transfer when safety is on - var transfer = containerSolution.AvailableVolume; - if (TryComp(entity.Owner, out var solTrans)) - { - transfer = solTrans.TransferAmount; - } - transfer = FixedPoint2.Min(transfer, targetSolution.Volume); - - if (transfer > 0) - { - var drained = _solutionContainerSystem.Drain(target, targetSoln.Value, transfer); - _solutionContainerSystem.TryAddSolution(containerSoln.Value, drained); - - _audio.PlayPvs(entity.Comp.RefillSound, entity.Owner); - _popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", entity.Owner)), - entity.Owner, args.Target.Value); - } - } - - private void OnGetInteractionVerbs(Entity entity, ref GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract) - return; - - var user = args.User; - var verb = new InteractionVerb - { - Act = () => ToggleSafety((entity.Owner, entity.Comp), user), - Text = Loc.GetString("fire-extinguisher-component-verb-text"), - }; - - args.Verbs.Add(verb); - } - - private void OnSprayAttempt(Entity entity, ref SprayAttemptEvent args) - { - if (entity.Comp.HasSafety && entity.Comp.Safety) - { - _popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-safety-on-message"), entity, args.User); - args.Cancel(); - } - } - - private void UpdateAppearance(Entity entity) - { - if (!Resolve(entity, ref entity.Comp2, false)) - return; - - if (entity.Comp1.HasSafety) - { - _appearance.SetData(entity, FireExtinguisherVisuals.Safety, entity.Comp1.Safety, entity.Comp2); - } - } - - public void ToggleSafety(Entity extinguisher, EntityUid user) - { - if (!Resolve(extinguisher, ref extinguisher.Comp)) - return; - - extinguisher.Comp.Safety = !extinguisher.Comp.Safety; - _audio.PlayPvs(extinguisher.Comp.SafetySound, extinguisher, AudioParams.Default.WithVariation(0.125f).WithVolume(-4f)); - UpdateAppearance((extinguisher.Owner, extinguisher.Comp)); - } -} diff --git a/Content.Server/Fluids/EntitySystems/SpraySystem.cs b/Content.Server/Fluids/EntitySystems/SpraySystem.cs index 5499070738..215ed7c33f 100644 --- a/Content.Server/Fluids/EntitySystems/SpraySystem.cs +++ b/Content.Server/Fluids/EntitySystems/SpraySystem.cs @@ -1,11 +1,11 @@ using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Chemistry.EntitySystems; -using Content.Server.Extinguisher; using Content.Server.Fluids.Components; using Content.Server.Gravity; using Content.Server.Popups; using Content.Shared.FixedPoint; +using Content.Shared.Fluids; using Content.Shared.Interaction; using Content.Shared.Timing; using Content.Shared.Vapor; @@ -34,7 +34,7 @@ public sealed class SpraySystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnAfterInteract, after: new[] { typeof(FireExtinguisherSystem) }); + SubscribeLocalEvent(OnAfterInteract); } private void OnAfterInteract(Entity entity, ref AfterInteractEvent args) @@ -48,7 +48,7 @@ public sealed class SpraySystem : EntitySystem return; var ev = new SprayAttemptEvent(args.User); - RaiseLocalEvent(entity, ev); + RaiseLocalEvent(entity, ref ev); if (ev.Cancelled) return; @@ -148,13 +148,3 @@ public sealed class SpraySystem : EntitySystem _useDelay.TryResetDelay((entity, useDelay)); } } - -public sealed class SprayAttemptEvent : CancellableEntityEventArgs -{ - public EntityUid User; - - public SprayAttemptEvent(EntityUid user) - { - User = user; - } -} diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs index 3b75392508..e5d8cc5f59 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs @@ -117,6 +117,7 @@ public sealed class SolutionTransferSystem : EntitySystem transferAmount = FixedPoint2.Min(transferAmount, maxRefill); var transferred = Transfer(args.User, target, targetSoln.Value, uid, ownerSoln.Value, transferAmount); + args.Handled = true; if (transferred > 0) { var toTheBrim = ownerRefill.AvailableVolume == 0; @@ -125,8 +126,6 @@ public sealed class SolutionTransferSystem : EntitySystem : "comp-solution-transfer-fill-normal"; _popup.PopupClient(Loc.GetString(msg, ("owner", args.Target), ("amount", transferred), ("target", uid)), uid, args.User); - - args.Handled = true; return; } } @@ -143,13 +142,11 @@ public sealed class SolutionTransferSystem : EntitySystem transferAmount = FixedPoint2.Min(transferAmount, maxRefill); var transferred = Transfer(args.User, uid, ownerSoln.Value, target, targetSoln.Value, transferAmount); - + args.Handled = true; if (transferred > 0) { var message = Loc.GetString("comp-solution-transfer-transfer-solution", ("amount", transferred), ("target", target)); _popup.PopupClient(message, uid, args.User); - - args.Handled = true; } } } @@ -202,6 +199,9 @@ public sealed class SolutionTransferSystem : EntitySystem var solution = _solution.SplitSolution(source, actualAmount); _solution.AddSolution(target, solution); + var ev = new SolutionTransferredEvent(sourceEntity, targetEntity, user, actualAmount); + RaiseLocalEvent(targetEntity, ref ev); + _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(user):player} transferred {SharedSolutionContainerSystem.ToPrettyString(solution)} to {ToPrettyString(targetEntity):target}, which now contains {SharedSolutionContainerSystem.ToPrettyString(targetSolution)}"); @@ -225,3 +225,9 @@ public record struct SolutionTransferAttemptEvent(EntityUid From, EntityUid To, CancelReason = reason; } } + +/// +/// Raised on the target entity when a non-zero amount of solution gets transferred. +/// +[ByRefEvent] +public record struct SolutionTransferredEvent(EntityUid From, EntityUid To, EntityUid User, FixedPoint2 Amount); diff --git a/Content.Shared/Extinguisher/SharedFireExtinguisherComponent.cs b/Content.Shared/Extinguisher/SharedFireExtinguisherComponent.cs deleted file mode 100644 index dbb1f6f2c4..0000000000 --- a/Content.Shared/Extinguisher/SharedFireExtinguisherComponent.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Robust.Shared.Audio; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Extinguisher; - -[NetworkedComponent] -public abstract partial class SharedFireExtinguisherComponent : Component -{ - [DataField("refillSound")] public SoundSpecifier RefillSound = new SoundPathSpecifier("/Audio/Effects/refill.ogg"); - - [DataField("hasSafety")] public bool HasSafety = true; - - [DataField("safety")] public bool Safety = true; - - [DataField("safetySound")] - public SoundSpecifier SafetySound { get; private set; } = new SoundPathSpecifier("/Audio/Machines/button.ogg"); -} - - -[Serializable, NetSerializable] -public enum FireExtinguisherVisuals : byte -{ - Safety -} diff --git a/Content.Shared/Fluids/Components/SpraySafetyComponent.cs b/Content.Shared/Fluids/Components/SpraySafetyComponent.cs new file mode 100644 index 0000000000..30827d4fd1 --- /dev/null +++ b/Content.Shared/Fluids/Components/SpraySafetyComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Shared.Fluids.Components; + +/// +/// Uses ItemToggle to control safety for a spray item. +/// You can't spray or refill it while safety is on. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SpraySafetySystem))] +public sealed partial class SpraySafetyComponent : Component +{ + /// + /// Popup shown when trying to spray or refill with safety on. + /// + [DataField] + public LocId Popup = "fire-extinguisher-component-safety-on-message"; + + /// + /// Sound to play after refilling. + /// + [DataField] + public SoundSpecifier RefillSound = new SoundPathSpecifier("/Audio/Effects/refill.ogg"); +} diff --git a/Content.Shared/Fluids/Events.cs b/Content.Shared/Fluids/Events.cs index e281de9137..198e888774 100644 --- a/Content.Shared/Fluids/Events.cs +++ b/Content.Shared/Fluids/Events.cs @@ -34,3 +34,15 @@ public sealed partial class AbsorbantDoAfterEvent : DoAfterEvent public override DoAfterEvent Clone() => this; } + +/// +/// Raised when trying to spray something, for example a fire extinguisher. +/// +[ByRefEvent] +public record struct SprayAttemptEvent(EntityUid User, bool Cancelled = false) +{ + public void Cancel() + { + Cancelled = true; + } +} diff --git a/Content.Shared/Fluids/SpraySafetySystem.cs b/Content.Shared/Fluids/SpraySafetySystem.cs new file mode 100644 index 0000000000..82006a995b --- /dev/null +++ b/Content.Shared/Fluids/SpraySafetySystem.cs @@ -0,0 +1,44 @@ +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Fluids.Components; +using Content.Shared.Item.ItemToggle; +using Content.Shared.Popups; +using Robust.Shared.Audio.Systems; + +namespace Content.Shared.Fluids; + +public sealed class SpraySafetySystem : EntitySystem +{ + [Dependency] private readonly ItemToggleSystem _toggle = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnTransferAttempt); + SubscribeLocalEvent(OnTransferred); + SubscribeLocalEvent(OnSprayAttempt); + } + + private void OnTransferAttempt(Entity ent, ref SolutionTransferAttemptEvent args) + { + var (uid, comp) = ent; + if (uid == args.To && !_toggle.IsActivated(uid)) + args.Cancel(Loc.GetString(comp.Popup)); + } + + private void OnTransferred(Entity ent, ref SolutionTransferredEvent args) + { + _audio.PlayPredicted(ent.Comp.RefillSound, ent, args.User); + } + + private void OnSprayAttempt(Entity ent, ref SprayAttemptEvent args) + { + if (!_toggle.IsActivated(ent.Owner)) + { + _popup.PopupEntity(Loc.GetString(ent.Comp.Popup), ent, args.User); + args.Cancel(); + } + } +} diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 5aaa58dbbe..89b421c97d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -7,8 +7,8 @@ - type: Sprite sprite: Objects/Misc/fire_extinguisher.rsi layers: - - state: fire_extinguisher_closed - map: [ "enabled" ] + - state: fire_extinguisher_closed + map: [ "enum.ToggleVisuals.Layer" ] - type: Item sprite: Objects/Misc/fire_extinguisher.rsi size: Normal @@ -24,6 +24,8 @@ - type: DrainableSolution solution: spray - type: SolutionTransfer + maxTransferAmount: 100 + transferAmount: 100 - type: UseDelay - type: Spray transferAmount: 10 @@ -34,8 +36,20 @@ vaporAmount: 3 vaporSpread: 90 sprayVelocity: 2.0 - - type: FireExtinguisher - hasSafety: true + - type: ItemToggle + soundActivate: + path: /Audio/Machines/button.ogg + params: + variation: 0.125 + volume: -4 + soundDeactivate: + path: /Audio/Machines/button.ogg + params: + variation: 0.125 + volume: -4 + - type: ToggleVerb + text: fire-extinguisher-component-verb-text + - type: SpraySafety - type: MeleeWeapon wideAnimationRotation: 180 damage: @@ -46,14 +60,14 @@ - type: Tool qualities: - Rolling - speedModifier: 0.5 # its very big, akward to use + speedModifier: 0.5 # its very big, awkward to use - type: Appearance - type: GenericVisualizer visuals: - enum.FireExtinguisherVisuals.Safety: - enabled: - True: { state: fire_extinguisher_closed } - False: { state: fire_extinguisher_open } + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { state: fire_extinguisher_open } + False: { state: fire_extinguisher_closed } - type: PhysicalComposition materialComposition: Steel: 100 @@ -107,4 +121,4 @@ - type: PhysicalComposition materialComposition: Steel: 50 - Glass: 40 \ No newline at end of file + Glass: 40