Fire extinguisher/spray refactor (#6314)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -1,115 +1,22 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Extinguisher;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Server.Extinguisher
|
||||
namespace Content.Server.Extinguisher;
|
||||
|
||||
[RegisterComponent]
|
||||
[Friend(typeof(FireExtinguisherSystem))]
|
||||
public class FireExtinguisherComponent : Component
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
[ComponentReference(typeof(SharedFireExtinguisherComponent))]
|
||||
public class FireExtinguisherComponent : SharedFireExtinguisherComponent, IAfterInteract, IActivate, IDropped
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
public override string Name => "FireExtinguisher";
|
||||
|
||||
public override string Name => "FireExtinguisher";
|
||||
[DataField("refillSound")] public SoundSpecifier RefillSound = new SoundPathSpecifier("/Audio/Effects/refill.ogg");
|
||||
|
||||
[DataField("refillSound")]
|
||||
SoundSpecifier _refillSound = new SoundPathSpecifier("/Audio/Effects/refill.ogg");
|
||||
[DataField("hasSafety")]
|
||||
private bool _hasSafety;
|
||||
[DataField("safety")]
|
||||
private bool _safety = true;
|
||||
[DataField("safetySound")]
|
||||
public SoundSpecifier SafetySound { get; } = new SoundPathSpecifier("/Audio/Machines/button.ogg");
|
||||
[DataField("hasSafety")] public bool HasSafety = true;
|
||||
|
||||
// Higher priority than sprays.
|
||||
int IAfterInteract.Priority => 1;
|
||||
[DataField("safety")] public bool Safety = true;
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
if (_hasSafety)
|
||||
{
|
||||
SetSafety(Owner, _safety);
|
||||
}
|
||||
}
|
||||
|
||||
async Task<bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||
{
|
||||
var solutionContainerSystem = EntitySystem.Get<SolutionContainerSystem>();
|
||||
if (eventArgs.Target == null || !eventArgs.CanReach)
|
||||
{
|
||||
if (_hasSafety && _safety)
|
||||
{
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-safety-on-message"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eventArgs.Target is not {Valid: true} target ||
|
||||
!_entMan.HasComponent<ReagentTankComponent>(target) ||
|
||||
!solutionContainerSystem.TryGetDrainableSolution(target, out var targetSolution) ||
|
||||
!solutionContainerSystem.TryGetDrainableSolution(Owner, out var container))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var transfer = FixedPoint2.Min(container.AvailableVolume, targetSolution.DrainAvailable);
|
||||
if (transfer > 0)
|
||||
{
|
||||
var drained = solutionContainerSystem.Drain(target, targetSolution, transfer);
|
||||
solutionContainerSystem.TryAddSolution(Owner, container, drained);
|
||||
|
||||
SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner);
|
||||
eventArgs.Target.Value.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("fire-extingusiher-component-after-interact-refilled-message", ("owner", Owner)));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
ToggleSafety(eventArgs.User);
|
||||
}
|
||||
|
||||
private void ToggleSafety(EntityUid user)
|
||||
{
|
||||
SoundSystem.Play(Filter.Pvs(Owner), SafetySound.GetSound(), Owner, AudioHelpers.WithVariation(0.125f).WithVolume(-4f));
|
||||
SetSafety(user, !_safety);
|
||||
}
|
||||
|
||||
private void SetSafety(EntityUid user, bool state)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user) || !_hasSafety)
|
||||
return;
|
||||
|
||||
_safety = state;
|
||||
|
||||
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance))
|
||||
appearance.SetData(FireExtinguisherVisuals.Safety, _safety);
|
||||
}
|
||||
|
||||
void IDropped.Dropped(DroppedEventArgs eventArgs)
|
||||
{
|
||||
if (_hasSafety && _entMan.TryGetComponent(Owner, out AppearanceComponent? appearance))
|
||||
appearance.SetData(FireExtinguisherVisuals.Safety, _safety);
|
||||
}
|
||||
}
|
||||
[DataField("safetySound")]
|
||||
public SoundSpecifier SafetySound { get; } = new SoundPathSpecifier("/Audio/Machines/button.ogg");
|
||||
}
|
||||
|
||||
156
Content.Server/Extinguisher/FireExtinguisherSystem.cs
Normal file
156
Content.Server/Extinguisher/FireExtinguisherSystem.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.CharacterAppearance.Systems;
|
||||
using Content.Shared.Extinguisher;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Extinguisher;
|
||||
|
||||
public class FireExtinguisherSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, ComponentInit>(OnFireExtinguisherInit);
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, DroppedEvent>(OnDropped);
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, UseInHandEvent>(OnUseInHand);
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, GetInteractionVerbsEvent>(OnGetInteractionVerbs);
|
||||
SubscribeLocalEvent<FireExtinguisherComponent, SprayAttemptEvent>(OnSprayAttempt);
|
||||
}
|
||||
|
||||
private void OnFireExtinguisherInit(EntityUid uid, FireExtinguisherComponent component, ComponentInit args)
|
||||
{
|
||||
if (component.HasSafety)
|
||||
{
|
||||
UpdateAppearance(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDropped(EntityUid uid, FireExtinguisherComponent component, DroppedEvent args)
|
||||
{
|
||||
// idk why this has to be done??????????
|
||||
UpdateAppearance(uid, component);
|
||||
}
|
||||
|
||||
private void OnUseInHand(EntityUid uid, FireExtinguisherComponent component, UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
ToggleSafety(uid, args.User, component);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, FireExtinguisherComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Target == null || !args.CanReach)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
if (component.HasSafety && component.Safety)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-safety-on-message"), uid,
|
||||
Filter.Entities(args.User));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Target is not {Valid: true} target ||
|
||||
!_solutionContainerSystem.TryGetDrainableSolution(target, out var targetSolution) ||
|
||||
!_solutionContainerSystem.TryGetRefillableSolution(uid, out var container))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var transfer = container.AvailableVolume;
|
||||
if (TryComp<SolutionTransferComponent>(uid, out var solTrans))
|
||||
{
|
||||
transfer = solTrans.TransferAmount;
|
||||
}
|
||||
transfer = FixedPoint2.Min(transfer, targetSolution.DrainAvailable);
|
||||
|
||||
if (transfer > 0)
|
||||
{
|
||||
var drained = _solutionContainerSystem.Drain(target, targetSolution, transfer);
|
||||
_solutionContainerSystem.TryAddSolution(uid, container, drained);
|
||||
|
||||
SoundSystem.Play(Filter.Pvs(uid), component.RefillSound.GetSound(), uid);
|
||||
_popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", uid)),
|
||||
uid, Filter.Entities(args.Target.Value));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetInteractionVerbs(EntityUid uid, FireExtinguisherComponent component, GetInteractionVerbsEvent args)
|
||||
{
|
||||
if (!args.CanInteract)
|
||||
return;
|
||||
|
||||
var verb = new Verb
|
||||
{
|
||||
Act = () => ToggleSafety(uid, args.User, component),
|
||||
Text = Loc.GetString("fire-extinguisher-component-verb-text"),
|
||||
};
|
||||
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void OnSprayAttempt(EntityUid uid, FireExtinguisherComponent component, SprayAttemptEvent args)
|
||||
{
|
||||
if (component.HasSafety && component.Safety)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("fire-extinguisher-component-safety-on-message"), uid,
|
||||
Filter.Entities(args.User));
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, FireExtinguisherComponent comp,
|
||||
AppearanceComponent? appearance=null)
|
||||
{
|
||||
if (!Resolve(uid, ref appearance, false))
|
||||
return;
|
||||
|
||||
if (comp.HasSafety)
|
||||
{
|
||||
appearance.SetData(FireExtinguisherVisuals.Safety, comp.Safety);
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleSafety(EntityUid uid, EntityUid user,
|
||||
FireExtinguisherComponent? extinguisher = null)
|
||||
{
|
||||
if (!Resolve(uid, ref extinguisher))
|
||||
return;
|
||||
|
||||
if (!_actionBlockerSystem.CanInteract(user) || !extinguisher.HasSafety)
|
||||
return;
|
||||
|
||||
extinguisher.Safety = !extinguisher.Safety;
|
||||
SoundSystem.Play(Filter.Pvs(uid), extinguisher.SafetySound.GetSound(), uid,
|
||||
AudioHelpers.WithVariation(0.125f).WithVolume(-4f));
|
||||
UpdateAppearance(uid, extinguisher);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user