#nullable enable using Content.Server.Administration; using Content.Server.Eui; using Content.Server.GameObjects.Components.GUI; using Content.Shared.Administration; using Content.Shared.Chemistry; using Content.Shared.Eui; using Content.Shared.GameObjects.Components.Chemistry; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.GameObjects.Verbs; using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; namespace Content.Server.GameObjects.Components.Chemistry { [RegisterComponent] [ComponentReference(typeof(SharedSolutionContainerComponent))] public class SolutionContainerComponent : SharedSolutionContainerComponent { /// /// Transfers solution from the held container to the target container. /// [Verb] private sealed class FillTargetVerb : Verb { protected override void GetData(IEntity user, SolutionContainerComponent component, VerbData data) { if (!ActionBlockerSystem.CanInteract(user) || !user.TryGetComponent(out var hands) || hands.GetActiveHand == null || hands.GetActiveHand.Owner == component.Owner || !hands.GetActiveHand.Owner.TryGetComponent(out var solution) || !solution.CanRemoveSolutions || !component.CanAddSolutions) { data.Visibility = VerbVisibility.Invisible; return; } var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? ""; var myName = component.Owner.Prototype?.Name ?? ""; var locHeldEntityName = Loc.GetString(heldEntityName); var locMyName = Loc.GetString(myName); data.Visibility = VerbVisibility.Visible; data.Text = Loc.GetString("Transfer liquid from [{0}] to [{1}].", locHeldEntityName, locMyName); } protected override void Activate(IEntity user, SolutionContainerComponent component) { if (!user.TryGetComponent(out var hands) || hands.GetActiveHand == null) { return; } if (!hands.GetActiveHand.Owner.TryGetComponent(out var handSolutionComp) || !handSolutionComp.CanRemoveSolutions || !component.CanAddSolutions) { return; } var transferQuantity = ReagentUnit.Min(component.MaxVolume - component.CurrentVolume, handSolutionComp.CurrentVolume, ReagentUnit.New(10)); if (transferQuantity <= 0) { return; } var transferSolution = handSolutionComp.SplitSolution(transferQuantity); component.TryAddSolution(transferSolution); } } /// /// Transfers solution from a target container to the held container. /// [Verb] private sealed class EmptyTargetVerb : Verb { protected override void GetData(IEntity user, SolutionContainerComponent component, VerbData data) { if (!ActionBlockerSystem.CanInteract(user) || !user.TryGetComponent(out var hands) || hands.GetActiveHand == null || hands.GetActiveHand.Owner == component.Owner || !hands.GetActiveHand.Owner.TryGetComponent(out var solution) || !solution.CanAddSolutions || !component.CanRemoveSolutions) { data.Visibility = VerbVisibility.Invisible; return; } var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? ""; var myName = component.Owner.Prototype?.Name ?? ""; var locHeldEntityName = Loc.GetString(heldEntityName); var locMyName = Loc.GetString(myName); data.Visibility = VerbVisibility.Visible; data.Text = Loc.GetString("Transfer liquid from [{0}] to [{1}].", locMyName, locHeldEntityName); return; } protected override void Activate(IEntity user, SolutionContainerComponent component) { if (!user.TryGetComponent(out var hands) || hands.GetActiveHand == null) { return; } if (!hands.GetActiveHand.Owner.TryGetComponent(out var handSolutionComp) || !handSolutionComp.CanAddSolutions || !component.CanRemoveSolutions) { return; } var transferQuantity = ReagentUnit.Min(handSolutionComp.MaxVolume - handSolutionComp.CurrentVolume, component.CurrentVolume, ReagentUnit.New(10)); if (transferQuantity <= 0) { return; } var transferSolution = component.SplitSolution(transferQuantity); handSolutionComp.TryAddSolution(transferSolution); } } [Verb] private sealed class AdminAddReagentVerb : Verb { private const AdminFlags ReqFlags = AdminFlags.Fun; protected override void GetData(IEntity user, SolutionContainerComponent component, VerbData data) { data.Text = Loc.GetString("Add Reagent..."); data.CategoryData = VerbCategories.Debug; data.Visibility = VerbVisibility.Invisible; var adminManager = IoCManager.Resolve(); if (user.TryGetComponent(out var player)) { if (adminManager.HasAdminFlag(player.playerSession, ReqFlags)) { data.Visibility = VerbVisibility.Visible; } } } protected override void Activate(IEntity user, SolutionContainerComponent component) { var groupController = IoCManager.Resolve(); if (user.TryGetComponent(out var player)) { if (groupController.HasAdminFlag(player.playerSession, ReqFlags)) OpenAddReagentMenu(player.playerSession, component); } } private static void OpenAddReagentMenu(IPlayerSession player, SolutionContainerComponent comp) { var euiMgr = IoCManager.Resolve(); euiMgr.OpenEui(new AdminAddReagentEui(comp), player); } private sealed class AdminAddReagentEui : BaseEui { private readonly SolutionContainerComponent _target; [Dependency] private readonly IAdminManager _adminManager = default!; public AdminAddReagentEui(SolutionContainerComponent target) { _target = target; IoCManager.InjectDependencies(this); } public override void Opened() { StateDirty(); } public override EuiStateBase GetNewState() { return new AdminAddReagentEuiState { CurVolume = _target.CurrentVolume, MaxVolume = _target.MaxVolume }; } public override void HandleMessage(EuiMessageBase msg) { switch (msg) { case AdminAddReagentEuiMsg.Close: Close(); break; case AdminAddReagentEuiMsg.DoAdd doAdd: // Double check that user wasn't de-adminned in the mean time... // Or the target was deleted. if (!_adminManager.HasAdminFlag(Player, ReqFlags) || _target.Deleted) { Close(); return; } _target.TryAddReagent(doAdd.ReagentId, doAdd.Amount, out _); StateDirty(); if (doAdd.CloseAfter) Close(); break; } } } } } }