From 1f5bae751f4d536f793b11595cee5a171d3dd656 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sun, 8 Jan 2023 11:36:32 +1300 Subject: [PATCH] MaterialComponent cleanup (#13326) --- .../Tests/Materials/MaterialTests.cs | 28 +++++++++++++------ Content.Server/Cargo/Systems/PricingSystem.cs | 17 +++++++++-- Content.Server/Lathe/LatheSystem.cs | 2 +- .../Materials/MaterialStorageSystem.cs | 3 ++ Content.Server/Stack/StackSystem.cs | 2 +- Content.Shared/Materials/MaterialComponent.cs | 27 +----------------- .../Materials/MaterialStorageComponent.cs | 12 ++++++-- .../Materials/SharedMaterialStorageSystem.cs | 23 ++++----------- .../Entities/Structures/Machines/lathe.yml | 1 + .../Prototypes/Reagents/Materials/glass.yml | 8 +++--- .../Reagents/Materials/materials.yml | 14 +++++----- .../Prototypes/Reagents/Materials/metals.yml | 8 +++--- 12 files changed, 70 insertions(+), 75 deletions(-) diff --git a/Content.IntegrationTests/Tests/Materials/MaterialTests.cs b/Content.IntegrationTests/Tests/Materials/MaterialTests.cs index 1ee2d5bb95..6d68598afc 100644 --- a/Content.IntegrationTests/Tests/Materials/MaterialTests.cs +++ b/Content.IntegrationTests/Tests/Materials/MaterialTests.cs @@ -38,20 +38,30 @@ namespace Content.IntegrationTests.Tests.Materials var allMaterialProtos = prototypeManager.EnumeratePrototypes(); var coords = testMap.GridCoords; - foreach (var proto in allMaterialProtos) + Assert.Multiple(() => { - if (proto.StackEntity == "") - continue; + foreach (var proto in allMaterialProtos) + { + if (proto.StackEntity == "") + continue; - var spawned = entityManager.SpawnEntity(proto.StackEntity, coords); + var spawned = entityManager.SpawnEntity(proto.StackEntity, coords); - Assert.That(entityManager.HasComponent(spawned), - $"{proto.ID} 'stack entity' {proto.StackEntity} has the stack component"); + Assert.That(entityManager.TryGetComponent(spawned, out var stack), + $"{proto.ID} 'stack entity' {proto.StackEntity} does not have the stack component"); - Assert.That(entityManager.HasComponent(spawned), - $"{proto.ID} 'material stack' {proto.StackEntity} has the material component"); - } + Assert.That(entityManager.HasComponent(spawned), + $"{proto.ID} 'material stack' {proto.StackEntity} does not have the material component"); + StackPrototype? stackProto = null; + Assert.That(stack?.StackTypeId != null && prototypeManager.TryIndex(stack.StackTypeId, out stackProto), + $"{proto.ID} material has no stack prototype"); + + if (stackProto != null) + Assert.That(proto.StackEntity, Is.EqualTo(stackProto.Spawn)); + } + }); + mapManager.DeleteMap(testMap.MapId); }); } diff --git a/Content.Server/Cargo/Systems/PricingSystem.cs b/Content.Server/Cargo/Systems/PricingSystem.cs index 3cbcd025d7..677b5b290b 100644 --- a/Content.Server/Cargo/Systems/PricingSystem.cs +++ b/Content.Server/Cargo/Systems/PricingSystem.cs @@ -163,6 +163,16 @@ public sealed class PricingSystem : EntitySystem return price; } + public double GetMaterialPrice(MaterialComponent component) + { + double price = 0; + foreach (var (id, quantity) in component.Materials) + { + price += _prototypeManager.Index(id).Price * quantity; + } + return price; + } + /// /// Appraises an entity, returning it's price. /// @@ -181,10 +191,11 @@ public sealed class PricingSystem : EntitySystem if (TryComp(uid, out var material) && !HasComp(uid)) { + var matPrice = GetMaterialPrice(material); if (TryComp(uid, out var stack)) - ev.Price += stack.Count * material.Materials.Sum(x => x.Price * material._materials[x.ID]); - else - ev.Price += material.Materials.Sum(x => x.Price); + matPrice *= stack.Count; + + ev.Price += matPrice; } if (TryComp(uid, out var containers)) diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index 1978c84718..6332e302ca 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -217,7 +217,7 @@ namespace Content.Server.Lathe private void OnMaterialEntityInserted(EntityUid uid, LatheComponent component, MaterialEntityInsertedEvent args) { - var lastMat = args.Materials.Keys.Last(); + var lastMat = args.MaterialComp.Materials.Keys.Last(); // We need the prototype to get the color _proto.TryIndex(lastMat, out MaterialPrototype? matProto); EnsureComp(uid).TimeRemaining = component.InsertionTime; diff --git a/Content.Server/Materials/MaterialStorageSystem.cs b/Content.Server/Materials/MaterialStorageSystem.cs index 4de304a7f1..29e803b745 100644 --- a/Content.Server/Materials/MaterialStorageSystem.cs +++ b/Content.Server/Materials/MaterialStorageSystem.cs @@ -27,6 +27,9 @@ public sealed class MaterialStorageSystem : SharedMaterialStorageSystem private void OnDeconstructed(EntityUid uid, MaterialStorageComponent component, MachineDeconstructedEvent args) { + if (!component.DropOnDeconstruct) + return; + foreach (var (material, amount) in component.Storage) { _stackSystem.SpawnMultipleFromMaterial(amount, material, Transform(uid).Coordinates); diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs index 5c7a7709e3..31a46fc318 100644 --- a/Content.Server/Stack/StackSystem.cs +++ b/Content.Server/Stack/StackSystem.cs @@ -110,7 +110,7 @@ namespace Content.Server.Stack return list; int maxCountPerStack = _sharedStack.GetMaxCount(stack); - var materialPerStack = material._materials[materialProto.ID]; + var materialPerStack = material.Materials[materialProto.ID]; var materialPerMaxCount = maxCountPerStack * materialPerStack; diff --git a/Content.Shared/Materials/MaterialComponent.cs b/Content.Shared/Materials/MaterialComponent.cs index fedba15298..25d4e68a23 100644 --- a/Content.Shared/Materials/MaterialComponent.cs +++ b/Content.Shared/Materials/MaterialComponent.cs @@ -1,6 +1,4 @@ -using System.Linq; using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; namespace Content.Shared.Materials @@ -13,29 +11,6 @@ namespace Content.Shared.Materials public sealed class MaterialComponent : Component { [DataField("materials", customTypeSerializer:typeof(PrototypeIdDictionarySerializer))] - // ReSharper disable once CollectionNeverUpdated.Local - public readonly Dictionary _materials = new(); - public List MaterialIds => _materials.Keys.ToList(); - - /// - /// Returns all materials which make up this entity. - /// This property has an IoC resolve and is generally slow, so be sure to cache the results if needed. - /// - [ViewVariables] - public IEnumerable Materials - { - get - { - var prototypeManager = IoCManager.Resolve(); - - foreach (var id in MaterialIds) - { - if(prototypeManager.TryIndex(id, out var material)) - yield return material; - else - Logger.Error($"Material prototype {id} does not exist! Entity: {Owner}"); - } - } - } + public readonly Dictionary Materials = new(); } } diff --git a/Content.Shared/Materials/MaterialStorageComponent.cs b/Content.Shared/Materials/MaterialStorageComponent.cs index 95b03c3d13..5f0d5a360d 100644 --- a/Content.Shared/Materials/MaterialStorageComponent.cs +++ b/Content.Shared/Materials/MaterialStorageComponent.cs @@ -26,6 +26,12 @@ public sealed class MaterialStorageComponent : Component [DataField("whitelist")] public EntityWhitelist? EntityWhitelist; + /// + /// Whether or not to drop contained materials when deconstructed. + /// + [DataField("dropOnDeconstruct")] + public bool DropOnDeconstruct = true; + /// /// Whitelist generated on runtime for what specific materials can be inserted into this entity. /// @@ -44,11 +50,11 @@ public sealed class MaterialStorageComponent : Component /// public readonly struct MaterialEntityInsertedEvent { - public readonly Dictionary Materials; + public readonly MaterialComponent MaterialComp; - public MaterialEntityInsertedEvent(Dictionary materials) + public MaterialEntityInsertedEvent(MaterialComponent materials) { - Materials = materials; + MaterialComp = materials; } } diff --git a/Content.Shared/Materials/SharedMaterialStorageSystem.cs b/Content.Shared/Materials/SharedMaterialStorageSystem.cs index 610ef94843..b1bbc1e1a7 100644 --- a/Content.Shared/Materials/SharedMaterialStorageSystem.cs +++ b/Content.Shared/Materials/SharedMaterialStorageSystem.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Content.Shared.Interaction; using Content.Shared.Stacks; using JetBrains.Annotations; @@ -152,24 +152,13 @@ public abstract class SharedMaterialStorageSystem : EntitySystem if (component.EntityWhitelist?.IsValid(toInsert) == false) return false; - if (component.MaterialWhiteList != null) - { - var matUsed = false; - foreach (var mat in material.Materials) - { - if (component.MaterialWhiteList.Contains(mat.ID)) - matUsed = true; - } - - if (!matUsed) - return false; - } + // Material Whitelist checked implicitly by CanChangeMaterialAmount(); var multiplier = TryComp(toInsert, out var stackComponent) ? stackComponent.Count : 1; var totalVolume = 0; - foreach (var (mat, vol) in component.Storage) + foreach (var (mat, vol) in material.Materials) { - if (!CanChangeMaterialAmount(receiver, mat, vol, component)) + if (!CanChangeMaterialAmount(receiver, mat, vol * multiplier, component)) return false; totalVolume += vol * multiplier; } @@ -177,12 +166,12 @@ public abstract class SharedMaterialStorageSystem : EntitySystem if (!CanTakeVolume(receiver, totalVolume, component)) return false; - foreach (var (mat, vol) in material._materials) + foreach (var (mat, vol) in material.Materials) { TryChangeMaterialAmount(receiver, mat, vol * multiplier, component); } - RaiseLocalEvent(component.Owner, new MaterialEntityInsertedEvent(material._materials)); + RaiseLocalEvent(component.Owner, new MaterialEntityInsertedEvent(material)); return true; } diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index a9c19be854..66ca596482 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -585,6 +585,7 @@ - type: Machine board: OreProcessorMachineCircuitboard - type: MaterialStorage + dropOnDeconstruct: false #should drop ores instead of ingots/sheets whitelist: tags: - Ore diff --git a/Resources/Prototypes/Reagents/Materials/glass.yml b/Resources/Prototypes/Reagents/Materials/glass.yml index 7225ef6801..d87e02460d 100644 --- a/Resources/Prototypes/Reagents/Materials/glass.yml +++ b/Resources/Prototypes/Reagents/Materials/glass.yml @@ -1,6 +1,6 @@ - type: material id: Glass - stackEntity: SheetGlass + stackEntity: SheetGlass1 name: materials-glass icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: glass } color: "#a8ccd7" @@ -8,7 +8,7 @@ - type: material id: ReinforcedGlass - stackEntity: SheetRGlass + stackEntity: SheetRGlass1 name: materials-reinforced-glass icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rglass } color: "#549bb0" @@ -16,7 +16,7 @@ - type: material id: PlasmaGlass - stackEntity: SheetPGlass + stackEntity: SheetPGlass1 name: materials-plasma-glass icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: pglass } color: "#b35989" @@ -24,7 +24,7 @@ - type: material id: ReinforcedPlasmaGlass - stackEntity: SheetRPGlass + stackEntity: SheetRPGlass1 name: materials-reinforced-plasma-glass icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } color: "#8c4069" diff --git a/Resources/Prototypes/Reagents/Materials/materials.yml b/Resources/Prototypes/Reagents/Materials/materials.yml index 3a3c86e10c..6c2eea38a8 100644 --- a/Resources/Prototypes/Reagents/Materials/materials.yml +++ b/Resources/Prototypes/Reagents/Materials/materials.yml @@ -1,6 +1,6 @@ - type: material id: Biomass - stackEntity: MaterialBiomass + stackEntity: MaterialBiomass1 name: materials-biomass icon: { sprite: /Textures/Objects/Misc/monkeycube.rsi, state: cube } color: "#8A9A5B" @@ -8,7 +8,7 @@ - type: material id: Cloth - stackEntity: MaterialCloth + stackEntity: MaterialCloth1 name: materials-cloth icon: { sprite: /Textures/Objects/Materials/materials.rsi, state: cloth } color: "#e7e7de" @@ -16,7 +16,7 @@ - type: material id: Durathread - stackEntity: MaterialDurathread + stackEntity: MaterialDurathread1 name: materials-durathread icon: { sprite: /Textures/Objects/Materials/materials.rsi, state: durathread } color: "#8291a1" @@ -24,7 +24,7 @@ - type: material id: Plasma - stackEntity: SheetPlasma + stackEntity: SheetPlasma1 name: materials-plasma icon: { sprite: Objects/Materials/Sheets/other.rsi, state: plasma } color: "#7e009e" @@ -32,7 +32,7 @@ - type: material id: Plastic - stackEntity: SheetPlastic + stackEntity: SheetPlastic1 name: materials-plastic icon: { sprite: Objects/Materials/Sheets/other.rsi, state: plastic } color: "#d9d9d9" @@ -40,7 +40,7 @@ - type: material id: Wood - stackEntity: MaterialWoodPlank + stackEntity: MaterialWoodPlank1 name: materials-wood icon: { sprite: Objects/Materials/materials.rsi, state: wood } color: "#966F33" @@ -48,7 +48,7 @@ - type: material id: Uranium - stackEntity: SheetUranium + stackEntity: SheetUranium1 name: materials-uranium icon: { sprite: Objects/Materials/Sheets/other.rsi, state: uranium } color: "#32a852" diff --git a/Resources/Prototypes/Reagents/Materials/metals.yml b/Resources/Prototypes/Reagents/Materials/metals.yml index 5baea2a86f..c442511571 100644 --- a/Resources/Prototypes/Reagents/Materials/metals.yml +++ b/Resources/Prototypes/Reagents/Materials/metals.yml @@ -1,13 +1,13 @@ - type: material id: Steel - stackEntity: SheetSteel + stackEntity: SheetSteel1 name: materials-steel icon: { sprite: Objects/Materials/Sheets/metal.rsi, state: steel } price: 0.05 - type: material id: Gold - stackEntity: IngotGold + stackEntity: IngotGold1 name: materials-gold icon: { sprite: Objects/Materials/ingots.rsi, state: gold } color: "#FFD700" @@ -15,7 +15,7 @@ - type: material id: Silver - stackEntity: IngotSilver + stackEntity: IngotSilver1 name: materials-silver icon: { sprite: Objects/Materials/ingots.rsi, state: silver } color: "#C0C0C0" @@ -23,7 +23,7 @@ - type: material id: Plasteel - stackEntity: SheetPlasteel + stackEntity: SheetPlasteel1 name: materials-plasteel icon: { sprite: Objects/Materials/Sheets/metal.rsi, state: plasteel } color: "#696969" #Okay, this is epic