Adds "Add Reagent" admin verb.

This commit is contained in:
Pieter-Jan Briers
2021-01-23 16:45:20 +01:00
parent fd7fcbadda
commit ae91059c0b
3 changed files with 307 additions and 3 deletions

View File

@@ -0,0 +1,172 @@
using Content.Client.Eui;
using Content.Shared.Administration;
using Content.Shared.Chemistry;
using Content.Shared.Eui;
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface
{
[UsedImplicitly]
public sealed class AdminAddReagentEui : BaseEui
{
[Dependency] private readonly IPrototypeManager _prototypes = default!;
private readonly Menu _window;
private bool _closed;
public AdminAddReagentEui()
{
_window = new Menu(this);
_window.OnClose += () => SendMessage(new AdminAddReagentEuiMsg.Close());
}
public override void Opened()
{
_window.OpenCentered();
}
public override void Closed()
{
_closed = true;
_window.Close();
}
public override void HandleState(EuiStateBase state)
{
_window.HandleState((AdminAddReagentEuiState) state);
}
private void DoAdd(bool close, string reagentId, ReagentUnit amount)
{
SendMessage(new AdminAddReagentEuiMsg.DoAdd
{
Amount = amount,
ReagentId = reagentId,
CloseAfter = close
});
}
private sealed class Menu : SS14Window
{
private readonly AdminAddReagentEui _eui;
private readonly Label _volumeLabel;
private readonly LineEdit _reagentIdEdit;
private readonly LineEdit _amountEdit;
private readonly Label _errorLabel;
private readonly Button _addButton;
private readonly Button _addCloseButton;
public Menu(AdminAddReagentEui eui)
{
_eui = eui;
Title = Loc.GetString("Add reagent...");
Contents.AddChild(new VBoxContainer
{
Children =
{
new GridContainer
{
Columns = 2,
Children =
{
new Label {Text = Loc.GetString("Cur volume: ")},
(_volumeLabel = new Label()),
new Label {Text = Loc.GetString("Reagent: ")},
(_reagentIdEdit = new LineEdit {PlaceHolder = Loc.GetString("Reagent ID...")}),
new Label {Text = Loc.GetString("Amount: ")},
(_amountEdit = new LineEdit
{
PlaceHolder = Loc.GetString("A number..."),
SizeFlagsHorizontal = SizeFlags.FillExpand
}),
},
SizeFlagsHorizontal = SizeFlags.FillExpand,
SizeFlagsVertical = SizeFlags.FillExpand
},
new HBoxContainer
{
Children =
{
(_errorLabel = new Label
{
SizeFlagsHorizontal = SizeFlags.FillExpand,
ClipText = true
}),
(_addButton = new Button {Text = Loc.GetString("Add")}),
(_addCloseButton = new Button {Text = Loc.GetString("Add & Close")})
}
}
}
});
_reagentIdEdit.OnTextChanged += _ => CheckErrors();
_amountEdit.OnTextChanged += _ => CheckErrors();
_addButton.OnPressed += _ => DoAdd(false);
_addCloseButton.OnPressed += _ => DoAdd(true);
CheckErrors();
}
private void DoAdd(bool close)
{
_eui.DoAdd(
close,
_reagentIdEdit.Text,
ReagentUnit.New(float.Parse(_amountEdit.Text)));
}
private void CheckErrors()
{
if (string.IsNullOrWhiteSpace(_reagentIdEdit.Text))
{
DoError(Loc.GetString("Must specify reagent ID"));
return;
}
if (!_eui._prototypes.HasIndex<ReagentPrototype>(_reagentIdEdit.Text))
{
DoError(Loc.GetString("'{0}' does not exist.", _reagentIdEdit.Text));
return;
}
if (string.IsNullOrWhiteSpace(_amountEdit.Text))
{
DoError(Loc.GetString("Must specify reagent amount"));
return;
}
if (!float.TryParse(_amountEdit.Text, out _))
{
DoError(Loc.GetString("Invalid amount"));
return;
}
_addButton.Disabled = false;
_addCloseButton.Disabled = false;
_errorLabel.Text = "";
void DoError(string text)
{
_errorLabel.Text = text;
_addButton.Disabled = true;
_addCloseButton.Disabled = true;
}
}
public void HandleState(AdminAddReagentEuiState state)
{
_volumeLabel.Text = Loc.GetString("{0}/{1}u", state.CurVolume, state.MaxVolume);
}
}
}
}

View File

@@ -1,11 +1,18 @@
#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
@@ -58,7 +65,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
return;
}
var transferQuantity = ReagentUnit.Min(component.MaxVolume - component.CurrentVolume, handSolutionComp.CurrentVolume, ReagentUnit.New(10));
var transferQuantity = ReagentUnit.Min(component.MaxVolume - component.CurrentVolume,
handSolutionComp.CurrentVolume, ReagentUnit.New(10));
if (transferQuantity <= 0)
{
@@ -108,14 +116,15 @@ namespace Content.Server.GameObjects.Components.Chemistry
return;
}
if(!hands.GetActiveHand.Owner.TryGetComponent<SolutionContainerComponent>(out var handSolutionComp) ||
if (!hands.GetActiveHand.Owner.TryGetComponent<SolutionContainerComponent>(out var handSolutionComp) ||
!handSolutionComp.CanAddSolutions ||
!component.CanRemoveSolutions)
{
return;
}
var transferQuantity = ReagentUnit.Min(handSolutionComp.MaxVolume - handSolutionComp.CurrentVolume, component.CurrentVolume, ReagentUnit.New(10));
var transferQuantity = ReagentUnit.Min(handSolutionComp.MaxVolume - handSolutionComp.CurrentVolume,
component.CurrentVolume, ReagentUnit.New(10));
if (transferQuantity <= 0)
{
@@ -126,5 +135,97 @@ namespace Content.Server.GameObjects.Components.Chemistry
handSolutionComp.TryAddSolution(transferSolution);
}
}
[Verb]
private sealed class AdminAddReagentVerb : Verb<SolutionContainerComponent>
{
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<IAdminManager>();
if (user.TryGetComponent<IActorComponent>(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<IAdminManager>();
if (user.TryGetComponent<IActorComponent>(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<EuiManager>();
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;
}
}
}
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using Content.Shared.Chemistry;
using Content.Shared.Eui;
using Robust.Shared.Serialization;
namespace Content.Shared.Administration
{
[Serializable, NetSerializable]
public sealed class AdminAddReagentEuiState : EuiStateBase
{
public ReagentUnit MaxVolume;
public ReagentUnit CurVolume;
}
public static class AdminAddReagentEuiMsg
{
[Serializable, NetSerializable]
public sealed class Close : EuiMessageBase
{
}
[Serializable, NetSerializable]
public sealed class DoAdd : EuiMessageBase
{
public bool CloseAfter;
public ReagentUnit Amount;
public string ReagentId;
}
}
}