diff --git a/Content.Server/Chemistry/Components/InjectorComponent.cs b/Content.Server/Chemistry/Components/InjectorComponent.cs index 466f49a22a..4783cc4c21 100644 --- a/Content.Server/Chemistry/Components/InjectorComponent.cs +++ b/Content.Server/Chemistry/Components/InjectorComponent.cs @@ -1,6 +1,9 @@ using System.Threading; using Content.Shared.Chemistry.Components; using Content.Shared.FixedPoint; +using Content.Server.UserInterface; +using Robust.Server.GameObjects; +using Content.Shared.Chemistry; namespace Content.Server.Chemistry.Components { @@ -22,6 +25,20 @@ namespace Content.Server.Chemistry.Components [DataField("injectOnly")] public bool InjectOnly; + /// + /// The minimum amount of solution that can be transferred at once from this solution. + /// + [DataField("minTransferAmount")] + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 MinimumTransferAmount { get; set; } = FixedPoint2.New(5); + + /// + /// The maximum amount of solution that can be transferred at once from this solution. + /// + [DataField("maxTransferAmount")] + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 MaximumTransferAmount { get; set; } = FixedPoint2.New(50); + /// /// Amount to inject or draw on each usage. If the injector is inject only, it will /// attempt to inject it's entire contents upon use. diff --git a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs b/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs index db61b9f522..caf2327af1 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs @@ -15,13 +15,22 @@ using Content.Shared.MobState.Components; using Robust.Shared.GameStates; using Robust.Shared.Player; using System.Threading; +using Content.Shared.Verbs; +using Robust.Server.GameObjects; +using Content.Shared.Popups; namespace Content.Server.Chemistry.EntitySystems; public sealed partial class ChemistrySystem { + + /// + /// Default transfer amounts for the set-transfer verb. + /// + public static readonly List TransferAmounts = new() { 5, 10, 15}; private void InitializeInjector() { + SubscribeLocalEvent>(AddSetTransferVerbs); SubscribeLocalEvent(OnSolutionChange); SubscribeLocalEvent(OnInjectorDeselected); SubscribeLocalEvent(OnInjectorStartup); @@ -33,6 +42,38 @@ public sealed partial class ChemistrySystem SubscribeLocalEvent(OnInjectionCancelled); } + private void AddSetTransferVerbs(EntityUid uid, InjectorComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands == null) + return; + + if (!EntityManager.TryGetComponent(args.User, out var actor)) + return; + + // Add specific transfer verbs according to the container's size + var priority = 0; + foreach (var amount in TransferAmounts) + { + if ( amount < component.MinimumTransferAmount.Int() || amount > component.MaximumTransferAmount.Int()) + continue; + + AlternativeVerb verb = new(); + verb.Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)); + verb.Category = VerbCategory.SetTransferAmount; + verb.Act = () => + { + component.TransferAmount = FixedPoint2.New(amount); + args.User.PopupMessage(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount))); + }; + + // we want to sort by size, not alphabetically by the verb text. + verb.Priority = priority; + priority--; + + args.Verbs.Add(verb); + } + } + private static void OnInjectionCancelled(InjectionCancelledEvent ev) { ev.Component.CancelToken = null; @@ -196,6 +237,10 @@ public sealed partial class ChemistrySystem return; var actualDelay = MathF.Max(component.Delay, 1f); + + // Injections take 1 second longer per additional 5u + actualDelay += (float) component.TransferAmount / component.Delay - 1; + if (user != target) { // Create a pop-up for the target