Make reagent dispensers gridinv-based instead of pseudo-listinv (#34205)
This simplifies the code and makes the experience of examining contents easier without the reagent dispenser UI, as well as adding the possibility for dispensers to have items of heterogeneous sizes in them, which would allow configuring reagent dispensers to accept smaller containers such as beakers or vials in order to allow for more types of smaller quantities of reagents, or other flexibilities brought by using a standard storage component.
This commit is contained in:
committed by
GitHub
parent
942b2b4dcb
commit
5a0e0524ca
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
@@ -9,15 +10,15 @@ namespace Content.Client.Chemistry.UI;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ReagentCardControl : Control
|
||||
{
|
||||
public string StorageSlotId { get; }
|
||||
public Action<string>? OnPressed;
|
||||
public Action<string>? OnEjectButtonPressed;
|
||||
public ItemStorageLocation StorageLocation { get; }
|
||||
public Action<ItemStorageLocation>? OnPressed;
|
||||
public Action<ItemStorageLocation>? OnEjectButtonPressed;
|
||||
|
||||
public ReagentCardControl(ReagentInventoryItem item)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
StorageSlotId = item.StorageSlotId;
|
||||
StorageLocation = item.StorageLocation;
|
||||
ColorPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = item.ReagentColor };
|
||||
ReagentNameLabel.Text = item.ReagentLabel;
|
||||
FillLabel.Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", item.Quantity));;
|
||||
@@ -26,7 +27,7 @@ public sealed partial class ReagentCardControl : Control
|
||||
if (item.Quantity == 0.0)
|
||||
MainButton.Disabled = true;
|
||||
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageSlotId);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageSlotId);
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageLocation);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace Content.Client.Chemistry.UI
|
||||
|
||||
_window.AmountGrid.OnButtonPressed += s => SendMessage(new ReagentDispenserSetDispenseAmountMessage(s));
|
||||
|
||||
_window.OnDispenseReagentButtonPressed += (id) => SendMessage(new ReagentDispenserDispenseReagentMessage(id));
|
||||
_window.OnEjectJugButtonPressed += (id) => SendMessage(new ItemSlotButtonPressedEvent(id));
|
||||
_window.OnDispenseReagentButtonPressed += (location) => SendMessage(new ReagentDispenserDispenseReagentMessage(location));
|
||||
_window.OnEjectJugButtonPressed += (location) => SendMessage(new ReagentDispenserEjectContainerMessage(location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
@@ -18,8 +19,8 @@ namespace Content.Client.Chemistry.UI
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
public event Action<string>? OnDispenseReagentButtonPressed;
|
||||
public event Action<string>? OnEjectJugButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnDispenseReagentButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnEjectJugButtonPressed;
|
||||
|
||||
/// <summary>
|
||||
/// Create and initialize the dispenser UI client-side. Creates the basic layout,
|
||||
|
||||
@@ -2,7 +2,6 @@ using Content.Shared.Whitelist;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Dispenser;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
@@ -15,47 +14,9 @@ namespace Content.Server.Chemistry.Components
|
||||
[Access(typeof(ReagentDispenserSystem))]
|
||||
public sealed partial class ReagentDispenserComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// String with the pack name that stores the initial fill of the dispenser. The initial
|
||||
/// fill is added to the dispenser on MapInit. Note that we don't use ContainerFill because
|
||||
/// we have to generate the storage slots at MapInit first, then fill them.
|
||||
/// </summary>
|
||||
[DataField("pack", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentDispenserInventoryPrototype>))]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? PackPrototypeId = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of internal storage slots. Dispenser can't store (or dispense) more than
|
||||
/// this many chemicals (without unloading and reloading).
|
||||
/// </summary>
|
||||
[DataField("numStorageSlots")]
|
||||
public int NumSlots = 25;
|
||||
|
||||
/// <summary>
|
||||
/// For each created storage slot for the reagent containers being dispensed, apply this
|
||||
/// entity whitelist. Makes sure weird containers don't fit in the dispenser and that beakers
|
||||
/// don't accidentally get slotted into the source slots.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityWhitelist? StorageWhitelist;
|
||||
|
||||
[DataField]
|
||||
public ItemSlot BeakerSlot = new();
|
||||
|
||||
/// <summary>
|
||||
/// Prefix for automatically-generated slot name for storage, up to NumSlots.
|
||||
/// </summary>
|
||||
public static string BaseStorageSlotId = "ReagentDispenser-storageSlot";
|
||||
|
||||
/// <summary>
|
||||
/// List of storage slots that were created at MapInit.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<string> StorageSlotIds = new List<string>();
|
||||
|
||||
[DataField]
|
||||
public List<ItemSlot> StorageSlots = new List<ItemSlot>();
|
||||
|
||||
[DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg");
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Dispenser;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Shared.Storage.EntitySystems;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -13,6 +14,8 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Labels.Components;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Server.Hands.Systems;
|
||||
|
||||
namespace Content.Server.Chemistry.EntitySystems
|
||||
{
|
||||
@@ -30,6 +33,7 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly OpenableSystem _openable = default!;
|
||||
[Dependency] private readonly HandsSystem _handsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -37,12 +41,13 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, ComponentStartup>(SubscribeUpdateUiState);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, SolutionContainerChangedEvent>(SubscribeUpdateUiState);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, EntInsertedIntoContainerMessage>(SubscribeUpdateUiState);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, EntRemovedFromContainerMessage>(SubscribeUpdateUiState);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, EntInsertedIntoContainerMessage>(SubscribeUpdateUiState, after: [typeof(SharedStorageSystem)]);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, EntRemovedFromContainerMessage>(SubscribeUpdateUiState, after: [typeof(SharedStorageSystem)]);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, BoundUIOpenedEvent>(SubscribeUpdateUiState);
|
||||
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserSetDispenseAmountMessage>(OnSetDispenseAmountMessage);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserDispenseReagentMessage>(OnDispenseReagentMessage);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserEjectContainerMessage>(OnEjectReagentMessage);
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserClearContainerSolutionMessage>(OnClearContainerSolutionMessage);
|
||||
|
||||
SubscribeLocalEvent<ReagentDispenserComponent, MapInitEvent>(OnMapInit, before: new []{typeof(ItemSlotsSystem)});
|
||||
@@ -82,32 +87,31 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
|
||||
private List<ReagentInventoryItem> GetInventory(Entity<ReagentDispenserComponent> reagentDispenser)
|
||||
{
|
||||
if (!TryComp<StorageComponent>(reagentDispenser.Owner, out var storage))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var inventory = new List<ReagentInventoryItem>();
|
||||
|
||||
for (var i = 0; i < reagentDispenser.Comp.NumSlots; i++)
|
||||
foreach (var (storedContainer, storageLocation) in storage.StoredItems)
|
||||
{
|
||||
var storageSlotId = ReagentDispenserComponent.BaseStorageSlotId + i;
|
||||
var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser.Owner, storageSlotId);
|
||||
|
||||
// Set label from manually-applied label, or metadata if unavailable
|
||||
string reagentLabel;
|
||||
if (TryComp<LabelComponent>(storedContainer, out var label) && !string.IsNullOrEmpty(label.CurrentLabel))
|
||||
reagentLabel = label.CurrentLabel;
|
||||
else if (storedContainer != null)
|
||||
reagentLabel = Name(storedContainer.Value);
|
||||
else
|
||||
continue;
|
||||
reagentLabel = Name(storedContainer);
|
||||
|
||||
// Get volume remaining and color of solution
|
||||
FixedPoint2 quantity = 0f;
|
||||
var reagentColor = Color.White;
|
||||
if (storedContainer != null && _solutionContainerSystem.TryGetDrainableSolution(storedContainer.Value, out _, out var sol))
|
||||
if (_solutionContainerSystem.TryGetDrainableSolution(storedContainer, out _, out var sol))
|
||||
{
|
||||
quantity = sol.Volume;
|
||||
reagentColor = sol.GetColor(_prototypeManager);
|
||||
}
|
||||
|
||||
inventory.Add(new ReagentInventoryItem(storageSlotId, reagentLabel, quantity, reagentColor));
|
||||
inventory.Add(new ReagentInventoryItem(storageLocation, reagentLabel, quantity, reagentColor));
|
||||
}
|
||||
|
||||
return inventory;
|
||||
@@ -122,8 +126,14 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
|
||||
private void OnDispenseReagentMessage(Entity<ReagentDispenserComponent> reagentDispenser, ref ReagentDispenserDispenseReagentMessage message)
|
||||
{
|
||||
if (!TryComp<StorageComponent>(reagentDispenser.Owner, out var storage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure that the reagent is something this reagent dispenser can dispense.
|
||||
var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, message.SlotId);
|
||||
var storageLocation = message.StorageLocation;
|
||||
var storedContainer = storage.StoredItems.FirstOrDefault(kvp => kvp.Value == storageLocation).Key;
|
||||
if (storedContainer == null)
|
||||
return;
|
||||
|
||||
@@ -131,13 +141,13 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
if (outputContainer is not { Valid: true } || !_solutionContainerSystem.TryGetFitsInDispenser(outputContainer.Value, out var solution, out _))
|
||||
return;
|
||||
|
||||
if (_solutionContainerSystem.TryGetDrainableSolution(storedContainer.Value, out var src, out _) &&
|
||||
if (_solutionContainerSystem.TryGetDrainableSolution(storedContainer, out var src, out _) &&
|
||||
_solutionContainerSystem.TryGetRefillableSolution(outputContainer.Value, out var dst, out _))
|
||||
{
|
||||
// force open container, if applicable, to avoid confusing people on why it doesn't dispense
|
||||
_openable.SetOpen(storedContainer.Value, true);
|
||||
_openable.SetOpen(storedContainer, true);
|
||||
_solutionTransferSystem.Transfer(reagentDispenser,
|
||||
storedContainer.Value, src.Value,
|
||||
storedContainer, src.Value,
|
||||
outputContainer.Value, dst.Value,
|
||||
(int)reagentDispenser.Comp.DispenseAmount);
|
||||
}
|
||||
@@ -146,6 +156,21 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
ClickSound(reagentDispenser);
|
||||
}
|
||||
|
||||
private void OnEjectReagentMessage(Entity<ReagentDispenserComponent> reagentDispenser, ref ReagentDispenserEjectContainerMessage message)
|
||||
{
|
||||
if (!TryComp<StorageComponent>(reagentDispenser.Owner, out var storage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var storageLocation = message.StorageLocation;
|
||||
var storedContainer = storage.StoredItems.FirstOrDefault(kvp => kvp.Value == storageLocation).Key;
|
||||
if (storedContainer == null)
|
||||
return;
|
||||
|
||||
_handsSystem.TryPickupAnyHand(message.Actor, storedContainer);
|
||||
}
|
||||
|
||||
private void OnClearContainerSolutionMessage(Entity<ReagentDispenserComponent> reagentDispenser, ref ReagentDispenserClearContainerSolutionMessage message)
|
||||
{
|
||||
var outputContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, SharedReagentDispenser.OutputSlotName);
|
||||
@@ -163,39 +188,11 @@ namespace Content.Server.Chemistry.EntitySystems
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Automatically generate storage slots for all NumSlots, and fill them with their initial chemicals.
|
||||
/// The actual spawning of entities happens in ItemSlotsSystem's MapInit.
|
||||
/// Initializes the beaker slot
|
||||
/// </summary>
|
||||
private void OnMapInit(EntityUid uid, ReagentDispenserComponent component, MapInitEvent args)
|
||||
private void OnMapInit(Entity<ReagentDispenserComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
// Get list of pre-loaded containers
|
||||
List<string> preLoad = new List<string>();
|
||||
if (component.PackPrototypeId is not null
|
||||
&& _prototypeManager.TryIndex(component.PackPrototypeId, out ReagentDispenserInventoryPrototype? packPrototype))
|
||||
{
|
||||
preLoad.AddRange(packPrototype.Inventory);
|
||||
}
|
||||
|
||||
// Populate storage slots with base storage slot whitelist
|
||||
for (var i = 0; i < component.NumSlots; i++)
|
||||
{
|
||||
var storageSlotId = ReagentDispenserComponent.BaseStorageSlotId + i;
|
||||
ItemSlot storageComponent = new();
|
||||
storageComponent.Whitelist = component.StorageWhitelist;
|
||||
storageComponent.Swap = false;
|
||||
storageComponent.EjectOnBreak = true;
|
||||
|
||||
// Check corresponding index in pre-loaded container (if exists) and set starting item
|
||||
if (i < preLoad.Count)
|
||||
storageComponent.StartingItem = preLoad[i];
|
||||
|
||||
component.StorageSlotIds.Add(storageSlotId);
|
||||
component.StorageSlots.Add(storageComponent);
|
||||
component.StorageSlots[i].Name = "Storage Slot " + (i+1);
|
||||
_itemSlotsSystem.AddItemSlot(uid, component.StorageSlotIds[i], component.StorageSlots[i]);
|
||||
}
|
||||
|
||||
_itemSlotsSystem.AddItemSlot(uid, SharedReagentDispenser.OutputSlotName, component.BeakerSlot);
|
||||
_itemSlotsSystem.AddItemSlot(ent.Owner, SharedReagentDispenser.OutputSlotName, ent.Comp.BeakerSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Chemistry.Dispenser
|
||||
{
|
||||
/// <summary>
|
||||
/// Is simply a list of reagents defined in yaml. This can then be set as a
|
||||
/// <see cref="SharedReagentDispenserComponent"/>s <c>pack</c> value (also in yaml),
|
||||
/// to define which reagents it's able to dispense. Based off of how vending
|
||||
/// machines define their inventory.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable, Prototype]
|
||||
public sealed partial class ReagentDispenserInventoryPrototype : IPrototype
|
||||
{
|
||||
[DataField("inventory", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
|
||||
public List<string> Inventory = new();
|
||||
|
||||
[ViewVariables, IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Chemistry
|
||||
@@ -66,11 +67,25 @@ namespace Content.Shared.Chemistry
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ReagentDispenserDispenseReagentMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly string SlotId;
|
||||
public readonly ItemStorageLocation StorageLocation;
|
||||
|
||||
public ReagentDispenserDispenseReagentMessage(string slotId)
|
||||
public ReagentDispenserDispenseReagentMessage(ItemStorageLocation storageLocation)
|
||||
{
|
||||
SlotId = slotId;
|
||||
StorageLocation = storageLocation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message sent by the user interface to ask the reagent dispenser to eject a container
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ReagentDispenserEjectContainerMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly ItemStorageLocation StorageLocation;
|
||||
|
||||
public ReagentDispenserEjectContainerMessage(ItemStorageLocation storageLocation)
|
||||
{
|
||||
StorageLocation = storageLocation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +109,9 @@ namespace Content.Shared.Chemistry
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ReagentInventoryItem(string storageSlotId, string reagentLabel, FixedPoint2 quantity, Color reagentColor)
|
||||
public sealed class ReagentInventoryItem(ItemStorageLocation storageLocation, string reagentLabel, FixedPoint2 quantity, Color reagentColor)
|
||||
{
|
||||
public string StorageSlotId = storageSlotId;
|
||||
public ItemStorageLocation StorageLocation = storageLocation;
|
||||
public string ReagentLabel = reagentLabel;
|
||||
public FixedPoint2 Quantity = quantity;
|
||||
public Color ReagentColor = reagentColor;
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
- type: reagentDispenserInventory
|
||||
id: SodaDispenserInventory
|
||||
inventory:
|
||||
- DrinkCoconutWaterJug
|
||||
- DrinkCoffeeJug
|
||||
- DrinkColaBottleFull
|
||||
- DrinkCreamCartonXL
|
||||
- DrinkDrGibbJug
|
||||
- DrinkEnergyDrinkJug
|
||||
- DrinkGreenTeaJug
|
||||
- DrinkIceJug
|
||||
- DrinkJuiceLimeCartonXL
|
||||
- DrinkJuiceOrangeCartonXL
|
||||
- DrinkLemonLimeJug
|
||||
- DrinkRootBeerJug
|
||||
- DrinkSodaWaterBottleFull
|
||||
- DrinkSpaceMountainWindBottleFull
|
||||
- DrinkSpaceUpBottleFull
|
||||
- DrinkSugarJug
|
||||
- DrinkTeaJug
|
||||
- DrinkTonicWaterBottleFull
|
||||
- DrinkWaterMelonJuiceJug
|
||||
|
||||
- type: reagentDispenserInventory
|
||||
id: BoozeDispenserInventory
|
||||
inventory:
|
||||
- DrinkAleBottleFullGrowler
|
||||
- DrinkBeerGrowler
|
||||
- DrinkCoffeeLiqueurBottleFull
|
||||
- DrinkCognacBottleFull
|
||||
- DrinkGinBottleFull
|
||||
- DrinkMeadJug
|
||||
- DrinkRumBottleFull
|
||||
- DrinkTequilaBottleFull
|
||||
- DrinkVermouthBottleFull
|
||||
- DrinkVodkaBottleFull
|
||||
- DrinkWhiskeyBottleFull
|
||||
- DrinkWineBottleFull
|
||||
@@ -1,26 +0,0 @@
|
||||
- type: reagentDispenserInventory
|
||||
id: ChemDispenserStandardInventory
|
||||
inventory:
|
||||
- JugAluminium
|
||||
- JugCarbon
|
||||
- JugChlorine
|
||||
- JugCopper
|
||||
- JugEthanol
|
||||
- JugFluorine
|
||||
- JugSugar
|
||||
- JugHydrogen
|
||||
- JugIodine
|
||||
- JugIron
|
||||
- JugLithium
|
||||
- JugMercury
|
||||
- JugNitrogen
|
||||
- JugOxygen
|
||||
- JugPhosphorus
|
||||
- JugPotassium
|
||||
- JugRadium
|
||||
- JugSilicon
|
||||
- JugSodium
|
||||
- JugSulfur
|
||||
|
||||
- type: reagentDispenserInventory
|
||||
id: EmptyInventory
|
||||
@@ -32,6 +32,8 @@
|
||||
interfaces:
|
||||
enum.ReagentDispenserUiKey.Key:
|
||||
type: ReagentDispenserBoundUserInterface
|
||||
enum.StorageUiKey.Key:
|
||||
type: StorageBoundUserInterface
|
||||
- type: Anchorable
|
||||
- type: Pullable
|
||||
- type: Damageable
|
||||
@@ -54,10 +56,11 @@
|
||||
- !type:PlaySoundBehavior
|
||||
sound:
|
||||
collection: MetalGlassBreak
|
||||
- type: Storage
|
||||
maxItemSize: Normal
|
||||
grid:
|
||||
- 0,0,19,5
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
tags:
|
||||
- Bottle
|
||||
beakerSlot:
|
||||
whitelistFailPopup: reagent-dispenser-component-cannot-put-entity-message
|
||||
whitelist:
|
||||
@@ -70,6 +73,7 @@
|
||||
machine_board: !type:Container
|
||||
machine_parts: !type:Container
|
||||
beakerSlot: !type:ContainerSlot
|
||||
storagebase: !type:Container
|
||||
- type: StaticPrice
|
||||
price: 1000
|
||||
- type: WiresPanel
|
||||
|
||||
@@ -10,11 +10,24 @@
|
||||
sprite: Structures/smalldispensers.rsi
|
||||
drawdepth: SmallObjects
|
||||
state: booze
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- DrinkBottle
|
||||
pack: BoozeDispenserInventory
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: DrinkAleBottleFullGrowler
|
||||
- id: DrinkBeerGrowler
|
||||
- id: DrinkCoffeeLiqueurBottleFull
|
||||
- id: DrinkCognacBottleFull
|
||||
- id: DrinkGinBottleFull
|
||||
- id: DrinkMeadJug
|
||||
- id: DrinkRumBottleFull
|
||||
- id: DrinkTequilaBottleFull
|
||||
- id: DrinkVermouthBottleFull
|
||||
- id: DrinkVodkaBottleFull
|
||||
- id: DrinkWhiskeyBottleFull
|
||||
- id: DrinkWineBottleFull
|
||||
- type: Transform
|
||||
noRot: false
|
||||
- type: Machine
|
||||
@@ -31,8 +44,7 @@
|
||||
suffix: Empty
|
||||
parent: BoozeDispenser
|
||||
components:
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- DrinkBottle
|
||||
pack: EmptyInventory
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
- type: entity
|
||||
id: ChemDispenser
|
||||
id: ChemDispenserEmpty
|
||||
name: chemical dispenser
|
||||
suffix: Filled
|
||||
suffix: Empty
|
||||
parent: ReagentDispenserBase
|
||||
description: An industrial grade chemical dispenser.
|
||||
components:
|
||||
@@ -9,11 +9,10 @@
|
||||
sprite: Structures/dispensers.rsi
|
||||
state: industrial-working
|
||||
snapCardinals: true
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- ChemDispensable
|
||||
pack: ChemDispenserStandardInventory
|
||||
- type: ApcPowerReceiver
|
||||
- type: ExtensionCableReceiver
|
||||
- type: Destructible
|
||||
@@ -50,10 +49,31 @@
|
||||
- MachineLayer
|
||||
|
||||
- type: entity
|
||||
id: ChemDispenserEmpty
|
||||
id: ChemDispenser
|
||||
name: chemical dispenser
|
||||
suffix: Empty
|
||||
parent: ChemDispenser
|
||||
suffix: Filled
|
||||
parent: ChemDispenserEmpty
|
||||
components:
|
||||
- type: ReagentDispenser
|
||||
pack: EmptyInventory
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: JugAluminium
|
||||
- id: JugCarbon
|
||||
- id: JugChlorine
|
||||
- id: JugCopper
|
||||
- id: JugEthanol
|
||||
- id: JugFluorine
|
||||
- id: JugSugar
|
||||
- id: JugHydrogen
|
||||
- id: JugIodine
|
||||
- id: JugIron
|
||||
- id: JugLithium
|
||||
- id: JugMercury
|
||||
- id: JugNitrogen
|
||||
- id: JugOxygen
|
||||
- id: JugPhosphorus
|
||||
- id: JugPotassium
|
||||
- id: JugRadium
|
||||
- id: JugSilicon
|
||||
- id: JugSodium
|
||||
- id: JugSulfur
|
||||
|
||||
@@ -10,11 +10,31 @@
|
||||
sprite: Structures/smalldispensers.rsi
|
||||
drawdepth: SmallObjects
|
||||
state: soda
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
- type: Storage
|
||||
whitelist:
|
||||
tags:
|
||||
- DrinkBottle
|
||||
pack: SodaDispenserInventory
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: DrinkCoconutWaterJug
|
||||
- id: DrinkCoffeeJug
|
||||
- id: DrinkColaBottleFull
|
||||
- id: DrinkCreamCartonXL
|
||||
- id: DrinkDrGibbJug
|
||||
- id: DrinkEnergyDrinkJug
|
||||
- id: DrinkGreenTeaJug
|
||||
- id: DrinkIceJug
|
||||
- id: DrinkJuiceLimeCartonXL
|
||||
- id: DrinkJuiceOrangeCartonXL
|
||||
- id: DrinkLemonLimeJug
|
||||
- id: DrinkRootBeerJug
|
||||
- id: DrinkSodaWaterBottleFull
|
||||
- id: DrinkSpaceMountainWindBottleFull
|
||||
- id: DrinkSpaceUpBottleFull
|
||||
- id: DrinkSugarJug
|
||||
- id: DrinkTeaJug
|
||||
- id: DrinkTonicWaterBottleFull
|
||||
- id: DrinkWaterMelonJuiceJug
|
||||
- type: Transform
|
||||
noRot: false
|
||||
- type: Machine
|
||||
@@ -28,9 +48,3 @@
|
||||
parent: SodaDispenser
|
||||
id: SodaDispenserEmpty
|
||||
suffix: Empty
|
||||
components:
|
||||
- type: ReagentDispenser
|
||||
storageWhitelist:
|
||||
tags:
|
||||
- DrinkBottle
|
||||
pack: EmptyInventory
|
||||
|
||||
Reference in New Issue
Block a user