Refactors stacks to be fully ECS. (#4046)

This commit is contained in:
Vera Aguilera Puerto
2021-05-26 10:20:57 +02:00
committed by GitHub
parent 0f8e330a3d
commit 33fa208214
18 changed files with 494 additions and 249 deletions

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.GameObjects.EntitySystems.DoAfter;
using Content.Shared.Construction;
using Content.Shared.GameObjects.Components.Interactable;
@@ -264,11 +265,17 @@ namespace Content.Server.GameObjects.Components.Construction
break;
case MaterialConstructionGraphStep materialStep:
if (materialStep.EntityValid(eventArgs.Using, out var sharedStack)
if (materialStep.EntityValid(eventArgs.Using, out var stack)
&& await doAfterSystem.DoAfter(doAfterArgs) == DoAfterStatus.Finished)
{
var stack = (StackComponent) sharedStack;
valid = stack.Split(materialStep.Amount, eventArgs.User.Transform.Coordinates, out entityUsing);
var splitStack = new StackSplitEvent() {Amount = materialStep.Amount, SpawnPosition = eventArgs.User.Transform.Coordinates};
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
if (splitStack.Result != null)
{
entityUsing = splitStack.Result;
valid = true;
}
}
break;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Content.Server.Construction;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
@@ -87,7 +88,14 @@ namespace Content.Server.GameObjects.Components.Construction
foreach (var (stackType, amount) in machineBoard.MaterialRequirements)
{
var s = StackHelpers.SpawnStack(stackType, amount, Owner.Transform.Coordinates);
var stackSpawn = new StackTypeSpawnEvent()
{Amount = amount, StackType = stackType, SpawnPosition = Owner.Transform.Coordinates};
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, stackSpawn);
var s = stackSpawn.Result;
if (s == null)
throw new Exception($"Couldn't spawn stack of type {stackType}!");
if (!partContainer.Insert(s))
throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}");

View File

@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Content.Server.Construction;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Construction;
using Content.Shared.GameObjects.Components.Tag;
using Content.Shared.Interfaces.GameObjects.Components;
@@ -314,10 +315,14 @@ namespace Content.Server.GameObjects.Components.Construction
return true;
}
if (!stack.Split(needed, Owner.Transform.Coordinates, out var newStack))
var splitStack = new StackSplitEvent()
{Amount = needed, SpawnPosition = Owner.Transform.Coordinates};
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
if (splitStack.Result == null)
return false;
if(!_partContainer.Insert(newStack))
if(!_partContainer.Insert(splitStack.Result))
return false;
_materialProgress[type] += needed;

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Audio;
using Content.Shared.Interfaces.GameObjects.Components;
using Content.Shared.Maps;
@@ -78,8 +79,14 @@ namespace Content.Server.GameObjects.Components.Items
var tile = mapGrid.GetTileRef(location);
var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
if (HasBaseTurf(currentTileDefinition, baseTurf.Name) && stack.Use(1))
if (HasBaseTurf(currentTileDefinition, baseTurf.Name))
{
var stackUse = new StackUseEvent() {Amount = 1};
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
if (!stackUse.Result)
continue;
PlaceAt(mapGrid, location, currentTileDefinition.TileId);
break;
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
@@ -41,10 +42,13 @@ namespace Content.Server.GameObjects.Components.Medical
return true;
}
if (Owner.TryGetComponent(out StackComponent? stack) &&
!stack.Use(1))
if (Owner.HasComponent<StackComponent>())
{
return true;
var stackUse = new StackUseEvent() {Amount = 1};
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
if(!stackUse.Result)
return true;
}
foreach (var (type, amount) in Heal)

View File

@@ -8,6 +8,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System.Threading.Tasks;
using Content.Server.GameObjects.EntitySystems;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Map;
@@ -49,8 +50,16 @@ namespace Content.Server.GameObjects.Components.Power
return true;
}
}
if (Owner.TryGetComponent<StackComponent>(out var stack) && !stack.Use(1))
return true;
if (Owner.HasComponent<StackComponent>())
{
var stackUse = new StackUseEvent(){Amount = 1};
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
if(!stackUse.Result)
return true;
}
Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
return true;
}

View File

@@ -1,14 +1,7 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Interfaces;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.Map;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -17,114 +10,10 @@ namespace Content.Server.GameObjects.Components.Stack
// TODO: Naming and presentation and such could use some improvement.
[RegisterComponent]
[ComponentReference(typeof(SharedStackComponent))]
public class StackComponent : SharedStackComponent, IInteractUsing, IExamine
public class StackComponent : SharedStackComponent, IExamine
{
private bool _throwIndividually = false;
[ViewVariables(VVAccess.ReadWrite)]
public bool ThrowIndividually
{
get => _throwIndividually;
private set
{
_throwIndividually = value;
Dirty();
}
}
public void Add(int amount)
{
Count += amount;
}
/// <summary>
/// Try to use an amount of items on this stack.
/// </summary>
/// <param name="amount"></param>
/// <returns>True if there were enough items to remove, false if not in which case nothing was changed.</returns>
public bool Use(int amount)
{
if (Count >= amount)
{
Count -= amount;
return true;
}
return false;
}
/// <summary>
/// Attempts to split this stack in two.
/// </summary>
/// <param name="amount">amount the new stack will have</param>
/// <param name="spawnPosition">the position the new stack will spawn at</param>
/// <param name="stack">the new stack</param>
/// <returns></returns>
public bool Split(int amount, EntityCoordinates spawnPosition, [NotNullWhen(true)] out IEntity? stack)
{
if (Count >= amount)
{
Count -= amount;
stack = Owner.EntityManager.SpawnEntity(Owner.Prototype?.ID, spawnPosition);
if (stack.TryGetComponent(out StackComponent? stackComp))
{
stackComp.Count = amount;
}
return true;
}
stack = null;
return false;
}
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent<StackComponent>(out var stack))
return false;
if (!stack.StackTypeId.Equals(StackTypeId))
{
return false;
}
var toTransfer = Math.Min(Count, stack.AvailableSpace);
Count -= toTransfer;
stack.Add(toTransfer);
var popupPos = eventArgs.ClickLocation;
if (popupPos == EntityCoordinates.Invalid)
{
popupPos = eventArgs.User.Transform.Coordinates;
}
if (toTransfer > 0)
{
popupPos.PopupMessage(eventArgs.User, $"+{toTransfer}");
if (stack.AvailableSpace == 0)
{
eventArgs.Using.SpawnTimer(
300,
() => popupPos.PopupMessage(
eventArgs.User,
Loc.GetString("comp-stack-becomes-full")
)
);
}
}
else if (toTransfer == 0 && stack.AvailableSpace == 0)
{
popupPos.PopupMessage(
eventArgs.User,
Loc.GetString("comp-stack-already-full")
);
}
return true;
}
public bool ThrowIndividually { get; set; } = false;
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
{