diff --git a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml
index 3de59cf5dc..e3d45c19da 100644
--- a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml
+++ b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml
@@ -22,6 +22,7 @@
+
diff --git a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs
index 9d7e500651..7a11885a89 100644
--- a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs
+++ b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs
@@ -103,6 +103,8 @@ namespace Content.Client.Options.UI.Tabs
ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
+ OpaqueStorageWindowCheckBox.OnToggled += OnCheckBoxToggled;
+ ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
@@ -124,6 +126,7 @@ namespace Content.Client.Options.UI.Tabs
FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible);
ShowHeldItemCheckBox.Pressed = _cfg.GetCVar(CCVars.HudHeldItemShow);
ShowCombatModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
+ OpaqueStorageWindowCheckBox.Pressed = _cfg.GetCVar(CCVars.OpaqueStorageWindow);
ShowLoocAboveHeadCheckBox.Pressed = _cfg.GetCVar(CCVars.LoocAboveHeadShow);
FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
@@ -174,6 +177,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed);
_cfg.SetCVar(CCVars.HudHeldItemShow, ShowHeldItemCheckBox.Pressed);
_cfg.SetCVar(CCVars.CombatModeIndicatorsPointShow, ShowCombatModeIndicatorsCheckBox.Pressed);
+ _cfg.SetCVar(CCVars.OpaqueStorageWindow, OpaqueStorageWindowCheckBox.Pressed);
_cfg.SetCVar(CCVars.LoocAboveHeadShow, ShowLoocAboveHeadCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
@@ -214,6 +218,7 @@ namespace Content.Client.Options.UI.Tabs
var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality);
var isShowHeldItemSame = ShowHeldItemCheckBox.Pressed == _cfg.GetCVar(CCVars.HudHeldItemShow);
var isCombatModeIndicatorsSame = ShowCombatModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
+ var isOpaqueStorageWindow = OpaqueStorageWindowCheckBox.Pressed == _cfg.GetCVar(CCVars.OpaqueStorageWindow);
var isLoocShowSame = ShowLoocAboveHeadCheckBox.Pressed == _cfg.GetCVar(CCVars.LoocAboveHeadShow);
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
@@ -233,6 +238,7 @@ namespace Content.Client.Options.UI.Tabs
isHudThemeSame &&
isShowHeldItemSame &&
isCombatModeIndicatorsSame &&
+ isOpaqueStorageWindow &&
isLoocShowSame &&
isFancyChatSame &&
isFancyBackgroundSame &&
diff --git a/Content.Client/UserInterface/Systems/Storage/Controls/ItemGridPiece.cs b/Content.Client/UserInterface/Systems/Storage/Controls/ItemGridPiece.cs
index 830d59bd90..e4f3506baa 100644
--- a/Content.Client/UserInterface/Systems/Storage/Controls/ItemGridPiece.cs
+++ b/Content.Client/UserInterface/Systems/Storage/Controls/ItemGridPiece.cs
@@ -1,9 +1,7 @@
-using System.Linq;
using System.Numerics;
using Content.Client.Items.Systems;
using Content.Shared.Item;
using Content.Shared.Storage;
-using Content.Shared.Storage.EntitySystems;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
@@ -12,8 +10,7 @@ namespace Content.Client.UserInterface.Systems.Storage.Controls;
public sealed class ItemGridPiece : Control
{
- private readonly ItemSystem _itemSystem;
- private readonly SpriteSystem _spriteSystem;
+ private readonly IEntityManager _entityManager;
private readonly StorageUIController _storageController;
private readonly List<(Texture, Vector2)> _texturesPositions = new();
@@ -49,8 +46,7 @@ public sealed class ItemGridPiece : Control
{
IoCManager.InjectDependencies(this);
- _itemSystem = entityManager.System();
- _spriteSystem = entityManager.System();
+ _entityManager = entityManager;
_storageController = UserInterfaceManager.GetUIController();
Entity = entity.Owner;
@@ -81,10 +77,17 @@ public sealed class ItemGridPiece : Control
{
base.Draw(handle);
+ // really just an "oh shit" catch.
+ if (!_entityManager.EntityExists(Entity))
+ {
+ Dispose();
+ return;
+ }
+
if (_storageController.IsDragging && _storageController.CurrentlyDragging == this)
return;
- var adjustedShape = _itemSystem.GetAdjustedItemShape((Entity, null), Location.Rotation, Vector2i.Zero);
+ var adjustedShape = _entityManager.System().GetAdjustedItemShape((Entity, null), Location.Rotation, Vector2i.Zero);
var boundingGrid = adjustedShape.GetBoundingBox();
var size = _centerTexture!.Size * 2 * UIScale;
@@ -130,7 +133,7 @@ public sealed class ItemGridPiece : Control
var iconOffset = new Vector2((boundingGrid.Width + 1) * size.X ,
(boundingGrid.Height + 1) * size.Y);
- _spriteSystem.ForceUpdate(Entity);
+ _entityManager.System().ForceUpdate(Entity);
handle.DrawEntity(Entity,
PixelPosition + iconOffset,
Vector2.One * 2 * UIScale,
diff --git a/Content.Client/UserInterface/Systems/Storage/Controls/StorageContainer.cs b/Content.Client/UserInterface/Systems/Storage/Controls/StorageContainer.cs
index 12bce74352..ba19d2aa90 100644
--- a/Content.Client/UserInterface/Systems/Storage/Controls/StorageContainer.cs
+++ b/Content.Client/UserInterface/Systems/Storage/Controls/StorageContainer.cs
@@ -34,6 +34,10 @@ public sealed class StorageContainer : BaseWindow
private Texture? _emptyTexture;
private readonly string _blockedTexturePath = "Storage/tile_blocked";
private Texture? _blockedTexture;
+ private readonly string _emptyOpaqueTexturePath = "Storage/tile_empty_opaque";
+ private Texture? _emptyOpaqueTexture;
+ private readonly string _blockedOpaqueTexturePath = "Storage/tile_blocked_opaque";
+ private Texture? _blockedOpaqueTexture;
private readonly string _exitTexturePath = "Storage/exit";
private Texture? _exitTexture;
private readonly string _backTexturePath = "Storage/back";
@@ -109,6 +113,8 @@ public sealed class StorageContainer : BaseWindow
_emptyTexture = Theme.ResolveTextureOrNull(_emptyTexturePath)?.Texture;
_blockedTexture = Theme.ResolveTextureOrNull(_blockedTexturePath)?.Texture;
+ _emptyOpaqueTexture = Theme.ResolveTextureOrNull(_emptyOpaqueTexturePath)?.Texture;
+ _blockedOpaqueTexture = Theme.ResolveTextureOrNull(_blockedOpaqueTexturePath)?.Texture;
_exitTexture = Theme.ResolveTextureOrNull(_exitTexturePath)?.Texture;
_backTexture = Theme.ResolveTextureOrNull(_backTexturePath)?.Texture;
_sidebarTopTexture = Theme.ResolveTextureOrNull(_sidebarTopTexturePath)?.Texture;
@@ -124,35 +130,17 @@ public sealed class StorageContainer : BaseWindow
if (entity == null)
return;
- BuildGridRepresentation(entity.Value);
+ BuildGridRepresentation();
}
- private void BuildGridRepresentation(Entity entity)
+ private void BuildGridRepresentation()
{
- var comp = entity.Comp;
- if (!comp.Grid.Any())
+ if (!_entity.TryGetComponent(StorageEntity, out var comp) || !comp.Grid.Any())
return;
var boundingGrid = comp.Grid.GetBoundingBox();
- _backgroundGrid.Children.Clear();
- _backgroundGrid.Rows = boundingGrid.Height + 1;
- _backgroundGrid.Columns = boundingGrid.Width + 1;
- for (var y = boundingGrid.Bottom; y <= boundingGrid.Top; y++)
- {
- for (var x = boundingGrid.Left; x <= boundingGrid.Right; x++)
- {
- var texture = comp.Grid.Contains(x, y)
- ? _emptyTexture
- : _blockedTexture;
-
- _backgroundGrid.AddChild(new TextureRect
- {
- Texture = texture,
- TextureScale = new Vector2(2, 2)
- });
- }
- }
+ BuildBackground();
#region Sidebar
_sidebar.Children.Clear();
@@ -209,6 +197,40 @@ public sealed class StorageContainer : BaseWindow
BuildItemPieces();
}
+ public void BuildBackground()
+ {
+ if (!_entity.TryGetComponent(StorageEntity, out var comp) || !comp.Grid.Any())
+ return;
+
+ var boundingGrid = comp.Grid.GetBoundingBox();
+
+ var emptyTexture = _storageController.OpaqueStorageWindow
+ ? _emptyOpaqueTexture
+ : _emptyTexture;
+ var blockedTexture = _storageController.OpaqueStorageWindow
+ ? _blockedOpaqueTexture
+ : _blockedTexture;
+
+ _backgroundGrid.Children.Clear();
+ _backgroundGrid.Rows = boundingGrid.Height + 1;
+ _backgroundGrid.Columns = boundingGrid.Width + 1;
+ for (var y = boundingGrid.Bottom; y <= boundingGrid.Top; y++)
+ {
+ for (var x = boundingGrid.Left; x <= boundingGrid.Right; x++)
+ {
+ var texture = comp.Grid.Contains(x, y)
+ ? emptyTexture
+ : blockedTexture;
+
+ _backgroundGrid.AddChild(new TextureRect
+ {
+ Texture = texture,
+ TextureScale = new Vector2(2, 2)
+ });
+ }
+ }
+ }
+
public void BuildItemPieces()
{
if (!_entity.TryGetComponent(StorageEntity, out var storageComp))
@@ -320,7 +342,7 @@ public sealed class StorageContainer : BaseWindow
origin,
currentLocation.Rotation);
- var validColor = usingInHand ? Color.Goldenrod : Color.Green;
+ var validColor = usingInHand ? Color.Goldenrod : Color.FromHex("#1E8000");
for (var y = itemBounding.Bottom; y <= itemBounding.Top; y++)
{
@@ -328,7 +350,7 @@ public sealed class StorageContainer : BaseWindow
{
if (TryGetBackgroundCell(x, y, out var cell) && itemShape.Contains(x, y))
{
- cell.ModulateSelfOverride = validLocation ? validColor : Color.Red;
+ cell.ModulateSelfOverride = validLocation ? validColor : Color.FromHex("#B40046");
}
}
}
diff --git a/Content.Client/UserInterface/Systems/Storage/StorageUIController.cs b/Content.Client/UserInterface/Systems/Storage/StorageUIController.cs
index d3bbd826ba..a08dae1dd7 100644
--- a/Content.Client/UserInterface/Systems/Storage/StorageUIController.cs
+++ b/Content.Client/UserInterface/Systems/Storage/StorageUIController.cs
@@ -38,6 +38,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged _menuDragHelper.IsDragging;
public ItemGridPiece? CurrentlyDragging => _menuDragHelper.Dragged;
@@ -52,6 +53,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged _ui.WindowRoot.Width ||
+ _lastContainerPosition.Value.Y > _ui.WindowRoot.Height))
{
_container.OpenCenteredAt(new Vector2(0.5f, 0.75f));
}
@@ -88,8 +96,11 @@ public sealed class StorageUIController : UIController, IOnSystemChanged(_container.StorageEntity, out var comp))
+ OnStorageOrderChanged((_container.StorageEntity.Value, comp));
+ }
+
+ private void OnOpaqueWindowChanged(bool obj)
+ {
+ if (OpaqueStorageWindow == obj)
+ return;
+ OpaqueStorageWindow = obj;
+ _container?.BuildBackground();
}
/// One might ask, Hey Emo, why are you parsing raw keyboard input just to rotate a rectangle?
@@ -321,7 +344,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged ToggleWalk =
CVarDef.Create("control.toggle_walk", false, CVar.CLIENTONLY | CVar.ARCHIVE);
+ /*
+ * STORAGE
+ */
+
///
/// Whether or not the storage UI is static and bound to the hotbar, or unbound and allowed to be dragged anywhere.
///
public static readonly CVarDef StaticStorageUI =
CVarDef.Create("control.static_storage_ui", true, CVar.CLIENTONLY | CVar.ARCHIVE);
+ ///
+ /// Whether or not the storage window uses a transparent or opaque sprite.
+ ///
+ public static readonly CVarDef OpaqueStorageWindow =
+ CVarDef.Create("control.opaque_storage_background", false, CVar.CLIENTONLY | CVar.ARCHIVE);
+
/*
* UPDATE
*/
diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs
index 2f6550bf2e..32ce24a971 100644
--- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs
+++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs
@@ -407,7 +407,7 @@ public abstract class SharedStorageSystem : EntitySystem
if (!_actionBlockerSystem.CanInteract(player, itemEnt) || !_sharedHandsSystem.IsHolding(player, itemEnt, out _))
return;
- InsertAt((storageEnt, storageComp), (itemEnt, null), msg.Location, out _, player);
+ InsertAt((storageEnt, storageComp), (itemEnt, null), msg.Location, out _, player, stackAutomatically: false);
}
private void OnBoundUIOpen(EntityUid uid, StorageComponent storageComp, BoundUIOpenedEvent args)
@@ -465,7 +465,7 @@ public abstract class SharedStorageSystem : EntitySystem
if (args.Cancelled || args.Container.ID != StorageComponent.ContainerId)
return;
- if (!CanInsert(uid, args.EntityUid, out _, component, ignoreStacks: true))
+ if (!CanInsert(uid, args.EntityUid, out _, component, ignoreStacks: true, includeContainerChecks: false))
args.Cancel();
}
@@ -534,7 +534,8 @@ public abstract class SharedStorageSystem : EntitySystem
StorageComponent? storageComp = null,
ItemComponent? item = null,
bool ignoreStacks = false,
- bool ignoreLocation = false)
+ bool ignoreLocation = false,
+ bool includeContainerChecks = true)
{
if (!Resolve(uid, ref storageComp) || !Resolve(insertEnt, ref item, false))
{
@@ -591,6 +592,12 @@ public abstract class SharedStorageSystem : EntitySystem
}
}
+ if (includeContainerChecks && !_containerSystem.CanInsert(insertEnt, storageComp.Container))
+ {
+ reason = null;
+ return false;
+ }
+
reason = null;
return true;
}
@@ -606,7 +613,8 @@ public abstract class SharedStorageSystem : EntitySystem
ItemStorageLocation location,
out EntityUid? stackedEntity,
EntityUid? user = null,
- bool playSound = true)
+ bool playSound = true,
+ bool stackAutomatically = true)
{
stackedEntity = null;
if (!Resolve(uid, ref uid.Comp))
@@ -617,7 +625,21 @@ public abstract class SharedStorageSystem : EntitySystem
uid.Comp.StoredItems[GetNetEntity(insertEnt)] = location;
Dirty(uid, uid.Comp);
- return Insert(uid, insertEnt, out stackedEntity, out _, user: user, storageComp: uid.Comp, playSound: playSound);
+
+ if (Insert(uid,
+ insertEnt,
+ out stackedEntity,
+ out _,
+ user: user,
+ storageComp: uid.Comp,
+ playSound: playSound,
+ stackAutomatically: stackAutomatically))
+ {
+ return true;
+ }
+
+ uid.Comp.StoredItems.Remove(GetNetEntity(insertEnt));
+ return false;
}
///
@@ -631,9 +653,10 @@ public abstract class SharedStorageSystem : EntitySystem
out EntityUid? stackedEntity,
EntityUid? user = null,
StorageComponent? storageComp = null,
- bool playSound = true)
+ bool playSound = true,
+ bool stackAutomatically = true)
{
- return Insert(uid, insertEnt, out stackedEntity, out _, user: user, storageComp: storageComp, playSound: playSound);
+ return Insert(uid, insertEnt, out stackedEntity, out _, user: user, storageComp: storageComp, playSound: playSound, stackAutomatically: stackAutomatically);
}
///
@@ -648,7 +671,8 @@ public abstract class SharedStorageSystem : EntitySystem
out string? reason,
EntityUid? user = null,
StorageComponent? storageComp = null,
- bool playSound = true)
+ bool playSound = true,
+ bool stackAutomatically = true)
{
stackedEntity = null;
reason = null;
@@ -665,7 +689,7 @@ public abstract class SharedStorageSystem : EntitySystem
* For now we just treat items as always being the same size regardless of stack count.
*/
- if (!_stackQuery.TryGetComponent(insertEnt, out var insertStack))
+ if (!stackAutomatically || !_stackQuery.TryGetComponent(insertEnt, out var insertStack))
{
if (!_containerSystem.Insert(insertEnt, storageComp.Container))
return false;
diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
index da9edc6f75..0b6a7df6f8 100644
--- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
+++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
@@ -29,6 +29,7 @@ ui-options-volume-percent = { TOSTRING($volume, "P0") }
ui-options-show-held-item = Show held item next to cursor?
ui-options-show-combat-mode-indicators = Show combat mode indicators with cursor?
+ui-options-opaque-storage-window = Enable opaque storage window?
ui-options-show-looc-on-head = Show LOOC chat above characters head?
ui-options-fancy-speech = Show names in speech bubbles?
ui-options-fancy-name-background = Add background to speech bubble names?
diff --git a/Resources/Textures/Interface/Default/Storage/tile_blocked_opaque.png b/Resources/Textures/Interface/Default/Storage/tile_blocked_opaque.png
new file mode 100644
index 0000000000..16a65e36db
Binary files /dev/null and b/Resources/Textures/Interface/Default/Storage/tile_blocked_opaque.png differ
diff --git a/Resources/Textures/Interface/Default/Storage/tile_empty_opaque.png b/Resources/Textures/Interface/Default/Storage/tile_empty_opaque.png
new file mode 100644
index 0000000000..6a6eb055a7
Binary files /dev/null and b/Resources/Textures/Interface/Default/Storage/tile_empty_opaque.png differ