]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Machine-code cleanup (#28489)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Wed, 5 Jun 2024 20:23:23 +0000 (16:23 -0400)
committerGitHub <noreply@github.com>
Wed, 5 Jun 2024 20:23:23 +0000 (16:23 -0400)
31 files changed:
Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs
Content.IntegrationTests/Tests/MachineBoardTest.cs
Content.IntegrationTests/Tests/MaterialArbitrageTest.cs
Content.Server/Construction/Components/IRefreshParts.cs [deleted file]
Content.Server/Construction/Components/MachineComponent.cs
Content.Server/Construction/Components/MachineFrameComponent.cs
Content.Server/Construction/Components/PartExchangerComponent.cs [deleted file]
Content.Server/Construction/Conditions/MachineFrameComplete.cs
Content.Server/Construction/ConstructionSystem.Graph.cs
Content.Server/Construction/ConstructionSystem.Guided.cs
Content.Server/Construction/ConstructionSystem.Initial.cs
Content.Server/Construction/ConstructionSystem.Machine.cs
Content.Server/Construction/ConstructionSystem.cs
Content.Server/Construction/MachineFrameSystem.cs
Content.Server/Construction/PartExchangerSystem.cs [deleted file]
Content.Server/Stack/StackSystem.cs
Content.Shared/Construction/Components/MachineBoardComponent.cs
Content.Shared/Construction/Components/MachinePartComponent.cs [deleted file]
Content.Shared/Construction/MachinePartSystem.cs
Content.Shared/Construction/Prototypes/MachinePartPrototype.cs [deleted file]
Content.Shared/Construction/SharedConstructionSystem.cs
Content.Shared/Construction/SharedFlatpackSystem.cs
Content.Shared/Lathe/LatheComponent.cs
Resources/Locale/en-US/construction/steps/arbitrary-insert-construction-graph-step.ftl
Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/cannons.yml
Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/particle_accelerator.yml
Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml
Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml
Resources/Prototypes/Entities/Objects/Power/powercells.yml
Resources/Prototypes/MachineParts/machine_parts.yml [deleted file]
Resources/Prototypes/Stacks/science_stacks.yml

index ad19bc30f42fc7849d5a6de5822e5632d4e6e729..002616323784164f416f8b4f0e0c612df3890438 100644 (file)
@@ -75,8 +75,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow
         else if (_currentBoard != null)
         {
             Dictionary<string, int> cost;
-            if (_entityManager.TryGetComponent(_currentBoard, out machineBoardComp) &&
-                machineBoardComp.Prototype is not null)
+            if (_entityManager.TryGetComponent(_currentBoard, out machineBoardComp))
                 cost = _flatpack.GetFlatpackCreationCost((_owner, flatpacker), (_currentBoard.Value, machineBoardComp));
             else
                 cost = _flatpack.GetFlatpackCreationCost((_owner, flatpacker));
index bd3a72f4c1d115dbc354ab78825ac2c9a91f505b..e741935be3405e56e02f8d77d97db3f6b4cc92cc 100644 (file)
@@ -2,6 +2,8 @@
 using System.Linq;
 using Content.Server.Construction.Components;
 using Content.Shared.Construction.Components;
+using Content.Shared.Prototypes;
+using Robust.Shared.GameObjects;
 using Robust.Shared.Prototypes;
 
 namespace Content.IntegrationTests.Tests;
@@ -49,12 +51,11 @@ public sealed class MachineBoardTest
 
                 Assert.Multiple(() =>
                 {
-                    Assert.That(mId, Is.Not.Null, $"Machine board {p.ID} does not have a corresponding machine.");
                     Assert.That(protoMan.TryIndex<EntityPrototype>(mId, out var mProto),
                         $"Machine board {p.ID}'s corresponding machine has an invalid prototype.");
                     Assert.That(mProto.TryGetComponent<MachineComponent>(out var mComp),
                         $"Machine board {p.ID}'s corresponding machine {mId} does not have MachineComponent");
-                    Assert.That(mComp.BoardPrototype, Is.EqualTo(p.ID),
+                    Assert.That(mComp.Board, Is.EqualTo(p.ID),
                         $"Machine {mId}'s BoardPrototype is not equal to it's corresponding machine board, {p.ID}");
                 });
             }
@@ -101,4 +102,40 @@ public sealed class MachineBoardTest
 
         await pair.CleanReturnAsync();
     }
+
+    /// <summary>
+    /// Ensures that every single computer board's corresponding entity
+    /// is a computer that can be properly deconstructed to the correct board
+    /// </summary>
+    [Test]
+    public async Task TestValidateBoardComponentRequirements()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var entMan = server.ResolveDependency<IEntityManager>();
+        var protoMan = server.ResolveDependency<IPrototypeManager>();
+
+        await server.WaitAssertion(() =>
+        {
+            foreach (var p in protoMan.EnumeratePrototypes<EntityPrototype>()
+                         .Where(p => !p.Abstract)
+                         .Where(p => !pair.IsTestPrototype(p))
+                         .Where(p => !_ignoredPrototypes.Contains(p.ID)))
+            {
+                if (!p.TryGetComponent<MachineBoardComponent>(out var board, entMan.ComponentFactory))
+                    continue;
+
+                Assert.Multiple(() =>
+                {
+                    foreach (var component in board.ComponentRequirements.Keys)
+                    {
+                        Assert.That(entMan.ComponentFactory.TryGetRegistration(component, out _), $"Invalid component requirement {component} specified on machine board entity {p}");
+                    }
+                });
+            }
+        });
+
+        await pair.CleanReturnAsync();
+    }
 }
index ed1e5549438f016f95593b001dc333db8354a179..19780591bdbca7306e9523e8873c14f3a42b94e3 100644 (file)
@@ -60,7 +60,8 @@ public sealed class MaterialArbitrageTest
         }
 
         // Lets assume the possible lathe for resource multipliers:
-        var multiplier = MathF.Pow(LatheComponent.DefaultPartRatingMaterialUseMultiplier, MachinePartComponent.MaxRating - 1);
+        // TODO: each recipe can technically have its own cost multiplier associated with it, so this test needs redone to factor that in.
+        var multiplier = MathF.Pow(0.85f, 3);
 
         // create construction dictionary
         Dictionary<string, ConstructionComponent> constructionRecipes = new();
diff --git a/Content.Server/Construction/Components/IRefreshParts.cs b/Content.Server/Construction/Components/IRefreshParts.cs
deleted file mode 100644 (file)
index 714ca72..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-using Content.Shared.Construction.Components;
-
-namespace Content.Server.Construction.Components
-{
-    [RequiresExplicitImplementation]
-    public interface IRefreshParts
-    {
-        void RefreshParts(IEnumerable<MachinePartComponent> parts);
-    }
-}
index 42c85e6d0b55d02877166bd5da3739928398c324..8a0f117712e84b6df6ad5f9a4cca458257873e75 100644 (file)
@@ -1,27 +1,17 @@
-using Robust.Shared.Containers;
+using Content.Shared.Construction.Components;
+using Robust.Shared.Containers;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
-namespace Content.Server.Construction.Components
-{
-    [RegisterComponent, ComponentProtoName("Machine")]
-    public sealed partial class MachineComponent : Component
-    {
-        [DataField("board", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-        public string? BoardPrototype { get; private set; }
+namespace Content.Server.Construction.Components;
 
-        [ViewVariables]
-        public Container BoardContainer = default!;
-        [ViewVariables]
-        public Container PartContainer = default!;
-    }
+[RegisterComponent]
+public sealed partial class MachineComponent : Component
+{
+    [DataField]
+    public EntProtoId<MachineBoardComponent>? Board { get; private set; }
 
-    /// <summary>
-    /// The different types of scaling that are available for machine upgrades
-    /// </summary>
-    public enum MachineUpgradeScalingType : byte
-    {
-        Linear,
-        Exponential
-    }
+    [ViewVariables]
+    public Container BoardContainer = default!;
+    [ViewVariables]
+    public Container PartContainer = default!;
 }
index 75cc486f24083e063dc8faaee3b40767eeb3c2e7..14e81e8dd32ee8b47ef1244dd5f0e17e4bfa4f0c 100644 (file)
@@ -1,7 +1,8 @@
 using Content.Shared.Construction.Components;
-using Content.Shared.Construction.Prototypes;
+using Content.Shared.Stacks;
+using Content.Shared.Tag;
 using Robust.Shared.Containers;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
+using Robust.Shared.Prototypes;
 
 namespace Content.Server.Construction.Components
 {
@@ -14,29 +15,23 @@ namespace Content.Server.Construction.Components
         [ViewVariables]
         public bool HasBoard => BoardContainer?.ContainedEntities.Count != 0;
 
-        [DataField("progress", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, MachinePartPrototype>))]
-        public Dictionary<string, int> Progress = new();
-
         [ViewVariables]
-        public readonly Dictionary<string, int> MaterialProgress = new();
+        public readonly Dictionary<ProtoId<StackPrototype>, int> MaterialProgress = new();
 
         [ViewVariables]
         public readonly Dictionary<string, int> ComponentProgress = new();
 
         [ViewVariables]
-        public readonly Dictionary<string, int> TagProgress = new();
-
-        [DataField("requirements", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, MachinePartPrototype>))]
-        public Dictionary<string, int> Requirements = new();
+        public readonly Dictionary<ProtoId<TagPrototype>, int> TagProgress = new();
 
         [ViewVariables]
-        public Dictionary<string, int> MaterialRequirements = new();
+        public Dictionary<ProtoId<StackPrototype>, int> MaterialRequirements = new();
 
         [ViewVariables]
         public Dictionary<string, GenericPartInfo> ComponentRequirements = new();
 
         [ViewVariables]
-        public Dictionary<string, GenericPartInfo> TagRequirements = new();
+        public Dictionary<ProtoId<TagPrototype>, GenericPartInfo> TagRequirements = new();
 
         [ViewVariables]
         public Container BoardContainer = default!;
diff --git a/Content.Server/Construction/Components/PartExchangerComponent.cs b/Content.Server/Construction/Components/PartExchangerComponent.cs
deleted file mode 100644 (file)
index a2579c9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-using Robust.Shared.Audio;
-
-namespace Content.Server.Construction.Components;
-
-[RegisterComponent]
-public sealed partial class PartExchangerComponent : Component
-{
-    /// <summary>
-    /// How long it takes to exchange the parts
-    /// </summary>
-    [DataField("exchangeDuration")]
-    public float ExchangeDuration = 3;
-
-    /// <summary>
-    /// Whether or not the distance check is needed.
-    /// Good for BRPED.
-    /// </summary>
-    /// <remarks>
-    /// I fucking hate BRPED and if you ever add it
-    /// i will personally kill your dog.
-    /// </remarks>
-    [DataField("doDistanceCheck")]
-    public bool DoDistanceCheck = true;
-
-    [DataField("exchangeSound")]
-    public SoundSpecifier ExchangeSound = new SoundPathSpecifier("/Audio/Items/rped.ogg");
-
-    public EntityUid? AudioStream;
-}
index fbba5eca996f9531c79f0e641fba21ac0e87c496..33174bb9fb0ba6362446179aa4086c0732fc71f1 100644 (file)
@@ -2,6 +2,7 @@ using Content.Server.Construction.Components;
 using Content.Shared.Construction;
 using Content.Shared.Examine;
 using JetBrains.Annotations;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Construction.Conditions
@@ -17,7 +18,7 @@ namespace Content.Server.Construction.Conditions
         public SpriteSpecifier? GuideIconBoard { get; private set; }
 
         [DataField("guideIconParts")]
-        public SpriteSpecifier? GuideIconPart { get; private set; }
+        public SpriteSpecifier? GuideIconParts { get; private set; }
 
 
         public bool Condition(EntityUid uid, IEntityManager entityManager)
@@ -33,6 +34,8 @@ namespace Content.Server.Construction.Conditions
             var entity = args.Examined;
 
             var entityManager = IoCManager.Resolve<IEntityManager>();
+            var protoManager = IoCManager.Resolve<IPrototypeManager>();
+            var constructionSys = entityManager.System<ConstructionSystem>();
 
             if (!entityManager.TryGetComponent(entity, out MachineFrameComponent? machineFrame))
                 return false;
@@ -47,17 +50,6 @@ namespace Content.Server.Construction.Conditions
                 return false;
 
             args.PushMarkup(Loc.GetString("construction-condition-machine-frame-requirement-label"));
-            foreach (var (part, required) in machineFrame.Requirements)
-            {
-                var amount = required - machineFrame.Progress[part];
-
-                if(amount == 0)
-                    continue;
-
-                args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
-                                           ("amount", amount),
-                                           ("elementName", Loc.GetString(part))));
-            }
 
             foreach (var (material, required) in machineFrame.MaterialRequirements)
             {
@@ -65,10 +57,12 @@ namespace Content.Server.Construction.Conditions
 
                 if(amount == 0)
                     continue;
+                var stack = protoManager.Index(material);
+                var stackEnt = protoManager.Index(stack.Spawn);
 
                 args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
                                            ("amount", amount),
-                                           ("elementName", Loc.GetString(material))));
+                                           ("elementName", stackEnt.Name)));
             }
 
             foreach (var (compName, info) in machineFrame.ComponentRequirements)
@@ -78,9 +72,10 @@ namespace Content.Server.Construction.Conditions
                 if(amount == 0)
                     continue;
 
+                var examineName = constructionSys.GetExamineName(info);
                 args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
                                                 ("amount", info.Amount),
-                                                ("elementName", Loc.GetString(info.ExamineName))));
+                                                ("elementName", examineName)));
             }
 
             foreach (var (tagName, info) in machineFrame.TagRequirements)
@@ -90,9 +85,10 @@ namespace Content.Server.Construction.Conditions
                 if(amount == 0)
                     continue;
 
+                var examineName = constructionSys.GetExamineName(info);
                 args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
                                     ("amount", info.Amount),
-                                    ("elementName", Loc.GetString(info.ExamineName)))
+                                    ("elementName", examineName))
                                 + "\n");
             }
 
@@ -111,7 +107,7 @@ namespace Content.Server.Construction.Conditions
             yield return new ConstructionGuideEntry()
             {
                 Localization = "construction-step-condition-machine-frame-parts",
-                Icon = GuideIconPart,
+                Icon = GuideIconParts,
                 EntryNumber = 0, // Set this to anything so the guide generation takes this as a numbered step.
             };
         }
index 570360bf09a31f7b5df38609b332a1f43a450169..1b74fd9d4e5669b93d7ab064618aa98e3b5abd3b 100644 (file)
@@ -50,7 +50,7 @@ namespace Content.Server.Construction
 
             // If the set graph prototype does not exist, also return null. This could be due to admemes changing values
             // in ViewVariables, so even though the construction state is invalid, just return null.
-            return _prototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph) ? graph : null;
+            return PrototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph) ? graph : null;
         }
 
         /// <summary>
@@ -300,7 +300,7 @@ namespace Content.Server.Construction
             }
 
             // Exit if the new entity's prototype is the same as the original, or the prototype is invalid
-            if (newEntity == metaData.EntityPrototype?.ID || !_prototypeManager.HasIndex<EntityPrototype>(newEntity))
+            if (newEntity == metaData.EntityPrototype?.ID || !PrototypeManager.HasIndex<EntityPrototype>(newEntity))
                 return null;
 
             // [Optional] Exit if the new entity's prototype is a parent of the original
@@ -310,7 +310,7 @@ namespace Content.Server.Construction
             if (GetCurrentNode(uid, construction)?.DoNotReplaceInheritingEntities == true &&
                 metaData.EntityPrototype?.ID != null)
             {
-                var parents = _prototypeManager.EnumerateParents<EntityPrototype>(metaData.EntityPrototype.ID)?.ToList();
+                var parents = PrototypeManager.EnumerateParents<EntityPrototype>(metaData.EntityPrototype.ID)?.ToList();
 
                 if (parents != null && parents.Any(x => x.ID == newEntity))
                     return null;
@@ -427,7 +427,7 @@ namespace Content.Server.Construction
             if (!Resolve(uid, ref construction))
                 return false;
 
-            if (!_prototypeManager.TryIndex<ConstructionGraphPrototype>(graphId, out var graph))
+            if (!PrototypeManager.TryIndex<ConstructionGraphPrototype>(graphId, out var graph))
                 return false;
 
             if(GetNodeFromGraph(graph, nodeId) is not {})
index e096bc02c3157248159c9945891274f4ea5c9369..157e4211586a739e6db71e8b33e03a84cc109416 100644 (file)
@@ -25,7 +25,7 @@ namespace Content.Server.Construction
 
         private void OnGuideRequested(RequestConstructionGuide msg, EntitySessionEventArgs args)
         {
-            if (!_prototypeManager.TryIndex(msg.ConstructionId, out ConstructionPrototype? prototype))
+            if (!PrototypeManager.TryIndex(msg.ConstructionId, out ConstructionPrototype? prototype))
                 return;
 
             if(GetGuide(prototype) is {} guide)
@@ -41,7 +41,7 @@ namespace Content.Server.Construction
                 component.Node == component.DeconstructionNode)
                 return;
 
-            if (!_prototypeManager.TryIndex(component.Graph, out ConstructionGraphPrototype? graph))
+            if (!PrototypeManager.TryIndex(component.Graph, out ConstructionGraphPrototype? graph))
                 return;
 
             if (component.DeconstructionNode == null)
@@ -145,7 +145,7 @@ namespace Content.Server.Construction
                 return guide;
 
             // If the graph doesn't actually exist, do nothing.
-            if (!_prototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph))
+            if (!PrototypeManager.TryIndex(construction.Graph, out ConstructionGraphPrototype? graph))
                 return null;
 
             // If either the start node or the target node are missing, do nothing.
index 5161ac358ac94a69adf10709fe121fa434ddc312..08dd139ef4cecf293456a9f6c846644cbd798a57 100644 (file)
@@ -325,13 +325,13 @@ namespace Content.Server.Construction
         // LEGACY CODE. See warning at the top of the file!
         public async Task<bool> TryStartItemConstruction(string prototype, EntityUid user)
         {
-            if (!_prototypeManager.TryIndex(prototype, out ConstructionPrototype? constructionPrototype))
+            if (!PrototypeManager.TryIndex(prototype, out ConstructionPrototype? constructionPrototype))
             {
                 Log.Error($"Tried to start construction of invalid recipe '{prototype}'!");
                 return false;
             }
 
-            if (!_prototypeManager.TryIndex(constructionPrototype.Graph,
+            if (!PrototypeManager.TryIndex(constructionPrototype.Graph,
                     out ConstructionGraphPrototype? constructionGraph))
             {
                 Log.Error(
@@ -404,14 +404,14 @@ namespace Content.Server.Construction
         // LEGACY CODE. See warning at the top of the file!
         private async void HandleStartStructureConstruction(TryStartStructureConstructionMessage ev, EntitySessionEventArgs args)
         {
-            if (!_prototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype))
+            if (!PrototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype))
             {
                 Log.Error($"Tried to start construction of invalid recipe '{ev.PrototypeName}'!");
                 RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack));
                 return;
             }
 
-            if (!_prototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph))
+            if (!PrototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph))
             {
                 Log.Error($"Invalid construction graph '{constructionPrototype.Graph}' in recipe '{ev.PrototypeName}'!");
                 RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack));
index 2e670dbe40d4acfe39fe79f31eb2de05af37bac4..eb922f198c7b69085e9e7ca9479959de694fe263 100644 (file)
@@ -1,23 +1,15 @@
-using System.Linq;
 using Content.Server.Construction.Components;
-using Content.Server.Examine;
 using Content.Shared.Construction.Components;
-using Content.Shared.Construction.Prototypes;
-using Content.Shared.Verbs;
 using Robust.Shared.Containers;
-using Robust.Shared.Utility;
 
 namespace Content.Server.Construction;
 
 public sealed partial class ConstructionSystem
 {
-    [Dependency] private readonly ExamineSystem _examineSystem = default!;
-
     private void InitializeMachines()
     {
         SubscribeLocalEvent<MachineComponent, ComponentInit>(OnMachineInit);
         SubscribeLocalEvent<MachineComponent, MapInitEvent>(OnMachineMapInit);
-        SubscribeLocalEvent<MachineComponent, GetVerbsEvent<ExamineVerb>>(OnMachineExaminableVerb);
     }
 
     private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args)
@@ -29,84 +21,6 @@ public sealed partial class ConstructionSystem
     private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args)
     {
         CreateBoardAndStockParts(uid, component);
-        RefreshParts(uid, component);
-    }
-
-    private void OnMachineExaminableVerb(EntityUid uid, MachineComponent component, GetVerbsEvent<ExamineVerb> args)
-    {
-        if (!args.CanInteract || !args.CanAccess)
-            return;
-
-        var markup = new FormattedMessage();
-        RaiseLocalEvent(uid, new UpgradeExamineEvent(ref markup));
-        if (markup.IsEmpty)
-            return; // Not upgradable.
-
-        markup = FormattedMessage.FromMarkup(markup.ToMarkup().TrimEnd('\n')); // Cursed workaround to https://github.com/space-wizards/RobustToolbox/issues/3371
-
-        var verb = new ExamineVerb()
-        {
-            Act = () =>
-            {
-                _examineSystem.SendExamineTooltip(args.User, uid, markup, getVerbs: false, centerAtCursor: false);
-            },
-            Text = Loc.GetString("machine-upgrade-examinable-verb-text"),
-            Message = Loc.GetString("machine-upgrade-examinable-verb-message"),
-            Category = VerbCategory.Examine,
-            Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/pickup.svg.192dpi.png"))
-        };
-
-        args.Verbs.Add(verb);
-    }
-
-    public List<MachinePartComponent> GetAllParts(EntityUid uid, MachineComponent? component = null)
-    {
-        if (!Resolve(uid, ref component))
-            return new List<MachinePartComponent>();
-
-        return GetAllParts(component);
-    }
-
-    public List<MachinePartComponent> GetAllParts(MachineComponent component)
-    {
-        var parts = new List<MachinePartComponent>();
-
-        foreach (var entity in component.PartContainer.ContainedEntities)
-        {
-            if (TryComp<MachinePartComponent>(entity, out var machinePart))
-                parts.Add(machinePart);
-        }
-
-        return parts;
-    }
-
-    public Dictionary<string, float> GetPartsRatings(List<MachinePartComponent> parts)
-    {
-        var output = new Dictionary<string, float>();
-        foreach (var type in _prototypeManager.EnumeratePrototypes<MachinePartPrototype>())
-        {
-            var amount = 0f;
-            var sumRating = 0f;
-            foreach (var part in parts.Where(part => part.PartType == type.ID))
-            {
-                amount++;
-                sumRating += part.Rating;
-            }
-            var rating = amount != 0 ? sumRating / amount : 0;
-            output.Add(type.ID, rating);
-        }
-
-        return output;
-    }
-
-    public void RefreshParts(EntityUid uid, MachineComponent component)
-    {
-        var parts = GetAllParts(component);
-        EntityManager.EventBus.RaiseLocalEvent(uid, new RefreshPartsEvent
-        {
-            Parts = parts,
-            PartRatings = GetPartsRatings(parts),
-        }, true);
     }
 
     private void CreateBoardAndStockParts(EntityUid uid, MachineComponent component)
@@ -115,54 +29,37 @@ public sealed partial class ConstructionSystem
         var boardContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.BoardContainerName);
         var partContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.PartContainerName);
 
-        if (string.IsNullOrEmpty(component.BoardPrototype))
+        if (string.IsNullOrEmpty(component.Board))
             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(uid).Coordinates);
-
-        if (!_container.Insert(board, component.BoardContainer))
+        var xform = Transform(uid);
+        if (!TrySpawnInContainer(component.Board, uid, MachineFrameComponent.BoardContainerName, out var board))
         {
-            throw new Exception($"Couldn't insert board with prototype {component.BoardPrototype} to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}!");
+            throw new Exception($"Couldn't insert board with prototype {component.Board} to machine with prototype {Prototype(uid)?.ID ?? "N/A"}!");
         }
 
         if (!TryComp<MachineBoardComponent>(board, out var machineBoard))
         {
-            throw new Exception($"Entity with prototype {component.BoardPrototype} doesn't have a {nameof(MachineBoardComponent)}!");
-        }
-
-        var xform = Transform(uid);
-        foreach (var (part, amount) in machineBoard.Requirements)
-        {
-            var partProto = _prototypeManager.Index<MachinePartPrototype>(part);
-            for (var i = 0; i < amount; i++)
-            {
-                var p = EntityManager.SpawnEntity(partProto.StockPartPrototype, xform.Coordinates);
-
-                if (!_container.Insert(p, partContainer))
-                    throw new Exception($"Couldn't insert machine part of type {part} to machine with prototype {partProto.StockPartPrototype}!");
-            }
+            throw new Exception($"Entity with prototype {component.Board} doesn't have a {nameof(MachineBoardComponent)}!");
         }
 
-        foreach (var (stackType, amount) in machineBoard.MaterialRequirements)
+        foreach (var (stackType, amount) in machineBoard.StackRequirements)
         {
-            var stack = _stackSystem.Spawn(amount, stackType, Transform(uid).Coordinates);
-
+            var stack = _stackSystem.Spawn(amount, stackType, xform.Coordinates);
             if (!_container.Insert(stack, partContainer))
-                throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}");
+                throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Prototype(uid)?.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(uid).Coordinates);
-
-                if(!_container.Insert(c, partContainer))
-                    throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}");
+                if(!TrySpawnInContainer(info.DefaultPrototype, uid, MachineFrameComponent.PartContainerName, out _))
+                    throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {Prototype(uid)?.ID ?? "N/A"}");
             }
         }
 
@@ -170,58 +67,9 @@ public sealed partial class ConstructionSystem
         {
             for (var i = 0; i < info.Amount; i++)
             {
-                var c = EntityManager.SpawnEntity(info.DefaultPrototype, Transform(uid).Coordinates);
-
-                if(!_container.Insert(c, partContainer))
-                    throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {MetaData(uid).EntityPrototype?.ID ?? "N/A"}");
+                if(!TrySpawnInContainer(info.DefaultPrototype, uid, MachineFrameComponent.PartContainerName, out _))
+                    throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {Prototype(uid)?.ID ?? "N/A"}");
             }
         }
     }
 }
-
-public sealed class RefreshPartsEvent : EntityEventArgs
-{
-    public IReadOnlyList<MachinePartComponent> Parts = new List<MachinePartComponent>();
-
-    public Dictionary<string, float> PartRatings = new();
-}
-
-public sealed class UpgradeExamineEvent : EntityEventArgs
-{
-    private FormattedMessage Message;
-
-    public UpgradeExamineEvent(ref FormattedMessage message)
-    {
-        Message = message;
-    }
-
-    /// <summary>
-    /// Add a line to the upgrade examine tooltip with a percentage-based increase or decrease.
-    /// </summary>
-    public void AddPercentageUpgrade(string upgradedLocId, float multiplier)
-    {
-        var percent = Math.Round(100 * MathF.Abs(multiplier - 1), 2);
-        var locId = multiplier switch {
-            < 1 => "machine-upgrade-decreased-by-percentage",
-            1 or float.NaN => "machine-upgrade-not-upgraded",
-            > 1 => "machine-upgrade-increased-by-percentage",
-        };
-        var upgraded = Loc.GetString(upgradedLocId);
-        this.Message.AddMarkup(Loc.GetString(locId, ("upgraded", upgraded), ("percent", percent)) + '\n');
-    }
-
-    /// <summary>
-    /// Add a line to the upgrade examine tooltip with a numeric increase or decrease.
-    /// </summary>
-    public void AddNumberUpgrade(string upgradedLocId, int number)
-    {
-        var difference = Math.Abs(number);
-        var locId = number switch {
-            < 0 => "machine-upgrade-decreased-by-amount",
-            0 => "machine-upgrade-not-upgraded",
-            > 0 => "machine-upgrade-increased-by-amount",
-        };
-        var upgraded = Loc.GetString(upgradedLocId);
-        this.Message.AddMarkup(Loc.GetString(locId, ("upgraded", upgraded), ("difference", difference)) + '\n');
-    }
-}
index 44c6318b7891c12b5470c41f7ecee53b8743d096..9d881dcef04a948c1ea43d4041ba2f0bf853a994 100644 (file)
@@ -16,7 +16,6 @@ namespace Content.Server.Construction
     [UsedImplicitly]
     public sealed partial class ConstructionSystem : SharedConstructionSystem
     {
-        [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
         [Dependency] private readonly IRobustRandom _robustRandom = default!;
         [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
         [Dependency] private readonly ContainerSystem _container = default!;
index e20c36d8498c59b6f681a53dfd399271eb279e7c..0fd5ad2e0e45084c089ff8423ffece70a3441ad2 100644 (file)
@@ -7,7 +7,7 @@ using Content.Shared.Stacks;
 using Content.Shared.Tag;
 using Content.Shared.Popups;
 using Robust.Shared.Containers;
-using Robust.Shared.Utility;
+using Robust.Shared.Prototypes;
 
 namespace Content.Server.Construction;
 
@@ -62,24 +62,7 @@ public sealed class MachineFrameSystem : EntitySystem
         // If this changes in the future, then RegenerateProgress() also needs to be updated.
         // Note that one entity is ALLOWED to satisfy more than one kind of component or tag requirements. This is
         // necessary in order to avoid weird entity-ordering shenanigans in RegenerateProgress().
-        var stack = CompOrNull<StackComponent>(args.Used);
-        var machinePart = CompOrNull<MachinePartComponent>(args.Used);
-        if (stack != null && machinePart != null)
-        {
-            if (TryInsertPartStack(uid, args.Used, component, machinePart, stack))
-                args.Handled = true;
-            return;
-        }
-
-        // Handle parts
-        if (machinePart != null)
-        {
-            if (TryInsertPart(uid, args.Used, component, machinePart))
-                args.Handled = true;
-            return;
-        }
-
-        if (stack != null)
+        if (TryComp<StackComponent>(args.Used, out var stack))
         {
             if (TryInsertStack(uid, args.Used, component, stack))
                 args.Handled = true;
@@ -172,67 +155,6 @@ public sealed class MachineFrameSystem : EntitySystem
         return true;
     }
 
-    /// <returns>Whether or not the function had any effect. Does not indicate success.</returns>
-    private bool TryInsertPart(EntityUid uid, EntityUid used, MachineFrameComponent component, MachinePartComponent machinePart)
-    {
-        DebugTools.Assert(!HasComp<StackComponent>(uid));
-        if (!component.Requirements.ContainsKey(machinePart.PartType))
-            return false;
-
-        if (component.Progress[machinePart.PartType] >= component.Requirements[machinePart.PartType])
-            return false;
-
-        if (!_container.TryRemoveFromContainer(used))
-            return false;
-
-        if (!_container.Insert(used, component.PartContainer))
-            return true;
-
-        component.Progress[machinePart.PartType]++;
-        if (IsComplete(component))
-            _popupSystem.PopupEntity(Loc.GetString("machine-frame-component-on-complete"), uid);
-
-        return true;
-    }
-
-    /// <returns>Whether or not the function had any effect. Does not indicate success.</returns>
-    private bool TryInsertPartStack(EntityUid uid, EntityUid used, MachineFrameComponent component, MachinePartComponent machinePart, StackComponent stack)
-    {
-        if (!component.Requirements.ContainsKey(machinePart.PartType))
-            return false;
-
-        var progress = component.Progress[machinePart.PartType];
-        var requirement = component.Requirements[machinePart.PartType];
-
-        var needed = requirement - progress;
-        if (needed <= 0)
-            return false;
-
-        var count = stack.Count;
-        if (count < needed)
-        {
-            if (!_container.Insert(used, component.PartContainer))
-                return true;
-
-            component.Progress[machinePart.PartType] += count;
-            return true;
-        }
-
-        var splitStack = _stack.Split(used, needed, Transform(uid).Coordinates, stack);
-
-        if (splitStack == null)
-            return false;
-
-        if (!_container.Insert(splitStack.Value, component.PartContainer))
-            return true;
-
-        component.Progress[machinePart.PartType] += needed;
-        if (IsComplete(component))
-            _popupSystem.PopupEntity(Loc.GetString("machine-frame-component-on-complete"), uid);
-
-        return true;
-    }
-
     /// <returns>Whether or not the function had any effect. Does not indicate success.</returns>
     private bool TryInsertStack(EntityUid uid, EntityUid used, MachineFrameComponent component, StackComponent stack)
     {
@@ -281,12 +203,6 @@ public sealed class MachineFrameSystem : EntitySystem
         if (!component.HasBoard)
             return false;
 
-        foreach (var (part, amount) in component.Requirements)
-        {
-            if (component.Progress[part] < amount)
-                return false;
-        }
-
         foreach (var (type, amount) in component.MaterialRequirements)
         {
             if (component.MaterialProgress[type] < amount)
@@ -310,21 +226,14 @@ public sealed class MachineFrameSystem : EntitySystem
 
     public void ResetProgressAndRequirements(MachineFrameComponent component, MachineBoardComponent machineBoard)
     {
-        component.Requirements = new Dictionary<string, int>(machineBoard.Requirements);
-        component.MaterialRequirements = new Dictionary<string, int>(machineBoard.MaterialIdRequirements);
+        component.MaterialRequirements = new Dictionary<ProtoId<StackPrototype>, int>(machineBoard.StackRequirements);
         component.ComponentRequirements = new Dictionary<string, GenericPartInfo>(machineBoard.ComponentRequirements);
-        component.TagRequirements = new Dictionary<string, GenericPartInfo>(machineBoard.TagRequirements);
+        component.TagRequirements = new Dictionary<ProtoId<TagPrototype>, GenericPartInfo>(machineBoard.TagRequirements);
 
-        component.Progress.Clear();
         component.MaterialProgress.Clear();
         component.ComponentProgress.Clear();
         component.TagProgress.Clear();
 
-        foreach (var (machinePart, _) in component.Requirements)
-        {
-            component.Progress[machinePart] = 0;
-        }
-
         foreach (var (stackType, _) in component.MaterialRequirements)
         {
             component.MaterialProgress[stackType] = 0;
@@ -349,7 +258,6 @@ public sealed class MachineFrameSystem : EntitySystem
             component.MaterialRequirements.Clear();
             component.ComponentRequirements.Clear();
             component.TagRequirements.Clear();
-            component.Progress.Clear();
             component.MaterialProgress.Clear();
             component.ComponentProgress.Clear();
             component.TagProgress.Clear();
@@ -368,19 +276,6 @@ public sealed class MachineFrameSystem : EntitySystem
 
         foreach (var part in component.PartContainer.ContainedEntities)
         {
-            if (TryComp<MachinePartComponent>(part, out var machinePart))
-            {
-                // Check this is part of the requirements...
-                if (!component.Requirements.ContainsKey(machinePart.PartType))
-                    continue;
-
-                if (!component.Progress.ContainsKey(machinePart.PartType))
-                    component.Progress[machinePart.PartType] = 1;
-                else
-                    component.Progress[machinePart.PartType]++;
-                continue;
-            }
-
             if (TryComp<StackComponent>(part, out var stack))
             {
                 var type = stack.StackTypeId;
@@ -404,9 +299,7 @@ public sealed class MachineFrameSystem : EntitySystem
                 if (!HasComp(part, registration.Type))
                     continue;
 
-                if (!component.ComponentProgress.ContainsKey(compName))
-                    component.ComponentProgress[compName] = 1;
-                else
+                if (!component.ComponentProgress.TryAdd(compName, 1))
                     component.ComponentProgress[compName]++;
             }
 
@@ -419,18 +312,17 @@ public sealed class MachineFrameSystem : EntitySystem
                 if (!_tag.HasTag(tagComp, tagName))
                     continue;
 
-                if (!component.TagProgress.ContainsKey(tagName))
-                    component.TagProgress[tagName] = 1;
-                else
+                if (!component.TagProgress.TryAdd(tagName, 1))
                     component.TagProgress[tagName]++;
             }
         }
     }
     private void OnMachineFrameExamined(EntityUid uid, MachineFrameComponent component, ExaminedEvent args)
     {
-        if (!args.IsInDetailsRange)
+        if (!args.IsInDetailsRange || !component.HasBoard)
             return;
-        if (component.HasBoard)
-            args.PushMarkup(Loc.GetString("machine-frame-component-on-examine-label", ("board", EntityManager.GetComponent<MetaDataComponent>(component.BoardContainer.ContainedEntities[0]).EntityName)));
+
+        var board = component.BoardContainer.ContainedEntities[0];
+        args.PushMarkup(Loc.GetString("machine-frame-component-on-examine-label", ("board", Name(board))));
     }
 }
diff --git a/Content.Server/Construction/PartExchangerSystem.cs b/Content.Server/Construction/PartExchangerSystem.cs
deleted file mode 100644 (file)
index 174dd1d..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-using System.Linq;
-using Content.Server.Construction.Components;
-using Content.Server.Storage.EntitySystems;
-using Content.Shared.DoAfter;
-using Content.Shared.Construction.Components;
-using Content.Shared.Exchanger;
-using Content.Shared.Interaction;
-using Content.Shared.Popups;
-using Content.Shared.Storage;
-using Robust.Shared.Containers;
-using Robust.Shared.Utility;
-using Content.Shared.Wires;
-using Robust.Shared.Audio.Systems;
-using Robust.Shared.Collections;
-
-namespace Content.Server.Construction;
-
-public sealed class PartExchangerSystem : EntitySystem
-{
-    [Dependency] private readonly ConstructionSystem _construction = default!;
-    [Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
-    [Dependency] private readonly SharedPopupSystem _popup = default!;
-    [Dependency] private readonly SharedContainerSystem _container = default!;
-    [Dependency] private readonly SharedAudioSystem _audio = default!;
-    [Dependency] private readonly StorageSystem _storage = default!;
-
-    /// <inheritdoc/>
-    public override void Initialize()
-    {
-        SubscribeLocalEvent<PartExchangerComponent, AfterInteractEvent>(OnAfterInteract);
-        SubscribeLocalEvent<PartExchangerComponent, ExchangerDoAfterEvent>(OnDoAfter);
-    }
-
-    private void OnDoAfter(EntityUid uid, PartExchangerComponent component, DoAfterEvent args)
-    {
-        if (args.Cancelled)
-        {
-            component.AudioStream = _audio.Stop(component.AudioStream);
-            return;
-        }
-
-        if (args.Handled || args.Args.Target == null)
-            return;
-
-        if (!TryComp<StorageComponent>(uid, out var storage))
-            return; //the parts are stored in here
-
-        var machinePartQuery = GetEntityQuery<MachinePartComponent>();
-        var machineParts = new List<(EntityUid, MachinePartComponent)>();
-
-        foreach (var item in storage.Container.ContainedEntities) //get parts in RPED
-        {
-            if (machinePartQuery.TryGetComponent(item, out var part))
-                machineParts.Add((item, part));
-        }
-
-        TryExchangeMachineParts(args.Args.Target.Value, uid, machineParts);
-        TryConstructMachineParts(args.Args.Target.Value, uid, machineParts);
-
-        args.Handled = true;
-    }
-
-    private void TryExchangeMachineParts(EntityUid uid, EntityUid storageUid, List<(EntityUid part, MachinePartComponent partComp)> machineParts)
-    {
-        if (!TryComp<MachineComponent>(uid, out var machine))
-            return;
-
-        var machinePartQuery = GetEntityQuery<MachinePartComponent>();
-        var board = machine.BoardContainer.ContainedEntities.FirstOrNull();
-
-        if (board == null || !TryComp<MachineBoardComponent>(board, out var macBoardComp))
-            return;
-
-        foreach (var item in new ValueList<EntityUid>(machine.PartContainer.ContainedEntities)) //clone so don't modify during enumeration
-        {
-            if (machinePartQuery.TryGetComponent(item, out var part))
-            {
-                machineParts.Add((item, part));
-                _container.RemoveEntity(uid, item);
-            }
-        }
-
-        machineParts.Sort((x, y) => y.partComp.Rating.CompareTo(x.partComp.Rating));
-
-        var updatedParts = new List<(EntityUid part, MachinePartComponent partComp)>();
-        foreach (var (type, amount) in macBoardComp.Requirements)
-        {
-            var target = machineParts.Where(p => p.partComp.PartType == type).Take(amount);
-            updatedParts.AddRange(target);
-        }
-        foreach (var part in updatedParts)
-        {
-            _container.Insert(part.part, machine.PartContainer);
-            machineParts.Remove(part);
-        }
-
-        //put the unused parts back into rped. (this also does the "swapping")
-        foreach (var (unused, _) in machineParts)
-        {
-            _storage.Insert(storageUid, unused, out _, playSound: false);
-        }
-        _construction.RefreshParts(uid, machine);
-    }
-
-    private void TryConstructMachineParts(EntityUid uid, EntityUid storageEnt, List<(EntityUid part, MachinePartComponent partComp)> machineParts)
-    {
-        if (!TryComp<MachineFrameComponent>(uid, out var machine))
-            return;
-
-        var machinePartQuery = GetEntityQuery<MachinePartComponent>();
-        var board = machine.BoardContainer.ContainedEntities.FirstOrNull();
-
-        if (!machine.HasBoard || !TryComp<MachineBoardComponent>(board, out var macBoardComp))
-            return;
-
-        foreach (var item in new ValueList<EntityUid>(machine.PartContainer.ContainedEntities)) //clone so don't modify during enumeration
-        {
-            if (machinePartQuery.TryGetComponent(item, out var part))
-            {
-                machineParts.Add((item, part));
-                _container.RemoveEntity(uid, item);
-                machine.Progress[part.PartType]--;
-            }
-        }
-
-        machineParts.Sort((x, y) => y.partComp.Rating.CompareTo(x.partComp.Rating));
-
-        var updatedParts = new List<(EntityUid part, MachinePartComponent partComp)>();
-        foreach (var (type, amount) in macBoardComp.Requirements)
-        {
-            var target = machineParts.Where(p => p.partComp.PartType == type).Take(amount);
-            updatedParts.AddRange(target);
-        }
-        foreach (var pair in updatedParts)
-        {
-            var part = pair.partComp;
-            var partEnt = pair.part;
-
-            if (!machine.Requirements.ContainsKey(part.PartType))
-                continue;
-
-            _container.Insert(partEnt, machine.PartContainer);
-            machine.Progress[part.PartType]++;
-            machineParts.Remove(pair);
-        }
-
-        //put the unused parts back into rped. (this also does the "swapping")
-        foreach (var (unused, _) in machineParts)
-        {
-            _storage.Insert(storageEnt, unused, out _, playSound: false);
-        }
-    }
-
-    private void OnAfterInteract(EntityUid uid, PartExchangerComponent component, AfterInteractEvent args)
-    {
-        if (component.DoDistanceCheck && !args.CanReach)
-            return;
-
-        if (args.Target == null)
-            return;
-
-        if (!HasComp<MachineComponent>(args.Target) && !HasComp<MachineFrameComponent>(args.Target))
-            return;
-
-        if (TryComp<WiresPanelComponent>(args.Target, out var panel) && !panel.Open)
-        {
-            _popup.PopupEntity(Loc.GetString("construction-step-condition-wire-panel-open"),
-                args.Target.Value);
-            return;
-        }
-
-        component.AudioStream = _audio.PlayPvs(component.ExchangeSound, uid).Value.Entity;
-
-        _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.ExchangeDuration, new ExchangerDoAfterEvent(), uid, target: args.Target, used: uid)
-        {
-            BreakOnDamage = true,
-            BreakOnMove = true
-        });
-    }
-}
index e34592b45f9c0f81f098f21c11da47e7ad036a22..bac789716ca7652afac95685675c8b5547f3737b 100644 (file)
@@ -71,6 +71,15 @@ namespace Content.Server.Stack
             return entity;
         }
 
+        /// <summary>
+        ///     Spawns a stack of a certain stack type. See <see cref="StackPrototype"/>.
+        /// </summary>
+        public EntityUid Spawn(int amount, ProtoId<StackPrototype> id, EntityCoordinates spawnPosition)
+        {
+            var proto = _prototypeManager.Index(id);
+            return Spawn(amount, proto, spawnPosition);
+        }
+
         /// <summary>
         ///     Spawns a stack of a certain stack type. See <see cref="StackPrototype"/>.
         /// </summary>
index dbca31606166b048728fb2d7193c559ee8adc19a..0469b59fd1e7de59b2eccdd91a0ab3ee192f5f96 100644 (file)
@@ -1,54 +1,47 @@
-using Content.Shared.Construction.Prototypes;
 using Content.Shared.Stacks;
+using Content.Shared.Tag;
 using Robust.Shared.GameStates;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
 
-namespace Content.Shared.Construction.Components
+namespace Content.Shared.Construction.Components;
+
+[RegisterComponent, NetworkedComponent]
+public sealed partial class MachineBoardComponent : Component
+{
+    /// <summary>
+    /// The stacks needed to construct this machine
+    /// </summary>
+    [DataField]
+    public Dictionary<ProtoId<StackPrototype>, int> StackRequirements = new();
+
+    /// <summary>
+    /// Entities needed to construct this machine, discriminated by tag.
+    /// </summary>
+    [DataField]
+    public Dictionary<ProtoId<TagPrototype>, GenericPartInfo> TagRequirements = new();
+
+    /// <summary>
+    /// Entities needed to construct this machine, discriminated by component.
+    /// </summary>
+    [DataField]
+    public Dictionary<string, GenericPartInfo> ComponentRequirements = new();
+
+    /// <summary>
+    /// The machine that's constructed when this machine board is completed.
+    /// </summary>
+    [DataField(required: true)]
+    public EntProtoId Prototype;
+}
+
+[DataDefinition, Serializable]
+public partial struct GenericPartInfo
 {
-    [RegisterComponent, NetworkedComponent]
-    public sealed partial class MachineBoardComponent : Component
-    {
-        [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
-
-        [DataField("requirements", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, MachinePartPrototype>))]
-        public Dictionary<string, int> Requirements = new();
-
-        [DataField("materialRequirements")]
-        public Dictionary<string, int> MaterialIdRequirements = new();
-
-        [DataField("tagRequirements")]
-        public Dictionary<string, GenericPartInfo> TagRequirements = new();
-
-        [DataField("componentRequirements")]
-        public Dictionary<string, GenericPartInfo> ComponentRequirements = new();
-
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("prototype")]
-        public string? Prototype { get; private set; }
-
-        public IEnumerable<KeyValuePair<StackPrototype, int>> MaterialRequirements
-        {
-            get
-            {
-                foreach (var (materialId, amount) in MaterialIdRequirements)
-                {
-                    var material = _prototypeManager.Index<StackPrototype>(materialId);
-                    yield return new KeyValuePair<StackPrototype, int>(material, amount);
-                }
-            }
-        }
-    }
-
-    [Serializable]
-    [DataDefinition]
-    public partial struct GenericPartInfo
-    {
-        [DataField("Amount")]
-        public int Amount;
-        [DataField("ExamineName")]
-        public string ExamineName;
-        [DataField("DefaultPrototype")]
-        public string DefaultPrototype;
-    }
+    [DataField(required: true)]
+    public int Amount;
+
+    [DataField(required: true)]
+    public EntProtoId DefaultPrototype;
+
+    [DataField]
+    public LocId? ExamineName;
 }
diff --git a/Content.Shared/Construction/Components/MachinePartComponent.cs b/Content.Shared/Construction/Components/MachinePartComponent.cs
deleted file mode 100644 (file)
index a68e349..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-using Content.Shared.Construction.Prototypes;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Shared.Construction.Components
-{
-    [RegisterComponent, NetworkedComponent]
-    public sealed partial class MachinePartComponent : Component
-    {
-        [DataField("part", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
-        public string PartType { get; private set; } = default!;
-
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("rating")]
-        public int Rating { get; private set; } = 1;
-
-        /// <summary>
-        ///     This number is used in tests to ensure that you can't use high quality machines for arbitrage. In
-        ///     principle there is nothing wrong with using higher quality parts, but you have to be careful to not
-        ///     allow them to be put into a lathe or something like that.
-        /// </summary>
-        public const int MaxRating = 4;
-    }
-}
index 359b58c8816f69e6f94de455b37cd2b6a56635f8..f357a395e64ffc384b24eebb53822aa1bc8ee30b 100644 (file)
@@ -1,10 +1,8 @@
 using System.Linq;
 using Content.Shared.Construction.Components;
-using Content.Shared.Construction.Prototypes;
 using Content.Shared.Examine;
 using Content.Shared.Lathe;
 using Content.Shared.Materials;
-using Content.Shared.Stacks;
 using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Construction
@@ -16,6 +14,7 @@ namespace Content.Shared.Construction
     {
         [Dependency] private readonly IPrototypeManager _prototype = default!;
         [Dependency] private readonly SharedLatheSystem _lathe = default!;
+        [Dependency] private readonly SharedConstructionSystem _construction = default!;
 
         public override void Initialize()
         {
@@ -31,32 +30,30 @@ namespace Content.Shared.Construction
             using (args.PushGroup(nameof(MachineBoardComponent)))
             {
                 args.PushMarkup(Loc.GetString("machine-board-component-on-examine-label"));
-                foreach (var (part, amount) in component.Requirements)
+                foreach (var (material, amount) in component.StackRequirements)
                 {
-                    args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text",
-                        ("amount", amount),
-                        ("requiredElement", Loc.GetString(_prototype.Index<MachinePartPrototype>(part).Name))));
-                }
+                    var stack = _prototype.Index(material);
+                    var name = _prototype.Index(stack.Spawn).Name;
 
-                foreach (var (material, amount) in component.MaterialRequirements)
-                {
                     args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text",
                         ("amount", amount),
-                        ("requiredElement", Loc.GetString(material.Name))));
+                        ("requiredElement", Loc.GetString(name))));
                 }
 
                 foreach (var (_, info) in component.ComponentRequirements)
                 {
+                    var examineName = _construction.GetExamineName(info);
                     args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text",
                         ("amount", info.Amount),
-                        ("requiredElement", Loc.GetString(info.ExamineName))));
+                        ("requiredElement", examineName)));
                 }
 
                 foreach (var (_, info) in component.TagRequirements)
                 {
+                    var examineName = _construction.GetExamineName(info);
                     args.PushMarkup(Loc.GetString("machine-board-component-required-element-entry-text",
                         ("amount", info.Amount),
-                        ("requiredElement", Loc.GetString(info.ExamineName))));
+                        ("requiredElement", examineName)));
                 }
             }
         }
@@ -66,30 +63,13 @@ namespace Content.Shared.Construction
             var (_, comp) = entity;
 
             var materials = new Dictionary<string, int>();
-            foreach (var (partId, amount) in comp.Requirements)
-            {
-                var partProto = _prototype.Index<MachinePartPrototype>(partId);
-
-                if (!_lathe.TryGetRecipesFromEntity(partProto.StockPartPrototype, out var recipes))
-                    continue;
-
-                var partRecipe = recipes[0];
-                if (recipes.Count > 1)
-                    partRecipe = recipes.MinBy(p => p.RequiredMaterials.Values.Sum());
-
-                foreach (var (mat, matAmount) in partRecipe!.RequiredMaterials)
-                {
-                    materials.TryAdd(mat, 0);
-                    materials[mat] += matAmount * amount * coefficient;
-                }
-            }
 
-            foreach (var (stackId, amount) in comp.MaterialIdRequirements)
+            foreach (var (stackId, amount) in comp.StackRequirements)
             {
-                var stackProto = _prototype.Index<StackPrototype>(stackId);
+                var stackProto = _prototype.Index(stackId);
                 var defaultProto = _prototype.Index(stackProto.Spawn);
 
-                if (defaultProto.TryGetComponent<PhysicalCompositionComponent>(out var physComp))
+                if (defaultProto.TryGetComponent<PhysicalCompositionComponent>(out var physComp, EntityManager.ComponentFactory))
                 {
                     foreach (var (mat, matAmount) in physComp.MaterialComposition)
                     {
@@ -130,7 +110,7 @@ namespace Content.Shared.Construction
                     }
                 }
                 else if (_prototype.TryIndex(defaultProtoId, out var defaultProto) &&
-                         defaultProto.TryGetComponent<PhysicalCompositionComponent>(out var physComp))
+                         defaultProto.TryGetComponent<PhysicalCompositionComponent>(out var physComp, EntityManager.ComponentFactory))
                 {
                     foreach (var (mat, matAmount) in physComp.MaterialComposition)
                     {
diff --git a/Content.Shared/Construction/Prototypes/MachinePartPrototype.cs b/Content.Shared/Construction/Prototypes/MachinePartPrototype.cs
deleted file mode 100644 (file)
index 7a080c9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Shared.Construction.Prototypes;
-
-/// <summary>
-/// This is a prototype for categorizing
-/// different types of machine parts.
-/// </summary>
-[Prototype("machinePart")]
-public sealed partial class MachinePartPrototype : IPrototype
-{
-    /// <inheritdoc/>
-    [IdDataField]
-    public string ID { get; private set; } = default!;
-
-    /// <summary>
-    /// A human-readable name for the machine part type.
-    /// </summary>
-    [DataField("name")]
-    public string Name = string.Empty;
-
-    /// <summary>
-    /// A stock part entity based on the machine part.
-    /// </summary>
-    [DataField("stockPartPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>), required: true)]
-    public string StockPartPrototype = string.Empty;
-}
index 069290d14315ad21fa86735d1bce2599eaf1a6ad..901b2f834d1989e91478a0a6d3138bbc2d7dc622 100644 (file)
@@ -1,5 +1,7 @@
 using System.Linq;
+using Content.Shared.Construction.Components;
 using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
 using static Content.Shared.Interaction.SharedInteractionSystem;
 
 namespace Content.Shared.Construction
@@ -7,6 +9,7 @@ namespace Content.Shared.Construction
     public abstract class SharedConstructionSystem : EntitySystem
     {
         [Dependency] private readonly IMapManager _mapManager = default!;
+        [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
 
         /// <summary>
         ///     Get predicate for construction obstruction checks.
@@ -22,5 +25,13 @@ namespace Content.Shared.Construction
             var ignored = grid.GetAnchoredEntities(coords).ToHashSet();
             return e => ignored.Contains(e);
         }
+
+        public string GetExamineName(GenericPartInfo info)
+        {
+            if (info.ExamineName is not null)
+                return Loc.GetString(info.ExamineName.Value);
+
+            return PrototypeManager.Index(info.DefaultPrototype).Name;
+        }
     }
 }
index 8b21bca52aea56255cf0b6b861881f7f56b22bea..62d2089fb7c34b6e7173b6c1f8095adbed94897e 100644 (file)
@@ -1,4 +1,3 @@
-using System.Numerics;
 using Content.Shared.Construction.Components;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
@@ -9,7 +8,6 @@ using Content.Shared.Popups;
 using Content.Shared.Tools.Systems;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Containers;
-using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Network;
 using Robust.Shared.Physics.Components;
@@ -88,7 +86,8 @@ public abstract class SharedFlatpackSystem : EntitySystem
         if (_net.IsServer)
         {
             var spawn = Spawn(comp.Entity, _map.GridTileToLocal(grid, gridComp, buildPos));
-            _adminLogger.Add(LogType.Construction, LogImpact.Low,
+            _adminLogger.Add(LogType.Construction,
+                LogImpact.Low,
                 $"{ToPrettyString(args.User):player} unpacked {ToPrettyString(spawn):entity} at {xform.Coordinates} from {ToPrettyString(uid):entity}");
             QueueDel(uid);
         }
@@ -115,9 +114,7 @@ public abstract class SharedFlatpackSystem : EntitySystem
             return;
 
         var machinePrototypeId = new EntProtoId();
-        if (TryComp<MachineBoardComponent>(board, out var machineBoard) && machineBoard.Prototype is not null)
-            machinePrototypeId = machineBoard.Prototype;
-        else if (TryComp<ComputerBoardComponent>(board, out var computerBoard) && computerBoard.Prototype is not null)
+        if (TryComp<ComputerBoardComponent>(board, out var computerBoard) && computerBoard.Prototype is not null)
             machinePrototypeId = computerBoard.Prototype;
 
         var comp = ent.Comp!;
index d4bf18b0507d9d1f40bb722a5dd961f14d6cd180..88ac8c05bfbf824c71e4bce5eab507471fedbfcf 100644 (file)
@@ -59,8 +59,6 @@ namespace Content.Shared.Lathe
         /// </summary>
         [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
         public float MaterialUseMultiplier = 1;
-
-        public const float DefaultPartRatingMaterialUseMultiplier = 0.85f;
         #endregion
     }
 
index 6a7998e57a20c49ae210b9c52714b7c960630c31..430888ed36530bdc326f56194c81fabbb5e844ce 100644 (file)
@@ -1,2 +1,10 @@
 # Shown when examining an in-construction object
-construction-insert-arbitrary-entity = Next, insert {$stepName}.
\ No newline at end of file
+construction-insert-arbitrary-entity = Next, insert {$stepName}.
+
+construction-insert-info-examine-name-instrument-brass = brass instrument
+construction-insert-info-examine-name-instrument-keyed = keyed instrument
+construction-insert-info-examine-name-instrument-percussion = percussion instrument
+construction-insert-info-examine-name-instrument-string = string intrument
+construction-insert-info-examine-name-instrument-woodwind = woodwind instrument
+construction-insert-info-examine-name-knife = knife
+construction-insert-info-examine-name-utensil = utensil
index 6db7f4b385edfc6d53a2c07cebb8f88a4f2df6c6..e4bde7ab84f6779ba606ec81fc059be259635618 100644 (file)
     state: security
   - type: MachineBoard
     prototype: ShuttleGunSvalinnMachineGun
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Manipulator: 4
-    materialRequirements:
       Steel: 5
       CableHV: 5
 
     state: security
   - type: MachineBoard
     prototype: ShuttleGunPerforator
-    requirements:
+    stackRequirements:
       MatterBin: 4
       Manipulator: 6
-    materialRequirements:
       Steel: 10
       CableHV: 5
 
     state: security
   - type: MachineBoard
     prototype: ShuttleGunFriendship
-    requirements:
+    stackRequirements:
       MatterBin: 3
       Manipulator: 2
-    materialRequirements:
       Steel: 7
       CableHV: 5
 
     state: security
   - type: MachineBoard
     prototype: ShuttleGunDuster
-    requirements:
+    stackRequirements:
       MatterBin: 6
       Manipulator: 4
-    materialRequirements:
       Steel: 10
       CableHV: 5
       Uranium: 2
@@ -84,9 +80,8 @@
     state: security
   - type: MachineBoard
     prototype: ShuttleGunKinetic
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Manipulator: 3
-    materialRequirements:
       Steel: 5
-      CableHV: 2
\ No newline at end of file
+      CableHV: 2
index 78e17e0745504d0945acf083305d728a22c4cd84..a1260f07c0c15c861c9efb414cf2d8ffa5dd814b 100644 (file)
@@ -8,7 +8,7 @@
       state: engineering
     - type: MachineBoard
       prototype: ParticleAcceleratorEndCapUnfinished
-      materialRequirements:
+      stackRequirements:
         Glass: 15
         Steel: 15
 
       prototype: ParticleAcceleratorFuelChamberUnfinished
       componentRequirements:
         AmeFuelContainer:
-          Amount: 1
-          DefaultPrototype: AmeJar
-          ExamineName: AME Fuel Jar
-      materialRequirements:
+          amount: 1
+          defaultPrototype: AmeJar
+      stackRequirements:
         Glass: 10
         Steel: 10
 
@@ -41,7 +40,7 @@
       state: engineering
     - type: MachineBoard
       prototype: ParticleAcceleratorPowerBoxUnfinished
-      materialRequirements:
+      stackRequirements:
         Glass: 5
         Steel: 5
 
@@ -57,7 +56,7 @@
       state: engineering
     - type: MachineBoard
       prototype: ParticleAcceleratorEmitterStarboardUnfinished
-      materialRequirements:
+      stackRequirements:
         Glass: 5
         Steel: 5
 
@@ -71,7 +70,7 @@
       state: engineering
     - type: MachineBoard
       prototype: ParticleAcceleratorEmitterForeUnfinished
-      materialRequirements:
+      stackRequirements:
         Glass: 5
         Steel: 5
 
@@ -85,6 +84,6 @@
       state: engineering
     - type: MachineBoard
       prototype: ParticleAcceleratorEmitterPortUnfinished
-      materialRequirements:
+      stackRequirements:
         Glass: 5
         Steel: 5
index 587e56865b4dbb399f5111101d867b5bcdd63950..d41923b569d0cc9efee2b131564a5a11dc430ea6 100644 (file)
@@ -6,10 +6,9 @@
   components:
     - type: MachineBoard
       prototype: Autolathe
-      requirements:
+      stackRequirements:
         MatterBin: 3
         Manipulator: 1
-      materialRequirements:
         Glass: 1
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: AutolatheHyperConvection
-    requirements:
+    stackRequirements:
       MatterBin: 3
-    materialRequirements:
       Glass: 1
     tagRequirements:
       Igniter:
-        Amount: 1
-        DefaultPrototype: Igniter
-        ExamineName: Igniter
+        amount: 1
+        defaultPrototype: Igniter
 
 - type: entity
   id: ProtolatheMachineCircuitboard
   components:
     - type: MachineBoard
       prototype: Protolathe
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 2
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
 
 - type: entity
   parent: BaseMachineCircuitboard
   components:
   - type: MachineBoard
     prototype: ProtolatheHyperConvection
-    requirements:
+    stackRequirements:
       MatterBin: 2
     tagRequirements:
       GlassBeaker:
-        Amount: 2
-        DefaultPrototype: Beaker
-        ExamineName: Glass Beaker
+        amount: 2
+        defaultPrototype: Beaker
       Igniter:
-        Amount: 1
-        DefaultPrototype: Igniter
-        ExamineName: Igniter
+        amount: 1
+        defaultPrototype: Igniter
 
 - type: entity
   id: BiofabricatorMachineCircuitboard
@@ -75,9 +69,8 @@
   components:
     - type: MachineBoard
       prototype: Biofabricator
-      requirements:
+      stackRequirements:
         MatterBin: 4
-      materialRequirements:
         Glass: 1
 
 - type: entity
       state: security
     - type: MachineBoard
       prototype: SecurityTechFab
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 2
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
 
 - type: entity
   id: AmmoTechFabCircuitboard
       state: security
     - type: MachineBoard
       prototype: AmmoTechFab
-      requirements:
+      stackRequirements:
         MatterBin: 1
         Manipulator: 1
 
       state: medical
     - type: MachineBoard
       prototype: MedicalTechFab
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 2
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
     - type: StealTarget
       stealGroup: MedicalTechFabCircuitboard
 
     state: science
   - type: MachineBoard
     prototype: CircuitImprinter
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 1
     tagRequirements:
       GlassBeaker:
-        Amount: 2
-        DefaultPrototype: Beaker
-        ExamineName: Glass Beaker
+        amount: 2
+        defaultPrototype: Beaker
 
 - type: entity
   parent: BaseMachineCircuitboard
     state: science
   - type: MachineBoard
     prototype: CircuitImprinterHyperConvection
-    requirements:
+    stackRequirements:
       MatterBin: 2
     tagRequirements:
       GlassBeaker:
-        Amount: 2
-        DefaultPrototype: Beaker
-        ExamineName: Glass Beaker
+        amount: 2
+        defaultPrototype: Beaker
       Igniter:
-        Amount: 1
-        DefaultPrototype: Igniter
-        ExamineName: Igniter
+        amount: 1
+        defaultPrototype: Igniter
 
 - type: entity
   id: ExosuitFabricatorMachineCircuitboard
     state: science
   - type: MachineBoard
     prototype: ExosuitFabricator
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 3
-    materialRequirements:
       Glass: 5
   - type: GuideHelp
     guides:
     state: science
   - type: MachineBoard
     prototype: ResearchAndDevelopmentServer
-    materialRequirements:
+    stackRequirements:
       Plasma: 5
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: UniformPrinter
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 2
 
     state: medical
   - type: MachineBoard
     prototype: Vaccinator
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 1
-    materialRequirements:
       Cable: 5
     tagRequirements:
         GlassBeaker:
-          Amount: 1
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 1
+          defaultPrototype: Beaker
 
 - type: entity
   id: DiagnoserMachineCircuitboard
     state: medical
   - type: MachineBoard
     prototype: DiseaseDiagnoser
-    materialRequirements:
+    stackRequirements:
       Cable: 5
     tagRequirements:
       GlassBeaker:
-        Amount: 1
-        DefaultPrototype: Beaker
-        ExamineName: Glass Beaker
+        amount: 1
+        defaultPrototype: Beaker
     componentRequirements:
-      DiseaseSwab:
-        Amount: 1
-        DefaultPrototype: DiseaseSwab
-        ExamineName: Swab
+      BotanySwab:
+        amount: 1
+        defaultPrototype: DiseaseSwab
 
 - type: entity
   id: ArtifactAnalyzerMachineCircuitboard
       state: science
     - type: MachineBoard
       prototype: MachineArtifactAnalyzer
-      requirements:
+      stackRequirements:
         Manipulator: 3
         Capacitor: 1
-      materialRequirements:
         Glass: 5
 
 - type: entity
     state: science
   - type: MachineBoard
     prototype: MachineArtifactCrusher
-    requirements:
+    stackRequirements:
       Manipulator: 2
-    materialRequirements:
       Glass: 1
       Steel: 5
 
       state: science
     - type: MachineBoard
       prototype: MachineAnomalyVessel
-      requirements:
+      stackRequirements:
         Capacitor: 3
-      materialRequirements:
         Cable: 1
         PlasmaGlass: 10
 
     state: science
   - type: MachineBoard
     prototype: MachineAnomalyVesselExperimental
-    requirements:
+    stackRequirements:
       Capacitor: 3
-    materialRequirements:
       Cable: 5
       PlasmaGlass: 15
       MetalRod: 4
       state: science
     - type: MachineBoard
       prototype: MachineAnomalySynchronizer
-      requirements:
+      stackRequirements:
         Manipulator: 2
         Capacitor: 5
-      materialRequirements:
         PlasmaGlass: 5
         Cable: 5
 
       state: science
     - type: MachineBoard
       prototype: MachineAPE
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         Cable: 1
         Glass: 1
 
     state: engineering
   - type: MachineBoard
     prototype: GasThermoMachineFreezer
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Capacitor: 2
-    materialRequirements:
       Cable: 5
   - type: Construction
     deconstructionTarget: null
     state: engineering
   - type: MachineBoard
     prototype: GasThermoMachineHeater
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Capacitor: 2
-    materialRequirements:
       Cable: 5
   - type: Construction
     graph: ThermomachineBoard
     state: engineering
   - type: MachineBoard
     prototype: GasThermoMachineHellfireFreezer
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Capacitor: 2
-    materialRequirements:
       Plasma: 1
   - type: Construction
     deconstructionTarget: null
     state: engineering
   - type: MachineBoard
     prototype: GasThermoMachineHellfireHeater
-    requirements:
+    stackRequirements:
       MatterBin: 2
       Capacitor: 2
-    materialRequirements:
       Plasma: 1
   - type: Construction
     graph: ThermomachineBoard
     state: engineering
   - type: MachineBoard
     prototype: BaseGasCondenser
-    requirements:
+    stackRequirements:
       MatterBin: 1
-    materialRequirements:
       Glass: 1
 
 - type: entity
     state: engineering
   - type: MachineBoard
     prototype: PortableScrubber
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 2
-    materialRequirements:
       Cable: 5
       Glass: 2
 
     state: engineering
   - type: MachineBoard
     prototype: SpaceHeater
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Capacitor: 2
-    materialRequirements:
       Cable: 5
 
 - type: entity
       state: medical
     - type: MachineBoard
       prototype: CloningPod
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 2
-      materialRequirements:
         Glass: 1
         Cable: 1
 
       state: medical
     - type: MachineBoard
       prototype: MedicalScanner
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         Glass: 5
         Cable: 1
 
   components:
     - type: MachineBoard
       prototype: CrewMonitoringServer
-      materialRequirements:
+      stackRequirements:
         Steel: 1
         Cable: 2
 
       state: medical
     - type: MachineBoard
       prototype: CryoPod
-      materialRequirements:
+      stackRequirements:
         Glass: 5
         Cable: 1
 
       state: medical
     - type: MachineBoard
       prototype: ChemMaster
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         Glass: 1
         Cable: 1
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
 
 - type: entity
   id: ChemDispenserMachineCircuitboard
       state: medical
     - type: MachineBoard
       prototype: ChemDispenserEmpty
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         Glass: 1
         Steel: 3
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
 
 - type: entity
   id: BiomassReclaimerMachineCircuitboard
   components:
     - type: MachineBoard
       prototype: BiomassReclaimer
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 1
+        Steel: 5
       tagRequirements:
         Knife:
-          Amount: 2
-          DefaultPrototype: KitchenKnife
-          ExamineName: Knife
-      materialRequirements:
-        Steel: 5
+          amount: 2
+          defaultPrototype: KitchenKnife
+          examineName: construction-insert-info-examine-name-knife
 
 - type: entity
   id: HydroponicsTrayMachineCircuitboard
       state: service
     - type: MachineBoard
       prototype: HydroponicsTrayEmpty
-      materialRequirements:
+      stackRequirements:
         # replacing the console screen
         Glass: 5
         Cable: 2
       tagRequirements:
         GlassBeaker:
-          Amount: 2
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 2
+          defaultPrototype: Beaker
 
 - type: entity
   id: SeedExtractorMachineCircuitboard
       state: service
     - type: MachineBoard
       prototype: SeedExtractor
-      requirements:
+      stackRequirements:
         Manipulator: 2
         Capacitor: 1
-      materialRequirements:
         # replacing the console screen
         Glass: 1
         Cable: 2
       state: power_mod
     - type: MachineBoard
       prototype: SMESBasicEmpty
-      requirements:
+      stackRequirements:
         Capacitor: 1
-        PowerCell: 4
-      materialRequirements:
         CableHV: 10
+      componentRequirements:
+        PowerCell:
+          amount: 4
+          defaultPrototype: PowerCellSmall
 
 - type: entity
   id: CellRechargerCircuitboard
       state: charger_APC
     - type: MachineBoard
       prototype: PowerCellRecharger
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         Cable: 5
     - type: PhysicalComposition
       materialComposition:
       state: charger_APC
     - type: MachineBoard
       prototype: PowerCageRecharger
-      requirements:
+      stackRequirements:
         Capacitor: 4
-      materialRequirements:
         Steel: 5
         Cable: 10
     - type: PhysicalComposition
       state: charger_APC
     - type: MachineBoard
       prototype: BorgCharger
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         Cable: 5
     - type: PhysicalComposition
       materialComposition:
       state: charger_APC
     - type: MachineBoard
       prototype: WeaponCapacitorRecharger
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         CableMV: 5
     - type: PhysicalComposition
       materialComposition:
     state: charger_APC
   - type: MachineBoard
     prototype: TurboItemRecharger
-    requirements:
+    stackRequirements:
       Capacitor: 2
-    materialRequirements:
       CableMV: 5
   - type: PhysicalComposition
     materialComposition:
   components:
     - type: MachineBoard
       prototype: SubstationBasicEmpty
-      requirements:
+      stackRequirements:
         Capacitor: 1
-        PowerCell: 1
-      materialRequirements:
         CableMV: 5
         CableHV: 5
+      componentRequirements:
+        PowerCell:
+          amount: 1
+          defaultPrototype: PowerCellSmall
     - type: PhysicalComposition
       materialComposition:
         Glass: 200
   components:
     - type: MachineBoard
       prototype: DawInstrument
-      materialRequirements:
+      stackRequirements:
         Glass: 1
         Cable: 1
       tagRequirements:
 #      One instrument to bring them all and in the darkness bind them...
        KeyedInstrument:
-          Amount: 1
-          DefaultPrototype: SynthesizerInstrument
-          ExamineName: Keyed Instrument
+          amount: 1
+          defaultPrototype: SynthesizerInstrument
+          examineName: construction-insert-info-examine-name-instrument-keyed
        StringInstrument:
-          Amount: 1
-          DefaultPrototype: AcousticGuitarInstrument
-          ExamineName: String Instrument
+          amount: 1
+          defaultPrototype: AcousticGuitarInstrument
+          examineName: construction-insert-info-examine-name-instrument-string
        PercussionInstrument:
-          Amount: 1
-          DefaultPrototype: GlockenspielInstrument
-          ExamineName: Percussion Instrument
+          amount: 1
+          defaultPrototype: GlockenspielInstrument
+          examineName: construction-insert-info-examine-name-instrument-percussion
        BrassInstrument:
-          Amount: 1
-          DefaultPrototype: TrumpetInstrument
-          ExamineName: Brass Instrument
+          amount: 1
+          defaultPrototype: TrumpetInstrument
+          examineName: construction-insert-info-examine-name-instrument-brass
        WoodwindInstrument:
-          Amount: 1
-          DefaultPrototype: SaxophoneInstrument
-          ExamineName: Woodwind Instrument
+          amount: 1
+          defaultPrototype: SaxophoneInstrument
+          examineName: construction-insert-info-examine-name-instrument-woodwind
 
 - type: entity
   id: PortableGeneratorPacmanMachineCircuitboard
       state: engineering
     - type: MachineBoard
       prototype: PortableGeneratorPacman
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         CableHV: 5
     - type: PhysicalComposition
       materialComposition:
   components:
   - type: MachineBoard
     prototype: Thruster
-    requirements:
+    stackRequirements:
       Capacitor: 4
-    materialRequirements:
       Steel: 5
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: Gyroscope
-    requirements:
+    stackRequirements:
       Manipulator: 2
       Capacitor: 1
-    materialRequirements:
       Glass: 2
 
 - type: entity
       state: engineering
     - type: MachineBoard
       prototype: PortableGeneratorSuperPacman
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         CableHV: 10
     - type: PhysicalComposition
       materialComposition:
       state: engineering
     - type: MachineBoard
       prototype: PortableGeneratorJrPacman
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         Cable: 10
     - type: PhysicalComposition
       materialComposition:
   components:
     - type: MachineBoard
       prototype: KitchenReagentGrinder
-      requirements:
+      stackRequirements:
         MatterBin: 2
         Manipulator: 2
       tagRequirements:
         GlassBeaker:
-          Amount: 1
-          DefaultPrototype: Beaker
-          ExamineName: Glass Beaker
+          amount: 1
+          defaultPrototype: Beaker
 
 - type: entity
   id: HotplateMachineCircuitboard
   components:
     - type: MachineBoard
       prototype: ChemistryHotplate
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         Glass: 1
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: KitchenElectricGrill
-    requirements:
+    stackRequirements:
       Capacitor: 4
-    materialRequirements:
       Glass: 2
       Cable: 5
 
       state: medical
     - type: MachineBoard
       prototype: StasisBed
-      requirements:
+      stackRequirements:
         Capacitor: 1
         Manipulator: 1
-      materialRequirements:
         Cable: 3
         Steel: 2
 
     state: medical
   - type: MachineBoard
     prototype: MachineElectrolysisUnit
-    requirements:
+    stackRequirements:
       Capacitor: 2
-    materialRequirements:
       Cable: 1
 
 - type: entity
     state: medical
   - type: MachineBoard
     prototype: MachineCentrifuge
-    requirements:
+    stackRequirements:
       Manipulator: 1
-    materialRequirements:
       Steel: 1
 
 - type: entity
       state: supply
     - type: MachineBoard
       prototype: MaterialReclaimer
-      requirements:
+      stackRequirements:
         Manipulator: 2
-      materialRequirements:
         Steel: 5
         Plastic: 5
 
       state: supply
     - type: MachineBoard
       prototype: OreProcessor
-      requirements:
+      stackRequirements:
         MatterBin: 1
         Manipulator: 3
-      materialRequirements:
         Glass: 1
 
 - type: entity
     state: supply
   - type: MachineBoard
     prototype: OreProcessorIndustrial
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 3
-    materialRequirements:
       Glass: 1
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: Sheetifier
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 1
 
       state: service
     - type: MachineBoard
       prototype: KitchenMicrowave
-      requirements:
+      stackRequirements:
         Capacitor: 1
-      materialRequirements:
         Glass: 2
         Cable: 2
     - type: Tag
       state: service
     - type: MachineBoard
       prototype: FatExtractor
-      requirements:
+      stackRequirements:
         Manipulator: 1
       componentRequirements:
         Utensil:
-          Amount: 1
-          DefaultPrototype: ForkPlastic
-          ExamineName: Utensil
+          amount: 1
+          defaultPrototype: ForkPlastic
+          examineName: construction-insert-info-examine-name-utensil
 
 - type: entity
   parent: BaseMachineCircuitboard
   components:
   - type: MachineBoard
     prototype: MachineFlatpacker
-    requirements:
+    stackRequirements:
       Manipulator: 2
       MatterBin: 1
-    materialRequirements:
       Steel: 1
 
 - type: entity
       state: engineering
     - type: MachineBoard
       prototype: Emitter
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         CableHV: 5
         Glass: 2
 
   components:
     - type: MachineBoard
       prototype: SurveillanceCameraRouterConstructed
-      materialRequirements:
+      stackRequirements:
         Cable: 1
 
 - type: entity
   components:
     - type: MachineBoard
       prototype: SurveillanceCameraWirelessRouterConstructed
-      materialRequirements:
+      stackRequirements:
         Cable: 2
         Glass: 1
 
   components:
     - type: MachineBoard
       prototype: SurveillanceWirelessCameraMovableConstructed
-      materialRequirements:
+      stackRequirements:
         Glass: 2
         Cable: 2
 
   components:
     - type: MachineBoard
       prototype: SurveillanceWirelessCameraAnchoredConstructed
-      materialRequirements:
+      stackRequirements:
         Cable: 2
         Glass: 1
 
   components:
   - type: MachineBoard
     prototype: GasRecycler
-    requirements:
+    stackRequirements:
       Capacitor: 1
       Manipulator: 1
-    materialRequirements:
       Steel: 10
       Plasma: 5
 
       state: service
     - type: MachineBoard
       prototype: BoozeDispenserEmpty
-      materialRequirements:
+      stackRequirements:
         Steel: 5
       tagRequirements:
           GlassBeaker:
-            Amount: 1
-            DefaultPrototype: Beaker
-            ExamineName: Glass Beaker
+            amount: 1
+            defaultPrototype: Beaker
 
 - type: entity
   id: CargoTelepadMachineCircuitboard
       state: supply
     - type: MachineBoard
       prototype: CargoTelepad
-      requirements:
+      stackRequirements:
         Capacitor: 2
-      materialRequirements:
         Steel: 5
 
 - type: entity
       state: service
     - type: MachineBoard
       prototype: SodaDispenserEmpty
-      materialRequirements:
+      stackRequirements:
         Steel: 5
       tagRequirements:
           GlassBeaker:
-            Amount: 1
-            DefaultPrototype: Beaker
-            ExamineName: Glass Beaker
+            amount: 1
+            defaultPrototype: Beaker
 
 - type: entity
   id: TelecomServerCircuitboard
   components:
     - type: MachineBoard
       prototype: TelecomServer
-      materialRequirements:
+      stackRequirements:
         Steel: 1
         Cable: 2
 
   components:
   - type: MachineBoard
     prototype: SalvageMagnet
-    requirements:
+    stackRequirements:
       Capacitor: 4
-    materialRequirements:
       Steel: 5
       CableHV: 5
       Cable: 2
   components:
   - type: MachineBoard
     prototype: GravityGeneratorMini
-    requirements:
+    stackRequirements:
       Capacitor: 4
       MatterBin: 3
-    materialRequirements:
       Steel: 5
       CableHV: 5
       Uranium: 2
   components:
   - type: MachineBoard
     prototype: ReagentGrinderIndustrial
-    requirements:
+    stackRequirements:
       MatterBin: 1
       Manipulator: 3
-    materialRequirements:
       Glass: 1
 
 - type: entity
   components:
   - type: MachineBoard
     prototype: Jukebox
-    materialRequirements:
+    stackRequirements:
       WoodPlank: 5
       Steel: 2
       Glass: 5
index 37de294cce89ae6523ccfd1a82fda4a2b0a95f5f..2f257db39651ba238a5f385025dd8fecda5dfd09 100644 (file)
@@ -21,9 +21,6 @@
   components:
     - type: Sprite
       state: capacitor
-    - type: MachinePart
-      part: Capacitor
-      rating: 1
     - type: Tag
       tags:
         - CapacitorStockPart
   components:
     - type: Sprite
       state: micro_mani
-    - type: MachinePart
-      part: Manipulator
-      rating: 1
     - type: Stack
-      stackType: MicroManipulator
+      stackType: Manipulator
 
 - type: entity
   id: MatterBinStockPart
@@ -54,8 +48,5 @@
   components:
     - type: Sprite
       state: matter_bin
-    - type: MachinePart
-      part: MatterBin
-      rating: 1
     - type: Stack
       stackType: MatterBin
index 7397bcaa517ea25a224ce56330863d010b928bd4..90f987fdc69f2ce6ca6c3a28709ad56b4a92162e 100644 (file)
@@ -73,9 +73,6 @@
   - type: Battery
     maxCharge: 360
     startingCharge: 360
-  - type: MachinePart
-    part: PowerCell
-    rating: 1
   - type: Tag
     tags:
       - PowerCellSmall
   - type: Battery
     maxCharge: 720
     startingCharge: 720
-  - type: MachinePart
-    part: PowerCell
-    rating: 2
 
 - type: entity
   id: PowerCellMediumPrinted
   - type: Battery
     maxCharge: 1080
     startingCharge: 1080
-  - type: MachinePart
-    part: PowerCell
-    rating: 3
 
 - type: entity
   id: PowerCellHighPrinted
   - type: Battery
     maxCharge: 1800
     startingCharge: 1800
-  - type: MachinePart
-    part: PowerCell
-    rating: 4
 
 - type: entity
   id: PowerCellHyperPrinted
diff --git a/Resources/Prototypes/MachineParts/machine_parts.yml b/Resources/Prototypes/MachineParts/machine_parts.yml
deleted file mode 100644 (file)
index 317e4b8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-- type: machinePart
-  id: Capacitor
-  name: machine-part-name-capacitor
-  stockPartPrototype: CapacitorStockPart
-
-- type: machinePart
-  id: Manipulator
-  name: machine-part-name-manipulator
-  stockPartPrototype: MicroManipulatorStockPart
-
-- type: machinePart
-  id: MatterBin
-  name: machine-part-name-matter-bin
-  stockPartPrototype: MatterBinStockPart
-  
-- type: machinePart
-  id: PowerCell
-  name: machine-part-name-power-cell
-  stockPartPrototype: PowerCellSmall
-
index bf58fad9154348c60e7a7af9b5804cb6c2a1d0e8..0d273c324e6b85fa06eb49dd341292af06af037f 100644 (file)
@@ -11,7 +11,7 @@
   maxCount: 10
 
 - type: stack
-  id: MicroManipulator
+  id: Manipulator
   name: micro manipulator
   spawn: MicroManipulatorStockPart
   maxCount: 10