From c2b6e26706917af7764bc4d0c811813937843f9a Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sun, 2 Feb 2025 08:56:47 -0800 Subject: [PATCH 1/2] Ideally how it works but there's a bug with IsTileBlocked --- .../Store/Systems/StoreSystem.Ui.cs | 60 ++++++++++++++++++- Resources/Locale/en-US/store/store.ftl | 2 + 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 5af6ce1c975c..02e43b14e828 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -5,15 +5,20 @@ using Content.Server.Stack; using Content.Server.Store.Components; using Content.Shared.Actions; +using Content.Shared.Coordinates.Helpers; using Content.Shared.Database; using Content.Shared.FixedPoint; using Content.Shared.Hands.EntitySystems; +using Content.Shared.Maps; using Content.Shared.Mind; +using Content.Shared.Physics; using Content.Shared.Store; using Content.Shared.Store.Components; using Content.Shared.UserInterface; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; +using Robust.Shared.Map; +using Robust.Shared.Physics; using Robust.Shared.Player; using Robust.Shared.Prototypes; @@ -30,6 +35,8 @@ public sealed partial class StoreSystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly TurfSystem _turf = default!; + [Dependency] private readonly IMapManager _mapMan = default!; private void InitializeUi() { @@ -163,6 +170,46 @@ private void OnBuyRequest(EntityUid uid, StoreComponent component, StoreBuyListi } } + // For entities that may displace the user when spawned, such as crates + // We need an unblocked tile in front of the player to spawn it if it exists + EntityCoordinates? offsetSpawnCoords = null; + if (listing.ProductEntity != null) + { + var fixtureProduct = Spawn(listing.ProductEntity); + if (TryComp(fixtureProduct, out var fixturesComponent)) + { + foreach (var productFixtures in fixturesComponent.Fixtures) + { + if (!productFixtures.Value.Hard) + continue; + + if ((productFixtures.Value.CollisionLayer & + (int)(CollisionGroup.Impassable | CollisionGroup.Opaque)) == 0) + continue; + + // If the productEntity occupies the impassible or opaque layers, + // check to see if the tile in the direction the buyer is facing isn't blocked + var buyerXform = Transform(buyer); + var offsetValue = buyerXform.LocalRotation.ToWorldVec(); + var coords = buyerXform.Coordinates.Offset(offsetValue).SnapToGrid(EntityManager, _mapMan); + var tile = coords.GetTileRef(EntityManager, _mapMan); + + if (tile == null) + break; + + if (_turf.IsTileBlocked(tile.Value, CollisionGroup.Impassable | CollisionGroup.Opaque)) + { + _popup.PopupCursor(Loc.GetString("store-ui-spawn-space-blocked")); + return; + } + + offsetSpawnCoords = _turf.GetTileCenter(tile.Value); + break; + } + } + QueueDel(fixtureProduct); + } + if (!IsOnStartingMap(uid, component)) component.RefundAllowed = false; @@ -179,8 +226,17 @@ private void OnBuyRequest(EntityUid uid, StoreComponent component, StoreBuyListi //spawn entity if (listing.ProductEntity != null) { - var product = Spawn(listing.ProductEntity, Transform(buyer).Coordinates); - _hands.PickupOrDrop(buyer, product); + EntityUid product; + + if (offsetSpawnCoords != null) + { + product = Spawn(listing.ProductEntity, offsetSpawnCoords.Value); + } + else + { + product = Spawn(listing.ProductEntity, Transform(buyer).Coordinates); + _hands.PickupOrDrop(buyer, product); + } HandleRefundComp(uid, component, product); diff --git a/Resources/Locale/en-US/store/store.ftl b/Resources/Locale/en-US/store/store.ftl index a0b349e6a2aa..434610ac91e7 100644 --- a/Resources/Locale/en-US/store/store.ftl +++ b/Resources/Locale/en-US/store/store.ftl @@ -6,6 +6,8 @@ store-ui-discount-display-with-currency = {$amount} off on {$currency} store-ui-discount-display = ({$amount} off!) store-ui-traitor-flavor = Copyright (C) NT -30643 store-ui-traitor-warning = Operatives must lock their uplinks after use to avoid detection. +store-ui-spawn-space-blocked = The spawning location is blocked. + store-withdraw-button-ui = Withdraw {$currency} store-ui-button-out-of-stock = {""} (Out of Stock) From 4cf5aa703fe1555d54b54d9026ab9a322be7fa91 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:13:10 -0800 Subject: [PATCH 2/2] Fixes turf system, spawns surplus crate in front of player --- Content.Server/Store/Systems/StoreSystem.Ui.cs | 2 +- Content.Shared/Maps/TurfSystem.cs | 3 ++- Resources/Locale/en-US/store/store.ftl | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 02e43b14e828..bcd8e4399abd 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -199,7 +199,7 @@ private void OnBuyRequest(EntityUid uid, StoreComponent component, StoreBuyListi if (_turf.IsTileBlocked(tile.Value, CollisionGroup.Impassable | CollisionGroup.Opaque)) { - _popup.PopupCursor(Loc.GetString("store-ui-spawn-space-blocked")); + _popup.PopupEntity(Loc.GetString("store-ui-spawn-space-blocked"), buyer, buyer); return; } diff --git a/Content.Shared/Maps/TurfSystem.cs b/Content.Shared/Maps/TurfSystem.cs index 8a4bbf68bed3..efd1940e7494 100644 --- a/Content.Shared/Maps/TurfSystem.cs +++ b/Content.Shared/Maps/TurfSystem.cs @@ -48,7 +48,8 @@ public bool IsTileBlocked(EntityUid gridUid, // This is scaled to 95 % so it doesn't encompass walls on other tiles. var tileAabb = Box2.UnitCentered.Scale(0.95f * size); - var worldBox = new Box2Rotated(tileAabb.Translated(worldPos), gridRot, worldPos); + var worldBox = tileAabb.Translated(worldPos); + // var worldBox = new Box2Rotated(tileAabb.Translated(worldPos), gridRot, worldPos); tileAabb = tileAabb.Translated(localPos); var intersectionArea = 0f; diff --git a/Resources/Locale/en-US/store/store.ftl b/Resources/Locale/en-US/store/store.ftl index 434610ac91e7..f2f36978b1ab 100644 --- a/Resources/Locale/en-US/store/store.ftl +++ b/Resources/Locale/en-US/store/store.ftl @@ -6,7 +6,7 @@ store-ui-discount-display-with-currency = {$amount} off on {$currency} store-ui-discount-display = ({$amount} off!) store-ui-traitor-flavor = Copyright (C) NT -30643 store-ui-traitor-warning = Operatives must lock their uplinks after use to avoid detection. -store-ui-spawn-space-blocked = The spawning location is blocked. +store-ui-spawn-space-blocked = Purchase failed, the area in front of you is blocked. store-withdraw-button-ui = Withdraw {$currency}