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]
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
var stack = entityManager.SpawnEntity(Prototype, coordinates);
|
||||
stack.EntityManager.EventBus.RaiseLocalEvent(stack.Uid, new StackChangeCountEvent(Amount), false);
|
||||
var stackEnt = entityManager.SpawnEntity(Prototype, coordinates);
|
||||
var stack = stackEnt.GetComponent<StackComponent>();
|
||||
EntitySystem.Get<StackSystem>().SetCount(stackEnt.Uid, stack, Amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -269,12 +269,11 @@ namespace Content.Server.Construction.Components
|
||||
if (materialStep.EntityValid(eventArgs.Using, out var stack)
|
||||
&& await doAfterSystem.DoAfter(doAfterArgs) == DoAfterStatus.Finished)
|
||||
{
|
||||
var splitStack = new StackSplitEvent() {Amount = materialStep.Amount, SpawnPosition = eventArgs.User.Transform.Coordinates};
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
|
||||
var splitStack = EntitySystem.Get<StackSystem>().Split(eventArgs.Using.Uid, stack, materialStep.Amount, eventArgs.User.Transform.Coordinates);
|
||||
|
||||
if (splitStack.Result != null)
|
||||
if (splitStack != null)
|
||||
{
|
||||
entityUsing = splitStack.Result;
|
||||
entityUsing = splitStack;
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,16 +86,12 @@ namespace Content.Server.Construction.Components
|
||||
|
||||
foreach (var (stackType, amount) in machineBoard.MaterialRequirements)
|
||||
{
|
||||
var stackSpawn = new StackTypeSpawnEvent()
|
||||
{Amount = amount, StackType = stackType, SpawnPosition = Owner.Transform.Coordinates};
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, stackSpawn);
|
||||
var stack = EntitySystem.Get<StackSystem>().Spawn(amount, stackType, Owner.Transform.Coordinates);
|
||||
|
||||
var s = stackSpawn.Result;
|
||||
|
||||
if (s == null)
|
||||
if (stack == null)
|
||||
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"}");
|
||||
}
|
||||
|
||||
|
||||
@@ -313,14 +313,12 @@ namespace Content.Server.Construction.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
var splitStack = new StackSplitEvent()
|
||||
{Amount = needed, SpawnPosition = Owner.Transform.Coordinates};
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(stack.Owner.Uid, splitStack);
|
||||
var splitStack = EntitySystem.Get<StackSystem>().Split(eventArgs.Using.Uid, stack, needed, Owner.Transform.Coordinates);
|
||||
|
||||
if (splitStack.Result == null)
|
||||
if (splitStack == null)
|
||||
return false;
|
||||
|
||||
if(!_partContainer.Insert(splitStack.Result))
|
||||
if(!_partContainer.Insert(splitStack))
|
||||
return false;
|
||||
|
||||
_materialProgress[type] += needed;
|
||||
|
||||
@@ -52,15 +52,15 @@ namespace Content.Server.Construction.Components
|
||||
var resultPosition = Owner.Transform.Coordinates;
|
||||
Owner.Delete();
|
||||
|
||||
// spawn each result afrer refine
|
||||
// spawn each result after refine
|
||||
foreach (var result in _refineResult!)
|
||||
{
|
||||
var droppedEnt = Owner.EntityManager.SpawnEntity(result, resultPosition);
|
||||
|
||||
// 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.
|
||||
if (droppedEnt.HasComponent<StackComponent>())
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(droppedEnt.Uid, new StackChangeCountEvent(1), false);
|
||||
if (droppedEnt.TryGetComponent<StackComponent>(out var stack))
|
||||
EntitySystem.Get<StackSystem>().SetCount(droppedEnt.Uid, stack, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -170,19 +170,17 @@ namespace Content.Server.Construction
|
||||
if (!materialStep.EntityValid(entity, out var stack))
|
||||
continue;
|
||||
|
||||
var splitStack = new StackSplitEvent()
|
||||
{Amount = materialStep.Amount, SpawnPosition = user.ToCoordinates()};
|
||||
RaiseLocalEvent(entity.Uid, splitStack);
|
||||
var splitStack = Get<StackSystem>().Split(entity.Uid, stack, materialStep.Amount, user.ToCoordinates());
|
||||
|
||||
if (splitStack.Result == null)
|
||||
if (splitStack == null)
|
||||
continue;
|
||||
|
||||
if (string.IsNullOrEmpty(materialStep.Store))
|
||||
{
|
||||
if (!container.Insert(splitStack.Result))
|
||||
if (!container.Insert(splitStack))
|
||||
continue;
|
||||
}
|
||||
else if (!GetContainer(materialStep.Store).Insert(splitStack.Result))
|
||||
else if (!GetContainer(materialStep.Store).Insert(splitStack))
|
||||
continue;
|
||||
|
||||
handled = true;
|
||||
|
||||
@@ -33,7 +33,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
if (EntityPrototypeHelpers.HasComponent<StackComponent>(entityId))
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.Engineering.Components;
|
||||
using Content.Server.Stack;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Helpers;
|
||||
using Content.Shared.Stacks;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -65,20 +66,15 @@ namespace Content.Server.Engineering.EntitySystems
|
||||
if (component.Deleted || component.Owner.Deleted)
|
||||
return;
|
||||
|
||||
var hasStack = component.Owner.HasComponent<StackComponent>();
|
||||
|
||||
if (hasStack && component.RemoveOnInteract)
|
||||
if (component.Owner.TryGetComponent<SharedStackComponent>(out var stackComp)
|
||||
&& component.RemoveOnInteract && !Get<StackSystem>().Use(uid, stackComp, 1))
|
||||
{
|
||||
var stackUse = new StackUseEvent() {Amount = 1};
|
||||
RaiseLocalEvent(component.Owner.Uid, stackUse);
|
||||
|
||||
if (!stackUse.Result)
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,13 +188,12 @@ namespace Content.Server.Hands
|
||||
}
|
||||
else
|
||||
{
|
||||
var splitStack = new StackSplitEvent() { Amount = 1, SpawnPosition = playerEnt.Transform.Coordinates };
|
||||
RaiseLocalEvent(throwEnt.Uid, splitStack);
|
||||
var splitStack = Get<StackSystem>().Split(throwEnt.Uid, stackComp, 1, playerEnt.Transform.Coordinates);
|
||||
|
||||
if (splitStack.Result == null)
|
||||
if (splitStack == null)
|
||||
return false;
|
||||
|
||||
throwEnt = splitStack.Result;
|
||||
throwEnt = splitStack;
|
||||
}
|
||||
|
||||
var direction = coords.ToMapPos(EntityManager) - playerEnt.Transform.WorldPosition;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Helpers;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
@@ -41,13 +42,9 @@ namespace Content.Server.Medical.Components
|
||||
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;
|
||||
}
|
||||
|
||||
foreach (var (type, amount) in Heal)
|
||||
|
||||
@@ -25,77 +25,63 @@ namespace Content.Server.Stack
|
||||
base.Initialize();
|
||||
|
||||
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>
|
||||
/// Try to use an amount of items on this stack.
|
||||
/// See <see cref="StackUseEvent"/>
|
||||
/// Try to use an amount of items on this stack. Returns whether this succeeded.
|
||||
/// </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...
|
||||
if (stack.Count < args.Amount)
|
||||
if (stack.Count <= amount)
|
||||
{
|
||||
// Not enough things in the stack, so we set the output result to false.
|
||||
args.Result = 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;
|
||||
// Not enough things in the stack, return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// We do have enough things in the stack, so remove them and change.
|
||||
SetCount(uid, stack, stack.Count - amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to split this stack into two.
|
||||
/// See <see cref="StackSplitEvent"/>
|
||||
/// Try to split this stack into two. Returns a non-null <see cref="IEntity"/> if successful.
|
||||
/// </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...
|
||||
var prototype = _prototypeManager.TryIndex<StackPrototype>(stack.StackTypeId, out var stackType)
|
||||
? stackType.Spawn
|
||||
: stack.Owner.Prototype?.ID ?? null;
|
||||
|
||||
// Remove the amount of things we want to split from the original stack...
|
||||
RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - args.Amount), false);
|
||||
// Try to remove the amount of things we want to split from the original stack...
|
||||
if (!Use(uid, stack, amount))
|
||||
return null;
|
||||
|
||||
// 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.
|
||||
RaiseLocalEvent(args.Result.Uid, new StackChangeCountEvent(args.Amount), false);
|
||||
SetCount(entity.Uid, stackComp, amount);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to spawn a stack of a certain type.
|
||||
/// See <see cref="StackTypeSpawnEvent"/>
|
||||
/// Spawns a stack of a certain stack type. See <see cref="StackPrototype"/>.
|
||||
/// </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...
|
||||
args.Result = EntityManager.SpawnEntity(args.StackType.Spawn, args.SpawnPosition);
|
||||
var stack = args.Result.GetComponent<StackComponent>();
|
||||
var entity = EntityManager.SpawnEntity(prototype.Spawn, spawnPosition);
|
||||
var stack = ComponentManager.GetComponent<StackComponent>(entity.Uid);
|
||||
|
||||
// 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)
|
||||
@@ -107,8 +93,8 @@ namespace Content.Server.Stack
|
||||
return;
|
||||
|
||||
var toTransfer = Math.Min(stack.Count, otherStack.AvailableSpace);
|
||||
RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - toTransfer), false);
|
||||
RaiseLocalEvent(args.Used.Uid, new StackChangeCountEvent(otherStack.Count + toTransfer), false);
|
||||
SetCount(uid, stack, stack.Count - toTransfer);
|
||||
SetCount(args.Used.Uid, otherStack, otherStack.Count + toTransfer);
|
||||
|
||||
var popupPos = args.ClickLocation;
|
||||
if (!popupPos.IsValid(EntityManager))
|
||||
@@ -145,110 +131,4 @@ namespace Content.Server.Stack
|
||||
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))
|
||||
{
|
||||
var stackUse = new StackUseEvent() {Amount = 1};
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
|
||||
|
||||
if (!stackUse.Result)
|
||||
if (!EntitySystem.Get<StackSystem>().Use(Owner.Uid, stack, 1))
|
||||
continue;
|
||||
|
||||
PlaceAt(mapGrid, location, currentTileDefinition.TileId);
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Content.Server.Wires.Components
|
||||
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...
|
||||
if (droppedEnt.HasComponent<StackComponent>())
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(droppedEnt.Uid, new StackChangeCountEvent(1), false);
|
||||
if (droppedEnt.TryGetComponent<StackComponent>(out var stack))
|
||||
EntitySystem.Get<StackSystem>().SetCount(droppedEnt.Uid, stack, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,14 +47,9 @@ namespace Content.Server.Wires.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (Owner.HasComponent<StackComponent>())
|
||||
{
|
||||
var stackUse = new StackUseEvent(){Amount = 1};
|
||||
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, stackUse);
|
||||
|
||||
if(!stackUse.Result)
|
||||
return true;
|
||||
}
|
||||
if (Owner.TryGetComponent<StackComponent>(out var stack)
|
||||
&& !EntitySystem.Get<StackSystem>().Use(Owner.Uid, stack, 1))
|
||||
return true;
|
||||
|
||||
Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos));
|
||||
return true;
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Content.Shared.Stacks
|
||||
return;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace Content.Shared.Stacks
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SharedStackComponent, ComponentStartup>(OnStackStarted);
|
||||
SubscribeLocalEvent<SharedStackComponent, StackChangeCountEvent>(OnStackCountChange);
|
||||
SubscribeLocalEvent<SharedStackComponent, ExaminedEvent>(OnStackExamined);
|
||||
}
|
||||
|
||||
@@ -26,26 +25,27 @@ namespace Content.Shared.Stacks
|
||||
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;
|
||||
|
||||
// Store old value for event-raising purposes...
|
||||
var old = component.Count;
|
||||
|
||||
if (args.Amount > component.MaxCount)
|
||||
// Clamp the value.
|
||||
if (amount > component.MaxCount)
|
||||
{
|
||||
args.Amount = component.MaxCount;
|
||||
args.Clamped = true;
|
||||
amount = component.MaxCount;
|
||||
}
|
||||
|
||||
if (args.Amount < 0)
|
||||
if (amount < 0)
|
||||
{
|
||||
args.Amount = 0;
|
||||
args.Clamped = true;
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
component.Count = args.Amount;
|
||||
component.Count = amount;
|
||||
component.Dirty();
|
||||
|
||||
// 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>
|
||||
/// Event raised when a stack's count has changed.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user