Revert "Add limited-reagent dispensers (#23907)"

This reverts commit 9394a26245.
This commit is contained in:
Aviu00
2024-01-27 08:12:04 +03:00
parent 2d2405ff93
commit 531becd592
18 changed files with 169 additions and 303 deletions

View File

@@ -57,23 +57,13 @@ namespace Content.Client.Chemistry.UI
_window.OnDispenseReagentButtonMouseEntered += (args, button) =>
{
if (_lastState is not null)
_window.UpdateContainerInfo(_lastState);
_window.UpdateContainerInfo(_lastState, button.ReagentId);
};
_window.OnDispenseReagentButtonMouseExited += (args, button) =>
{
if (_lastState is not null)
_window.UpdateContainerInfo(_lastState);
};
_window.OnEjectJugButtonPressed += (args, button) => SendMessage(new ItemSlotButtonPressedEvent(button.ReagentId));
_window.OnEjectJugButtonMouseEntered += (args, button) => {
if (_lastState is not null)
_window.UpdateContainerInfo(_lastState);
};
_window.OnEjectJugButtonMouseExited += (args, button) => {
if (_lastState is not null)
_window.UpdateContainerInfo(_lastState);
};
}
/// <summary>

View File

@@ -1,7 +1,8 @@
<DefaultWindow xmlns="https://spacestation14.io"
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'reagent-dispenser-bound-user-interface-title'}"
MinSize="680 450">
SetSize="620 450"
MinSize="620 450">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'reagent-dispenser-window-amount-to-dispense-label'}"/>
@@ -17,8 +18,10 @@
<Button Name="DispenseButton100" Access="Public" Text="100" StyleClasses="OpenLeft"/>
</BoxContainer>
<Control MinSize="0 10"/>
<GridContainer Name="ChemicalList" HorizontalExpand="True" VerticalExpand="True" Access="Public" Columns="6">
</GridContainer>
<ScrollContainer HScrollEnabled="False" HorizontalExpand="True" MinSize="0 170">
<GridContainer Name="ChemicalList" Access="Public" Columns="4">
</GridContainer>
</ScrollContainer>
<Control MinSize="0 10"/>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'reagent-dispenser-window-container-label'}"/>

View File

@@ -23,10 +23,6 @@ namespace Content.Client.Chemistry.UI
public event Action<GUIMouseHoverEventArgs, DispenseReagentButton>? OnDispenseReagentButtonMouseEntered;
public event Action<GUIMouseHoverEventArgs, DispenseReagentButton>? OnDispenseReagentButtonMouseExited;
public event Action<BaseButton.ButtonEventArgs, EjectJugButton>? OnEjectJugButtonPressed;
public event Action<GUIMouseHoverEventArgs, EjectJugButton>? OnEjectJugButtonMouseEntered;
public event Action<GUIMouseHoverEventArgs, EjectJugButton>? OnEjectJugButtonMouseExited;
/// <summary>
/// Create and initialize the dispenser UI client-side. Creates the basic layout,
/// actual data isn't filled in until the server sends data about the dispenser.
@@ -52,25 +48,25 @@ namespace Content.Client.Chemistry.UI
/// Update the button grid of reagents which can be dispensed.
/// </summary>
/// <param name="inventory">Reagents which can be dispensed by this dispenser</param>
public void UpdateReagentsList(List<KeyValuePair<string, KeyValuePair<string,string>>> inventory)
public void UpdateReagentsList(List<ReagentId> inventory)
{
if (ChemicalList == null)
return;
ChemicalList.Children.Clear();
foreach (KeyValuePair<string, KeyValuePair<string, string>> entry in inventory)
foreach (var entry in inventory
.OrderBy(r => {_prototypeManager.TryIndex(r.Prototype, out ReagentPrototype? p); return p?.LocalizedName;}))
{
var button = new DispenseReagentButton(entry.Key, entry.Value.Key, entry.Value.Value);
var localizedName = _prototypeManager.TryIndex(entry.Prototype, out ReagentPrototype? p)
? p.LocalizedName
: Loc.GetString("reagent-dispenser-window-reagent-name-not-found-text");
var button = new DispenseReagentButton(entry, localizedName);
button.OnPressed += args => OnDispenseReagentButtonPressed?.Invoke(args, button);
button.OnMouseEntered += args => OnDispenseReagentButtonMouseEntered?.Invoke(args, button);
button.OnMouseExited += args => OnDispenseReagentButtonMouseExited?.Invoke(args, button);
ChemicalList.AddChild(button);
var ejectButton = new EjectJugButton(entry.Key);
ejectButton.OnPressed += args => OnEjectJugButtonPressed?.Invoke(args, ejectButton);
ejectButton.OnMouseEntered += args => OnEjectJugButtonMouseEntered?.Invoke(args, ejectButton);
ejectButton.OnMouseExited += args => OnEjectJugButtonMouseExited?.Invoke(args, ejectButton);
ChemicalList.AddChild(ejectButton);
}
}
@@ -125,8 +121,9 @@ namespace Content.Client.Chemistry.UI
/// <para>Also highlights a reagent if it's dispense button is being mouse hovered.</para>
/// </summary>
/// <param name="state">State data for the dispenser.</param>
/// <param name="highlightedReagentId">Prototype ID of the reagent whose dispense button is currently being mouse hovered,
/// or null if no button is being hovered.</param>
public void UpdateContainerInfo(ReagentDispenserBoundUserInterfaceState state)
public void UpdateContainerInfo(ReagentDispenserBoundUserInterfaceState state, ReagentId? highlightedReagentId = null)
{
ContainerInfo.Children.Clear();
@@ -164,6 +161,12 @@ namespace Content.Client.Chemistry.UI
StyleClasses = {StyleNano.StyleClassLabelSecondaryColor},
};
// Check if the reagent is being moused over. If so, color it green.
if (reagent == highlightedReagentId) {
nameLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
quantityLabel.SetOnlyStyleClass(StyleNano.StyleClassPowerStateGood);
}
ContainerInfo.Children.Add(new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
@@ -177,27 +180,13 @@ namespace Content.Client.Chemistry.UI
}
}
public sealed class DispenseReagentButton : Button
{
public string ReagentId { get; }
public sealed class DispenseReagentButton : Button {
public ReagentId ReagentId { get; }
public DispenseReagentButton(string reagentId, string text, string amount)
public DispenseReagentButton(ReagentId reagentId, string text)
{
AddStyleClass("OpenRight");
ReagentId = reagentId;
Text = text + " " + amount;
}
}
public sealed class EjectJugButton : Button
{
public string ReagentId { get; }
public EjectJugButton(string reagentId)
{
AddStyleClass("OpenLeft");
ReagentId = reagentId;
Text = "⏏";
Text = text;
}
}
}

View File

@@ -1,7 +1,6 @@
using Content.Client.Chemistry.UI;
using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Chemistry;
using Content.Server.Chemistry.Components;
using Content.Shared.Containers.ItemSlots;
namespace Content.IntegrationTests.Tests.Chemistry;
@@ -25,7 +24,7 @@ public sealed class DispenserTest : InteractionTest
await Interact();
// Eject beaker via BUI.
var ev = new ItemSlotButtonPressedEvent(ReagentDispenserComponent.BeakerSlotId);
var ev = new ItemSlotButtonPressedEvent(SharedChemMaster.InputSlotName);
await SendBui(ReagentDispenserUiKey.Key, ev);
// Beaker is back in the player's hands

View File

@@ -1,5 +1,3 @@
using Content.Shared.Whitelist;
using Content.Shared.Containers.ItemSlots;
using Content.Server.Chemistry.EntitySystems;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Dispenser;
@@ -9,57 +7,20 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
namespace Content.Server.Chemistry.Components
{
/// <summary>
/// A machine that dispenses reagents into a solution container from containers in its storage slots.
/// A machine that dispenses reagents into a solution container.
/// </summary>
[RegisterComponent]
[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;
/// <summary>
/// Slot for container to dispense into.
/// </summary>
public static string BeakerSlotId = "ReagentDispenser-beakerSlot";
[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("emagPack", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentDispenserInventoryPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public string? EmagPackPrototypeId = default!;
[DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg");

View File

@@ -1,18 +1,14 @@
using Content.Server.Administration.Logs;
using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Nutrition.Components;
using Content.Server.Nutrition.EntitySystems;
using Content.Server.Labels.Components;
using Content.Server.Chemistry;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.Dispenser;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using JetBrains.Annotations;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
@@ -32,13 +28,10 @@ namespace Content.Server.Chemistry.EntitySystems
{
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly SolutionTransferSystem _solutionTransferSystem = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly OpenableSystem _openable = default!;
public override void Initialize()
{
base.Initialize();
@@ -48,12 +41,11 @@ namespace Content.Server.Chemistry.EntitySystems
SubscribeLocalEvent<ReagentDispenserComponent, EntInsertedIntoContainerMessage>(SubscribeUpdateUiState);
SubscribeLocalEvent<ReagentDispenserComponent, EntRemovedFromContainerMessage>(SubscribeUpdateUiState);
SubscribeLocalEvent<ReagentDispenserComponent, BoundUIOpenedEvent>(SubscribeUpdateUiState);
SubscribeLocalEvent<ReagentDispenserComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserSetDispenseAmountMessage>(OnSetDispenseAmountMessage);
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserDispenseReagentMessage>(OnDispenseReagentMessage);
SubscribeLocalEvent<ReagentDispenserComponent, ReagentDispenserClearContainerSolutionMessage>(OnClearContainerSolutionMessage);
SubscribeLocalEvent<ReagentDispenserComponent, MapInitEvent>(OnMapInit, before: new []{typeof(ItemSlotsSystem)});
}
private void SubscribeUpdateUiState<T>(Entity<ReagentDispenserComponent> ent, ref T ev)
@@ -88,38 +80,35 @@ namespace Content.Server.Chemistry.EntitySystems
return null;
}
private List<KeyValuePair<string, KeyValuePair<string, string>>> GetInventory(ReagentDispenserComponent reagentDispenser)
private List<ReagentId> GetInventory(Entity<ReagentDispenserComponent> ent)
{
var inventory = new List<KeyValuePair<string, KeyValuePair<string, string>>>();
var reagentDispenser = ent.Comp;
var inventory = new List<ReagentId>();
for (var i = 0; i < reagentDispenser.NumSlots; i++)
if (reagentDispenser.PackPrototypeId is not null
&& _prototypeManager.TryIndex(reagentDispenser.PackPrototypeId, out ReagentDispenserInventoryPrototype? packPrototype))
{
var storageSlotId = ReagentDispenserComponent.BaseStorageSlotId + i;
var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser.Owner, storageSlotId);
inventory.AddRange(packPrototype.Inventory.Select(x => new ReagentId(x, null)));
}
// 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;
// Add volume remaining label
FixedPoint2 quantity = 0f;
if (storedContainer != null && _solutionContainerSystem.TryGetDrainableSolution(storedContainer.Value, out _, out var sol))
{
quantity = sol.Volume;
}
var storedAmount = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", quantity));
inventory.Add(new KeyValuePair<string, KeyValuePair<string, string>>(storageSlotId, new KeyValuePair<string, string>(reagentLabel, storedAmount)));
if (HasComp<EmaggedComponent>(ent)
&& reagentDispenser.EmagPackPrototypeId is not null
&& _prototypeManager.TryIndex(reagentDispenser.EmagPackPrototypeId, out ReagentDispenserInventoryPrototype? emagPackPrototype))
{
inventory.AddRange(emagPackPrototype.Inventory.Select(x => new ReagentId(x, null)));
}
return inventory;
}
private void OnEmagged(Entity<ReagentDispenserComponent> reagentDispenser, ref GotEmaggedEvent args)
{
// adding component manually to have correct state
EntityManager.AddComponent<EmaggedComponent>(reagentDispenser);
UpdateUiState(reagentDispenser);
args.Handled = true;
}
private void OnSetDispenseAmountMessage(Entity<ReagentDispenserComponent> reagentDispenser, ref ReagentDispenserSetDispenseAmountMessage message)
{
reagentDispenser.Comp.DispenseAmount = message.ReagentDispenserDispenseAmount;
@@ -130,23 +119,18 @@ namespace Content.Server.Chemistry.EntitySystems
private void OnDispenseReagentMessage(Entity<ReagentDispenserComponent> reagentDispenser, ref ReagentDispenserDispenseReagentMessage message)
{
// Ensure that the reagent is something this reagent dispenser can dispense.
var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, message.SlotId);
if (storedContainer == null)
if (!GetInventory(reagentDispenser).Contains(message.ReagentId))
return;
var outputContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, SharedReagentDispenser.OutputSlotName);
if (outputContainer is not { Valid: true } || !_solutionContainerSystem.TryGetFitsInDispenser(outputContainer.Value, out var solution, out _))
return;
if (_solutionContainerSystem.TryGetDrainableSolution(storedContainer.Value, out var src, out _) &&
_solutionContainerSystem.TryGetRefillableSolution(outputContainer.Value, out var dst, out _))
if (_solutionContainerSystem.TryAddReagent(solution.Value, message.ReagentId, (int) reagentDispenser.Comp.DispenseAmount, out var dispensedAmount)
&& message.Session.AttachedEntity is not null)
{
// force open container, if applicable, to avoid confusing people on why it doesn't dispense
_openable.SetOpen(storedContainer.Value, true);
_solutionTransferSystem.Transfer(reagentDispenser,
storedContainer.Value, src.Value,
outputContainer.Value, dst.Value,
(int)reagentDispenser.Comp.DispenseAmount);
_adminLogger.Add(LogType.ChemicalReaction, LogImpact.Medium,
$"{ToPrettyString(message.Session.AttachedEntity.Value):player} dispensed {dispensedAmount}u of {message.ReagentId} into {ToPrettyString(outputContainer.Value):entity}");
}
UpdateUiState(reagentDispenser);
@@ -168,41 +152,5 @@ namespace Content.Server.Chemistry.EntitySystems
{
_audioSystem.PlayPvs(reagentDispenser.Comp.ClickSound, reagentDispenser, AudioParams.Default.WithVolume(-2f));
}
/// <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.
/// </summary>
private void OnMapInit(EntityUid uid, ReagentDispenserComponent component, 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, ReagentDispenserComponent.BeakerSlotId, component.BeakerSlot);
}
}
}

View File

@@ -1,4 +1,4 @@
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
@@ -14,7 +14,8 @@ namespace Content.Shared.Chemistry.Dispenser
[Serializable, NetSerializable, Prototype("reagentDispenserInventory")]
public sealed partial class ReagentDispenserInventoryPrototype : IPrototype
{
[DataField("inventory", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
// TODO use ReagentId
[DataField("inventory", customTypeSerializer: typeof(PrototypeIdListSerializer<ReagentPrototype>))]
public List<string> Inventory = new();
[ViewVariables, IdDataField]

View File

@@ -8,7 +8,7 @@ namespace Content.Shared.Chemistry
/// </summary>
public sealed class SharedReagentDispenser
{
public const string OutputSlotName = "ReagentDispenser-beakerSlot";
public const string OutputSlotName = "beakerSlot";
}
[Serializable, NetSerializable]
@@ -25,11 +25,11 @@ namespace Content.Shared.Chemistry
[Serializable, NetSerializable]
public sealed class ReagentDispenserDispenseReagentMessage : BoundUserInterfaceMessage
{
public readonly string SlotId;
public readonly ReagentId ReagentId;
public ReagentDispenserDispenseReagentMessage(string slotId)
public ReagentDispenserDispenseReagentMessage(ReagentId reagentId)
{
SlotId = slotId;
ReagentId = reagentId;
}
}
@@ -59,11 +59,11 @@ namespace Content.Shared.Chemistry
/// <summary>
/// A list of the reagents which this dispenser can dispense.
/// </summary>
public readonly List<KeyValuePair<string, KeyValuePair<string, string>>> Inventory;
public readonly List<ReagentId> Inventory;
public readonly ReagentDispenserDispenseAmount SelectedDispenseAmount;
public ReagentDispenserBoundUserInterfaceState(ContainerInfo? outputContainer, List<KeyValuePair<string, KeyValuePair<string, string>>> inventory, ReagentDispenserDispenseAmount selectedDispenseAmount)
public ReagentDispenserBoundUserInterfaceState(ContainerInfo? outputContainer, List<ReagentId> inventory, ReagentDispenserDispenseAmount selectedDispenseAmount)
{
OutputContainer = outputContainer;
Inventory = inventory;

View File

@@ -67,8 +67,8 @@ namespace Content.Shared.Containers.ItemSlots
CopyFrom(other);
}
[DataField("whitelist")]
[Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)]
public EntityWhitelist? Whitelist;
[DataField("blacklist")]
@@ -179,7 +179,6 @@ namespace Content.Shared.Containers.ItemSlots
/// The actual deconstruction logic is handled by the server-side EmptyOnMachineDeconstructSystem.
/// </remarks>
[DataField("ejectOnDeconstruct")]
[Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)]
[NonSerialized]
public bool EjectOnDeconstruct = true;
@@ -188,7 +187,6 @@ namespace Content.Shared.Containers.ItemSlots
/// ejected when it is broken or destroyed?
/// </summary>
[DataField("ejectOnBreak")]
[Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)]
[NonSerialized]
public bool EjectOnBreak = false;
@@ -207,7 +205,6 @@ namespace Content.Shared.Containers.ItemSlots
/// want to insert more than one item that matches the same whitelist.
/// </remarks>
[DataField("swap")]
[Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)]
public bool Swap = true;
public string? ID => ContainerSlot?.ID;

View File

@@ -1,43 +1,61 @@
- type: reagentDispenserInventory
id: SodaDispenserInventory
inventory:
- DrinkIceJug
- DrinkCoffeeJug
- DrinkCreamCartonXL
- DrinkTeaJug
- DrinkGreenTeaJug
- DrinkIcedTeaJug
- DrinkColaBottleFull
- DrinkSpaceMountainWindBottleFull
- DrinkDrGibbJug
- DrinkRootBeerJug
- DrinkSpaceUpBottleFull
- DrinkTonicWaterBottleFull
- DrinkSodaWaterBottleFull
- DrinkLemonLimeJug
- DrinkSugarJug
- DrinkJuiceOrangeCartonXL
- DrinkJuiceLimeCartonXL
- DrinkWaterMelonJuiceJug
- Ice
- Coffee
- Cream
- Tea
- GreenTea
- IcedTea
- IcedGreenTea
- Cola
- SpaceMountainWind
- DrGibb
- RootBeer
- SpaceUp
- TonicWater
- SodaWater
- LemonLime
- Sugar
- JuiceOrange
- JuiceLime
- JuiceWatermelon
###Hacked
#- Fourteen Loko
#- GrapeSoda
- type: reagentDispenserInventory
id: BoozeDispenserInventory
inventory:
- DrinkLemonLimeJug
- DrinkSugarJug
- DrinkJuiceOrangeCartonXL
- DrinkJuiceLimeCartonXL
- DrinkTonicWaterBottleFull
- DrinkSodaWaterBottleFull
- DrinkBeerGrowler
- DrinkCoffeeLiqueurBottleFull
- DrinkWhiskeyBottleFull
- DrinkWineBottleFull
- DrinkVodkaBottleFull
- DrinkGinBottleFull
- DrinkRumBottleFull
- DrinkTequilaBottleFull
- DrinkVermouthBottleFull
- DrinkCognacBottleFull
- DrinkAleBottleFullGrowler
- DrinkMeadJug
- Beer
- CoffeeLiqueur
- Whiskey
- Wine
- Vodka
- Gin
- Rum
- Tequila
- Vermouth
- Cognac
- Ale
- Mead
###Hacked
#- Goldschlager
#- Patron
#- JuiceWatermelon
#- JuiceBerry
- type: reagentDispenserInventory
id: SodaDispenserEmagInventory
inventory:
- FourteenLoko
- Ephedrine
- Histamine
- type: reagentDispenserInventory
id: BoozeDispenserEmagInventory
inventory:
- AtomicBomb
- Ethanol
- Iron

View File

@@ -1,26 +1,31 @@
- 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
- Aluminium
- Carbon
- Chlorine
- Copper
- Ethanol
- Fluorine
- Sugar
- Hydrogen
- Iodine
- Iron
- Lithium
- Mercury
- Nitrogen
- Oxygen
- Phosphorus
- Potassium
- Radium
- Silicon
- Sodium
- Sulfur
- type: reagentDispenserInventory
id: EmptyInventory
id: ChemDispenserEmaggedInventory
inventory: ##Feel free to change this to something more interesting when more chems are added
- Napalm
- Toxin
- Epinephrine
- Ultravasculine

View File

@@ -553,7 +553,7 @@
- type: Sprite
state: medical
- type: MachineBoard
prototype: ChemDispenserEmpty
prototype: ChemDispenser
requirements:
Capacitor: 1
materialRequirements:
@@ -1168,7 +1168,7 @@
- type: Sprite
state: service
- type: MachineBoard
prototype: BoozeDispenserEmpty
prototype: BoozeDispenser
materialRequirements:
Steel: 5
tagRequirements:
@@ -1201,7 +1201,7 @@
- type: Sprite
state: service
- type: MachineBoard
prototype: SodaDispenserEmpty
prototype: soda_dispenser
materialRequirements:
Steel: 5
tagRequirements:

View File

@@ -47,9 +47,6 @@
price: 60
- type: Label
originalName: jug
- type: Tag
tags:
- ChemDispensable
- type: entity
parent: Jug

View File

@@ -1,4 +1,4 @@
- type: entity
- type: entity
abstract: true
id: ReagentDispenserBase
parent: ConstructibleMachine
@@ -55,20 +55,18 @@
sound:
collection: MetalGlassBreak
- type: ReagentDispenser
storageWhitelist:
tags:
- Bottle
beakerSlot:
whitelistFailPopup: reagent-dispenser-component-cannot-put-entity-message
whitelist:
components:
- FitsInDispenser
- type: ItemSlots
slots:
beakerSlot:
whitelistFailPopup: reagent-dispenser-component-cannot-put-entity-message
whitelist:
components:
- FitsInDispenser
- type: ContainerContainer
containers:
machine_board: !type:Container
machine_parts: !type:Container
ReagentDispenser-beakerSlot: !type:ContainerSlot
beakerSlot: !type:ContainerSlot
- type: StaticPrice
price: 1000
- type: Wires

View File

@@ -1,7 +1,6 @@
- type: entity
id: BoozeDispenser
name: booze dispenser
suffix: Filled
description: A booze dispenser with a single slot for a container to be filled.
parent: ReagentDispenserBase
components:
@@ -11,10 +10,8 @@
drawdepth: SmallObjects
state: booze
- type: ReagentDispenser
storageWhitelist:
tags:
- DrinkBottle
pack: BoozeDispenserInventory
emagPack: BoozeDispenserEmagInventory
- type: Transform
noRot: false
- type: Machine
@@ -27,14 +24,3 @@
- Bartender
- type: StealTarget
stealGroup: BoozeDispenser
- type: entity
id: BoozeDispenserEmpty
suffix: Empty
parent: BoozeDispenser
components:
- type: ReagentDispenser
storageWhitelist:
tags:
- DrinkBottle
pack: EmptyInventory

View File

@@ -1,19 +1,16 @@
- type: entity
- type: entity
id: ChemDispenser
name: chemical dispenser
suffix: Filled
parent: ReagentDispenserBase
description: An industrial grade chemical dispenser.
description: An industrial grade chemical dispenser with a sizeable chemical supply.
components:
- type: Sprite
sprite: Structures/dispensers.rsi
state: industrial-working
snapCardinals: true
- type: ReagentDispenser
storageWhitelist:
tags:
- ChemDispensable
pack: ChemDispenserStandardInventory
emagPack: ChemDispenserEmaggedInventory
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: Destructible
@@ -40,12 +37,3 @@
- Chemist
- type: StealTarget
stealGroup: ChemDispenser
- type: entity
id: ChemDispenserEmpty
name: chemical dispenser
suffix: Empty
parent: ChemDispenser
components:
- type: ReagentDispenser
pack: EmptyInventory

View File

@@ -1,7 +1,6 @@
- type: entity
id: soda_dispenser
name: soda dispenser
suffix: Filled
parent: ReagentDispenserBase
description: A beverage dispenser with a selection of soda and several other common beverages. Has a single fill slot for containers.
components:
@@ -11,10 +10,8 @@
drawdepth: SmallObjects
state: soda
- type: ReagentDispenser
storageWhitelist:
tags:
- DrinkBottle
pack: SodaDispenserInventory
emagPack: SodaDispenserEmagInventory
- type: Transform
noRot: false
- type: Machine
@@ -25,14 +22,3 @@
- type: GuideHelp
guides:
- Bartender
- type: entity
id: SodaDispenserEmpty
suffix: Empty
parent: soda_dispenser
components:
- type: ReagentDispenser
storageWhitelist:
tags:
- DrinkBottle
pack: EmptyInventory

View File

@@ -252,7 +252,7 @@
- type: Tag
id: CannonBall
- type: Tag
id: CannonRestrict