diff --git a/Content.Client/Chemistry/UI/ButtonGrid.cs b/Content.Client/Chemistry/UI/ButtonGrid.cs new file mode 100644 index 0000000000..0abd9ef8a4 --- /dev/null +++ b/Content.Client/Chemistry/UI/ButtonGrid.cs @@ -0,0 +1,119 @@ +using System; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.Chemistry.UI; + +/// +/// Creates a grid of buttons given a comma-seperated list of Text +/// +public sealed class ButtonGrid : GridContainer +{ + private string _buttonList = ""; + + /// + /// A comma-seperated list of text to use for each button. These will be inserted sequentially. + /// + public string ButtonList + { + get => _buttonList; + set + { + _buttonList = value; + Update(); + } + } + + public bool RadioGroup { get; set; } = false; + + private string? _selected; + + /// + /// Which button is currently selected. Only matters when is true. + /// + public string? Selected + { + get => _selected; + set + { + _selected = value; + Update(); + } + } + + public Action? OnButtonPressed; + + /// + /// + /// + public new int Columns + { + get => base.Columns; + set + { + base.Columns = value; + Update(); + } + } + + /// + /// + /// + public new int Rows + { + get => base.Rows; + set + { + base.Rows = value; + Update(); + } + } + + private void Update() + { + if (ButtonList == "") + return; + + this.Children.Clear(); + var i = 0; + var list = ButtonList.Split(","); + + var group = new ButtonGroup(); + + foreach (var button in list) + { + var btn = new Button(); + btn.Text = button; + btn.OnPressed += _ => + { + if (RadioGroup) + btn.Pressed = true; + Selected = button; + OnButtonPressed?.Invoke(button); + }; + if (button == Selected) + btn.Pressed = true; + var sep = HSeparationOverride ?? 0; + // ReSharper disable once PossibleLossOfFraction + // btn.SetWidth = (this.PixelWidth - sep * (Columns - 1)) / 3; + btn.Group = group; + + var row = i / Columns; + var col = i % Columns; + var last = i == list.Length - 1; + var lastCol = i == Columns - 1; + var lastRow = row == list.Length / Columns - 1; + + if (row == 0 && (lastCol || last)) + btn.AddStyleClass("OpenLeft"); + else if (col == 0 && lastRow) + btn.AddStyleClass("OpenRight"); + else + btn.AddStyleClass("OpenBoth"); + + this.Children.Add(btn); + + i++; + } + } +} diff --git a/Content.Client/Chemistry/UI/ReagentCardControl.xaml b/Content.Client/Chemistry/UI/ReagentCardControl.xaml new file mode 100644 index 0000000000..257b0b6c52 --- /dev/null +++ b/Content.Client/Chemistry/UI/ReagentCardControl.xaml @@ -0,0 +1,36 @@ + + + + + + + diff --git a/Content.Client/Chemistry/UI/ReagentCardControl.xaml.cs b/Content.Client/Chemistry/UI/ReagentCardControl.xaml.cs new file mode 100644 index 0000000000..f7cadcc264 --- /dev/null +++ b/Content.Client/Chemistry/UI/ReagentCardControl.xaml.cs @@ -0,0 +1,32 @@ +using Content.Shared.Chemistry; +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.Chemistry.UI; + +[GenerateTypedNameReferences] +public sealed partial class ReagentCardControl : Control +{ + public string StorageSlotId { get; } + public Action? OnPressed; + public Action? OnEjectButtonPressed; + + public ReagentCardControl(ReagentInventoryItem item) + { + RobustXamlLoader.Load(this); + + StorageSlotId = item.StorageSlotId; + ColorPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = item.ReagentColor }; + ReagentNameLabel.Text = item.ReagentLabel; + FillLabel.Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", item.Quantity));; + EjectButtonIcon.Text = Loc.GetString("reagent-dispenser-window-eject-container-button"); + + if (item.Quantity == 0.0) + MainButton.Disabled = true; + + MainButton.OnPressed += args => OnPressed?.Invoke(StorageSlotId); + EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageSlotId); + } +} diff --git a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs index c94759a6c1..fce57a6ec5 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs @@ -42,28 +42,11 @@ namespace Content.Client.Chemistry.UI // Setup static button actions. _window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName)); _window.ClearButton.OnPressed += _ => SendMessage(new ReagentDispenserClearContainerSolutionMessage()); - _window.DispenseButton1.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U1)); - _window.DispenseButton5.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U5)); - _window.DispenseButton10.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U10)); - _window.DispenseButton15.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U15)); - _window.DispenseButton20.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U20)); - _window.DispenseButton25.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U25)); - _window.DispenseButton30.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U30)); - _window.DispenseButton50.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U50)); - _window.DispenseButton100.OnPressed += _ => SendMessage(new ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount.U100)); - // Setup reagent button actions. - _window.OnDispenseReagentButtonPressed += (args, button) => SendMessage(new ReagentDispenserDispenseReagentMessage(button.ReagentId)); - _window.OnDispenseReagentButtonMouseEntered += (args, button) => - { - if (_lastState is not null) - _window.UpdateContainerInfo(_lastState, button.ReagentId); - }; - _window.OnDispenseReagentButtonMouseExited += (args, button) => - { - if (_lastState is not null) - _window.UpdateContainerInfo(_lastState); - }; + _window.AmountGrid.OnButtonPressed += s => SendMessage(new ReagentDispenserSetDispenseAmountMessage(s)); + + _window.OnDispenseReagentButtonPressed += (id) => SendMessage(new ReagentDispenserDispenseReagentMessage(id)); + _window.OnEjectJugButtonPressed += (id) => SendMessage(new ItemSlotButtonPressedEvent(id)); } /// diff --git a/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml b/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml index 20bff6f966..9da340f8a7 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml +++ b/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml @@ -1,53 +1,78 @@ - - - - [GenerateTypedNameReferences] - public sealed partial class ReagentDispenserWindow : DefaultWindow + public sealed partial class ReagentDispenserWindow : FancyWindow { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!; - - public event Action? OnDispenseReagentButtonPressed; - public event Action? OnDispenseReagentButtonMouseEntered; - public event Action? OnDispenseReagentButtonMouseExited; + public event Action? OnDispenseReagentButtonPressed; + public event Action? OnEjectJugButtonPressed; /// /// Create and initialize the dispenser UI client-side. Creates the basic layout, @@ -33,45 +29,27 @@ namespace Content.Client.Chemistry.UI { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - - var dispenseAmountGroup = new ButtonGroup(); - DispenseButton1.Group = dispenseAmountGroup; - DispenseButton5.Group = dispenseAmountGroup; - DispenseButton10.Group = dispenseAmountGroup; - DispenseButton15.Group = dispenseAmountGroup; - DispenseButton20.Group = dispenseAmountGroup; - DispenseButton25.Group = dispenseAmountGroup; - DispenseButton30.Group = dispenseAmountGroup; - DispenseButton50.Group = dispenseAmountGroup; - DispenseButton100.Group = dispenseAmountGroup; } /// /// Update the button grid of reagents which can be dispensed. /// /// Reagents which can be dispensed by this dispenser - public void UpdateReagentsList(List inventory) + public void UpdateReagentsList(List inventory) { - if (ChemicalList == null) + if (ReagentList == null) return; - ChemicalList.Children.Clear(); + ReagentList.Children.Clear(); + //Sort inventory by reagentLabel + inventory.Sort((x, y) => x.ReagentLabel.CompareTo(y.ReagentLabel)); - foreach (var entry in inventory.OrderBy(r => - { - _prototypeManager.TryIndex(r.Prototype, out ReagentPrototype? p); - return p?.LocalizedName; - })) + foreach (var item in inventory) { - 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 card = new ReagentCardControl(item); + card.OnPressed += OnDispenseReagentButtonPressed; + card.OnEjectButtonPressed += OnEjectJugButtonPressed; + ReagentList.Children.Add(card); } } @@ -92,36 +70,7 @@ namespace Content.Client.Chemistry.UI ClearButton.Disabled = castState.OutputContainer is null; EjectButton.Disabled = castState.OutputContainer is null; - switch (castState.SelectedDispenseAmount) - { - case ReagentDispenserDispenseAmount.U1: - DispenseButton1.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U5: - DispenseButton5.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U10: - DispenseButton10.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U15: - DispenseButton15.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U20: - DispenseButton20.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U25: - DispenseButton25.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U30: - DispenseButton30.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U50: - DispenseButton50.Pressed = true; - break; - case ReagentDispenserDispenseAmount.U100: - DispenseButton100.Pressed = true; - break; - } + AmountGrid.Selected = ((int)castState.SelectedDispenseAmount).ToString(); } /// @@ -129,31 +78,22 @@ namespace Content.Client.Chemistry.UI /// Also highlights a reagent if it's dispense button is being mouse hovered. /// /// State data for the dispenser. - /// Prototype ID of the reagent whose dispense button is currently being mouse hovered, /// or null if no button is being hovered. - public void UpdateContainerInfo(ReagentDispenserBoundUserInterfaceState state, ReagentId? highlightedReagentId = null) + public void UpdateContainerInfo(ReagentDispenserBoundUserInterfaceState state) { ContainerInfo.Children.Clear(); if (state.OutputContainer is null) { + ContainerInfoName.Text = ""; + ContainerInfoFill.Text = ""; ContainerInfo.Children.Add(new Label { Text = Loc.GetString("reagent-dispenser-window-no-container-loaded-text") }); return; } - ContainerInfo.Children.Add(new BoxContainer // Name of the container and its fill status (Ex: 44/100u) - { - Orientation = LayoutOrientation.Horizontal, - Children = - { - new Label {Text = $"{state.OutputContainer.DisplayName}: "}, - new Label - { - Text = $"{state.OutputContainer.CurrentVolume}/{state.OutputContainer.MaxVolume}", - StyleClasses = {StyleNano.StyleClassLabelSecondaryColor} - } - } - }); + // Set Name of the container and its fill status (Ex: 44/100u) + ContainerInfoName.Text = state.OutputContainer.DisplayName; + ContainerInfoFill.Text = state.OutputContainer.CurrentVolume + "/" + state.OutputContainer.MaxVolume; foreach (var (reagent, quantity) in state.OutputContainer.Reagents!) { @@ -169,12 +109,6 @@ 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, @@ -187,14 +121,4 @@ namespace Content.Client.Chemistry.UI } } } - - public sealed class DispenseReagentButton : Button { - public ReagentId ReagentId { get; } - - public DispenseReagentButton(ReagentId reagentId, string text) - { - ReagentId = reagentId; - Text = text; - } - } } diff --git a/Content.IntegrationTests/Tests/Chemistry/DispenserTest.cs b/Content.IntegrationTests/Tests/Chemistry/DispenserTest.cs index 13a0bee28e..a5449308be 100644 --- a/Content.IntegrationTests/Tests/Chemistry/DispenserTest.cs +++ b/Content.IntegrationTests/Tests/Chemistry/DispenserTest.cs @@ -1,6 +1,7 @@ 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; @@ -24,7 +25,7 @@ public sealed class DispenserTest : InteractionTest await Interact(); // Eject beaker via BUI. - var ev = new ItemSlotButtonPressedEvent(SharedChemMaster.InputSlotName); + var ev = new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName); await SendBui(ReagentDispenserUiKey.Key, ev); // Beaker is back in the player's hands diff --git a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs index 832f584ecb..33d0da12d7 100644 --- a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs +++ b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Whitelist; +using Content.Shared.Containers.ItemSlots; using Content.Server.Chemistry.EntitySystems; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Dispenser; @@ -7,20 +9,52 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy namespace Content.Server.Chemistry.Components { /// - /// A machine that dispenses reagents into a solution container. + /// A machine that dispenses reagents into a solution container from containers in its storage slots. /// [RegisterComponent] [Access(typeof(ReagentDispenserSystem), typeof(ChemMasterSystem))] public sealed partial class ReagentDispenserComponent : Component { - + /// + /// 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. + /// [DataField("pack", customTypeSerializer:typeof(PrototypeIdSerializer))] [ViewVariables(VVAccess.ReadWrite)] public string? PackPrototypeId = default!; - [DataField("emagPack", customTypeSerializer:typeof(PrototypeIdSerializer))] - [ViewVariables(VVAccess.ReadWrite)] - public string? EmagPackPrototypeId = default!; + /// + /// Maximum number of internal storage slots. Dispenser can't store (or dispense) more than + /// this many chemicals (without unloading and reloading). + /// + [DataField("numStorageSlots")] + public int NumSlots = 25; + + /// + /// 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. + /// + [DataField] + public EntityWhitelist? StorageWhitelist; + + [DataField] + public ItemSlot BeakerSlot = new(); + + /// + /// Prefix for automatically-generated slot name for storage, up to NumSlots. + /// + public static string BaseStorageSlotId = "ReagentDispenser-storageSlot"; + + /// + /// List of storage slots that were created at MapInit. + /// + [DataField] + public List StorageSlotIds = new List(); + + [DataField] + public List StorageSlots = new List(); [DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index 8b1bc4c8c1..2c58be074c 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -1,6 +1,5 @@ using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.DeviceLinking.Systems; using Content.Server.Labels; using Content.Server.Popups; using Content.Server.Storage.EntitySystems; @@ -11,7 +10,6 @@ using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reagent; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; -using Content.Shared.DeviceLinking.Events; using Content.Shared.FixedPoint; using Content.Shared.Storage; using JetBrains.Annotations; @@ -25,7 +23,6 @@ using System.Linq; namespace Content.Server.Chemistry.EntitySystems { - /// /// Contains all the server-side logic for ChemMasters. /// @@ -41,8 +38,6 @@ namespace Content.Server.Chemistry.EntitySystems [Dependency] private readonly StorageSystem _storageSystem = default!; [Dependency] private readonly LabelSystem _labelSystem = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly ReagentDispenserSystem _dispenserSystem = default!; // WD - [Dependency] private readonly DeviceLinkSystem _signalSystem = default!; // WD [ValidatePrototypeId] private const string PillPrototypeId = "Pill"; @@ -56,14 +51,7 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); - - // WD START - SubscribeLocalEvent(OnComponentInit); - SubscribeLocalEvent(OnPortDisconnected); - SubscribeLocalEvent(OnAnchor); - // WD END - - + SubscribeLocalEvent(OnSetModeMessage); SubscribeLocalEvent(OnSetPillTypeMessage); SubscribeLocalEvent(OnReagentButtonMessage); @@ -71,30 +59,6 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(OnOutputToBottleMessage); } - // WD START - private void OnComponentInit(EntityUid uid, ChemMasterComponent clonePod, ComponentInit args) - { - _signalSystem.EnsureSinkPorts(uid, ChemMasterComponent.ChemMasterPort); - } - - private void OnPortDisconnected(EntityUid uid, ChemMasterComponent component, PortDisconnectedEvent args) - { - component.ConnectedDispenser = null; - } - - private void OnAnchor(EntityUid uid, ChemMasterComponent component, ref AnchorStateChangedEvent args) - { - if (component.ConnectedDispenser == null || - !TryComp(component.ConnectedDispenser, out var dispenserComp)) - return; - - if (!args.Anchored) - return; - - _dispenserSystem.UpdateConnection(component.ConnectedDispenser.Value, uid, dispenserComp, component); - } - // WD END - private void SubscribeUpdateUiState(Entity ent, ref T ev) { UpdateUiState(ent); diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index 7d638bf111..2361125d96 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -1,26 +1,20 @@ +using Content.Server.Administration.Logs; using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.DeviceLinking.Systems; +using Content.Server.Nutrition.Components; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Dispenser; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Containers.ItemSlots; -using Content.Shared.Database; -using Content.Shared.DeviceLinking; -using Content.Shared.DeviceLinking.Events; -using Content.Shared.Emag.Components; -using Content.Shared.Emag.Systems; using Content.Shared.FixedPoint; +using Content.Shared.Nutrition.EntitySystems; using JetBrains.Annotations; using Robust.Server.Audio; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.Prototypes; -using System.Linq; -using Content.Server.Administration.Logs; -using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.Reagent; +using Content.Shared.Labels.Components; namespace Content.Server.Chemistry.EntitySystems { @@ -33,13 +27,13 @@ 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 DeviceLinkSystem _signalSystem = default!; // WD - [Dependency] private readonly ChemMasterSystem _chemMasterSystem = default!; // WD [Dependency] private readonly IAdminLogManager _adminLogger = default!; - + [Dependency] private readonly OpenableSystem _openable = default!; + public override void Initialize() { base.Initialize(); @@ -50,108 +44,13 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); - // WD START - SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnNewLink); - SubscribeLocalEvent(OnPortDisconnected); - SubscribeLocalEvent(OnAnchorChanged); - // WD END - - SubscribeLocalEvent(OnEmagged); - SubscribeLocalEvent(OnSetDispenseAmountMessage); SubscribeLocalEvent(OnDispenseReagentMessage); SubscribeLocalEvent(OnClearContainerSolutionMessage); + + SubscribeLocalEvent(OnMapInit, before: new []{typeof(ItemSlotsSystem)}); } - // WD START - private void OnInit(EntityUid uid, ReagentDispenserComponent component, ComponentInit args) - { - _signalSystem.EnsureSourcePorts(uid, ReagentDispenserComponent.ChemMasterPort); - } - - private void OnMapInit(EntityUid uid, ReagentDispenserComponent component, MapInitEvent args) - { - if (!TryComp(uid, out var receiver)) - return; - - foreach (var port in receiver.Outputs.Values.SelectMany(ports => ports)) - { - if (!TryComp(port, out var master)) - continue; - - UpdateConnection(uid, port, component, master); - break; - } - } - - private void OnNewLink(EntityUid uid, ReagentDispenserComponent component, NewLinkEvent args) - { - if (TryComp(args.Sink, out var master) && args.SourcePort == ReagentDispenserComponent.ChemMasterPort) - UpdateConnection(uid, args.Sink, component, master); - } - - private void OnPortDisconnected(EntityUid uid, ReagentDispenserComponent component, PortDisconnectedEvent args) - { - if (args.Port != ReagentDispenserComponent.ChemMasterPort) - return; - - component.ChemMaster = null; - component.ChemMasterInRange = false; - } - - private void OnAnchorChanged(EntityUid uid, ReagentDispenserComponent component, ref AnchorStateChangedEvent args) - { - if (args.Anchored) - RecheckConnections(uid, component); - } - - public void UpdateConnection( - EntityUid dispenser, - EntityUid chemMaster, - ReagentDispenserComponent? dispenserComp = null, - ChemMasterComponent? chemMasterComp = null) - { - if (!Resolve(dispenser, ref dispenserComp) || !Resolve(chemMaster, ref chemMasterComp)) - return; - - if (dispenserComp.ChemMaster.HasValue && dispenserComp.ChemMaster.Value != chemMaster && - TryComp(dispenserComp.ChemMaster, out ChemMasterComponent? oldMaster)) - { - oldMaster.ConnectedDispenser = null; - } - - if (chemMasterComp.ConnectedDispenser.HasValue && chemMasterComp.ConnectedDispenser.Value != dispenser && - TryComp(dispenserComp.ChemMaster, out ReagentDispenserComponent? oldDispenser)) - { - oldDispenser.ChemMaster = null; - oldDispenser.ChemMasterInRange = false; - } - - dispenserComp.ChemMaster = chemMaster; - chemMasterComp.ConnectedDispenser = dispenser; - - RecheckConnections(dispenser, dispenserComp); - } - - private void RecheckConnections(EntityUid dispenser, ReagentDispenserComponent? component = null) - { - if (!Resolve(dispenser, ref component)) - return; - - if (component.ChemMaster == null) - { - component.ChemMasterInRange = false; - return; - } - - Transform(component.ChemMaster.Value).Coordinates - .TryDistance(EntityManager, Transform(dispenser).Coordinates, out var distance); - component.ChemMasterInRange = distance <= 1.5f; - } - // WD END - private void SubscribeUpdateUiState(Entity ent, ref T ev) { UpdateUiState(ent); @@ -184,35 +83,39 @@ namespace Content.Server.Chemistry.EntitySystems return null; } - private List GetInventory(Entity ent) + private List GetInventory(Entity reagentDispenser) { - var reagentDispenser = ent.Comp; - var inventory = new List(); + var inventory = new List(); - if (reagentDispenser.PackPrototypeId is not null - && _prototypeManager.TryIndex(reagentDispenser.PackPrototypeId, out ReagentDispenserInventoryPrototype? packPrototype)) + for (var i = 0; i < reagentDispenser.Comp.NumSlots; i++) { - inventory.AddRange(packPrototype.Inventory.Select(x => new ReagentId(x, null))); - } + var storageSlotId = ReagentDispenserComponent.BaseStorageSlotId + i; + var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser.Owner, storageSlotId); - if (HasComp(ent) - && reagentDispenser.EmagPackPrototypeId is not null - && _prototypeManager.TryIndex(reagentDispenser.EmagPackPrototypeId, out ReagentDispenserInventoryPrototype? emagPackPrototype)) - { - inventory.AddRange(emagPackPrototype.Inventory.Select(x => new ReagentId(x, null))); + // Set label from manually-applied label, or metadata if unavailable + string reagentLabel; + if (TryComp(storedContainer, out var label) && !string.IsNullOrEmpty(label.CurrentLabel)) + reagentLabel = label.CurrentLabel; + else if (storedContainer != null) + reagentLabel = Name(storedContainer.Value); + else + continue; + + // 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)) + { + quantity = sol.Volume; + reagentColor = sol.GetColor(_prototypeManager); + } + + inventory.Add(new ReagentInventoryItem(storageSlotId, reagentLabel, quantity, reagentColor)); } return inventory; } - private void OnEmagged(Entity reagentDispenser, ref GotEmaggedEvent args) - { - // adding component manually to have correct state - EntityManager.AddComponent(reagentDispenser); - UpdateUiState(reagentDispenser); - args.Handled = true; - } - private void OnSetDispenseAmountMessage(Entity reagentDispenser, ref ReagentDispenserSetDispenseAmountMessage message) { reagentDispenser.Comp.DispenseAmount = message.ReagentDispenserDispenseAmount; @@ -223,33 +126,23 @@ namespace Content.Server.Chemistry.EntitySystems private void OnDispenseReagentMessage(Entity reagentDispenser, ref ReagentDispenserDispenseReagentMessage message) { // Ensure that the reagent is something this reagent dispenser can dispense. - if (!GetInventory(reagentDispenser).Contains(message.ReagentId)) + var storedContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, message.SlotId); + if (storedContainer == null) return; var outputContainer = _itemSlotsSystem.GetItemOrNull(reagentDispenser, SharedReagentDispenser.OutputSlotName); if (outputContainer is not { Valid: true } || !_solutionContainerSystem.TryGetFitsInDispenser(outputContainer.Value, out var solution, out _)) - { - // WD EDIT START - var chemMasterUid = reagentDispenser.Comp.ChemMaster; - if (!reagentDispenser.Comp.ChemMasterInRange || - !TryComp(chemMasterUid, out ChemMasterComponent? chemMaster) || - !TryComp(chemMasterUid, out SolutionContainerManagerComponent? solutionContainer) || - !_solutionContainerSystem.TryGetSolution((chemMasterUid.Value, solutionContainer), - SharedChemMaster.BufferSolutionName, out var bufferSolution)) - return; - - bufferSolution.Value.Comp.Solution.AddReagent(message.ReagentId, FixedPoint2.New((int)reagentDispenser.Comp.DispenseAmount)); - _chemMasterSystem.UpdateUiState((chemMasterUid.Value, chemMaster)); - ClickSound(reagentDispenser); - return; - } // WD EDIT END - if (_solutionContainerSystem.TryAddReagent(solution.Value, message.ReagentId, (int) reagentDispenser.Comp.DispenseAmount, out var dispensedAmount) - && message.Session.AttachedEntity is not null) + if (_solutionContainerSystem.TryGetDrainableSolution(storedContainer.Value, out var src, out _) && + _solutionContainerSystem.TryGetRefillableSolution(outputContainer.Value, out var dst, out _)) { - _adminLogger.Add(LogType.ChemicalReaction, LogImpact.Medium, - $"{ToPrettyString(message.Session.AttachedEntity.Value):player} dispensed {dispensedAmount}u of {message.ReagentId} into {ToPrettyString(outputContainer.Value):entity}"); + // 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); } UpdateUiState(reagentDispenser); @@ -271,5 +164,41 @@ namespace Content.Server.Chemistry.EntitySystems { _audioSystem.PlayPvs(reagentDispenser.Comp.ClickSound, reagentDispenser, AudioParams.Default.WithVolume(-2f)); } + + /// + /// Automatically generate storage slots for all NumSlots, and fill them with their initial chemicals. + /// The actual spawning of entities happens in ItemSlotsSystem's MapInit. + /// + private void OnMapInit(EntityUid uid, ReagentDispenserComponent component, MapInitEvent args) + { + // Get list of pre-loaded containers + List preLoad = new List(); + 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); + } } } diff --git a/Content.Shared/Chemistry/Dispenser/ReagentDispenserInventoryPrototype.cs b/Content.Shared/Chemistry/Dispenser/ReagentDispenserInventoryPrototype.cs index c362535e4f..5cdc8aed80 100644 --- a/Content.Shared/Chemistry/Dispenser/ReagentDispenserInventoryPrototype.cs +++ b/Content.Shared/Chemistry/Dispenser/ReagentDispenserInventoryPrototype.cs @@ -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,8 +14,7 @@ namespace Content.Shared.Chemistry.Dispenser [Serializable, NetSerializable, Prototype("reagentDispenserInventory")] public sealed partial class ReagentDispenserInventoryPrototype : IPrototype { - // TODO use ReagentId - [DataField("inventory", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [DataField("inventory", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List Inventory = new(); [ViewVariables, IdDataField] diff --git a/Content.Shared/Chemistry/SharedReagentDispenser.cs b/Content.Shared/Chemistry/SharedReagentDispenser.cs index bfae45ea95..c7ecd0ff43 100644 --- a/Content.Shared/Chemistry/SharedReagentDispenser.cs +++ b/Content.Shared/Chemistry/SharedReagentDispenser.cs @@ -1,67 +1,133 @@ using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; using Robust.Shared.Serialization; -namespace Content.Shared.Chemistry; - -/// -/// This class holds constants that are shared between client and server. -/// -public sealed class SharedReagentDispenser +namespace Content.Shared.Chemistry { - public const string OutputSlotName = "beakerSlot"; -} - -[Serializable, NetSerializable] -public sealed class ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount amount) - : BoundUserInterfaceMessage -{ - public readonly ReagentDispenserDispenseAmount ReagentDispenserDispenseAmount = amount; -} - -[Serializable, NetSerializable] -public sealed class ReagentDispenserDispenseReagentMessage(ReagentId reagentId) : BoundUserInterfaceMessage -{ - public readonly 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( - ContainerInfo? outputContainer, - NetEntity? outputContainerEntity, - List inventory, - ReagentDispenserDispenseAmount selectedDispenseAmount) - : BoundUserInterfaceState -{ - public readonly ContainerInfo? OutputContainer = outputContainer; - - public readonly NetEntity? OutputContainerEntity = outputContainerEntity; - /// - /// A list of the reagents which this dispenser can dispense. + /// This class holds constants that are shared between client and server. /// - public readonly List Inventory = inventory; + public sealed class SharedReagentDispenser + { + public const string OutputSlotName = "beakerSlot"; + } - public readonly ReagentDispenserDispenseAmount SelectedDispenseAmount = selectedDispenseAmount; + [Serializable, NetSerializable] + public sealed class ReagentDispenserSetDispenseAmountMessage : BoundUserInterfaceMessage + { + public readonly ReagentDispenserDispenseAmount ReagentDispenserDispenseAmount; + + public ReagentDispenserSetDispenseAmountMessage(ReagentDispenserDispenseAmount amount) + { + ReagentDispenserDispenseAmount = amount; + } + + /// + /// Create a new instance from interpreting a String as an integer, + /// throwing an exception if it is unable to parse. + /// + public ReagentDispenserSetDispenseAmountMessage(String s) + { + switch (s) + { + case "1": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U1; + break; + case "5": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U5; + break; + case "10": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U10; + break; + case "15": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U15; + break; + case "20": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U20; + break; + case "25": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U25; + break; + case "30": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U30; + break; + case "50": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U50; + break; + case "100": + ReagentDispenserDispenseAmount = ReagentDispenserDispenseAmount.U100; + break; + default: + throw new Exception($"Cannot convert the string `{s}` into a valid ReagentDispenser DispenseAmount"); + } + } + } + + [Serializable, NetSerializable] + public sealed class ReagentDispenserDispenseReagentMessage : BoundUserInterfaceMessage + { + public readonly string SlotId; + + public ReagentDispenserDispenseReagentMessage(string slotId) + { + SlotId = slotId; + } + } + + [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 ReagentInventoryItem(string storageSlotId, string reagentLabel, FixedPoint2 quantity, Color reagentColor) + { + public string StorageSlotId = storageSlotId; + public string ReagentLabel = reagentLabel; + public FixedPoint2 Quantity = quantity; + public Color ReagentColor = reagentColor; + } + + [Serializable, NetSerializable] + public sealed class ReagentDispenserBoundUserInterfaceState : BoundUserInterfaceState + { + public readonly ContainerInfo? OutputContainer; + + public readonly NetEntity? OutputContainerEntity; + + /// + /// A list of the reagents which this dispenser can dispense. + /// + public readonly List Inventory; + + public readonly ReagentDispenserDispenseAmount SelectedDispenseAmount; + + public ReagentDispenserBoundUserInterfaceState(ContainerInfo? outputContainer, NetEntity? outputContainerEntity, List inventory, ReagentDispenserDispenseAmount selectedDispenseAmount) + { + OutputContainer = outputContainer; + OutputContainerEntity = outputContainerEntity; + Inventory = inventory; + SelectedDispenseAmount = selectedDispenseAmount; + } + } + + [Serializable, NetSerializable] + public enum ReagentDispenserUiKey + { + Key + } } - -[Serializable, NetSerializable] -public enum ReagentDispenserUiKey -{ - Key -} \ No newline at end of file diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs index 7904816f57..372d9a980b 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs @@ -12,14 +12,16 @@ namespace Content.Shared.Containers.ItemSlots /// Used for entities that can hold items in different slots. Needed by ItemSlotSystem to support basic /// insert/eject interactions. /// - [RegisterComponent, Access(typeof(ItemSlotsSystem)), NetworkedComponent] + [RegisterComponent] + [Access(typeof(ItemSlotsSystem))] + [NetworkedComponent] public sealed partial class ItemSlotsComponent : Component { /// /// The dictionary that stores all of the item slots whose interactions will be managed by the . /// - [DataField(readOnly: true)] + [DataField("slots", readOnly:true)] public Dictionary Slots = new(); // There are two ways to use item slots: @@ -39,21 +41,26 @@ namespace Content.Shared.Containers.ItemSlots } [Serializable, NetSerializable] - public sealed class ItemSlotsComponentState(Dictionary slots) : ComponentState + public sealed class ItemSlotsComponentState : ComponentState { - public readonly Dictionary Slots = slots; + public readonly Dictionary Slots; + + public ItemSlotsComponentState(Dictionary slots) + { + Slots = slots; + } } /// /// This is effectively a wrapper for a ContainerSlot that adds content functionality like entity whitelists and /// insert/eject sounds. /// - [DataDefinition, Access(typeof(ItemSlotsSystem)), Serializable, NetSerializable] + [DataDefinition] + [Access(typeof(ItemSlotsSystem))] + [Serializable, NetSerializable] public sealed partial class ItemSlot { - public ItemSlot() - { - } + public ItemSlot() { } public ItemSlot(ItemSlot other) { @@ -61,6 +68,7 @@ namespace Content.Shared.Containers.ItemSlots } [DataField] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] public EntityWhitelist? Whitelist; [DataField] @@ -79,8 +87,8 @@ namespace Content.Shared.Containers.ItemSlots /// This will be passed through Loc.GetString. If the name is an empty string, then verbs will use the name /// of the currently held or currently inserted entity instead. /// - [DataField(readOnly: true), Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] - // FIXME Friends + [DataField(readOnly: true)] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends public string Name = string.Empty; /// @@ -91,9 +99,9 @@ namespace Content.Shared.Containers.ItemSlots /// property of that component (e.g., cell slot size category), and this can lead to unnecessary changes /// when mapping. /// - [DataField(readOnly: true, customTypeSerializer: typeof(PrototypeIdSerializer)), - Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute), NonSerialized] - // FIXME Friends + [DataField(readOnly: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] // FIXME Friends + [NonSerialized] public string? StartingItem; /// @@ -103,8 +111,9 @@ namespace Content.Shared.Containers.ItemSlots /// This doesn't have to mean the slot is somehow physically locked. In the case of the item cabinet, the /// cabinet may simply be closed at the moment and needs to be opened first. /// - [DataField(readOnly: true), ViewVariables(VVAccess.ReadWrite)] - public bool Locked; + [DataField(readOnly: true)] + [ViewVariables(VVAccess.ReadWrite)] + public bool Locked = false; /// /// Prevents adding the eject alt-verb, but still lets you swap items. @@ -113,7 +122,7 @@ namespace Content.Shared.Containers.ItemSlots /// This does not affect EjectOnInteract, since if you do that you probably want ejecting to work. /// [DataField, ViewVariables(VVAccess.ReadWrite)] - public bool DisableEject; + public bool DisableEject = false; /// /// Whether the item slots system will attempt to insert item from the user's hands into this slot when interacted with. @@ -131,7 +140,7 @@ namespace Content.Shared.Containers.ItemSlots /// contents when clicked on normally. /// [DataField] - public bool EjectOnInteract; + public bool EjectOnInteract = false; /// /// If true, and if this slot is attached to an item, then it will attempt to eject slot when to the slot is @@ -143,7 +152,7 @@ namespace Content.Shared.Containers.ItemSlots /// menu, nor will it disable alt-click interactions. /// [DataField] - public bool EjectOnUse; + public bool EjectOnUse = false; /// /// Override the insert verb text. Defaults to using the slot's name (if specified) or the name of the @@ -160,7 +169,7 @@ namespace Content.Shared.Containers.ItemSlots public string? EjectVerbText; [ViewVariables, NonSerialized] - public ContainerSlot? ContainerSlot; + public ContainerSlot? ContainerSlot = default!; /// /// If this slot belongs to some de-constructible component, should the item inside the slot be ejected upon @@ -169,15 +178,19 @@ namespace Content.Shared.Containers.ItemSlots /// /// The actual deconstruction logic is handled by the server-side EmptyOnMachineDeconstructSystem. /// - [DataField, NonSerialized] + [DataField] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] + [NonSerialized] public bool EjectOnDeconstruct = true; /// /// If this slot belongs to some breakable or destructible entity, should the item inside the slot be /// ejected when it is broken or destroyed? /// - [DataField, NonSerialized] - public bool EjectOnBreak; + [DataField] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] + [NonSerialized] + public bool EjectOnBreak = false; /// /// When specified, a popup will be generated whenever someone attempts to insert a bad item into this slot. @@ -207,23 +220,20 @@ namespace Content.Shared.Containers.ItemSlots /// want to insert more than one item that matches the same whitelist. /// [DataField] + [Access(typeof(ItemSlotsSystem), Other = AccessPermissions.ReadWriteExecute)] public bool Swap = true; public string? ID => ContainerSlot?.ID; // Convenience properties public bool HasItem => ContainerSlot?.ContainedEntity != null; - public EntityUid? Item => ContainerSlot?.ContainedEntity; /// /// Priority for use with the eject & insert verbs for this slot. /// [DataField] - public int Priority; - - [DataField("maxStackAmount")] // WD - public int MaxStackAmount; + public int Priority = 0; /// /// If false, errors when adding an item slot with a duplicate key are suppressed. Local==true implies that @@ -232,6 +242,9 @@ namespace Content.Shared.Containers.ItemSlots [NonSerialized] public bool Local = true; + [DataField] // WD + public int MaxStackAmount; + public void CopyFrom(ItemSlot other) { // These fields are mutable reference types. But they generally don't get modified, so this should be fine. @@ -247,10 +260,10 @@ namespace Content.Shared.Containers.ItemSlots InsertVerbText = other.InsertVerbText; EjectVerbText = other.EjectVerbText; WhitelistFailPopup = other.WhitelistFailPopup; - LockedFailPopup = other.LockedFailPopup; - InsertSuccessPopup = other.InsertSuccessPopup; Swap = other.Swap; Priority = other.Priority; + + MaxStackAmount = other.MaxStackAmount; } } @@ -258,21 +271,11 @@ namespace Content.Shared.Containers.ItemSlots /// Event raised on the slot entity and the item being inserted to determine if an item can be inserted into an item slot. /// [ByRefEvent] - public record struct ItemSlotInsertAttemptEvent( - EntityUid SlotEntity, - EntityUid Item, - EntityUid? User, - ItemSlot Slot, - bool Cancelled = false); + public record struct ItemSlotInsertAttemptEvent(EntityUid SlotEntity, EntityUid Item, EntityUid? User, ItemSlot Slot, bool Cancelled = false); /// /// Event raised on the slot entity and the item being inserted to determine if an item can be ejected from an item slot. /// [ByRefEvent] - public record struct ItemSlotEjectAttemptEvent( - EntityUid SlotEntity, - EntityUid Item, - EntityUid? User, - ItemSlot Slot, - bool Cancelled = false); -} \ No newline at end of file + public record struct ItemSlotEjectAttemptEvent(EntityUid SlotEntity, EntityUid Item, EntityUid? User, ItemSlot Slot, bool Cancelled = false); +} diff --git a/Resources/Locale/en-US/_white/reagents/fun.ftl b/Resources/Locale/en-US/_white/reagents/fun.ftl new file mode 100644 index 0000000000..71016fb0c1 --- /dev/null +++ b/Resources/Locale/en-US/_white/reagents/fun.ftl @@ -0,0 +1,2 @@ +reagent-name-tranquility = tranquility +reagent-desc-tranquility = Emits a strange aura of tranquility... \ No newline at end of file diff --git a/Resources/Locale/en-US/chemistry/components/reagent-dispenser-component.ftl b/Resources/Locale/en-US/chemistry/components/reagent-dispenser-component.ftl index 48ec8f5213..37697c4517 100644 --- a/Resources/Locale/en-US/chemistry/components/reagent-dispenser-component.ftl +++ b/Resources/Locale/en-US/chemistry/components/reagent-dispenser-component.ftl @@ -10,9 +10,9 @@ reagent-dispenser-bound-user-interface-title = Reagent dispenser ## UI reagent-dispenser-window-amount-to-dispense-label = Amount -reagent-dispenser-window-container-label = Container: reagent-dispenser-window-clear-button = Clear reagent-dispenser-window-eject-button = Eject +reagent-dispenser-window-eject-container-button = ⏏ reagent-dispenser-window-no-container-loaded-text = No container loaded. reagent-dispenser-window-reagent-name-not-found-text = Reagent name not found reagent-dispenser-window-unknown-reagent-text = Unknown reagent diff --git a/Resources/Locale/en-US/reagents/meta/fun.ftl b/Resources/Locale/en-US/reagents/meta/fun.ftl index a4a8c0f150..127fb7f45b 100644 --- a/Resources/Locale/en-US/reagents/meta/fun.ftl +++ b/Resources/Locale/en-US/reagents/meta/fun.ftl @@ -26,4 +26,4 @@ reagent-name-laughter = laughter reagent-desc-laughter = Some say that this is the best medicine, but recent studies have proven that to be untrue. reagent-name-weh = juice that makes you Weh -reagent-desc-weh = Pure essence of lizard plush. Makes you Weh! +reagent-desc-weh = Pure essence of lizard plush. Makes you Weh! \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_white/object/chemical/containers.ftl b/Resources/Locale/ru-RU/_white/object/chemical/containers.ftl new file mode 100644 index 0000000000..9ffd8ca174 --- /dev/null +++ b/Resources/Locale/ru-RU/_white/object/chemical/containers.ftl @@ -0,0 +1,48 @@ +ent-ChemicalCartridge = химический картридж + .desc = Используется для хранения огромного количества химикатов. Используется в химических раздатчиках +ent-ChemicalCartridgeCarbon = химический картридж (углерод) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeIodine = химический картридж (йод) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeFluorine = химический картридж (фтор) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeChlorine = химический картридж (хлор) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeAluminium = химический картридж (алюминий) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgePhosphorus = химический картридж (фосфор) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSulfur = химический картридж (сера) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSilicon = химический картридж (кремний) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeHydrogen = химический картридж (водород) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeLithium = химический картридж (литий) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSodium = химический картридж (натрий) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgePotassium = химический картридж (калий) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeRadium = химический картридж (радий) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeIron = химический картридж (железо) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeCopper = химический картридж (медь) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeGold = химический картридж (золото) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSugar = химический картридж (сахар) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeMercury = химический картридж (ртуть) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSilver = химический картридж (серебро) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeEthanol = химический картридж (этанол) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeSugar = химический картридж (сахар) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeNitrogen = химический картридж (азот) + .desc = { ent-ChemicalCartridge.desc } +ent-ChemicalCartridgeOxygen = химический картридж (кислород) + .desc = { ent-ChemicalCartridge.desc } \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_white/reagents/fun.ftl b/Resources/Locale/ru-RU/_white/reagents/fun.ftl index a6ac973807..bb938db24b 100644 --- a/Resources/Locale/ru-RU/_white/reagents/fun.ftl +++ b/Resources/Locale/ru-RU/_white/reagents/fun.ftl @@ -1 +1,4 @@ reagent-popup-tranquility = Вы чувствуете себя странно спокойными... + +reagent-name-tranquility = спокойствие +reagent-desc-tranquility = Источает странную ауру спокойствия... \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_white/reagents/meta/medicine.ftl b/Resources/Locale/ru-RU/_white/reagents/meta/medicine.ftl deleted file mode 100644 index 04619f4cba..0000000000 --- a/Resources/Locale/ru-RU/_white/reagents/meta/medicine.ftl +++ /dev/null @@ -1,4 +0,0 @@ -reagent-name-potassium-iodide = Йодид калия -reagent-desc-potassium-iodide = Снижает поражающее действие радиации на 90%. Только для профилактического применения. -reagent-name-haloperidol = Галоперидол -reagent-desc-haloperidol = Выводит большинство стимулирующих/галлюциногенных препаратов. Уменьшает наркотические эффекты и нервозность. Вызывает сонливость. diff --git a/Resources/Locale/ru-RU/locales-new/autotranslate-29.ftl b/Resources/Locale/ru-RU/locales-new/autotranslate-29.ftl index e14a3f1356..173188e814 100644 --- a/Resources/Locale/ru-RU/locales-new/autotranslate-29.ftl +++ b/Resources/Locale/ru-RU/locales-new/autotranslate-29.ftl @@ -2,41 +2,32 @@ ent-EnergyShield = энергетический щит .desc = Экзотический энергетический щит в сложенном виде может поместиться даже в кармане. ent-BrokenEnergyShield = сломанный энергетический щит .desc = Что-то внутри сгорело, оно больше не работает. -ent-Jug = кувшин - .desc = Используется для содержания очень большого количества химикатов или растворов. Пыхтение крайне опрометчиво. -ent-JugCarbon = кувшин (углерод) - .desc = { ent-Jug.desc } -ent-JugIodine = кувшин (йод) - .desc = { ent-Jug.desc } -ent-JugFluorine = кувшин (фтор) - .desc = { ent-Jug.desc } -ent-JugChlorine = кувшин (хлор) - .desc = { ent-Jug.desc } -ent-JugAluminium = кувшин (алюминий) - .desc = { ent-Jug.desc } -ent-JugPhosphorus = кувшин (фосфор) - .desc = { ent-Jug.desc } -ent-JugSulfur = кувшин (сера) - .desc = { ent-Jug.desc } -ent-JugSilicon = кувшин (кремний) - .desc = { ent-Jug.desc } -ent-JugHydrogen = кувшин (водород) - .desc = { ent-Jug.desc } -ent-JugLithium = кувшин (литий) - .desc = { ent-Jug.desc } -ent-JugSodium = кувшин (натрий) - .desc = { ent-Jug.desc } -ent-JugPotassium = кувшин (калий) - .desc = { ent-Jug.desc } -ent-JugRadium = кувшин (радий) - .desc = { ent-Jug.desc } -ent-JugIron = кувшин (железо) - .desc = { ent-Jug.desc } -ent-JugCopper = кувшин (медь) - .desc = { ent-Jug.desc } -ent-JugGold = кувшин (золото) - .desc = { ent-Jug.desc } -ent-JugSugar = кувшин (сахар) - .desc = { ent-Jug.desc } -ent-JugWeldingFuel = кувшин (сварочное топливо) - .desc = { ent-Jug.desc } + +ent-CognizineChemistryBottle = бутылка когнизина + .desc = { ent-BaseChemistryEmptyBottle.desc } +ent-ToxinChemistryBottle = бутылка с токсином + .desc = { ent-BaseChemistryEmptyBottle.desc } +ent-BaseBeakerMetallic = "" + .desc = "" +ent-CryoxadoneBeakerSmall = стакан криоксадона + .desc = Заполнен реагентом, используемым в криогенных пробирках. +ent-SyringeBluespace = блюспейс шприц + .desc = Внедрение передовой технологии bluespace. +ent-SyndicateSponge = куб обезьяны + .desc = Просто добавь воды! +ent-WatermelonSeeds = пакет арбузных семечек + .desc = { ent-SeedBase.desc } +ent-GrapeSeeds = пакет виноградных косточек + .desc = { ent-SeedBase.desc } +ent-MopBucketFull = Ведро для мытья пола + .desc = { ent-MopBucket.desc } +ent-WetFloorSignMineExplosive = табличка 'Мокрый пол' + .desc = Осторожность! Мокрый пол! +ent-Plunger = вантуз + .desc = Вантуз с красной пластиковой присоской и деревянной ручкой. Используется для прочистки стоков. +ent-MegaSprayBottle = мега распылитель + .desc = Огромный распылитель, способный на непревзойденную уборочную мощь. +ent-BigVapor = "" + .desc = "" +ent-MechEquipmentGrabberSmall = небольшой гидравлический зажим + .desc = Дает меху возможность хватать предметы и перетаскивать их. diff --git a/Resources/Locale/ru-RU/locales-new/autotranslate-30.ftl b/Resources/Locale/ru-RU/locales-new/autotranslate-30.ftl deleted file mode 100644 index e3dac21515..0000000000 --- a/Resources/Locale/ru-RU/locales-new/autotranslate-30.ftl +++ /dev/null @@ -1,40 +0,0 @@ -ent-JugMercury = кувшин (ртуть) - .desc = { ent-Jug.desc } -ent-JugSilver = кувшин (серебро) - .desc = { ent-Jug.desc } -ent-JugEthanol = кувшин (этанол) - .desc = { ent-Jug.desc } -ent-JugSugar = jug (sugar) - .desc = { ent-Jug.desc } -ent-JugNitrogen = кувшин (азот) - .desc = { ent-Jug.desc } -ent-JugOxygen = кувшин (кислород) - .desc = { ent-Jug.desc } -ent-CognizineChemistryBottle = бутылка когнизина - .desc = { ent-BaseChemistryEmptyBottle.desc } -ent-ToxinChemistryBottle = бутылка с токсином - .desc = { ent-BaseChemistryEmptyBottle.desc } -ent-BaseBeakerMetallic = "" - .desc = "" -ent-CryoxadoneBeakerSmall = стакан криоксадона - .desc = Заполнен реагентом, используемым в криогенных пробирках. -ent-SyringeBluespace = блюспейс шприц - .desc = Внедрение передовой технологии bluespace. -ent-SyndicateSponge = куб обезьяны - .desc = Просто добавь воды! -ent-WatermelonSeeds = пакет арбузных семечек - .desc = { ent-SeedBase.desc } -ent-GrapeSeeds = пакет виноградных косточек - .desc = { ent-SeedBase.desc } -ent-MopBucketFull = Ведро для мытья пола - .desc = { ent-MopBucket.desc } -ent-WetFloorSignMineExplosive = табличка 'Мокрый пол' - .desc = Осторожность! Мокрый пол! -ent-Plunger = вантуз - .desc = Вантуз с красной пластиковой присоской и деревянной ручкой. Используется для прочистки стоков. -ent-MegaSprayBottle = мега распылитель - .desc = Огромный распылитель, способный на непревзойденную уборочную мощь. -ent-BigVapor = "" - .desc = "" -ent-MechEquipmentGrabberSmall = небольшой гидравлический зажим - .desc = Дает меху возможность хватать предметы и перетаскивать их. diff --git a/Resources/Locale/ru-RU/locales-new/autotranslate-40.ftl b/Resources/Locale/ru-RU/locales-new/autotranslate-40.ftl index 6f04806b8d..ed86317f5e 100644 --- a/Resources/Locale/ru-RU/locales-new/autotranslate-40.ftl +++ b/Resources/Locale/ru-RU/locales-new/autotranslate-40.ftl @@ -26,8 +26,8 @@ ent-CrystalBlue = синий кристалл .desc = Это блестящий синий кристалл. ent-CrystalCyan = голубой кристалл .desc = Это блестящий голубой кристалл. -ent-ChemDispenser = дозатор химикатов - .desc = Дозатор химикатов промышленного класса с большим запасом химикатов. +ent-ChemDispenser = раздатчик химикатов + .desc = Раздатчик химикатов промышленного класса с большим запасом химикатов. ent-AirlockExternalCargoLocked = { ent-AirlockExternal } .desc = { ent-AirlockExternal.desc } .suffix = Внешний, Карго, Закрыт diff --git a/Resources/Locale/ru-RU/objects/chemical/storage.ftl b/Resources/Locale/ru-RU/objects/chemical/storage.ftl new file mode 100644 index 0000000000..3fac71e9f0 --- /dev/null +++ b/Resources/Locale/ru-RU/objects/chemical/storage.ftl @@ -0,0 +1,50 @@ +ent-Jug = кувшин + .desc = Используется для содержания очень большого количества химикатов или растворов. Пыхтение крайне опрометчиво. +ent-JugCarbon = кувшин (углерод) + .desc = { ent-Jug.desc } +ent-JugIodine = кувшин (йод) + .desc = { ent-Jug.desc } +ent-JugFluorine = кувшин (фтор) + .desc = { ent-Jug.desc } +ent-JugChlorine = кувшин (хлор) + .desc = { ent-Jug.desc } +ent-JugAluminium = кувшин (алюминий) + .desc = { ent-Jug.desc } +ent-JugPhosphorus = кувшин (фосфор) + .desc = { ent-Jug.desc } +ent-JugSulfur = кувшин (сера) + .desc = { ent-Jug.desc } +ent-JugSilicon = кувшин (кремний) + .desc = { ent-Jug.desc } +ent-JugHydrogen = кувшин (водород) + .desc = { ent-Jug.desc } +ent-JugLithium = кувшин (литий) + .desc = { ent-Jug.desc } +ent-JugSodium = кувшин (натрий) + .desc = { ent-Jug.desc } +ent-JugPotassium = кувшин (калий) + .desc = { ent-Jug.desc } +ent-JugRadium = кувшин (радий) + .desc = { ent-Jug.desc } +ent-JugIron = кувшин (железо) + .desc = { ent-Jug.desc } +ent-JugCopper = кувшин (медь) + .desc = { ent-Jug.desc } +ent-JugGold = кувшин (золото) + .desc = { ent-Jug.desc } +ent-JugSugar = кувшин (сахар) + .desc = { ent-Jug.desc } +ent-JugWeldingFuel = кувшин (сварочное топливо) + .desc = { ent-Jug.desc } +ent-JugMercury = кувшин (ртуть) + .desc = { ent-Jug.desc } +ent-JugSilver = кувшин (серебро) + .desc = { ent-Jug.desc } +ent-JugEthanol = кувшин (этанол) + .desc = { ent-Jug.desc } +ent-JugSugar = кувшин (сахар) + .desc = { ent-Jug.desc } +ent-JugNitrogen = кувшин (азот) + .desc = { ent-Jug.desc } +ent-JugOxygen = кувшин (кислород) + .desc = { ent-Jug.desc } \ No newline at end of file diff --git a/Resources/Locale/ru-RU/reagents/meta/biological.ftl b/Resources/Locale/ru-RU/reagents/meta/biological.ftl index f32e92faa4..c0f3154565 100644 --- a/Resources/Locale/ru-RU/reagents/meta/biological.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/biological.ftl @@ -7,9 +7,15 @@ reagent-desc-insect-blood = Окей, это уже реально мерзко. reagent-name-slime = слизь reagent-desc-slime = Сначала вам показалось, что это градиент крови, но вы ошиблись. +reagent-name-sap = живица +reagent-desc-sap = Липкая, сладкая кровь деревьев. + reagent-name-hemocyanin-blood = синяя кровь reagent-desc-hemocyanin-blood = Содержит медь, а не железо, что придаёт ей ярко выраженный голубой цвет. +reagent-name-ammonia-blood = анаэробная кровь +reagent-desc-ammonia-blood = Ничто во всей вселенной не пахнет так ужасно. + reagent-name-zombie-blood = кровь зомби reagent-desc-zombie-blood = Не рекомендуется употреблять в пищу. Может быть использована для создания вакцины от инфекции. @@ -21,3 +27,6 @@ reagent-desc-fat = Независимо от того, как он был пол reagent-name-vomit = рвота reagent-desc-vomit = Вы можете увидеть в ней несколько кусков чьей-то последней еды. + +reagent-name-grey-matter = серое вещество +reagent-desc-grey-matter = Сок мыслей, вытекающий из ваших ушей. diff --git a/Resources/Locale/ru-RU/reagents/meta/chemicals.ftl b/Resources/Locale/ru-RU/reagents/meta/chemicals.ftl index a22a0cb8fc..4778af0a23 100644 --- a/Resources/Locale/ru-RU/reagents/meta/chemicals.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/chemicals.ftl @@ -6,3 +6,22 @@ reagent-name-sodium-carbonate = карбонат натрия reagent-desc-sodium-carbonate = Белая водорастворимая соль без запаха, которая образует щелочной раствор в воде. Также известен как кальцинированная сода. reagent-name-artifexium = артистизм reagent-desc-artifexium = Лавандовая смесь микроскопических фрагментов артефакта и сильной кислоты. Обладает способностью активировать артефакты.. + +reagent-name-benzene = бензол +reagent-desc-benzene = Ароматическое, слегка канцерогенное углеродное кольцо, образующее основу для многих органических соединений. + +reagent-name-hydroxide = гидроксид +reagent-desc-hydroxide = Сильнощелочное химическое вещество, образующее основу для многих органических соединений. + +reagent-name-sodium-hydroxide = гидроксид натрия +reagent-desc-sodium-hydroxide = Белая водорастворимая соль без запаха, образующая в воде сильный щелочной раствор. При проглатывании вызывает ожоги и рвоту. + +reagent-name-fersilicite = ферсилицит +reagent-desc-fersilicite = Интерметаллическое соединение с необычными магнитными свойствами при низких температурах. + +reagent-name-sodium-polyacrylate = полиакрилат натрия +reagent-desc-sodium-polyacrylate = Супервпитывающий полимер, имеющий разнообразное промышленное применение. + +reagent-name-cellulose = целлюлозные волокна +reagent-desc-cellulose = Кристаллический полимер полидекстрозы. Растения любят этот материал. + diff --git a/Resources/Locale/ru-RU/reagents/meta/consumable/drink/drinks.ftl b/Resources/Locale/ru-RU/reagents/meta/consumable/drink/drinks.ftl index 3a9706b5e3..0268d7063e 100644 --- a/Resources/Locale/ru-RU/reagents/meta/consumable/drink/drinks.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/consumable/drink/drinks.ftl @@ -30,8 +30,8 @@ reagent-name-nothing = ничего reagent-desc-nothing = Абсолютно ничего. reagent-name-nuclear-cola = ядерная кола reagent-desc-nuclear-cola = Кола, кола никогда не меняется. -reagent-name-soda-water = содовая -reagent-desc-soda-water = Газированная вода. Почему бы не сделать виски с содовой? +reagent-name-soda-water = газировка +reagent-desc-soda-water = Газированная вода. Почему бы не сделать виски с газировкой? reagent-name-soy-latte = соевый латте reagent-desc-soy-latte = Кофейный напиток, приготовленный из эспрессо и подогретого соевого молока. reagent-name-tea = чай diff --git a/Resources/Locale/ru-RU/reagents/meta/consumable/food/condiments.ftl b/Resources/Locale/ru-RU/reagents/meta/consumable/food/condiments.ftl index a6848b4319..a61813e3d1 100644 --- a/Resources/Locale/ru-RU/reagents/meta/consumable/food/condiments.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/consumable/food/condiments.ftl @@ -14,6 +14,10 @@ reagent-name-ketchup = кетчуп reagent-desc-ketchup = Приготовлен из томатного пюре с добавлением специяй. reagent-name-ketchunaise = кетчюнез reagent-desc-ketchunaise = Так называемый русский соус, популярный среди космонавтов. + +reagent-name-laughin-syrup = Ржачный сироп +reagent-desc-laughin-syrup = Сок Ржачных Бобов. Шипучий, и меняет вкус в зависимости от того, с чем его едят! + reagent-name-mayo = майонез reagent-desc-mayo = Соус, сделанный из масла, яйца и немного (съедобной) кислоты. reagent-name-vinaigrette = винегрет @@ -22,3 +26,9 @@ reagent-name-soysauce = соевый соус reagent-desc-soysauce = Соленая приправа на основе сои. reagent-name-table-salt = столовая соль reagent-desc-table-salt = Хлорид натрия, широко известный как соль, часто используется в качестве пищевой приправы или для мгновенного уничтожения мозговых червей. + +reagent-name-mustard = горчица +reagent-desc-mustard = Желтая горчица, изготовленная из семян горчичного растения. + +reagent-name-syrup = сироп +reagent-desc-syrup = Вкусный сироп из древесного сока, более липкий, чем клей. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/reagents/meta/consumable/food/food.ftl b/Resources/Locale/ru-RU/reagents/meta/consumable/food/food.ftl index 662c95485d..305beb965a 100644 --- a/Resources/Locale/ru-RU/reagents/meta/consumable/food/food.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/consumable/food/food.ftl @@ -6,3 +6,12 @@ reagent-name-vitamin = витамины reagent-desc-vitamin = Содержатся в здоровом, полноценном питании. reagent-name-protein = протеины reagent-desc-protein = Также известные как белки. Содержатся в некоторых блюдах, полезны для здоровья организма. + +reagent-name-cocoapowder = какао порошок +reagent-desc-cocoapowder = Из лучших сортов какао-бобов + +reagent-name-butter = масло +reagent-desc-butter = Вы можете ему верить! + +reagent-name-pumpkin-flesh = тыквенная мякоть +reagent-desc-pumpkin-flesh = Мягкий, сладкий плод тыквы. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/reagents/meta/consumable/food/ingredients.ftl b/Resources/Locale/ru-RU/reagents/meta/consumable/food/ingredients.ftl index 5971c5a5e4..9b56e3fb00 100644 --- a/Resources/Locale/ru-RU/reagents/meta/consumable/food/ingredients.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/consumable/food/ingredients.ftl @@ -6,8 +6,12 @@ reagent-name-oats = овёс reagent-desc-oats = Используется для различных вкусных целей. reagent-name-enzyme = универсальный фермент reagent-desc-enzyme = Используется в приготовлении различных блюд. -reagent-name-egg = яйцо -reagent-desc-egg = Используется в выпечке. +reagent-name-egg = приготовленное яйцо +reagent-desc-egg = Вареный куриный эмбрион. Очень вкусно! + +reagent-name-raw-egg = сырое яйцо +reagent-desc-raw-egg = используется в готовке. + reagent-name-sugar = сахар reagent-desc-sugar = Вкусный космический сахар! reagent-name-blackpepper = чёрный перец diff --git a/Resources/Locale/ru-RU/reagents/meta/fun.ftl b/Resources/Locale/ru-RU/reagents/meta/fun.ftl index c460b83366..e36d6b9fac 100644 --- a/Resources/Locale/ru-RU/reagents/meta/fun.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/fun.ftl @@ -10,3 +10,12 @@ reagent-name-saxoite = саксонит reagent-desc-saxoite = Отдаёт джазом. reagent-name-licoxide = ликоксид reagent-desc-licoxide = Это выглядит... электризующе. + +reagent-name-fresium = Фрезиум +reagent-desc-fresium = Загадочное соединение, замедляющее вибрацию атомов и молекул... каким-то образом. По-простому, от него становится холодно... ОЧЕНЬ холодно. При проглатывании может вызвать длительные проблемы с передвижением. + +reagent-name-weh = Сок, заставляющий вас Weh! +reagent-desc-weh = Чистая эссенция игрушки ящера. Заставляет вас Weh! + +reagent-name-razorium = разориум +reagent-desc-razorium = Странное неньютоновское химическое вещество. Образуется при объединении двух лекарств от физических повреждений. При попадании в организм образует миллионы крошечных острых лезвий. Очень острых. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/reagents/meta/medicine.ftl b/Resources/Locale/ru-RU/reagents/meta/medicine.ftl index f8198140ab..be9cfc81a0 100644 --- a/Resources/Locale/ru-RU/reagents/meta/medicine.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/medicine.ftl @@ -52,6 +52,9 @@ reagent-desc-barozine = Сильнодействующий химикат, пр reagent-name-phalanximine = фалангимин reagent-desc-phalanximine = Современный препарат, используемый при лечении рака. Вызывает умеренное лучевое поражение организма и тошноту. Потенциально может удалить ген смерти у растений. +reagent-name-polypyrylium-oligomers = Полипирилиевые олигомеры +reagent-desc-polypyrylium-oligomers = Пурпурная смесь коротких полиэлектролитных цепей, не синтезируемых в лаборатории. Лечат удушье и физические травмы. Со временем останавливает кровотечение. + reagent-name-ambuzol = амбузол reagent-desc-ambuzol = Высокотехнологичный препарат, способный остановить развитие зомби-вируса. @@ -138,3 +141,15 @@ reagent-desc-silversulfadiazine = Это соединение, обладающ reagent-name-stypticpowder = кровоостанавливающая пудра reagent-desc-stypticpowder = Кровоостанавливающий порошок из сульфата алюминия помогает остановить кровотечение и способствует заживлению телесных повреждений. + +reagent-name-mannitol = маннитол +reagent-desc-mannitol = Устраняет повреждения мозга. + +reagent-name-psicodine = псикодин +reagent-desc-psicodine = Подавляет тревогу и прочие формы ментальных проблем. Передозировка вызывает галлюцинации и интоксикацию. + +reagent-name-potassium-iodide = йодистый калий +reagent-desc-potassium-iodide = Снижает поражающее действие от радиации на 90%. Только профилактическое применение. + +reagent-name-haloperidol = галоперидол +reagent-desc-haloperidol = Выводит из организма большую часть стимулирующих или галлюцигенных химикатов. Вызывает сонливость. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/reagents/meta/narcotics.ftl b/Resources/Locale/ru-RU/reagents/meta/narcotics.ftl index 9e05e41c63..51b3efd90b 100644 --- a/Resources/Locale/ru-RU/reagents/meta/narcotics.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/narcotics.ftl @@ -10,7 +10,11 @@ reagent-name-thc = ТГК reagent-desc-thc = Он же тетрагидроканнабинол. Основное психоактивное вещество в конопле. reagent-name-thc-oil = масло ТГК reagent-desc-thc-oil = Чистое масло ТГК, полученное из листьев конопли. Оно намного сильнее, чем в натуральной форме, и может использоваться для снятия хронической боли у пациентов. -reagent-name-nicotine = никотин + +reagent-name-bananadine = бананадин +reagent-desc-bananadine = Слабый психоделик, содержащийся в небольших в шкурках от бананов. + +reagent-name-nicotine = никотинколичествах reagent-desc-nicotine = Опасен и вызывает сильное привыкание. reagent-name-impedrezene = импедризин reagent-desc-impedrezene = Наркотик, который лишает человека дееспособности, замедляя высшие функции клеток мозга. Вызывает обширные повреждения мозга. @@ -22,3 +26,10 @@ reagent-name-mute-toxin = токсин немоты reagent-desc-mute-toxin = Лишает вас возможности разговаривать пока в организме. reagent-name-norepinephric-acid = норэпинефриновая кислота reagent-desc-norepinephric-acid = Лишает вас возможности видеть пока усваивается организмом. + +reagent-name-tear-gas = слезоточивый газ +reagent-desc-tear-gas = Химическое вещество, вызывающее сильное раздражение и слезы, обычно используемое при борьбе с толпой. + +reagent-name-happiness = счастье +reagent-desc-happiness = Наполняет экстатическим оцепенением и вызывает незначительные травмы мозга. Вызывает привыкание крайне быстро. Передозировка вызывает резкие перепады настроения. + diff --git a/Resources/Locale/ru-RU/reagents/meta/toxins.ftl b/Resources/Locale/ru-RU/reagents/meta/toxins.ftl index b7c8fc4d79..eabd9de90b 100644 --- a/Resources/Locale/ru-RU/reagents/meta/toxins.ftl +++ b/Resources/Locale/ru-RU/reagents/meta/toxins.ftl @@ -13,6 +13,9 @@ reagent-desc-polytrinic-acid = Чрезвычайно едкое химичес reagent-name-chloral-hydrate = хлоралгидрат reagent-desc-chloral-hydrate = Успокаивающее и гипнотическое химическое вещество. Обычно используется для усыпления других людей, независимо от того, хотят они этого или нет. +reagent-name-gastrotoxin = гастротоксин +reagent-desc-gastrotoxin = Токсичный побочный продукт разложения. Чаще всего встречается в просроченых продуктах. + reagent-name-ferrochromic-acid = феррохромовая кислота reagent-desc-ferrochromic-acid = Слабоагрессивный раствор, не способный вызвать серьезную опасность, если только его не выпить. @@ -72,3 +75,6 @@ reagent-desc-vestine = Вызывает негативную реакцию в reagent-name-tazinide = тазинид reagent-desc-tazinide = Очень опасная металлическая смесь, которая может нарушить возможность передвигаться благодаря электризующему воздействию. + +reagent-name-lipolicide = липолицид +reagent-desc-lipolicide = Мощный токсин, который разрушает жировые клетки, значительно снижая массу тела за короткое время. Смертельно для тех, у кого нет питательных веществ в организме. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/crates/medical.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/crates/medical.ftl index dd63709e48..f83fcef3b2 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/crates/medical.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/crates/medical.ftl @@ -31,3 +31,10 @@ ent-CrateEmergencyAdvancedKit = Продвинутый аварийный наб ent-CrateEmergencyRadiationKit = Аварийный набор выведения радиации .desc = Ящик, содержащий 4 набора для выведения радиации. .suffix = { "" } + +ent-CrateChemistryP = ящик химикатов (P) + .desc = Содержит химикаты из P-блока периодической таблицы элементов. +ent-CrateChemistryS = ящик химикатов (S) + .desc = Содержит химикаты из S-блока периодической таблицы элементов. +ent-CrateChemistryD = ящик химикатов (D) + .desc = Содержит химикаты из D-блока периодической таблицы элементов. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks.ftl index b0b3cc2817..6dae16068e 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks.ftl @@ -71,7 +71,7 @@ ent-DrinkBooger = козявка .desc = Фууу... .suffix = { "" } ent-DrinkBraveBullGlass = бокал храброго быка - .desc = Текилла и кофейный ликер, объединенные в аппетитный микс. Выпьем. + .desc = Текила и кофейный ликер, объединенные в аппетитный микс. Выпьем. .suffix = { "" } ent-DrinkCarrotJuice = морковный сок .desc = Как морковь, но не хрустит. @@ -394,3 +394,7 @@ ent-DrinkGlassCoupeShaped = бокал ent-DrinkFlaskBar = металлическая фляжка .desc = Металлическая фляжка, часто выдаваемая барменом взаймы. Не забудьте вернуть ее! .suffix = { "" } +ent-DrinkIcedTeaJug = бидон холодного чая + .desc = Для тех, кто считает обычный чай слишком "горячим". Слабаки. +ent-DrinkSugarJug = кувшин сахара + .desc = Некоторые люди кладут его в свое кофе. Отвратительно! diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks_bottles.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks_bottles.ftl index 37d337aa2b..781b02ab48 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks_bottles.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/consumable/drinks/drinks_bottles.ftl @@ -32,7 +32,7 @@ ent-DrinkMelonLiquorBottleFull = дынный ликёр Эмеральдин .desc = Бутылка 23-градусного Дынного ликёра Эмеральдин. Сладкий и легкий. .suffix = { "" } ent-DrinkPatronBottleFull = бутылка покровителя в художественной обёртке - .desc = Текилла с привкусом серебра, которую подают в ночных клубах по всей галактике. + .desc = Текила с привкусом серебра, которую подают в ночных клубах по всей галактике. .suffix = { "" } ent-DrinkPoisonWinebottleFull = бутылка колдовского бархата .desc = Какая восхитительная упаковка для несомненно высококачественного вина! Урожай, должно быть, потрясающий! diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml b/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml index ccdc74d1b6..49cd51cd38 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml @@ -114,7 +114,7 @@ sprite: Objects/Specific/Service/vending_machine_restock.rsi state: base product: CrateVendingMachineRestockChemVendFilled - cost: 3820 + cost: 4000 category: cargoproduct-category-name-medical group: market diff --git a/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml b/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml index 089f560dc3..62b166ebc1 100644 --- a/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml +++ b/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml @@ -1,57 +1,43 @@ - type: reagentDispenserInventory id: SodaDispenserInventory inventory: - - CoconutWater - - Coffee - - Cola - - Cream - - DrGibb - - GreenTea - - Ice - - JuiceLime - - JuiceOrange - - LemonLime - - RootBeer - - SodaWater - - SpaceMountainWind - - SpaceUp - - Sugar - - Tea - - TonicWater - - JuiceWatermelon + - DrinkIceJug + - DrinkCoffeeJug + - DrinkCreamCartonXL + - DrinkTeaJug + - DrinkGreenTeaJug + - DrinkIcedTeaJug + - DrinkColaBottleFull + - DrinkSpaceMountainWindBottleFull + - DrinkDrGibbJug + - DrinkRootBeerJug + - DrinkSpaceUpBottleFull + - DrinkTonicWaterBottleFull + - DrinkSodaWaterBottleFull + - DrinkLemonLimeJug + - DrinkSugarJug + - DrinkJuiceOrangeCartonXL + - DrinkJuiceLimeCartonXL + - DrinkWaterMelonJuiceJug - type: reagentDispenserInventory id: BoozeDispenserInventory inventory: - - 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 + - DrinkLemonLimeJug + - DrinkSugarJug + - DrinkJuiceOrangeCartonXL + - DrinkJuiceLimeCartonXL + - DrinkTonicWaterBottleFull + - DrinkSodaWaterBottleFull + - DrinkBeerGrowler + - DrinkCoffeeLiqueurBottleFull + - DrinkWhiskeyBottleFull + - DrinkWineBottleFull + - DrinkVodkaBottleFull + - DrinkGinBottleFull + - DrinkRumBottleFull + - DrinkTequilaBottleFull + - DrinkVermouthBottleFull + - DrinkCognacBottleFull + - DrinkAleBottleFullGrowler + - DrinkMeadJug diff --git a/Resources/Prototypes/Catalog/ReagentDispensers/chemical.yml b/Resources/Prototypes/Catalog/ReagentDispensers/chemical.yml index 6d9c729fc9..f03eae1ff4 100644 --- a/Resources/Prototypes/Catalog/ReagentDispensers/chemical.yml +++ b/Resources/Prototypes/Catalog/ReagentDispensers/chemical.yml @@ -1,31 +1,26 @@ - type: reagentDispenserInventory id: ChemDispenserStandardInventory inventory: - - Aluminium - - Carbon - - Chlorine - - Copper - - Ethanol - - Fluorine - - Sugar - - Hydrogen - - Iodine - - Iron - - Lithium - - Mercury - - Nitrogen - - Oxygen - - Phosphorus - - Potassium - - Radium - - Silicon - - Sodium - - Sulfur + - ChemicalCartridgeAluminium + - ChemicalCartridgeCarbon + - ChemicalCartridgeChlorine + - ChemicalCartridgeCopper + - ChemicalCartridgeEthanol + - ChemicalCartridgeFluorine + - ChemicalCartridgeSugar + - ChemicalCartridgeHydrogen + - ChemicalCartridgeIodine + - ChemicalCartridgeIron + - ChemicalCartridgeLithium + - ChemicalCartridgeMercury + - ChemicalCartridgeNitrogen + - ChemicalCartridgeOxygen + - ChemicalCartridgePhosphorus + - ChemicalCartridgePotassium + - ChemicalCartridgeRadium + - ChemicalCartridgeSilicon + - ChemicalCartridgeSodium + - ChemicalCartridgeSulfur - type: reagentDispenserInventory - id: ChemDispenserEmaggedInventory - inventory: ##Feel free to change this to something more interesting when more chems are added - - Napalm - - Toxin - - Epinephrine - - Ultravasculine + id: EmptyInventory diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml index e8e47bade2..1c6ca424f3 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml @@ -1,27 +1,28 @@ - type: vendingMachineInventory id: ChemVendInventory startingInventory: - Jug: 2 - JugAluminium: 1 - JugCarbon: 1 - JugChlorine: 1 - JugCopper: 1 - JugEthanol: 1 - JugFluorine: 1 - JugHydrogen: 1 - JugIodine: 1 - JugIron: 1 - JugLithium: 1 - JugMercury: 1 - JugNitrogen: 1 - JugOxygen: 1 - JugPhosphorus: 1 - JugPotassium: 1 - JugRadium: 1 - JugSilicon: 1 - JugSodium: 1 - JugSugar: 1 - JugSulfur: 1 + Jug: 8 + ChemicalCartridge: 2 + ChemicalCartridgeAluminium: 1 + ChemicalCartridgeCarbon: 1 + ChemicalCartridgeChlorine: 1 + ChemicalCartridgeCopper: 1 + ChemicalCartridgeEthanol: 1 + ChemicalCartridgeFluorine: 1 + ChemicalCartridgeHydrogen: 1 + ChemicalCartridgeIodine: 1 + ChemicalCartridgeIron: 1 + ChemicalCartridgeLithium: 1 + ChemicalCartridgeMercury: 1 + ChemicalCartridgeNitrogen: 1 + ChemicalCartridgeOxygen: 1 + ChemicalCartridgePhosphorus: 1 + ChemicalCartridgePotassium: 1 + ChemicalCartridgeRadium: 1 + ChemicalCartridgeSilicon: 1 + ChemicalCartridgeSodium: 1 + ChemicalCartridgeSugar: 1 + ChemicalCartridgeSulfur: 1 emaggedInventory: ToxinChemistryBottle: 1 diff --git a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml index e773cda116..9c80bbc15e 100644 --- a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml +++ b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml @@ -91,9 +91,8 @@ animationState: foam-dissolve - type: Slippery - type: StepTrigger - # disabled until foam reagent duplication is fixed - #- type: ScoopableSolution - # solution: solutionArea + - type: ScoopableSolution + solution: solutionArea - type: entity id: MetalFoam diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml index 0b0f7e2af7..435fd2636d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml @@ -212,7 +212,7 @@ - ReagentId: Cognac Quantity: 100 - type: Label - currentLabel: cognac + currentLabel: коньяк - type: Sprite sprite: Objects/Consumable/Drinks/cognacbottle.rsi - type: Sealable @@ -230,7 +230,7 @@ - ReagentId: Cola Quantity: 100 - type: Label - currentLabel: cola + currentLabel: кола - type: Sprite sprite: Objects/Consumable/Drinks/colabottle.rsi - type: Sealable @@ -268,7 +268,7 @@ - ReagentId: Gin Quantity: 100 - type: Label - currentLabel: gin + currentLabel: джин - type: Sprite sprite: Objects/Consumable/Drinks/ginbottle.rsi - type: Sealable @@ -302,7 +302,7 @@ - ReagentId: CoffeeLiqueur Quantity: 100 - type: Label - currentLabel: coffee liqueur + currentLabel: кофейный ликёр - type: Sprite sprite: Objects/Consumable/Drinks/coffeeliqueurbottle.rsi - type: Sealable @@ -378,7 +378,7 @@ - ReagentId: Rum Quantity: 100 - type: Label - currentLabel: rum + currentLabel: ром - type: Sprite sprite: Objects/Consumable/Drinks/rumbottle.rsi - type: Sealable @@ -397,7 +397,7 @@ Quantity: 100 - type: Drink - type: Label - currentLabel: space mountain wind + currentLabel: маунтин винд - type: Sprite sprite: Objects/Consumable/Drinks/space_mountain_wind_bottle.rsi - type: Sealable @@ -416,7 +416,7 @@ Quantity: 100 - type: Drink - type: Label - currentLabel: space-up + currentLabel: спейс-ап - type: Sprite sprite: Objects/Consumable/Drinks/space-up_bottle.rsi - type: Sealable @@ -434,7 +434,7 @@ - ReagentId: Tequila Quantity: 100 - type: Label - currentLabel: tequila + currentLabel: текила - type: Sprite sprite: Objects/Consumable/Drinks/tequillabottle.rsi - type: Sealable @@ -452,7 +452,7 @@ - ReagentId: Vermouth Quantity: 100 - type: Label - currentLabel: vermouth + currentLabel: вермут - type: Sprite sprite: Objects/Consumable/Drinks/vermouthbottle.rsi - type: Sealable @@ -470,7 +470,7 @@ - ReagentId: Vodka Quantity: 100 - type: Label - currentLabel: vodka + currentLabel: водка - type: Sprite sprite: Objects/Consumable/Drinks/vodkabottle.rsi - type: Sealable @@ -488,7 +488,7 @@ - ReagentId: Whiskey Quantity: 100 - type: Label - currentLabel: whiskey + currentLabel: виски - type: Sprite sprite: Objects/Consumable/Drinks/whiskeybottle.rsi - type: Sealable @@ -506,7 +506,7 @@ - ReagentId: Wine Quantity: 100 - type: Label - currentLabel: wine + currentLabel: вино - type: Sprite sprite: Objects/Consumable/Drinks/winebottle.rsi - type: Sealable @@ -553,7 +553,7 @@ - ReagentId: Beer Quantity: 150 - type: Label - currentLabel: beer + currentLabel: пиво - type: Sprite sprite: Objects/Consumable/Drinks/beer.rsi - type: Openable @@ -597,7 +597,7 @@ - ReagentId: Ale Quantity: 150 - type: Label - currentLabel: ale + currentLabel: эль - type: Sprite sprite: Objects/Consumable/Drinks/alebottle.rsi - type: Openable @@ -649,7 +649,7 @@ - ReagentId: SodaWater Quantity: 150 - type: Label - currentLabel: soda water + currentLabel: газировка - type: entity parent: DrinkWaterBottleFull @@ -665,7 +665,7 @@ - ReagentId: TonicWater Quantity: 150 - type: Label - currentLabel: tonic water + currentLabel: тоник - type: entity parent: [DrinkBottleVisualsOpenable, DrinkBottleGlassBaseFull] @@ -680,7 +680,7 @@ - ReagentId: Sake Quantity: 50 - type: Label - currentLabel: Sake + currentLabel: Саке - type: Sprite sprite: Objects/Consumable/Drinks/sakebottle.rsi - type: Sealable @@ -702,7 +702,7 @@ Quantity: 150 - type: Drink - type: Label - currentLabel: lime juice + currentLabel: лаймовый сок - type: Sprite sprite: Objects/Consumable/Drinks/limejuice.rsi @@ -721,7 +721,7 @@ Quantity: 150 - type: Drink - type: Label - currentLabel: orange juice + currentLabel: апельсиновый сок - type: Sprite sprite: Objects/Consumable/Drinks/orangejuice.rsi @@ -740,7 +740,7 @@ Quantity: 150 - type: Drink - type: Label - currentLabel: cream + currentLabel: сливки - type: Sprite sprite: Objects/Consumable/Drinks/cream.rsi @@ -777,7 +777,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: lemon-lime + currentLabel: лимон-лайм - type: entity parent: DrinkBottlePlasticBaseFull @@ -794,7 +794,7 @@ Quantity: 150 - type: Drink - type: Label - currentLabel: mead + currentLabel: медовуха - type: entity parent: DrinkBottlePlasticBaseFull @@ -811,7 +811,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: ice + currentLabel: лёд - type: entity parent: DrinkBottlePlasticBaseFull @@ -828,7 +828,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: coconut water + currentLabel: кокосовая вода - type: entity parent: DrinkBottlePlasticBaseFull @@ -845,7 +845,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: coffee + currentLabel: кофе - type: entity parent: DrinkBottlePlasticBaseFull @@ -862,7 +862,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: tea + currentLabel: чай - type: entity parent: DrinkBottlePlasticBaseFull @@ -879,7 +879,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: green tea + currentLabel: зеленый чай - type: entity parent: DrinkBottlePlasticBaseFull @@ -895,6 +895,8 @@ - ReagentId: IcedTea Quantity: 300 - type: Drink + - type: Label + currentLabel: холодный чай - type: entity parent: DrinkBottlePlasticBaseFull @@ -911,7 +913,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: dr gibb + currentLabel: доктор Гибб - type: entity parent: DrinkBottlePlasticBaseFull @@ -928,7 +930,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: root beer + currentLabel: рутбир - type: entity parent: DrinkBottlePlasticBaseFull @@ -945,7 +947,7 @@ Quantity: 300 - type: Drink - type: Label - currentLabel: watermelon juice + currentLabel: арбузный сок - type: entity parent: DrinkBottlePlasticBaseFull @@ -962,7 +964,7 @@ Quantity: 100 - type: Drink - type: Label - currentLabel: red bool + currentLabel: редбул - type: entity parent: DrinkBottlePlasticBaseFull diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 3e2acf30ec..8d7641b01c 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -569,7 +569,7 @@ - type: Sprite state: medical - type: MachineBoard - prototype: ChemDispenser + prototype: ChemDispenserEmpty requirements: Capacitor: 1 materialRequirements: @@ -1187,7 +1187,7 @@ - type: Sprite state: service - type: MachineBoard - prototype: BoozeDispenser + prototype: BoozeDispenserEmpty materialRequirements: Steel: 5 tagRequirements: @@ -1220,7 +1220,7 @@ - type: Sprite state: service - type: MachineBoard - prototype: soda_dispenser + prototype: SodaDispenserEmpty materialRequirements: Steel: 5 tagRequirements: diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml index 040ceb6b30..170e61efe2 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemical-containers.yml @@ -43,40 +43,10 @@ - type: SolutionContainerVisuals maxFillLevels: 6 fillBaseName: jug - inHandsMaxFillLevels: 5 - inHandsFillBaseName: -fill- - type: StaticPrice price: 60 - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger - damage: 20 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - params: - volume: -4 - - !type:SpillBehavior { } - - !type:SpawnEntitiesBehavior - spawn: - SheetPlastic1: - min: 0 - max: 1 - transferForensics: true - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Label - originalName: jug + originalName: кувшин - type: MeleeWeapon canBeBlocked: false soundNoDamage: diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index c7df5e6ef4..8507bfed13 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -55,13 +55,15 @@ 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 diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml b/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml index 712083b7ff..7bc12ca966 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml @@ -1,6 +1,7 @@ - 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: @@ -10,8 +11,10 @@ drawdepth: SmallObjects state: booze - type: ReagentDispenser + storageWhitelist: + tags: + - DrinkBottle pack: BoozeDispenserInventory - emagPack: BoozeDispenserEmagInventory - type: Transform noRot: false - type: Machine @@ -21,3 +24,14 @@ - Bartender - type: StealTarget stealGroup: BoozeDispenser + +- type: entity + id: BoozeDispenserEmpty + suffix: Empty + parent: BoozeDispenser + components: + - type: ReagentDispenser + storageWhitelist: + tags: + - DrinkBottle + pack: EmptyInventory diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 09ec0a812e..6c70cf9bca 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -1,16 +1,19 @@ - type: entity id: ChemDispenser name: chemical dispenser + suffix: Filled parent: ReagentDispenserBase - description: An industrial grade chemical dispenser with a sizeable chemical supply. + description: An industrial grade chemical dispenser. 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 @@ -28,12 +31,21 @@ acts: ["Destruction"] - type: Machine board: ChemDispenserMachineCircuitboard + - type: Wires + boardName: wires-board-name-chemdispenser + layoutId: ChemDispenser - type: GuideHelp guides: - Chemicals - Chemist - type: StealTarget stealGroup: ChemDispenser - - type: DeviceNetwork - deviceNetId: Wired - receiveFrequencyId: BasicDevice + +- type: entity + id: ChemDispenserEmpty + name: chemical dispenser + suffix: Empty + parent: ChemDispenser + components: + - type: ReagentDispenser + pack: EmptyInventory diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml b/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml index 59fd97b2cf..72468973ee 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml @@ -1,6 +1,7 @@ - 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: @@ -10,8 +11,10 @@ drawdepth: SmallObjects state: soda - type: ReagentDispenser + storageWhitelist: + tags: + - DrinkBottle pack: SodaDispenserInventory - emagPack: SodaDispenserEmagInventory - type: Transform noRot: false - type: Machine @@ -19,3 +22,14 @@ - type: GuideHelp guides: - Bartender + +- type: entity + id: SodaDispenserEmpty + suffix: Empty + parent: soda_dispenser + components: + - type: ReagentDispenser + storageWhitelist: + tags: + - DrinkBottle + pack: EmptyInventory diff --git a/Resources/Prototypes/_White/Entities/Objects/Specific/Chemical/containers.yml b/Resources/Prototypes/_White/Entities/Objects/Specific/Chemical/containers.yml new file mode 100644 index 0000000000..605dbf690b --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Objects/Specific/Chemical/containers.yml @@ -0,0 +1,370 @@ +- type: entity + id: ChemicalCartridge + name: chemical cartridge + parent: [DrinkBottleVisualsOpenable, BaseItem] + description: Used to contain a very large amount of chemicals or solutions. Used in chemical dispensers + components: + - type: SolutionContainerManager + solutions: + beaker: + maxVol: 500 + canMix: true + - type: Openable + sound: + collection: bottleCloseSounds + closeable: true + closeSound: + collection: bottleCloseSounds + - type: Sprite + sprite: White/Objects/Specific/Chemical/chemical_cartridge.rsi + state: icon + scale: 0.8, 0.8 + - type: Item + size: Huge + - type: RefillableSolution + solution: beaker + - type: DrainableSolution + solution: beaker + - type: ExaminableSolution + solution: beaker + - type: SolutionTransfer + canChangeTransferAmount: false + - type: Spillable + solution: beaker + - type: StaticPrice + price: 150 + - type: Label + originalName: химический картридж + - type: Tag + tags: + - ChemDispensable + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (carbon) + id: ChemicalCartridgeCarbon + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-carbon + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Carbon + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (iodine) + id: ChemicalCartridgeIodine + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-iodine + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Iodine + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (fluorine) + id: ChemicalCartridgeFluorine + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-fluorine + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Fluorine + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (chlorine) + id: ChemicalCartridgeChlorine + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-chlorine + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Chlorine + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (aluminium) + id: ChemicalCartridgeAluminium + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-aluminium + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Aluminium + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (phosphorus) + id: ChemicalCartridgePhosphorus + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-phosphorus + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Phosphorus + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (sulfur) + id: ChemicalCartridgeSulfur + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-sulfur + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Sulfur + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (silicon) + id: ChemicalCartridgeSilicon + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-silicon + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Silicon + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (hydrogen) + id: ChemicalCartridgeHydrogen + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-hydrogen + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Hydrogen + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (lithium) + id: ChemicalCartridgeLithium + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-lithium + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Lithium + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (sodium) + id: ChemicalCartridgeSodium + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-sodium + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Sodium + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (potassium) + id: ChemicalCartridgePotassium + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-potassium + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Potassium + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (radium) + id: ChemicalCartridgeRadium + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-radium + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Radium + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (iron) + id: ChemicalCartridgeIron + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-iron + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Iron + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (copper) + id: ChemicalCartridgeCopper + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-copper + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Copper + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (gold) + id: ChemicalCartridgeGold + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-gold + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Gold + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (mercury) + id: ChemicalCartridgeMercury + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-mercury + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Mercury + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (silver) + id: ChemicalCartridgeSilver + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-silver + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Silver + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (ethanol) + id: ChemicalCartridgeEthanol + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-ethanol + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Ethanol + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (Sugar) + id: ChemicalCartridgeSugar + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-sugar + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Sugar + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (nitrogen) + id: ChemicalCartridgeNitrogen + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-nitrogen + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Nitrogen + Quantity: 500 + +- type: entity + parent: ChemicalCartridge + name: chemical cartridge (oxygen) + id: ChemicalCartridgeOxygen + noSpawn: true + components: + - type: Label + currentLabel: reagent-name-oxygen + - type: SolutionContainerManager + solutions: + beaker: + reagents: + - ReagentId: Oxygen + Quantity: 500 \ No newline at end of file diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 72c2e46d9b..b05d664b08 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -263,7 +263,7 @@ - type: Tag id: CannonBall - + - type: Tag id: CannonRestrict diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon.png new file mode 100644 index 0000000000..5330b43eb3 Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon_open.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon_open.png new file mode 100644 index 0000000000..9acb493764 Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/icon_open.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left-open.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left-open.png new file mode 100644 index 0000000000..4631bf6295 Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left-open.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left.png new file mode 100644 index 0000000000..0565dd5fb8 Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right-open.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right-open.png new file mode 100644 index 0000000000..c6931fae90 Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right-open.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right.png b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right.png new file mode 100644 index 0000000000..f72d03ca3c Binary files /dev/null and b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/meta.json b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/meta.json new file mode 100644 index 0000000000..6af17830f7 --- /dev/null +++ b/Resources/Textures/White/Objects/Specific/Chemical/chemical_cartridge.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by 6mirage6", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "icon_open" + }, + { + "name": "inhand-left-open", + "directions": 4 + }, + { + "name": "inhand-right-open", + "directions": 4 + } + ] +}