ReagentDispenser ECS (#11418)

This commit is contained in:
0x6273
2022-10-04 02:57:32 +02:00
committed by GitHub
parent f89b4f0a1d
commit 0c24f8b69b
17 changed files with 351 additions and 640 deletions

View File

@@ -1,118 +0,0 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.FixedPoint;
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry.Dispenser
{
/// <summary>
/// Shared class for <c>ReagentDispenserComponent</c>. Provides a way for entities to dispense and remove reagents from other entities with SolutionComponents via a user interface.
/// <para>This is useful for machines such as the chemical dispensers, booze dispensers, or soda dispensers.</para>
/// <para>The chemicals which may be dispensed are defined by specifying a reagent pack. See <see cref="ReagentDispenserInventoryPrototype"/> for more information on that.</para>
/// </summary>
[Virtual]
public class SharedReagentDispenserComponent : Component
{
public const string BeakerSlotId = "ReagentDispenser-beaker";
[DataField("beakerSlot")]
public ItemSlot BeakerSlot = new();
/// <summary>
/// A list of reagents which this may dispense. Defined in yaml prototype, see <see cref="ReagentDispenserInventoryPrototype"/>.
/// </summary>
public readonly List<ReagentDispenserInventoryEntry> Inventory = new();
[Serializable, NetSerializable]
public sealed class ReagentDispenserBoundUserInterfaceState : BoundUserInterfaceState
{
public readonly bool HasPower;
public readonly bool HasBeaker;
public readonly FixedPoint2 BeakerCurrentVolume;
public readonly FixedPoint2 BeakerMaxVolume;
public readonly string ContainerName;
/// <summary>
/// A list of the reagents which this dispenser can dispense.
/// </summary>
public readonly List<ReagentDispenserInventoryEntry> Inventory;
/// <summary>
/// A list of the reagents and their amounts within the beaker/reagent container, if applicable.
/// </summary>
public readonly List<Components.Solution.ReagentQuantity>? ContainerReagents;
public readonly string DispenserName;
public readonly FixedPoint2 SelectedDispenseAmount;
public ReagentDispenserBoundUserInterfaceState(bool hasPower, bool hasBeaker, FixedPoint2 beakerCurrentVolume, FixedPoint2 beakerMaxVolume, string containerName,
List<ReagentDispenserInventoryEntry> inventory, string dispenserName, List<Components.Solution.ReagentQuantity>? containerReagents, FixedPoint2 selectedDispenseAmount)
{
HasPower = hasPower;
HasBeaker = hasBeaker;
BeakerCurrentVolume = beakerCurrentVolume;
BeakerMaxVolume = beakerMaxVolume;
ContainerName = containerName;
Inventory = inventory;
DispenserName = dispenserName;
ContainerReagents = containerReagents;
SelectedDispenseAmount = selectedDispenseAmount;
}
}
/// <summary>
/// Message data sent from client to server when a dispenser ui button is pressed.
/// </summary>
[Serializable, NetSerializable]
public sealed class UiButtonPressedMessage : BoundUserInterfaceMessage
{
public readonly UiButton Button;
public readonly int DispenseIndex; //Index of dispense button / reagent being pressed. Only used when a dispense button is pressed.
public UiButtonPressedMessage(UiButton button, int dispenseIndex)
{
Button = button;
DispenseIndex = dispenseIndex;
}
}
[Serializable, NetSerializable]
public enum ReagentDispenserUiKey
{
Key
}
/// <summary>
/// Used in <see cref="UiButtonPressedMessage"/> to specify which button was pressed.
/// </summary>
public enum UiButton
{
Clear,
SetDispenseAmount1,
SetDispenseAmount5,
SetDispenseAmount10,
SetDispenseAmount15,
SetDispenseAmount20,
SetDispenseAmount25,
SetDispenseAmount30,
SetDispenseAmount50,
SetDispenseAmount100,
/// <summary>
/// Used when any dispense button is pressed. Such as "Carbon", or "Oxygen" buttons on the chem dispenser.
/// The index of the reagent attached to that dispense button is sent as <see cref="UiButtonPressedMessage.DispenseIndex"/>.
/// </summary>
Dispense
}
/// <summary>
/// Information about a reagent which the dispenser can dispense.
/// </summary>
[Serializable, NetSerializable]
public struct ReagentDispenserInventoryEntry
{
public readonly string ID;
public ReagentDispenserInventoryEntry(string id)
{
ID = id;
}
}
}
}

View File

@@ -1,30 +0,0 @@
using JetBrains.Annotations;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Chemistry.Dispenser;
namespace Content.Shared.Chemistry.EntitySystems
{
[UsedImplicitly]
public abstract class SharedReagentDispenserSystem : EntitySystem
{
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SharedReagentDispenserComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<SharedReagentDispenserComponent, ComponentRemove>(OnComponentRemove);
}
private void OnComponentInit(EntityUid uid, SharedReagentDispenserComponent component, ComponentInit args)
{
_itemSlotsSystem.AddItemSlot(uid, SharedReagentDispenserComponent.BeakerSlotId, component.BeakerSlot);
}
private void OnComponentRemove(EntityUid uid, SharedReagentDispenserComponent component, ComponentRemove args)
{
_itemSlotsSystem.RemoveItemSlot(uid, component.BeakerSlot);
}
}
}

View File

@@ -159,7 +159,6 @@ namespace Content.Shared.Chemistry
/// A list of the reagents and their amounts within the buffer, if applicable.
/// </summary>
public readonly IReadOnlyList<Solution.ReagentQuantity> BufferReagents;
public readonly string DispenserName;
public readonly ChemMasterMode Mode;
@@ -171,14 +170,12 @@ namespace Content.Shared.Chemistry
public readonly bool UpdateLabel;
public ChemMasterBoundUserInterfaceState(
ChemMasterMode mode, string dispenserName,
ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
ChemMasterMode mode, ContainerInfo? inputContainerInfo, ContainerInfo? outputContainerInfo,
IReadOnlyList<Solution.ReagentQuantity> bufferReagents, FixedPoint2 bufferCurrentVolume,
uint selectedPillType, uint pillDosageLimit, bool updateLabel)
{
InputContainerInfo = inputContainerInfo;
OutputContainerInfo = outputContainerInfo;
DispenserName = dispenserName;
BufferReagents = bufferReagents;
Mode = mode;
BufferCurrentVolume = bufferCurrentVolume;

View File

@@ -0,0 +1,78 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry
{
/// <summary>
/// This class holds constants that are shared between client and server.
/// </summary>
public sealed class SharedReagentDispenser
{
public const string OutputSlotName = "beakerSlot";
}
[Serializable, NetSerializable]
public sealed class ReagentDispenserSetDispenseAmountMessage : BoundUserInterfaceMessage
{
public readonly ReagentDispenserDispenseAmount ReagentDispenserDispenseAmount;
public ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount amount)
{
ReagentDispenserDispenseAmount = amount;
}
}
[Serializable, NetSerializable]
public sealed class ReagentDispenserDispenseReagentMessage : BoundUserInterfaceMessage
{
public readonly string ReagentId;
public ReagentDispenserDispenseReagentMessage(string reagentId)
{
ReagentId = reagentId;
}
}
[Serializable, NetSerializable]
public sealed class ReagentDispenserClearContainerSolutionMessage : BoundUserInterfaceMessage
{
}
public enum ReagentDispenserDispenseAmount
{
U1 = 1,
U5 = 5,
U10 = 10,
U15 = 15,
U20 = 20,
U25 = 25,
U30 = 30,
U50 = 50,
U100 = 100,
}
[Serializable, NetSerializable]
public sealed class ReagentDispenserBoundUserInterfaceState : BoundUserInterfaceState
{
public readonly ContainerInfo? OutputContainer;
/// <summary>
/// A list of the reagents which this dispenser can dispense.
/// </summary>
public readonly List<string> Inventory;
public readonly ReagentDispenserDispenseAmount SelectedDispenseAmount;
public ReagentDispenserBoundUserInterfaceState(ContainerInfo? outputContainer, List<string> inventory, ReagentDispenserDispenseAmount selectedDispenseAmount)
{
OutputContainer = outputContainer;
Inventory = inventory;
SelectedDispenseAmount = selectedDispenseAmount;
}
}
[Serializable, NetSerializable]
public enum ReagentDispenserUiKey
{
Key
}
}