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"}"); } } } }