From 42102b17c164a56a9139b9ed5f923f89068d4484 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 3 Feb 2022 10:04:46 +1100 Subject: [PATCH] ECS construction machines (#6354) --- .../Construction/Completions/BuildMachine.cs | 4 +- .../Components/MachineComponent.cs | 123 ++---------------- .../ConstructionSystem.Machine.cs | 112 ++++++++++++++++ .../Construction/ConstructionSystem.cs | 3 + 4 files changed, 124 insertions(+), 118 deletions(-) create mode 100644 Content.Server/Construction/ConstructionSystem.Machine.cs diff --git a/Content.Server/Construction/Completions/BuildMachine.cs b/Content.Server/Construction/Completions/BuildMachine.cs index 8dc732f7c7..01707ab551 100644 --- a/Content.Server/Construction/Completions/BuildMachine.cs +++ b/Content.Server/Construction/Completions/BuildMachine.cs @@ -1,11 +1,9 @@ using System.Linq; -using System.Threading.Tasks; using Content.Server.Construction.Components; using Content.Shared.Construction; using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Serialization.Manager.Attributes; @@ -101,7 +99,7 @@ namespace Content.Server.Construction.Completions if (entityManager.TryGetComponent(machine, out MachineComponent? machineComp)) { - machineComp.RefreshParts(); + constructionSystem.RefreshParts(machineComp); } entityManager.DeleteEntity(uid); diff --git a/Content.Server/Construction/Components/MachineComponent.cs b/Content.Server/Construction/Components/MachineComponent.cs index a5e34f0a3e..0284278598 100644 --- a/Content.Server/Construction/Components/MachineComponent.cs +++ b/Content.Server/Construction/Components/MachineComponent.cs @@ -1,125 +1,18 @@ -using System; -using System.Collections.Generic; -using Content.Server.Stack; -using Robust.Shared.Containers; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.Construction.Components { - [RegisterComponent] - public class MachineComponent : Component, IMapInit + [RegisterComponent, ComponentProtoName("Machine")] + public sealed class MachineComponent : Component { - [Dependency] private readonly IEntityManager _entMan = default!; - - [DataField("board")] + [DataField("board", customTypeSerializer: typeof(PrototypeIdSerializer))] public string? BoardPrototype { get; private set; } - private Container _boardContainer = default!; - private Container _partContainer = default!; - - protected override void Initialize() - { - base.Initialize(); - - _boardContainer = Owner.EnsureContainer(MachineFrameComponent.BoardContainer); - _partContainer = Owner.EnsureContainer(MachineFrameComponent.PartContainer); - } - - public IEnumerable GetAllParts() - { - foreach (var entity in _partContainer.ContainedEntities) - { - if (_entMan.TryGetComponent(entity, out var machinePart)) - yield return machinePart; - } - } - - public void RefreshParts() - { - foreach (var refreshable in _entMan.GetComponents(Owner)) - { - refreshable.RefreshParts(GetAllParts()); - } - } - - public void CreateBoardAndStockParts() - { - // Entity might not be initialized yet. - var boardContainer = Owner.EnsureContainer(MachineFrameComponent.BoardContainer, out var existedBoard); - var partContainer = Owner.EnsureContainer(MachineFrameComponent.PartContainer, out var existedParts); - - if (string.IsNullOrEmpty(BoardPrototype)) - return; - - var entityManager = _entMan; - - if (existedBoard || existedParts) - { - // We're done here, let's suppose all containers are correct just so we don't screw SaveLoadSave. - if (boardContainer.ContainedEntities.Count > 0) - return; - } - - var board = entityManager.SpawnEntity(BoardPrototype, _entMan.GetComponent(Owner).Coordinates); - - if (!_boardContainer.Insert(board)) - { - throw new Exception($"Couldn't insert board with prototype {BoardPrototype} to machine with prototype {_entMan.GetComponent(Owner).EntityPrototype?.ID ?? "N/A"}!"); - } - - if (!_entMan.TryGetComponent(board, out var machineBoard)) - { - throw new Exception($"Entity with prototype {BoardPrototype} doesn't have a {nameof(MachineBoardComponent)}!"); - } - - foreach (var (part, amount) in machineBoard.Requirements) - { - for (var i = 0; i < amount; i++) - { - var p = entityManager.SpawnEntity(MachinePartComponent.Prototypes[part], _entMan.GetComponent(Owner).Coordinates); - - if (!partContainer.Insert(p)) - throw new Exception($"Couldn't insert machine part of type {part} to machine with prototype {_entMan.GetComponent(Owner).EntityPrototype?.ID ?? "N/A"}!"); - } - } - - foreach (var (stackType, amount) in machineBoard.MaterialRequirements) - { - var stack = EntitySystem.Get().Spawn(amount, stackType, _entMan.GetComponent(Owner).Coordinates); - - if (!partContainer.Insert(stack)) - throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {_entMan.GetComponent(Owner).EntityPrototype?.ID ?? "N/A"}"); - } - - foreach (var (compName, info) in machineBoard.ComponentRequirements) - { - for (var i = 0; i < info.Amount; i++) - { - var c = entityManager.SpawnEntity(info.DefaultPrototype, _entMan.GetComponent(Owner).Coordinates); - - if(!partContainer.Insert(c)) - throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {_entMan.GetComponent(Owner).EntityPrototype?.ID ?? "N/A"}"); - } - } - - foreach (var (tagName, info) in machineBoard.TagRequirements) - { - for (var i = 0; i < info.Amount; i++) - { - var c = entityManager.SpawnEntity(info.DefaultPrototype, _entMan.GetComponent(Owner).Coordinates); - - if(!partContainer.Insert(c)) - throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {_entMan.GetComponent(Owner).EntityPrototype?.ID ?? "N/A"}"); - } - } - } - - public void MapInit() - { - CreateBoardAndStockParts(); - RefreshParts(); - } + public Container BoardContainer = default!; + public Container PartContainer = default!; } } diff --git a/Content.Server/Construction/ConstructionSystem.Machine.cs b/Content.Server/Construction/ConstructionSystem.Machine.cs new file mode 100644 index 0000000000..9e03a622ba --- /dev/null +++ b/Content.Server/Construction/ConstructionSystem.Machine.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using Content.Server.Construction.Components; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; + +namespace Content.Server.Construction; + +public sealed partial class ConstructionSystem +{ + private void InitializeMachines() + { + SubscribeLocalEvent(OnMachineInit); + SubscribeLocalEvent(OnMachineMapInit); + } + + private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args) + { + component.BoardContainer = _container.EnsureContainer(uid, MachineFrameComponent.BoardContainer); + component.PartContainer = _container.EnsureContainer(uid, MachineFrameComponent.PartContainer); + } + + private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args) + { + CreateBoardAndStockParts(component); + RefreshParts(component); + } + + public IEnumerable GetAllParts(MachineComponent component) + { + foreach (var entity in component.PartContainer.ContainedEntities) + { + if (TryComp(entity, out var machinePart)) + yield return machinePart; + } + } + + public void RefreshParts(MachineComponent component) + { + foreach (var refreshable in EntityManager.GetComponents(component.Owner)) + { + refreshable.RefreshParts(GetAllParts(component)); + } + } + + public void CreateBoardAndStockParts(MachineComponent component) + { + // Entity might not be initialized yet. + var boardContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.BoardContainer); + var partContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.PartContainer); + + if (string.IsNullOrEmpty(component.BoardPrototype)) + return; + + // We're done here, let's suppose all containers are correct just so we don't screw SaveLoadSave. + if (boardContainer.ContainedEntities.Count > 0) + return; + + var board = EntityManager.SpawnEntity(component.BoardPrototype, Transform(component.Owner).Coordinates); + + if (!component.BoardContainer.Insert(board)) + { + throw new Exception($"Couldn't insert board with prototype {component.BoardPrototype} to machine with prototype {MetaData(component.Owner).EntityPrototype?.ID ?? "N/A"}!"); + } + + if (!TryComp(board, out var machineBoard)) + { + throw new Exception($"Entity with prototype {component.BoardPrototype} doesn't have a {nameof(MachineBoardComponent)}!"); + } + + foreach (var (part, amount) in machineBoard.Requirements) + { + for (var i = 0; i < amount; i++) + { + var p = EntityManager.SpawnEntity(MachinePartComponent.Prototypes[part], Transform(component.Owner).Coordinates); + + if (!partContainer.Insert(p)) + throw new Exception($"Couldn't insert machine part of type {part} to machine with prototype {MetaData(component.Owner).EntityPrototype?.ID ?? "N/A"}!"); + } + } + + foreach (var (stackType, amount) in machineBoard.MaterialRequirements) + { + var stack = _stackSystem.Spawn(amount, stackType, Transform(component.Owner).Coordinates); + + if (!partContainer.Insert(stack)) + throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {MetaData(component.Owner).EntityPrototype?.ID ?? "N/A"}"); + } + + foreach (var (compName, info) in machineBoard.ComponentRequirements) + { + for (var i = 0; i < info.Amount; i++) + { + var c = EntityManager.SpawnEntity(info.DefaultPrototype, Transform(component.Owner).Coordinates); + + if(!partContainer.Insert(c)) + throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {MetaData(component.Owner).EntityPrototype?.ID ?? "N/A"}"); + } + } + + foreach (var (tagName, info) in machineBoard.TagRequirements) + { + for (var i = 0; i < info.Amount; i++) + { + var c = EntityManager.SpawnEntity(info.DefaultPrototype, Transform(component.Owner).Coordinates); + + if(!partContainer.Insert(c)) + throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {MetaData(component.Owner).EntityPrototype?.ID ?? "N/A"}"); + } + } + } +} diff --git a/Content.Server/Construction/ConstructionSystem.cs b/Content.Server/Construction/ConstructionSystem.cs index 9386cf1889..96036b28fa 100644 --- a/Content.Server/Construction/ConstructionSystem.cs +++ b/Content.Server/Construction/ConstructionSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.Examine; using Content.Shared.Popups; using Content.Shared.Verbs; using JetBrains.Annotations; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; @@ -28,6 +29,7 @@ namespace Content.Server.Construction [Dependency] private readonly DoAfterSystem _doAfterSystem = default!; [Dependency] private readonly StackSystem _stackSystem = default!; [Dependency] private readonly ToolSystem _toolSystem = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; private const string SawmillName = "Construction"; private ISawmill _sawmill = default!; @@ -42,6 +44,7 @@ namespace Content.Server.Construction InitializeGuided(); InitializeInteractions(); InitializeInitial(); + InitializeMachines(); SubscribeLocalEvent(OnConstructionInit); SubscribeLocalEvent(OnConstructionStartup);