Refactor stacks to not use method events (#4177)
This commit is contained in:
committed by
GitHub
parent
ca4e665296
commit
0093a961bc
@@ -16,14 +16,14 @@ namespace Content.Server.Construction.Completions
|
|||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public class SetStackCount : IGraphAction
|
public class SetStackCount : IGraphAction
|
||||||
{
|
{
|
||||||
[DataField("amount")] public int Amount { get; private set; } = 1;
|
[DataField("amount")] public int Amount { get; } = 1;
|
||||||
|
|
||||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||||
{
|
{
|
||||||
if (entity.Deleted) return;
|
if (entity.Deleted) return;
|
||||||
if(!entity.HasComponent<StackComponent>()) return;
|
if(!entity.TryGetComponent<StackComponent>(out var stack)) return;
|
||||||
|
|
||||||
entity.EntityManager.EventBus.RaiseLocalEvent(entity.Uid, new StackChangeCountEvent(Amount), false);
|
EntitySystem.Get<StackSystem>().SetCount(entity.Uid, stack, Amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ namespace Content.Server.Construction.Completions
|
|||||||
|
|
||||||
if (EntityPrototypeHelpers.HasComponent<StackComponent>(Prototype))
|
if (EntityPrototypeHelpers.HasComponent<StackComponent>(Prototype))
|
||||||
{
|
{
|
||||||
var stack = entityManager.SpawnEntity(Prototype, coordinates);
|
var stackEnt = entityManager.SpawnEntity(Prototype, coordinates);
|
||||||
stack.EntityManager.EventBus.RaiseLocalEvent(stack.Uid, new StackChangeCountEvent(Amount), false);
|
var stack = stackEnt.GetComponent<StackComponent>();
|
||||||
|
EntitySystem.Get<StackSystem>().SetCount(stackEnt.Uid, stack, Amount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -269,12 +269,11 @@ namespace Content.Server.Construction.Components
|
|||||||
if (materialStep.EntityValid(eventArgs.Using, out var stack)
|
if (materialStep.EntityValid(eventArgs.Using, out var stack)
|
||||||
&& await doAfterSystem.DoAfter(doAfterArgs) == DoAfterStatus.Finished)
|
&& await doAfterSystem.DoAfter(doAfterArgs) == DoAfterStatus.Finished)
|
||||||
{
|
{
|
||||||
var splitStack = new StackSplitEvent() {Amount = materialStep.Amount, SpawnPosition = eventArgs.User.Transform.Coordinates};
|
var splitStack = EntitySystem.Get<StackSystem>().Split(eventArgs.Using.Uid, stack, materialStep.Amount, eventArgs.User.Transform.Coordinates);
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
|
|
||||||
|
|
||||||
if (splitStack.Result != null)
|
if (splitStack != null)
|
||||||
{
|
{
|
||||||
entityUsing = splitStack.Result;
|
entityUsing = splitStack;
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,16 +86,12 @@ namespace Content.Server.Construction.Components
|
|||||||
|
|
||||||
foreach (var (stackType, amount) in machineBoard.MaterialRequirements)
|
foreach (var (stackType, amount) in machineBoard.MaterialRequirements)
|
||||||
{
|
{
|
||||||
var stackSpawn = new StackTypeSpawnEvent()
|
var stack = EntitySystem.Get<StackSystem>().Spawn(amount, stackType, Owner.Transform.Coordinates);
|
||||||
{Amount = amount, StackType = stackType, SpawnPosition = Owner.Transform.Coordinates};
|
|
||||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, stackSpawn);
|
|
||||||
|
|
||||||
var s = stackSpawn.Result;
|
if (stack == null)
|
||||||
|
|
||||||
if (s == null)
|
|
||||||
throw new Exception($"Couldn't spawn stack of type {stackType}!");
|
throw new Exception($"Couldn't spawn stack of type {stackType}!");
|
||||||
|
|
||||||
if (!partContainer.Insert(s))
|
if (!partContainer.Insert(stack))
|
||||||
throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}");
|
throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,14 +313,12 @@ namespace Content.Server.Construction.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var splitStack = new StackSplitEvent()
|
var splitStack = EntitySystem.Get<StackSystem>().Split(eventArgs.Using.Uid, stack, needed, Owner.Transform.Coordinates);
|
||||||
{Amount = needed, SpawnPosition = Owner.Transform.Coordinates};
|
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
|
|
||||||
|
|
||||||
if (splitStack.Result == null)
|
if (splitStack == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!_partContainer.Insert(splitStack.Result))
|
if(!_partContainer.Insert(splitStack))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_materialProgress[type] += needed;
|
_materialProgress[type] += needed;
|
||||||
|
|||||||
@@ -52,15 +52,15 @@ namespace Content.Server.Construction.Components
|
|||||||
var resultPosition = Owner.Transform.Coordinates;
|
var resultPosition = Owner.Transform.Coordinates;
|
||||||
Owner.Delete();
|
Owner.Delete();
|
||||||
|
|
||||||
// spawn each result afrer refine
|
// spawn each result after refine
|
||||||
foreach (var result in _refineResult!)
|
foreach (var result in _refineResult!)
|
||||||
{
|
{
|
||||||
var droppedEnt = Owner.EntityManager.SpawnEntity(result, resultPosition);
|
var droppedEnt = Owner.EntityManager.SpawnEntity(result, resultPosition);
|
||||||
|
|
||||||
// TODO: If something has a stack... Just use a prototype with a single thing in the stack.
|
// TODO: If something has a stack... Just use a prototype with a single thing in the stack.
|
||||||
// This is not a good way to do it.
|
// This is not a good way to do it.
|
||||||
if (droppedEnt.HasComponent<StackComponent>())
|
if (droppedEnt.TryGetComponent<StackComponent>(out var stack))
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(droppedEnt.Uid, new StackChangeCountEvent(1), false);
|
EntitySystem.Get<StackSystem>().SetCount(droppedEnt.Uid, stack, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -170,19 +170,17 @@ namespace Content.Server.Construction
|
|||||||
if (!materialStep.EntityValid(entity, out var stack))
|
if (!materialStep.EntityValid(entity, out var stack))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var splitStack = new StackSplitEvent()
|
var splitStack = Get<StackSystem>().Split(entity.Uid, stack, materialStep.Amount, user.ToCoordinates());
|
||||||
{Amount = materialStep.Amount, SpawnPosition = user.ToCoordinates()};
|
|
||||||
RaiseLocalEvent(entity.Uid, splitStack);
|
|
||||||
|
|
||||||
if (splitStack.Result == null)
|
if (splitStack == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(materialStep.Store))
|
if (string.IsNullOrEmpty(materialStep.Store))
|
||||||
{
|
{
|
||||||
if (!container.Insert(splitStack.Result))
|
if (!container.Insert(splitStack))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!GetContainer(materialStep.Store).Insert(splitStack.Result))
|
else if (!GetContainer(materialStep.Store).Insert(splitStack))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
if (EntityPrototypeHelpers.HasComponent<StackComponent>(entityId))
|
if (EntityPrototypeHelpers.HasComponent<StackComponent>(entityId))
|
||||||
{
|
{
|
||||||
var spawned = owner.EntityManager.SpawnEntity(entityId, owner.Transform.MapPosition);
|
var spawned = owner.EntityManager.SpawnEntity(entityId, owner.Transform.MapPosition);
|
||||||
owner.EntityManager.EventBus.RaiseLocalEvent(spawned.Uid, new StackChangeCountEvent(count), false);
|
var stack = spawned.GetComponent<StackComponent>();
|
||||||
|
EntitySystem.Get<StackSystem>().SetCount(spawned.Uid, stack, count);
|
||||||
spawned.RandomOffset(0.5f);
|
spawned.RandomOffset(0.5f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.Engineering.Components;
|
|||||||
using Content.Server.Stack;
|
using Content.Server.Stack;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Interaction.Helpers;
|
using Content.Shared.Interaction.Helpers;
|
||||||
|
using Content.Shared.Stacks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
@@ -65,20 +66,15 @@ namespace Content.Server.Engineering.EntitySystems
|
|||||||
if (component.Deleted || component.Owner.Deleted)
|
if (component.Deleted || component.Owner.Deleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hasStack = component.Owner.HasComponent<StackComponent>();
|
if (component.Owner.TryGetComponent<SharedStackComponent>(out var stackComp)
|
||||||
|
&& component.RemoveOnInteract && !Get<StackSystem>().Use(uid, stackComp, 1))
|
||||||
if (hasStack && component.RemoveOnInteract)
|
|
||||||
{
|
{
|
||||||
var stackUse = new StackUseEvent() {Amount = 1};
|
|
||||||
RaiseLocalEvent(component.Owner.Uid, stackUse);
|
|
||||||
|
|
||||||
if (!stackUse.Result)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityManager.SpawnEntity(component.Prototype, args.ClickLocation.SnapToGrid(grid));
|
EntityManager.SpawnEntity(component.Prototype, args.ClickLocation.SnapToGrid(grid));
|
||||||
|
|
||||||
if (component.RemoveOnInteract && !hasStack && !component.Owner.Deleted)
|
if (component.RemoveOnInteract && stackComp == null && !component.Owner.Deleted)
|
||||||
component.Owner.Delete();
|
component.Owner.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,13 +188,12 @@ namespace Content.Server.Hands
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var splitStack = new StackSplitEvent() { Amount = 1, SpawnPosition = playerEnt.Transform.Coordinates };
|
var splitStack = Get<StackSystem>().Split(throwEnt.Uid, stackComp, 1, playerEnt.Transform.Coordinates);
|
||||||
RaiseLocalEvent(throwEnt.Uid, splitStack);
|
|
||||||
|
|
||||||
if (splitStack.Result == null)
|
if (splitStack == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
throwEnt = splitStack.Result;
|
throwEnt = splitStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
var direction = coords.ToMapPos(EntityManager) - playerEnt.Transform.WorldPosition;
|
var direction = coords.ToMapPos(EntityManager) - playerEnt.Transform.WorldPosition;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Damage.Components;
|
using Content.Shared.Damage.Components;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Interaction.Helpers;
|
using Content.Shared.Interaction.Helpers;
|
||||||
|
using Content.Shared.Stacks;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
@@ -41,12 +42,8 @@ namespace Content.Server.Medical.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Owner.HasComponent<StackComponent>())
|
if (Owner.TryGetComponent<SharedStackComponent>(out var stack) && !EntitySystem.Get<StackSystem>().Use(Owner.Uid, stack, 1))
|
||||||
{
|
{
|
||||||
var stackUse = new StackUseEvent() {Amount = 1};
|
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
|
|
||||||
|
|
||||||
if(!stackUse.Result)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,77 +25,63 @@ namespace Content.Server.Stack
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<StackComponent, InteractUsingEvent>(OnStackInteractUsing);
|
SubscribeLocalEvent<StackComponent, InteractUsingEvent>(OnStackInteractUsing);
|
||||||
|
|
||||||
// The following subscriptions are basically the "method calls" of this entity system.
|
|
||||||
SubscribeLocalEvent<StackComponent, StackUseEvent>(OnStackUse);
|
|
||||||
SubscribeLocalEvent<StackComponent, StackSplitEvent>(OnStackSplit);
|
|
||||||
SubscribeLocalEvent<StackTypeSpawnEvent>(OnStackTypeSpawn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to use an amount of items on this stack.
|
/// Try to use an amount of items on this stack. Returns whether this succeeded.
|
||||||
/// See <see cref="StackUseEvent"/>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnStackUse(EntityUid uid, StackComponent stack, StackUseEvent args)
|
public bool Use(EntityUid uid, SharedStackComponent stack, int amount)
|
||||||
{
|
{
|
||||||
// Check if we have enough things in the stack for this...
|
// Check if we have enough things in the stack for this...
|
||||||
if (stack.Count < args.Amount)
|
if (stack.Count <= amount)
|
||||||
{
|
{
|
||||||
// Not enough things in the stack, so we set the output result to false.
|
// Not enough things in the stack, return false.
|
||||||
args.Result = false;
|
return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We do have enough things in the stack, so remove them and set the output result to true.
|
|
||||||
RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - args.Amount), false);
|
|
||||||
args.Result = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We do have enough things in the stack, so remove them and change.
|
||||||
|
SetCount(uid, stack, stack.Count - amount);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to split this stack into two.
|
/// Try to split this stack into two. Returns a non-null <see cref="IEntity"/> if successful.
|
||||||
/// See <see cref="StackSplitEvent"/>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnStackSplit(EntityUid uid, StackComponent stack, StackSplitEvent args)
|
public IEntity? Split(EntityUid uid, SharedStackComponent stack, int amount, EntityCoordinates spawnPosition)
|
||||||
{
|
{
|
||||||
// If the stack doesn't have enough things as specified in the parameters, we do nothing.
|
|
||||||
if (stack.Count < args.Amount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked...
|
// Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked...
|
||||||
var prototype = _prototypeManager.TryIndex<StackPrototype>(stack.StackTypeId, out var stackType)
|
var prototype = _prototypeManager.TryIndex<StackPrototype>(stack.StackTypeId, out var stackType)
|
||||||
? stackType.Spawn
|
? stackType.Spawn
|
||||||
: stack.Owner.Prototype?.ID ?? null;
|
: stack.Owner.Prototype?.ID ?? null;
|
||||||
|
|
||||||
// Remove the amount of things we want to split from the original stack...
|
// Try to remove the amount of things we want to split from the original stack...
|
||||||
RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - args.Amount), false);
|
if (!Use(uid, stack, amount))
|
||||||
|
return null;
|
||||||
|
|
||||||
// Set the output parameter in the event instance to the newly split stack.
|
// Set the output parameter in the event instance to the newly split stack.
|
||||||
args.Result = EntityManager.SpawnEntity(prototype, args.SpawnPosition);
|
var entity = EntityManager.SpawnEntity(prototype, spawnPosition);
|
||||||
|
|
||||||
if (args.Result.TryGetComponent(out StackComponent? stackComp))
|
if (ComponentManager.TryGetComponent(entity.Uid, out SharedStackComponent? stackComp))
|
||||||
{
|
{
|
||||||
// Set the split stack's count.
|
// Set the split stack's count.
|
||||||
RaiseLocalEvent(args.Result.Uid, new StackChangeCountEvent(args.Amount), false);
|
SetCount(entity.Uid, stackComp, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to spawn a stack of a certain type.
|
/// Spawns a stack of a certain stack type. See <see cref="StackPrototype"/>.
|
||||||
/// See <see cref="StackTypeSpawnEvent"/>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnStackTypeSpawn(StackTypeSpawnEvent args)
|
public IEntity Spawn(int amount, StackPrototype prototype, EntityCoordinates spawnPosition)
|
||||||
{
|
{
|
||||||
// Can't spawn a stack for an invalid type.
|
|
||||||
if (args.StackType == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set the output result parameter to the new stack entity...
|
// Set the output result parameter to the new stack entity...
|
||||||
args.Result = EntityManager.SpawnEntity(args.StackType.Spawn, args.SpawnPosition);
|
var entity = EntityManager.SpawnEntity(prototype.Spawn, spawnPosition);
|
||||||
var stack = args.Result.GetComponent<StackComponent>();
|
var stack = ComponentManager.GetComponent<StackComponent>(entity.Uid);
|
||||||
|
|
||||||
// And finally, set the correct amount!
|
// And finally, set the correct amount!
|
||||||
RaiseLocalEvent(args.Result.Uid, new StackChangeCountEvent(args.Amount), false);
|
SetCount(entity.Uid, stack, amount);
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStackInteractUsing(EntityUid uid, StackComponent stack, InteractUsingEvent args)
|
private void OnStackInteractUsing(EntityUid uid, StackComponent stack, InteractUsingEvent args)
|
||||||
@@ -107,8 +93,8 @@ namespace Content.Server.Stack
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var toTransfer = Math.Min(stack.Count, otherStack.AvailableSpace);
|
var toTransfer = Math.Min(stack.Count, otherStack.AvailableSpace);
|
||||||
RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - toTransfer), false);
|
SetCount(uid, stack, stack.Count - toTransfer);
|
||||||
RaiseLocalEvent(args.Used.Uid, new StackChangeCountEvent(otherStack.Count + toTransfer), false);
|
SetCount(args.Used.Uid, otherStack, otherStack.Count + toTransfer);
|
||||||
|
|
||||||
var popupPos = args.ClickLocation;
|
var popupPos = args.ClickLocation;
|
||||||
if (!popupPos.IsValid(EntityManager))
|
if (!popupPos.IsValid(EntityManager))
|
||||||
@@ -145,110 +131,4 @@ namespace Content.Server.Stack
|
|||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The following events are actually funny ECS method calls!
|
|
||||||
*
|
|
||||||
* Instead of coupling systems together into a ball of spaghetti,
|
|
||||||
* we raise events that act as method calls.
|
|
||||||
*
|
|
||||||
* So for example, instead of having an Use() method in the
|
|
||||||
* stack component or stack system, we have a StackUseEvent.
|
|
||||||
* Before raising the event, you would set the Amount property,
|
|
||||||
* which acts as a parameter or argument, and afterwards the
|
|
||||||
* entity system in charge of handling this would perform the logic
|
|
||||||
* and then set the Result on the event instance.
|
|
||||||
* Then you can access this property to see whether your Use attempt succeeded.
|
|
||||||
*
|
|
||||||
* This is very powerful, as it completely removes the coupling
|
|
||||||
* between entity systems and allows for greater flexibility.
|
|
||||||
* If you want to intercept this event with another entity system, you can.
|
|
||||||
* And you don't have to write any bad, hacky code for this!
|
|
||||||
* You could even use handled events, or cancellable events...
|
|
||||||
* The possibilities are endless.
|
|
||||||
*
|
|
||||||
* Of course, not everything needs to be directed events!
|
|
||||||
* Broadcast events also work in the same way.
|
|
||||||
* For example, we use a broadcast event to spawn a stack of a certain type.
|
|
||||||
*
|
|
||||||
* Wrapping your head around this may be difficult at first,
|
|
||||||
* but soon you'll get it, coder. Soon you'll grasp the wisdom.
|
|
||||||
* Go forth and write some beautiful and robust code!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uses an amount of things from a stack.
|
|
||||||
/// Whether this succeeded is stored in <see cref="Result"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class StackUseEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of things to use on the stack.
|
|
||||||
/// Consider this the equivalent of a parameter for a method call.
|
|
||||||
/// </summary>
|
|
||||||
public int Amount { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the action succeeded or not.
|
|
||||||
/// Set by the <see cref="StackSystem"/> after handling this event.
|
|
||||||
/// Consider this the equivalent of a return value for a method call.
|
|
||||||
/// </summary>
|
|
||||||
public bool Result { get; set; } = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to split a stack into two.
|
|
||||||
/// If this succeeds, <see cref="Result"/> will be the new stack.
|
|
||||||
/// </summary>
|
|
||||||
public class StackSplitEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of things to take from the original stack.
|
|
||||||
/// Input parameter.
|
|
||||||
/// </summary>
|
|
||||||
public int Amount { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The position where to spawn the new stack.
|
|
||||||
/// Input parameter.
|
|
||||||
/// </summary>
|
|
||||||
public EntityCoordinates SpawnPosition { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The newly split stack. May be null if the split failed.
|
|
||||||
/// Output parameter.
|
|
||||||
/// </summary>
|
|
||||||
public IEntity? Result { get; set; } = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to spawn a stack of a certain type.
|
|
||||||
/// If this succeeds, <see cref="Result"/> will be the new stack.
|
|
||||||
/// </summary>
|
|
||||||
public class StackTypeSpawnEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of things the spawned stack will have.
|
|
||||||
/// Input parameter.
|
|
||||||
/// </summary>
|
|
||||||
public int Amount { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The stack type to be spawned.
|
|
||||||
/// Input parameter.
|
|
||||||
/// </summary>
|
|
||||||
public StackPrototype? StackType { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The position where the new stack will be spawned.
|
|
||||||
/// Input parameter.
|
|
||||||
/// </summary>
|
|
||||||
public EntityCoordinates SpawnPosition { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The newly spawned stack, or null if this failed.
|
|
||||||
/// Output parameter.
|
|
||||||
/// </summary>
|
|
||||||
public IEntity? Result { get; set; } = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,10 +80,7 @@ namespace Content.Server.Tiles
|
|||||||
|
|
||||||
if (HasBaseTurf(currentTileDefinition, baseTurf.Name))
|
if (HasBaseTurf(currentTileDefinition, baseTurf.Name))
|
||||||
{
|
{
|
||||||
var stackUse = new StackUseEvent() {Amount = 1};
|
if (!EntitySystem.Get<StackSystem>().Use(Owner.Uid, stack, 1))
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
|
|
||||||
|
|
||||||
if (!stackUse.Result)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
PlaceAt(mapGrid, location, currentTileDefinition.TileId);
|
PlaceAt(mapGrid, location, currentTileDefinition.TileId);
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ namespace Content.Server.Wires.Components
|
|||||||
var droppedEnt = Owner.EntityManager.SpawnEntity(_wireDroppedOnCutPrototype, eventArgs.ClickLocation);
|
var droppedEnt = Owner.EntityManager.SpawnEntity(_wireDroppedOnCutPrototype, eventArgs.ClickLocation);
|
||||||
|
|
||||||
// TODO: Literally just use a prototype that has a single thing in the stack, it's not that complicated...
|
// TODO: Literally just use a prototype that has a single thing in the stack, it's not that complicated...
|
||||||
if (droppedEnt.HasComponent<StackComponent>())
|
if (droppedEnt.TryGetComponent<StackComponent>(out var stack))
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(droppedEnt.Uid, new StackChangeCountEvent(1), false);
|
EntitySystem.Get<StackSystem>().SetCount(droppedEnt.Uid, stack, 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,14 +47,9 @@ namespace Content.Server.Wires.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Owner.HasComponent<StackComponent>())
|
if (Owner.TryGetComponent<StackComponent>(out var stack)
|
||||||
{
|
&& !EntitySystem.Get<StackSystem>().Use(Owner.Uid, stack, 1))
|
||||||
var stackUse = new StackUseEvent(){Amount = 1};
|
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
|
|
||||||
|
|
||||||
if(!stackUse.Result)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
|
Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Content.Shared.Stacks
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// This will change the count and call events.
|
// This will change the count and call events.
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new StackChangeCountEvent(cast.Count));
|
EntitySystem.Get<SharedStackSystem>().SetCount(Owner.Uid, this, cast.Count);
|
||||||
MaxCount = cast.MaxCount;
|
MaxCount = cast.MaxCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace Content.Shared.Stacks
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<SharedStackComponent, ComponentStartup>(OnStackStarted);
|
SubscribeLocalEvent<SharedStackComponent, ComponentStartup>(OnStackStarted);
|
||||||
SubscribeLocalEvent<SharedStackComponent, StackChangeCountEvent>(OnStackCountChange);
|
|
||||||
SubscribeLocalEvent<SharedStackComponent, ExaminedEvent>(OnStackExamined);
|
SubscribeLocalEvent<SharedStackComponent, ExaminedEvent>(OnStackExamined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,26 +25,27 @@ namespace Content.Shared.Stacks
|
|||||||
appearance.SetData(StackVisuals.Hide, false);
|
appearance.SetData(StackVisuals.Hide, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void OnStackCountChange(EntityUid uid, SharedStackComponent component, StackChangeCountEvent args)
|
public void SetCount(EntityUid uid, SharedStackComponent component, int amount)
|
||||||
{
|
{
|
||||||
if (args.Amount == component.Count)
|
// Do nothing if amount is already the same.
|
||||||
|
if (amount == component.Count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Store old value for event-raising purposes...
|
||||||
var old = component.Count;
|
var old = component.Count;
|
||||||
|
|
||||||
if (args.Amount > component.MaxCount)
|
// Clamp the value.
|
||||||
|
if (amount > component.MaxCount)
|
||||||
{
|
{
|
||||||
args.Amount = component.MaxCount;
|
amount = component.MaxCount;
|
||||||
args.Clamped = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.Amount < 0)
|
if (amount < 0)
|
||||||
{
|
{
|
||||||
args.Amount = 0;
|
amount = 0;
|
||||||
args.Clamped = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component.Count = args.Amount;
|
component.Count = amount;
|
||||||
component.Dirty();
|
component.Dirty();
|
||||||
|
|
||||||
// Queue delete stack if count reaches zero.
|
// Queue delete stack if count reaches zero.
|
||||||
@@ -74,32 +74,6 @@ namespace Content.Shared.Stacks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to change the amount of things in a stack to a specific number.
|
|
||||||
/// If the amount had to be clamped to zero or the max amount, <see cref="Clamped"/> will be true
|
|
||||||
/// and the amount will be changed to match the value set.
|
|
||||||
/// Does nothing if the amount is the same as the stack count already.
|
|
||||||
/// </summary>
|
|
||||||
public class StackChangeCountEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Amount to set the stack to.
|
|
||||||
/// Input/Output parameter.
|
|
||||||
/// </summary>
|
|
||||||
public int Amount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the <see cref="Amount"/> had to be clamped.
|
|
||||||
/// Output parameter.
|
|
||||||
/// </summary>
|
|
||||||
public bool Clamped { get; set; }
|
|
||||||
|
|
||||||
public StackChangeCountEvent(int amount)
|
|
||||||
{
|
|
||||||
Amount = amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event raised when a stack's count has changed.
|
/// Event raised when a stack's count has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user