diff --git a/Content.Server/Construction/Completions/BuildMachine.cs b/Content.Server/Construction/Completions/BuildMachine.cs index 9c22e3b6b2..230613e260 100644 --- a/Content.Server/Construction/Completions/BuildMachine.cs +++ b/Content.Server/Construction/Completions/BuildMachine.cs @@ -24,34 +24,34 @@ namespace Content.Server.Construction.Completions return; } - if (!machineFrame.IsComplete) + if (!EntitySystem.Get().IsComplete(machineFrame)) { Logger.Warning($"Machine frame entity {uid} doesn't have all required parts to be built! Aborting build machine action."); return; } - if (!containerManager.TryGetContainer(MachineFrameComponent.BoardContainer, out var entBoardContainer)) + if (!containerManager.TryGetContainer(MachineFrameComponent.BoardContainerName, out var entBoardContainer)) { - Logger.Warning($"Machine frame entity {uid} did not have the '{MachineFrameComponent.BoardContainer}' container! Aborting build machine action."); + Logger.Warning($"Machine frame entity {uid} did not have the '{MachineFrameComponent.BoardContainerName}' container! Aborting build machine action."); return; } - if (!containerManager.TryGetContainer(MachineFrameComponent.PartContainer, out var entPartContainer)) + if (!containerManager.TryGetContainer(MachineFrameComponent.PartContainerName, out var entPartContainer)) { - Logger.Warning($"Machine frame entity {uid} did not have the '{MachineFrameComponent.PartContainer}' container! Aborting build machine action."); + Logger.Warning($"Machine frame entity {uid} did not have the '{MachineFrameComponent.PartContainerName}' container! Aborting build machine action."); return; } if (entBoardContainer.ContainedEntities.Count != 1) { - Logger.Warning($"Machine frame entity {uid} did not have exactly one item in the '{MachineFrameComponent.BoardContainer}' container! Aborting build machine action."); + Logger.Warning($"Machine frame entity {uid} did not have exactly one item in the '{MachineFrameComponent.BoardContainerName}' container! Aborting build machine action."); } var board = entBoardContainer.ContainedEntities[0]; if (!entityManager.TryGetComponent(board, out MachineBoardComponent? boardComponent)) { - Logger.Warning($"Machine frame entity {uid} had an invalid entity in container \"{MachineFrameComponent.BoardContainer}\"! Aborting build machine action."); + Logger.Warning($"Machine frame entity {uid} had an invalid entity in container \"{MachineFrameComponent.BoardContainerName}\"! Aborting build machine action."); return; } @@ -61,7 +61,7 @@ namespace Content.Server.Construction.Completions var machine = entityManager.SpawnEntity(boardComponent.Prototype, transform.Coordinates); entityManager.GetComponent(machine).LocalRotation = transform.LocalRotation; - var boardContainer = machine.EnsureContainer(MachineFrameComponent.BoardContainer, out var existed); + var boardContainer = machine.EnsureContainer(MachineFrameComponent.BoardContainerName, out var existed); if (existed) { @@ -69,7 +69,7 @@ namespace Content.Server.Construction.Completions boardContainer.CleanContainer(); } - var partContainer = machine.EnsureContainer(MachineFrameComponent.PartContainer, out existed); + var partContainer = machine.EnsureContainer(MachineFrameComponent.PartContainerName, out existed); if (existed) { @@ -90,8 +90,8 @@ namespace Content.Server.Construction.Completions if (entityManager.TryGetComponent(machine, out ConstructionComponent? construction)) { // We only add these two container. If some construction needs to take other containers into account, fix this. - constructionSystem.AddContainer(machine, MachineFrameComponent.BoardContainer, construction); - constructionSystem.AddContainer(machine, MachineFrameComponent.PartContainer, construction); + constructionSystem.AddContainer(machine, MachineFrameComponent.BoardContainerName, construction); + constructionSystem.AddContainer(machine, MachineFrameComponent.PartContainerName, construction); } if (entityManager.TryGetComponent(machine, out MachineComponent? machineComp)) diff --git a/Content.Server/Construction/Completions/MachineFrameRegenerateProgress.cs b/Content.Server/Construction/Completions/MachineFrameRegenerateProgress.cs index 61d063988d..1abb3f72cf 100644 --- a/Content.Server/Construction/Completions/MachineFrameRegenerateProgress.cs +++ b/Content.Server/Construction/Completions/MachineFrameRegenerateProgress.cs @@ -12,7 +12,7 @@ namespace Content.Server.Construction.Completions { if (entityManager.TryGetComponent(uid, out var machineFrame)) { - machineFrame.RegenerateProgress(); + EntitySystem.Get().RegenerateProgress(machineFrame); } } } diff --git a/Content.Server/Construction/Components/MachineFrameComponent.cs b/Content.Server/Construction/Components/MachineFrameComponent.cs index e935a8a69f..774e06436e 100644 --- a/Content.Server/Construction/Components/MachineFrameComponent.cs +++ b/Content.Server/Construction/Components/MachineFrameComponent.cs @@ -8,352 +8,43 @@ using Robust.Shared.Containers; namespace Content.Server.Construction.Components { [RegisterComponent] - public sealed class MachineFrameComponent : Component, IInteractUsing + public sealed class MachineFrameComponent : Component { - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IComponentFactory _componentFactory = default!; - - public const string PartContainer = "machine_parts"; - public const string BoardContainer = "machine_board"; + public const string PartContainerName = "machine_parts"; + public const string BoardContainerName = "machine_board"; [ViewVariables] - public bool IsComplete - { - get - { - if (!HasBoard || Requirements == null || MaterialRequirements == null) - return false; - - foreach (var (part, amount) in Requirements) - { - if (_progress[part] < amount) - return false; - } - - foreach (var (type, amount) in MaterialRequirements) - { - if (_materialProgress[type] < amount) - return false; - } - - foreach (var (compName, info) in ComponentRequirements) - { - if (_componentProgress[compName] < info.Amount) - return false; - } - - foreach (var (tagName, info) in TagRequirements) - { - if (_tagProgress[tagName] < info.Amount) - return false; - } - - return true; - } - } + public bool HasBoard => BoardContainer?.ContainedEntities.Count != 0; [ViewVariables] - public bool HasBoard => _boardContainer?.ContainedEntities.Count != 0; + public readonly Dictionary Progress = new(); [ViewVariables] - private readonly Dictionary _progress = new(); + public readonly Dictionary MaterialProgress = new(); [ViewVariables] - private readonly Dictionary _materialProgress = new(); + public readonly Dictionary ComponentProgress = new(); [ViewVariables] - private readonly Dictionary _componentProgress = new(); + public readonly Dictionary TagProgress = new(); [ViewVariables] - private readonly Dictionary _tagProgress = new(); + public Dictionary Requirements = new(); [ViewVariables] - private Dictionary _requirements = new(); + public Dictionary MaterialRequirements = new(); [ViewVariables] - private Dictionary _materialRequirements = new(); + public Dictionary ComponentRequirements = new(); [ViewVariables] - private Dictionary _componentRequirements = new(); + public Dictionary TagRequirements = new(); [ViewVariables] - private Dictionary _tagRequirements = new(); + public Container BoardContainer = default!; [ViewVariables] - private Container _boardContainer = default!; - - [ViewVariables] - private Container _partContainer = default!; - - public IReadOnlyDictionary Progress => _progress; - - public IReadOnlyDictionary MaterialProgress => _materialProgress; - - public IReadOnlyDictionary ComponentProgress => _componentProgress; - - public IReadOnlyDictionary TagProgress => _tagProgress; - - public IReadOnlyDictionary Requirements => _requirements; - - public IReadOnlyDictionary MaterialRequirements => _materialRequirements; - - public IReadOnlyDictionary ComponentRequirements => _componentRequirements; - - public IReadOnlyDictionary TagRequirements => _tagRequirements; - - protected override void Initialize() - { - base.Initialize(); - - _boardContainer = ContainerHelpers.EnsureContainer(Owner, BoardContainer); - _partContainer = ContainerHelpers.EnsureContainer(Owner, PartContainer); - } - - protected override void Startup() - { - base.Startup(); - - RegenerateProgress(); - - if (_entMan.TryGetComponent(Owner, out var construction)) - { - // Attempt to set pathfinding to the machine node... - EntitySystem.Get().SetPathfindingTarget(Owner, "machine", construction); - } - } - - private void ResetProgressAndRequirements(MachineBoardComponent machineBoard) - { - _requirements = new Dictionary(machineBoard.Requirements); - _materialRequirements = new Dictionary(machineBoard.MaterialIdRequirements); - _componentRequirements = new Dictionary(machineBoard.ComponentRequirements); - _tagRequirements = new Dictionary(machineBoard.TagRequirements); - - _progress.Clear(); - _materialProgress.Clear(); - _componentProgress.Clear(); - _tagProgress.Clear(); - - foreach (var (machinePart, _) in Requirements) - { - _progress[machinePart] = 0; - } - - foreach (var (stackType, _) in MaterialRequirements) - { - _materialProgress[stackType] = 0; - } - - foreach (var (compName, _) in ComponentRequirements) - { - _componentProgress[compName] = 0; - } - - foreach (var (compName, _) in TagRequirements) - { - _tagProgress[compName] = 0; - } - } - - public void RegenerateProgress() - { - AppearanceComponent? appearance; - - if (!HasBoard) - { - if (_entMan.TryGetComponent(Owner, out appearance)) - { - appearance.SetData(MachineFrameVisuals.State, 1); - } - - _requirements.Clear(); - _materialRequirements.Clear(); - _componentRequirements.Clear(); - _tagRequirements.Clear(); - _progress.Clear(); - _materialProgress.Clear(); - _componentProgress.Clear(); - _tagProgress.Clear(); - - return; - } - - var board = _boardContainer.ContainedEntities[0]; - - if (!_entMan.TryGetComponent(board, out var machineBoard)) - return; - - if (_entMan.TryGetComponent(Owner, out appearance)) - { - appearance.SetData(MachineFrameVisuals.State, 2); - } - - ResetProgressAndRequirements(machineBoard); - - foreach (var part in _partContainer.ContainedEntities) - { - if (_entMan.TryGetComponent(part, out var machinePart)) - { - // Check this is part of the requirements... - if (!Requirements.ContainsKey(machinePart.PartType)) - continue; - - if (!_progress.ContainsKey(machinePart.PartType)) - _progress[machinePart.PartType] = 1; - else - _progress[machinePart.PartType]++; - } - - if (_entMan.TryGetComponent(part, out var stack)) - { - var type = stack.StackTypeId; - // Check this is part of the requirements... - if (!MaterialRequirements.ContainsKey(type)) - continue; - - if (!_materialProgress.ContainsKey(type)) - _materialProgress[type] = 1; - else - _materialProgress[type]++; - } - - // I have many regrets. - foreach (var (compName, _) in ComponentRequirements) - { - var registration = _componentFactory.GetRegistration(compName); - - if (!_entMan.HasComponent(part, registration.Type)) - continue; - - if (!_componentProgress.ContainsKey(compName)) - _componentProgress[compName] = 1; - else - _componentProgress[compName]++; - } - - var tagSystem = EntitySystem.Get(); - - // I have MANY regrets. - foreach (var (tagName, _) in TagRequirements) - { - if (!tagSystem.HasTag(part, tagName)) - continue; - - if (!_tagProgress.ContainsKey(tagName)) - _tagProgress[tagName] = 1; - else - _tagProgress[tagName]++; - } - } - } - - async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) - { - if (!HasBoard && _entMan.TryGetComponent(eventArgs.Using, out var machineBoard)) - { - if (eventArgs.Using.TryRemoveFromContainer()) - { - // Valid board! - _boardContainer.Insert(eventArgs.Using); - - // Setup requirements and progress... - ResetProgressAndRequirements(machineBoard); - - if (_entMan.TryGetComponent(Owner, out var appearance)) - { - appearance.SetData(MachineFrameVisuals.State, 2); - } - - if (_entMan.TryGetComponent(Owner, out ConstructionComponent? construction)) - { - // So prying the components off works correctly. - EntitySystem.Get().ResetEdge(Owner, construction); - } - - return true; - } - } - else if (HasBoard) - { - if (_entMan.TryGetComponent(eventArgs.Using, out var machinePart)) - { - if (!Requirements.ContainsKey(machinePart.PartType)) - return false; - - if (_progress[machinePart.PartType] != Requirements[machinePart.PartType] - && eventArgs.Using.TryRemoveFromContainer() && _partContainer.Insert(eventArgs.Using)) - { - _progress[machinePart.PartType]++; - return true; - } - } - - if (_entMan.TryGetComponent(eventArgs.Using, out var stack)) - { - var type = stack.StackTypeId; - if (!MaterialRequirements.ContainsKey(type)) - return false; - - if (_materialProgress[type] == MaterialRequirements[type]) - return false; - - var needed = MaterialRequirements[type] - _materialProgress[type]; - var count = stack.Count; - - if (count < needed) - { - if(!_partContainer.Insert(stack.Owner)) - return false; - - _materialProgress[type] += count; - return true; - } - - var splitStack = EntitySystem.Get().Split(eventArgs.Using, needed, _entMan.GetComponent(Owner).Coordinates, stack); - - if (splitStack == null) - return false; - - if(!_partContainer.Insert(splitStack.Value)) - return false; - - _materialProgress[type] += needed; - return true; - } - - foreach (var (compName, info) in ComponentRequirements) - { - if (_componentProgress[compName] >= info.Amount) - continue; - - var registration = _componentFactory.GetRegistration(compName); - - if (!_entMan.HasComponent(eventArgs.Using, registration.Type)) - continue; - - if (!eventArgs.Using.TryRemoveFromContainer() || !_partContainer.Insert(eventArgs.Using)) continue; - _componentProgress[compName]++; - return true; - } - - var tags = EntitySystem.Get(); - - foreach (var (tagName, info) in TagRequirements) - { - if (_tagProgress[tagName] >= info.Amount) - continue; - - if (!tags.HasTag(eventArgs.Using, tagName)) - continue; - - if (!eventArgs.Using.TryRemoveFromContainer() || !_partContainer.Insert(eventArgs.Using)) continue; - _tagProgress[tagName]++; - return true; - } - } - - return false; - } + public Container PartContainer = default!; } [DataDefinition] diff --git a/Content.Server/Construction/Conditions/MachineFrameComplete.cs b/Content.Server/Construction/Conditions/MachineFrameComplete.cs index f2eddd6e50..af205926d6 100644 --- a/Content.Server/Construction/Conditions/MachineFrameComplete.cs +++ b/Content.Server/Construction/Conditions/MachineFrameComplete.cs @@ -25,7 +25,7 @@ namespace Content.Server.Construction.Conditions if (!entityManager.TryGetComponent(uid, out MachineFrameComponent? machineFrame)) return false; - return machineFrame.IsComplete; + return EntitySystem.Get().IsComplete(machineFrame); } public bool DoExamine(ExaminedEvent args) @@ -41,7 +41,7 @@ namespace Content.Server.Construction.Conditions return true; } - if (machineFrame.IsComplete) return false; + if (EntitySystem.Get().IsComplete(machineFrame)) return false; args.Message.AddMarkup(Loc.GetString("construction-condition-machine-frame-requirement-label") + "\n"); foreach (var (part, required) in machineFrame.Requirements) diff --git a/Content.Server/Construction/ConstructionSystem.Machine.cs b/Content.Server/Construction/ConstructionSystem.Machine.cs index 9bb935018a..bcbc919c0f 100644 --- a/Content.Server/Construction/ConstructionSystem.Machine.cs +++ b/Content.Server/Construction/ConstructionSystem.Machine.cs @@ -13,8 +13,8 @@ public sealed partial class ConstructionSystem private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args) { - component.BoardContainer = _container.EnsureContainer(uid, MachineFrameComponent.BoardContainer); - component.PartContainer = _container.EnsureContainer(uid, MachineFrameComponent.PartContainer); + component.BoardContainer = _container.EnsureContainer(uid, MachineFrameComponent.BoardContainerName); + component.PartContainer = _container.EnsureContainer(uid, MachineFrameComponent.PartContainerName); } private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args) @@ -47,8 +47,8 @@ public sealed partial class ConstructionSystem public void CreateBoardAndStockParts(MachineComponent component) { // Entity might not be initialized yet. - var boardContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.BoardContainer); - var partContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.PartContainer); + var boardContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.BoardContainerName); + var partContainer = _container.EnsureContainer(component.Owner, MachineFrameComponent.PartContainerName); if (string.IsNullOrEmpty(component.BoardPrototype)) return; diff --git a/Content.Server/Construction/MachineFrameSystem.cs b/Content.Server/Construction/MachineFrameSystem.cs new file mode 100644 index 0000000000..b62925f12e --- /dev/null +++ b/Content.Server/Construction/MachineFrameSystem.cs @@ -0,0 +1,298 @@ +using Content.Server.Construction.Components; +using Content.Server.Stack; +using Content.Shared.Construction; +using Content.Shared.Interaction; +using Content.Shared.Tag; +using Robust.Shared.Containers; + +namespace Content.Server.Construction; + +public sealed class MachineFrameSystem : EntitySystem +{ + [Dependency] private readonly IComponentFactory _factory = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly TagSystem _tag = default!; + [Dependency] private readonly StackSystem _stack = default!; + [Dependency] private readonly ConstructionSystem _construction = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnInteractUsing); + } + + private void OnInit(EntityUid uid, MachineFrameComponent component, ComponentInit args) + { + component.BoardContainer = _container.EnsureContainer(uid, MachineFrameComponent.BoardContainerName); + component.PartContainer = _container.EnsureContainer(uid, MachineFrameComponent.PartContainerName); + } + + private void OnStartup(EntityUid uid, MachineFrameComponent component, ComponentStartup args) + { + RegenerateProgress(component); + + if (TryComp(uid, out var construction)) + { + // Attempt to set pathfinding to the machine node... + _construction.SetPathfindingTarget(uid, "machine", construction); + } + } + + private void OnInteractUsing(EntityUid uid, MachineFrameComponent component, InteractUsingEvent args) + { + if (!component.HasBoard && TryComp(args.Used, out var machineBoard)) + { + if (args.Used.TryRemoveFromContainer()) + { + // Valid board! + component.BoardContainer.Insert(args.Used); + + // Setup requirements and progress... + ResetProgressAndRequirements(component, machineBoard); + + if (TryComp(uid, out var appearance)) + appearance.SetData(MachineFrameVisuals.State, 2); + + if (TryComp(uid, out ConstructionComponent? construction)) + { + // So prying the components off works correctly. + _construction.ResetEdge(uid, construction); + } + } + } + else if (component.HasBoard) + { + if (TryComp(args.Used, out var machinePart)) + { + if (!component.Requirements.ContainsKey(machinePart.PartType)) + return; + + if (component.Progress[machinePart.PartType] != component.Requirements[machinePart.PartType] + && args.Used.TryRemoveFromContainer() && component.PartContainer.Insert(args.Used)) + { + component.Progress[machinePart.PartType]++; + args.Handled = true; + return; + } + } + + if (TryComp(args.Used, out var stack)) + { + var type = stack.StackTypeId; + if (!component.MaterialRequirements.ContainsKey(type)) + return; + + if (component.MaterialProgress[type] == component.MaterialRequirements[type]) + return; + + var needed = component.MaterialRequirements[type] - component.MaterialProgress[type]; + var count = stack.Count; + + if (count < needed) + { + if (!component.PartContainer.Insert(stack.Owner)) + return; + + component.MaterialProgress[type] += count; + args.Handled = true; + return; + } + + var splitStack = _stack.Split(args.Used, needed, + Comp(uid).Coordinates, stack); + + if (splitStack == null) + return; + + if (!component.PartContainer.Insert(splitStack.Value)) + return; + + component.MaterialProgress[type] += needed; + args.Handled = true; + return; + } + + foreach (var (compName, info) in component.ComponentRequirements) + { + if (component.ComponentProgress[compName] >= info.Amount) + continue; + + var registration = _factory.GetRegistration(compName); + + if (!HasComp(args.Used, registration.Type)) + continue; + + if (!args.Used.TryRemoveFromContainer() || !component.PartContainer.Insert(args.Used)) continue; + component.ComponentProgress[compName]++; + args.Handled = true; + return; + } + + foreach (var (tagName, info) in component.TagRequirements) + { + if (component.TagProgress[tagName] >= info.Amount) + continue; + + if (!_tag.HasTag(args.Used, tagName)) + continue; + + if (!args.Used.TryRemoveFromContainer() || !component.PartContainer.Insert(args.Used)) continue; + component.TagProgress[tagName]++; + args.Handled = true; + return; + } + } + } + + public bool IsComplete(MachineFrameComponent component) + { + 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) + return false; + } + + foreach (var (compName, info) in component.ComponentRequirements) + { + if (component.ComponentProgress[compName] < info.Amount) + return false; + } + + foreach (var (tagName, info) in component.TagRequirements) + { + if (component.TagProgress[tagName] < info.Amount) + return false; + } + + return true; + } + + public void ResetProgressAndRequirements(MachineFrameComponent component, MachineBoardComponent machineBoard) + { + component.Requirements = new Dictionary(machineBoard.Requirements); + component.MaterialRequirements = new Dictionary(machineBoard.MaterialIdRequirements); + component.ComponentRequirements = new Dictionary(machineBoard.ComponentRequirements); + component.TagRequirements = new Dictionary(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; + } + + foreach (var (compName, _) in component.ComponentRequirements) + { + component.ComponentProgress[compName] = 0; + } + + foreach (var (compName, _) in component.TagRequirements) + { + component.TagProgress[compName] = 0; + } + } + + public void RegenerateProgress(MachineFrameComponent component) + { + AppearanceComponent? appearance; + + if (!component.HasBoard) + { + if (TryComp(component.Owner, out appearance)) appearance.SetData(MachineFrameVisuals.State, 1); + + component.TagRequirements.Clear(); + component.MaterialRequirements.Clear(); + component.ComponentRequirements.Clear(); + component.TagRequirements.Clear(); + component.Progress.Clear(); + component.MaterialProgress.Clear(); + component.ComponentProgress.Clear(); + component.TagProgress.Clear(); + + return; + } + + var board = component.BoardContainer.ContainedEntities[0]; + + if (!TryComp(board, out var machineBoard)) + return; + + if (TryComp(component.Owner, out appearance)) appearance.SetData(MachineFrameVisuals.State, 2); + + ResetProgressAndRequirements(component, machineBoard); + + foreach (var part in component.PartContainer.ContainedEntities) + { + if (TryComp(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]++; + } + + if (TryComp(part, out var stack)) + { + var type = stack.StackTypeId; + // Check this is part of the requirements... + if (!component.MaterialRequirements.ContainsKey(type)) + continue; + + if (!component.MaterialProgress.ContainsKey(type)) + component.MaterialProgress[type] = 1; + else + component.MaterialProgress[type]++; + } + + // I have many regrets. + foreach (var (compName, _) in component.ComponentRequirements) + { + var registration = _factory.GetRegistration(compName); + + if (!HasComp(part, registration.Type)) + continue; + + if (!component.ComponentProgress.ContainsKey(compName)) + component.ComponentProgress[compName] = 1; + else + component.ComponentProgress[compName]++; + } + + // I have MANY regrets. + foreach (var (tagName, _) in component.TagRequirements) + { + if (!_tag.HasTag(part, tagName)) + continue; + + if (!component.TagProgress.ContainsKey(tagName)) + component.TagProgress[tagName] = 1; + else + component.TagProgress[tagName]++; + } + } + } +}