make printed items from lathes automatically stack (#13603)

Closes https://github.com/space-wizards/space-station-14/issues/10402
This commit is contained in:
Nemanja
2023-01-19 23:06:02 -05:00
committed by GitHub
parent d626a04fbd
commit d506311985
2 changed files with 54 additions and 13 deletions

View File

@@ -6,6 +6,7 @@ using Content.Server.Lathe.Components;
using Content.Server.Materials; using Content.Server.Materials;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Stack;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Lathe; using Content.Shared.Lathe;
@@ -29,6 +30,7 @@ namespace Content.Server.Lathe
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UserInterfaceSystem _uiSys = default!; [Dependency] private readonly UserInterfaceSystem _uiSys = default!;
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!; [Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
[Dependency] private readonly StackSystem _stack = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -85,22 +87,22 @@ namespace Content.Server.Lathe
} }
[PublicAPI] [PublicAPI]
public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List<string>? recipes, LatheComponent? component = null) public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List<string>? recipes, [NotNullWhen(true)] LatheComponent? component = null)
{ {
recipes = null; recipes = null;
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
return false; return false;
recipes = GetAvailableRecipes(component); recipes = GetAvailableRecipes(uid, component);
return true; return true;
} }
public List<string> GetAvailableRecipes(LatheComponent component) public List<string> GetAvailableRecipes(EntityUid uid, LatheComponent component)
{ {
var ev = new LatheGetRecipesEvent(component.Owner) var ev = new LatheGetRecipesEvent(uid)
{ {
Recipes = component.StaticRecipes Recipes = component.StaticRecipes
}; };
RaiseLocalEvent(component.Owner, ev); RaiseLocalEvent(uid, ev);
return ev.Recipes; return ev.Recipes;
} }
@@ -147,7 +149,7 @@ namespace Content.Server.Lathe
lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier; lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier;
component.CurrentRecipe = recipe; component.CurrentRecipe = recipe;
_audio.PlayPvs(component.ProducingSound, component.Owner); _audio.PlayPvs(component.ProducingSound, uid);
UpdateRunningAppearance(uid, true); UpdateRunningAppearance(uid, true);
UpdateUserInterfaceState(uid, component); UpdateUserInterfaceState(uid, component);
return true; return true;
@@ -159,13 +161,17 @@ namespace Content.Server.Lathe
return; return;
if (comp.CurrentRecipe != null) if (comp.CurrentRecipe != null)
Spawn(comp.CurrentRecipe.Result, Transform(uid).Coordinates); {
var result = Spawn(comp.CurrentRecipe.Result, Transform(uid).Coordinates);
_stack.TryMergeToContacts(result);
}
comp.CurrentRecipe = null; comp.CurrentRecipe = null;
prodComp.StartTime = _timing.CurTime; prodComp.StartTime = _timing.CurTime;
if (!TryStartProducing(uid, comp)) if (!TryStartProducing(uid, comp))
{ {
RemCompDeferred(prodComp.Owner, prodComp); RemCompDeferred(uid, prodComp);
UpdateUserInterfaceState(uid, comp); UpdateUserInterfaceState(uid, comp);
UpdateRunningAppearance(uid, false); UpdateRunningAppearance(uid, false);
} }
@@ -179,7 +185,7 @@ namespace Content.Server.Lathe
var ui = _uiSys.GetUi(uid, LatheUiKey.Key); var ui = _uiSys.GetUi(uid, LatheUiKey.Key);
var producing = component.CurrentRecipe ?? component.Queue.FirstOrDefault(); var producing = component.CurrentRecipe ?? component.Queue.FirstOrDefault();
var state = new LatheUpdateState(GetAvailableRecipes(component), component.Queue, producing); var state = new LatheUpdateState(GetAvailableRecipes(uid, component), component.Queue, producing);
_uiSys.SetUiState(ui, state); _uiSys.SetUiState(ui, state);
} }
@@ -254,7 +260,7 @@ namespace Content.Server.Lathe
protected override bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component) protected override bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component)
{ {
return GetAvailableRecipes(component).Contains(recipe.ID); return GetAvailableRecipes(uid, component).Contains(recipe.ID);
} }
#region UI Messages #region UI Messages

View File

@@ -5,6 +5,7 @@ using Content.Shared.Interaction;
using Content.Shared.Popups; using Content.Shared.Popups;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -14,13 +15,15 @@ namespace Content.Shared.Stacks
[UsedImplicitly] [UsedImplicitly]
public abstract class SharedStackSystem : EntitySystem public abstract class SharedStackSystem : EntitySystem
{ {
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IViewVariablesManager _vvm = default!;
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
[Dependency] protected readonly SharedHandsSystem HandsSystem = default!; [Dependency] protected readonly SharedHandsSystem HandsSystem = default!;
[Dependency] protected readonly SharedTransformSystem Xform = default!; [Dependency] protected readonly SharedTransformSystem Xform = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
[Dependency] private readonly IViewVariablesManager _vvm = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -96,6 +99,9 @@ namespace Content.Shared.Stacks
StackComponent? recipientStack = null) StackComponent? recipientStack = null)
{ {
transfered = 0; transfered = 0;
if (donor == recipient)
return false;
if (!Resolve(recipient, ref recipientStack, false) || !Resolve(donor, ref donorStack, false)) if (!Resolve(recipient, ref recipientStack, false) || !Resolve(donor, ref donorStack, false))
return false; return false;
@@ -190,6 +196,35 @@ namespace Content.Shared.Stacks
return true; return true;
} }
/// <summary>
/// Tries to merge a stack into any of the stacks it is touching.
/// </summary>
/// <returns>Whether or not it was successfully merged into another stack</returns>
public bool TryMergeToContacts(EntityUid uid, StackComponent? stack = null, TransformComponent? xform = null)
{
if (!Resolve(uid, ref stack, ref xform, false))
return false;
var map = xform.MapID;
var bounds = _physics.GetWorldAABB(uid);
var intersecting = _entityLookup.GetComponentsIntersecting<StackComponent>(map, bounds,
LookupFlags.Dynamic | LookupFlags.Sundries);
var merged = false;
foreach (var otherStack in intersecting)
{
var otherEnt = otherStack.Owner;
if (!TryMergeStacks(uid, otherEnt, out _, stack, otherStack))
continue;
merged = true;
if (stack.Count <= 0)
break;
}
return merged;
}
/// <summary> /// <summary>
/// Gets the max count for a given entity prototype /// Gets the max count for a given entity prototype
/// </summary> /// </summary>