diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index 3892204b41..f71c618c1a 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Lathe.Components; using Content.Server.Materials; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; +using Content.Server.Stack; using Content.Server.UserInterface; using Content.Shared.Database; using Content.Shared.Lathe; @@ -29,6 +30,7 @@ namespace Content.Server.Lathe [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly UserInterfaceSystem _uiSys = default!; [Dependency] private readonly MaterialStorageSystem _materialStorage = default!; + [Dependency] private readonly StackSystem _stack = default!; public override void Initialize() { @@ -85,22 +87,22 @@ namespace Content.Server.Lathe } [PublicAPI] - public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List? recipes, LatheComponent? component = null) + public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List? recipes, [NotNullWhen(true)] LatheComponent? component = null) { recipes = null; if (!Resolve(uid, ref component)) return false; - recipes = GetAvailableRecipes(component); + recipes = GetAvailableRecipes(uid, component); return true; } - public List GetAvailableRecipes(LatheComponent component) + public List GetAvailableRecipes(EntityUid uid, LatheComponent component) { - var ev = new LatheGetRecipesEvent(component.Owner) + var ev = new LatheGetRecipesEvent(uid) { Recipes = component.StaticRecipes }; - RaiseLocalEvent(component.Owner, ev); + RaiseLocalEvent(uid, ev); return ev.Recipes; } @@ -147,7 +149,7 @@ namespace Content.Server.Lathe lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier; component.CurrentRecipe = recipe; - _audio.PlayPvs(component.ProducingSound, component.Owner); + _audio.PlayPvs(component.ProducingSound, uid); UpdateRunningAppearance(uid, true); UpdateUserInterfaceState(uid, component); return true; @@ -159,13 +161,17 @@ namespace Content.Server.Lathe return; 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; prodComp.StartTime = _timing.CurTime; if (!TryStartProducing(uid, comp)) { - RemCompDeferred(prodComp.Owner, prodComp); + RemCompDeferred(uid, prodComp); UpdateUserInterfaceState(uid, comp); UpdateRunningAppearance(uid, false); } @@ -179,7 +185,7 @@ namespace Content.Server.Lathe var ui = _uiSys.GetUi(uid, LatheUiKey.Key); 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); } @@ -254,7 +260,7 @@ namespace Content.Server.Lathe 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 diff --git a/Content.Shared/Stacks/SharedStackSystem.cs b/Content.Shared/Stacks/SharedStackSystem.cs index 213d626cdf..29e5947ae9 100644 --- a/Content.Shared/Stacks/SharedStackSystem.cs +++ b/Content.Shared/Stacks/SharedStackSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Shared.GameStates; +using Robust.Shared.Physics.Systems; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -14,13 +15,15 @@ namespace Content.Shared.Stacks [UsedImplicitly] public abstract class SharedStackSystem : EntitySystem { + [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IViewVariablesManager _vvm = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; - [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; [Dependency] protected readonly SharedHandsSystem HandsSystem = default!; [Dependency] protected readonly SharedTransformSystem Xform = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IViewVariablesManager _vvm = default!; + [Dependency] private readonly EntityLookupSystem _entityLookup = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; public override void Initialize() { @@ -96,6 +99,9 @@ namespace Content.Shared.Stacks StackComponent? recipientStack = null) { transfered = 0; + if (donor == recipient) + return false; + if (!Resolve(recipient, ref recipientStack, false) || !Resolve(donor, ref donorStack, false)) return false; @@ -190,6 +196,35 @@ namespace Content.Shared.Stacks return true; } + /// + /// Tries to merge a stack into any of the stacks it is touching. + /// + /// Whether or not it was successfully merged into another stack + 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(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; + } + /// /// Gets the max count for a given entity prototype ///