Machine frame ECS (#9713)
This commit is contained in:
@@ -24,34 +24,34 @@ namespace Content.Server.Construction.Completions
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!machineFrame.IsComplete)
|
if (!EntitySystem.Get<MachineFrameSystem>().IsComplete(machineFrame))
|
||||||
{
|
{
|
||||||
Logger.Warning($"Machine frame entity {uid} doesn't have all required parts to be built! Aborting build machine action.");
|
Logger.Warning($"Machine frame entity {uid} doesn't have all required parts to be built! Aborting build machine action.");
|
||||||
return;
|
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;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entBoardContainer.ContainedEntities.Count != 1)
|
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];
|
var board = entBoardContainer.ContainedEntities[0];
|
||||||
|
|
||||||
if (!entityManager.TryGetComponent(board, out MachineBoardComponent? boardComponent))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ namespace Content.Server.Construction.Completions
|
|||||||
var machine = entityManager.SpawnEntity(boardComponent.Prototype, transform.Coordinates);
|
var machine = entityManager.SpawnEntity(boardComponent.Prototype, transform.Coordinates);
|
||||||
entityManager.GetComponent<TransformComponent>(machine).LocalRotation = transform.LocalRotation;
|
entityManager.GetComponent<TransformComponent>(machine).LocalRotation = transform.LocalRotation;
|
||||||
|
|
||||||
var boardContainer = machine.EnsureContainer<Container>(MachineFrameComponent.BoardContainer, out var existed);
|
var boardContainer = machine.EnsureContainer<Container>(MachineFrameComponent.BoardContainerName, out var existed);
|
||||||
|
|
||||||
if (existed)
|
if (existed)
|
||||||
{
|
{
|
||||||
@@ -69,7 +69,7 @@ namespace Content.Server.Construction.Completions
|
|||||||
boardContainer.CleanContainer();
|
boardContainer.CleanContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
var partContainer = machine.EnsureContainer<Container>(MachineFrameComponent.PartContainer, out existed);
|
var partContainer = machine.EnsureContainer<Container>(MachineFrameComponent.PartContainerName, out existed);
|
||||||
|
|
||||||
if (existed)
|
if (existed)
|
||||||
{
|
{
|
||||||
@@ -90,8 +90,8 @@ namespace Content.Server.Construction.Completions
|
|||||||
if (entityManager.TryGetComponent(machine, out ConstructionComponent? construction))
|
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.
|
// 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.BoardContainerName, construction);
|
||||||
constructionSystem.AddContainer(machine, MachineFrameComponent.PartContainer, construction);
|
constructionSystem.AddContainer(machine, MachineFrameComponent.PartContainerName, construction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entityManager.TryGetComponent(machine, out MachineComponent? machineComp))
|
if (entityManager.TryGetComponent(machine, out MachineComponent? machineComp))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Content.Server.Construction.Completions
|
|||||||
{
|
{
|
||||||
if (entityManager.TryGetComponent<MachineFrameComponent>(uid, out var machineFrame))
|
if (entityManager.TryGetComponent<MachineFrameComponent>(uid, out var machineFrame))
|
||||||
{
|
{
|
||||||
machineFrame.RegenerateProgress();
|
EntitySystem.Get<MachineFrameSystem>().RegenerateProgress(machineFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,352 +8,43 @@ using Robust.Shared.Containers;
|
|||||||
namespace Content.Server.Construction.Components
|
namespace Content.Server.Construction.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class MachineFrameComponent : Component, IInteractUsing
|
public sealed class MachineFrameComponent : Component
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
public const string PartContainerName = "machine_parts";
|
||||||
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
public const string BoardContainerName = "machine_board";
|
||||||
|
|
||||||
public const string PartContainer = "machine_parts";
|
|
||||||
public const string BoardContainer = "machine_board";
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool IsComplete
|
public bool HasBoard => BoardContainer?.ContainedEntities.Count != 0;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool HasBoard => _boardContainer?.ContainedEntities.Count != 0;
|
public readonly Dictionary<MachinePart, int> Progress = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly Dictionary<MachinePart, int> _progress = new();
|
public readonly Dictionary<string, int> MaterialProgress = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly Dictionary<string, int> _materialProgress = new();
|
public readonly Dictionary<string, int> ComponentProgress = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly Dictionary<string, int> _componentProgress = new();
|
public readonly Dictionary<string, int> TagProgress = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly Dictionary<string, int> _tagProgress = new();
|
public Dictionary<MachinePart, int> Requirements = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private Dictionary<MachinePart, int> _requirements = new();
|
public Dictionary<string, int> MaterialRequirements = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private Dictionary<string, int> _materialRequirements = new();
|
public Dictionary<string, GenericPartInfo> ComponentRequirements = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private Dictionary<string, GenericPartInfo> _componentRequirements = new();
|
public Dictionary<string, GenericPartInfo> TagRequirements = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private Dictionary<string, GenericPartInfo> _tagRequirements = new();
|
public Container BoardContainer = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private Container _boardContainer = default!;
|
public Container PartContainer = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private Container _partContainer = default!;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<MachinePart, int> Progress => _progress;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, int> MaterialProgress => _materialProgress;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, int> ComponentProgress => _componentProgress;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, int> TagProgress => _tagProgress;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<MachinePart, int> Requirements => _requirements;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, int> MaterialRequirements => _materialRequirements;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, GenericPartInfo> ComponentRequirements => _componentRequirements;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, GenericPartInfo> TagRequirements => _tagRequirements;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
_boardContainer = ContainerHelpers.EnsureContainer<Container>(Owner, BoardContainer);
|
|
||||||
_partContainer = ContainerHelpers.EnsureContainer<Container>(Owner, PartContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Startup()
|
|
||||||
{
|
|
||||||
base.Startup();
|
|
||||||
|
|
||||||
RegenerateProgress();
|
|
||||||
|
|
||||||
if (_entMan.TryGetComponent<ConstructionComponent?>(Owner, out var construction))
|
|
||||||
{
|
|
||||||
// Attempt to set pathfinding to the machine node...
|
|
||||||
EntitySystem.Get<ConstructionSystem>().SetPathfindingTarget(Owner, "machine", construction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetProgressAndRequirements(MachineBoardComponent machineBoard)
|
|
||||||
{
|
|
||||||
_requirements = new Dictionary<MachinePart, int>(machineBoard.Requirements);
|
|
||||||
_materialRequirements = new Dictionary<string, int>(machineBoard.MaterialIdRequirements);
|
|
||||||
_componentRequirements = new Dictionary<string, GenericPartInfo>(machineBoard.ComponentRequirements);
|
|
||||||
_tagRequirements = new Dictionary<string, GenericPartInfo>(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<MachineBoardComponent?>(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<MachinePartComponent?>(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<StackComponent?>(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<TagSystem>();
|
|
||||||
|
|
||||||
// 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<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (!HasBoard && _entMan.TryGetComponent<MachineBoardComponent?>(eventArgs.Using, out var machineBoard))
|
|
||||||
{
|
|
||||||
if (eventArgs.Using.TryRemoveFromContainer())
|
|
||||||
{
|
|
||||||
// Valid board!
|
|
||||||
_boardContainer.Insert(eventArgs.Using);
|
|
||||||
|
|
||||||
// Setup requirements and progress...
|
|
||||||
ResetProgressAndRequirements(machineBoard);
|
|
||||||
|
|
||||||
if (_entMan.TryGetComponent<AppearanceComponent?>(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<ConstructionSystem>().ResetEdge(Owner, construction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (HasBoard)
|
|
||||||
{
|
|
||||||
if (_entMan.TryGetComponent<MachinePartComponent?>(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<StackComponent?>(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<StackSystem>().Split(eventArgs.Using, needed, _entMan.GetComponent<TransformComponent>(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<TagSystem>();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Content.Server.Construction.Conditions
|
|||||||
if (!entityManager.TryGetComponent(uid, out MachineFrameComponent? machineFrame))
|
if (!entityManager.TryGetComponent(uid, out MachineFrameComponent? machineFrame))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return machineFrame.IsComplete;
|
return EntitySystem.Get<MachineFrameSystem>().IsComplete(machineFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DoExamine(ExaminedEvent args)
|
public bool DoExamine(ExaminedEvent args)
|
||||||
@@ -41,7 +41,7 @@ namespace Content.Server.Construction.Conditions
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (machineFrame.IsComplete) return false;
|
if (EntitySystem.Get<MachineFrameSystem>().IsComplete(machineFrame)) return false;
|
||||||
|
|
||||||
args.Message.AddMarkup(Loc.GetString("construction-condition-machine-frame-requirement-label") + "\n");
|
args.Message.AddMarkup(Loc.GetString("construction-condition-machine-frame-requirement-label") + "\n");
|
||||||
foreach (var (part, required) in machineFrame.Requirements)
|
foreach (var (part, required) in machineFrame.Requirements)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ public sealed partial class ConstructionSystem
|
|||||||
|
|
||||||
private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args)
|
private void OnMachineInit(EntityUid uid, MachineComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
component.BoardContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.BoardContainer);
|
component.BoardContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.BoardContainerName);
|
||||||
component.PartContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.PartContainer);
|
component.PartContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.PartContainerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args)
|
private void OnMachineMapInit(EntityUid uid, MachineComponent component, MapInitEvent args)
|
||||||
@@ -47,8 +47,8 @@ public sealed partial class ConstructionSystem
|
|||||||
public void CreateBoardAndStockParts(MachineComponent component)
|
public void CreateBoardAndStockParts(MachineComponent component)
|
||||||
{
|
{
|
||||||
// Entity might not be initialized yet.
|
// Entity might not be initialized yet.
|
||||||
var boardContainer = _container.EnsureContainer<Container>(component.Owner, MachineFrameComponent.BoardContainer);
|
var boardContainer = _container.EnsureContainer<Container>(component.Owner, MachineFrameComponent.BoardContainerName);
|
||||||
var partContainer = _container.EnsureContainer<Container>(component.Owner, MachineFrameComponent.PartContainer);
|
var partContainer = _container.EnsureContainer<Container>(component.Owner, MachineFrameComponent.PartContainerName);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(component.BoardPrototype))
|
if (string.IsNullOrEmpty(component.BoardPrototype))
|
||||||
return;
|
return;
|
||||||
|
|||||||
298
Content.Server/Construction/MachineFrameSystem.cs
Normal file
298
Content.Server/Construction/MachineFrameSystem.cs
Normal file
@@ -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<MachineFrameComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<MachineFrameComponent, ComponentStartup>(OnStartup);
|
||||||
|
SubscribeLocalEvent<MachineFrameComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, MachineFrameComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
component.BoardContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.BoardContainerName);
|
||||||
|
component.PartContainer = _container.EnsureContainer<Container>(uid, MachineFrameComponent.PartContainerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStartup(EntityUid uid, MachineFrameComponent component, ComponentStartup args)
|
||||||
|
{
|
||||||
|
RegenerateProgress(component);
|
||||||
|
|
||||||
|
if (TryComp<ConstructionComponent>(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<MachineBoardComponent?>(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<AppearanceComponent?>(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<MachinePartComponent>(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<StackComponent?>(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<TransformComponent>(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<MachinePart, int>(machineBoard.Requirements);
|
||||||
|
component.MaterialRequirements = new Dictionary<string, int>(machineBoard.MaterialIdRequirements);
|
||||||
|
component.ComponentRequirements = new Dictionary<string, GenericPartInfo>(machineBoard.ComponentRequirements);
|
||||||
|
component.TagRequirements = new Dictionary<string, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<MachineBoardComponent>(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<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]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryComp<StackComponent>(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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user