From 87b0fb3e04986665440914cadbde85ae8965f97a Mon Sep 17 00:00:00 2001 From: Aviu00 <93730715+Aviu00@users.noreply.github.com> Date: Wed, 23 Aug 2023 15:12:11 +0300 Subject: [PATCH] Chem stuff QoL (#321) --- .../Chemistry/UI/ChemMasterWindow.xaml | 2 +- .../Chemistry/UI/ChemMasterWindow.xaml.cs | 13 +- .../Components/ChemMasterComponent.cs | 9 +- .../Components/ReagentDispenserComponent.cs | 12 +- .../EntitySystems/ChemMasterSystem.cs | 37 +++++- .../EntitySystems/ReagentDispenserSystem.cs | 114 ++++++++++++++++++ Content.Shared/Chemistry/SharedChemMaster.cs | 4 + .../Prototypes/DeviceLinking/sink_ports.yml | 5 + .../Prototypes/DeviceLinking/source_ports.yml | 5 + .../Dispensers/base_structuredispensers.yml | 9 +- .../Entities/Structures/Dispensers/chem.yml | 5 +- .../Structures/Machines/chem_master.yml | 7 ++ 12 files changed, 215 insertions(+), 7 deletions(-) diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml index 26a490b0f3..f1aab4f54a 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml @@ -2,7 +2,7 @@ xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client" - MinSize="620 670" + MinSize="670 670" Title="{Loc 'chem-master-bound-user-interface-title'}"> diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs index 5eace08a7f..2f7cedd196 100644 --- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs +++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs @@ -208,10 +208,13 @@ namespace Content.Client.Chemistry.UI MakeReagentButton("1", ChemMasterReagentAmount.U1, reagent, true, StyleBase.ButtonOpenRight), MakeReagentButton("5", ChemMasterReagentAmount.U5, reagent, true, StyleBase.ButtonOpenBoth), MakeReagentButton("10", ChemMasterReagentAmount.U10, reagent, true, StyleBase.ButtonOpenBoth), + MakeReagentButton("15", ChemMasterReagentAmount.U15, reagent, true, StyleBase.ButtonOpenBoth), + MakeReagentButton("20", ChemMasterReagentAmount.U20, reagent, true, StyleBase.ButtonOpenBoth), MakeReagentButton("25", ChemMasterReagentAmount.U25, reagent, true, StyleBase.ButtonOpenBoth), + MakeReagentButton("30", ChemMasterReagentAmount.U30, reagent, true, StyleBase.ButtonOpenBoth), MakeReagentButton("50", ChemMasterReagentAmount.U50, reagent, true, StyleBase.ButtonOpenBoth), + MakeReagentButton("75", ChemMasterReagentAmount.U75, reagent, true, StyleBase.ButtonOpenBoth), MakeReagentButton("100", ChemMasterReagentAmount.U100, reagent, true, StyleBase.ButtonOpenBoth), - MakeReagentButton(Loc.GetString("chem-master-window-buffer-all-amount"), ChemMasterReagentAmount.All, reagent, true, StyleBase.ButtonOpenLeft), } }); } @@ -299,10 +302,18 @@ namespace Content.Client.Chemistry.UI "5", ChemMasterReagentAmount.U5, id, false, StyleBase.ButtonOpenBoth)); cs.Add(MakeReagentButton( "10", ChemMasterReagentAmount.U10, id, false, StyleBase.ButtonOpenBoth)); + cs.Add(MakeReagentButton( + "15", ChemMasterReagentAmount.U15, id, false, StyleBase.ButtonOpenBoth)); + cs.Add(MakeReagentButton( + "20", ChemMasterReagentAmount.U20, id, false, StyleBase.ButtonOpenBoth)); cs.Add(MakeReagentButton( "25", ChemMasterReagentAmount.U25, id, false, StyleBase.ButtonOpenBoth)); + cs.Add(MakeReagentButton( + "30", ChemMasterReagentAmount.U30, id, false, StyleBase.ButtonOpenBoth)); cs.Add(MakeReagentButton( "50", ChemMasterReagentAmount.U50, id, false, StyleBase.ButtonOpenBoth)); + cs.Add(MakeReagentButton( + "75", ChemMasterReagentAmount.U75, id, false, StyleBase.ButtonOpenBoth)); cs.Add(MakeReagentButton( "100", ChemMasterReagentAmount.U100, id, false, StyleBase.ButtonOpenBoth)); cs.Add(MakeReagentButton( diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs index 9578755ba7..aff7bbd01b 100644 --- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs +++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs @@ -9,7 +9,7 @@ namespace Content.Server.Chemistry.Components /// /// [RegisterComponent] - [Access(typeof(ChemMasterSystem))] + [Access(typeof(ChemMasterSystem), typeof(ReagentDispenserSystem))] // WD EDIT public sealed partial class ChemMasterComponent : Component { [DataField("pillType"), ViewVariables(VVAccess.ReadWrite)] @@ -23,5 +23,12 @@ namespace Content.Server.Chemistry.Components [DataField("clickSound"), ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); + + // WD START + public const string ChemMasterPort = "ChemMasterReceiver"; + + [ViewVariables] + public EntityUid? ConnectedDispenser; + // WD END } } diff --git a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs index 7229010228..832f584ecb 100644 --- a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs +++ b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs @@ -10,7 +10,7 @@ namespace Content.Server.Chemistry.Components /// A machine that dispenses reagents into a solution container. /// [RegisterComponent] - [Access(typeof(ReagentDispenserSystem))] + [Access(typeof(ReagentDispenserSystem), typeof(ChemMasterSystem))] public sealed partial class ReagentDispenserComponent : Component { @@ -27,5 +27,15 @@ namespace Content.Server.Chemistry.Components [ViewVariables(VVAccess.ReadWrite)] public ReagentDispenserDispenseAmount DispenseAmount = ReagentDispenserDispenseAmount.U10; + + // WD START + public const string ChemMasterPort = "ChemMasterSender"; + + [ViewVariables] + public bool ChemMasterInRange; + + [ViewVariables] + public EntityUid? ChemMaster; + // WD END } } diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index ab91044574..8b1bc4c8c1 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -1,5 +1,6 @@ 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; @@ -10,6 +11,7 @@ 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; @@ -39,6 +41,8 @@ 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"; @@ -53,6 +57,13 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); + // WD START + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnPortDisconnected); + SubscribeLocalEvent(OnAnchor); + // WD END + + SubscribeLocalEvent(OnSetModeMessage); SubscribeLocalEvent(OnSetPillTypeMessage); SubscribeLocalEvent(OnReagentButtonMessage); @@ -60,12 +71,36 @@ 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); } - private void UpdateUiState(Entity ent, bool updateLabel = false) + public void UpdateUiState(Entity ent, bool updateLabel = false) // WD EDIT { var (owner, chemMaster) = ent; if (!_solutionContainerSystem.TryGetSolution(owner, SharedChemMaster.BufferSolutionName, out _, out var bufferSolution)) diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index aeb141fe35..ca0cf8011d 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -1,12 +1,15 @@ using Content.Server.Administration.Logs; using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; +using Content.Server.DeviceLinking.Systems; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Dispenser; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reagent; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; +using Content.Shared.DeviceLinking; +using Content.Shared.DeviceLinking.Events; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using JetBrains.Annotations; @@ -16,6 +19,8 @@ using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.Prototypes; using System.Linq; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.FixedPoint; namespace Content.Server.Chemistry.EntitySystems { @@ -32,6 +37,9 @@ namespace Content.Server.Chemistry.EntitySystems [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly DeviceLinkSystem _signalSystem = default!; // WD + [Dependency] private readonly ChemMasterSystem _chemMasterSystem = default!; // WD + public override void Initialize() { base.Initialize(); @@ -41,6 +49,15 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); SubscribeLocalEvent(SubscribeUpdateUiState); + + // WD START + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnNewLink); + SubscribeLocalEvent(OnPortDisconnected); + SubscribeLocalEvent(OnAnchorChanged); + // WD END + SubscribeLocalEvent(OnEmagged); SubscribeLocalEvent(OnSetDispenseAmountMessage); @@ -48,6 +65,90 @@ namespace Content.Server.Chemistry.EntitySystems SubscribeLocalEvent(OnClearContainerSolutionMessage); } + // 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); @@ -124,7 +225,20 @@ namespace Content.Server.Chemistry.EntitySystems 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)); + return; + } // WD EDIT END if (_solutionContainerSystem.TryAddReagent(solution.Value, message.ReagentId, (int) reagentDispenser.Comp.DispenseAmount, out var dispensedAmount) && message.Session.AttachedEntity is not null) diff --git a/Content.Shared/Chemistry/SharedChemMaster.cs b/Content.Shared/Chemistry/SharedChemMaster.cs index 762131d761..7139405e16 100644 --- a/Content.Shared/Chemistry/SharedChemMaster.cs +++ b/Content.Shared/Chemistry/SharedChemMaster.cs @@ -94,8 +94,12 @@ namespace Content.Shared.Chemistry U1 = 1, U5 = 5, U10 = 10, + U15 = 15, + U20 = 20, U25 = 25, + U30 = 30, U50 = 50, + U75 = 75, U100 = 100, All, } diff --git a/Resources/Prototypes/DeviceLinking/sink_ports.yml b/Resources/Prototypes/DeviceLinking/sink_ports.yml index f05934f3ba..a23a19a534 100644 --- a/Resources/Prototypes/DeviceLinking/sink_ports.yml +++ b/Resources/Prototypes/DeviceLinking/sink_ports.yml @@ -107,3 +107,8 @@ id: SetParticleZeta name: signal-port-name-set-particle-zeta description: signal-port-description-set-particle-zeta + +- type: sinkPort + id: ChemMasterReceiver + name: ХимМастер + description: Приёмник сигнала ХимМастера diff --git a/Resources/Prototypes/DeviceLinking/source_ports.yml b/Resources/Prototypes/DeviceLinking/source_ports.yml index 18b9b831e6..152ca01c1e 100644 --- a/Resources/Prototypes/DeviceLinking/source_ports.yml +++ b/Resources/Prototypes/DeviceLinking/source_ports.yml @@ -149,3 +149,8 @@ id: PowerDischarging name: signal-port-name-power-discharging description: signal-port-description-power-discharging + +- type: sourcePort + id: ChemMasterSender + name: Раздатчик + description: Передатчик сигнала ХимМастера diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index e170ce8255..bbbdd83454 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity abstract: true id: ReagentDispenserBase parent: ConstructibleMachine @@ -71,3 +71,10 @@ price: 1000 - type: Wires - type: WiresPanel + - type: DeviceList + - type: DeviceNetwork + deviceNetId: Wired + - type: DeviceLinkSource + range: 1.5 + ports: + - ChemMasterSender diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 916b2b748c..23527aeef6 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: ChemDispenser name: chemical dispenser parent: ReagentDispenserBase @@ -37,3 +37,6 @@ - Chemist - type: StealTarget stealGroup: ChemDispenser + - type: DeviceNetwork + deviceNetId: Wired + receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index cd893c4326..e4b77f9648 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -93,3 +93,10 @@ guides: - Chemicals - Chemist + - type: DeviceList + - type: DeviceNetwork + deviceNetId: Wired + receiveFrequencyId: BasicDevice + - type: DeviceLinkSink + ports: + - ChemMasterReceiver