Revert engine reverties (#34968)
This commit is contained in:
@@ -1,39 +1,80 @@
|
|||||||
using Content.Client.Storage.Systems;
|
using Content.Client.UserInterface.Systems.Storage;
|
||||||
|
using Content.Client.UserInterface.Systems.Storage.Controls;
|
||||||
using Content.Shared.Storage;
|
using Content.Shared.Storage;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
|
||||||
namespace Content.Client.Storage;
|
namespace Content.Client.Storage;
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class StorageBoundUserInterface : BoundUserInterface
|
public sealed class StorageBoundUserInterface : BoundUserInterface
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
private StorageWindow? _window;
|
||||||
|
|
||||||
private readonly StorageSystem _storage;
|
|
||||||
|
|
||||||
[Obsolete] public override bool DeferredClose => false;
|
|
||||||
|
|
||||||
public StorageBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
public StorageBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
_storage = _entManager.System<StorageSystem>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Open()
|
protected override void Open()
|
||||||
{
|
{
|
||||||
base.Open();
|
base.Open();
|
||||||
|
|
||||||
if (_entManager.TryGetComponent<StorageComponent>(Owner, out var comp))
|
_window = IoCManager.Resolve<IUserInterfaceManager>()
|
||||||
_storage.OpenStorageWindow((Owner, comp));
|
.GetUIController<StorageUIController>()
|
||||||
|
.CreateStorageWindow(Owner);
|
||||||
|
|
||||||
|
if (EntMan.TryGetComponent(Owner, out StorageComponent? storage))
|
||||||
|
{
|
||||||
|
_window.UpdateContainer((Owner, storage));
|
||||||
|
}
|
||||||
|
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_window.FlagDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
_window?.FlagDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reclaim()
|
||||||
|
{
|
||||||
|
if (_window == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_window.OnClose -= Close;
|
||||||
|
_window.Orphan();
|
||||||
|
_window = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
if (!disposing)
|
|
||||||
|
Reclaim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hide()
|
||||||
|
{
|
||||||
|
if (_window == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_storage.CloseStorageWindow(Owner);
|
_window.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show()
|
||||||
|
{
|
||||||
|
if (_window == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_window.Visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReOpen()
|
||||||
|
{
|
||||||
|
_window?.Orphan();
|
||||||
|
_window = null;
|
||||||
|
Open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ using Content.Client.Animations;
|
|||||||
using Content.Shared.Hands;
|
using Content.Shared.Hands;
|
||||||
using Content.Shared.Storage;
|
using Content.Shared.Storage;
|
||||||
using Content.Shared.Storage.EntitySystems;
|
using Content.Shared.Storage.EntitySystems;
|
||||||
using Robust.Shared.Collections;
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -13,114 +14,95 @@ namespace Content.Client.Storage.Systems;
|
|||||||
public sealed class StorageSystem : SharedStorageSystem
|
public sealed class StorageSystem : SharedStorageSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
[Dependency] private readonly EntityPickupAnimationSystem _entityPickupAnimation = default!;
|
[Dependency] private readonly EntityPickupAnimationSystem _entityPickupAnimation = default!;
|
||||||
|
|
||||||
private readonly List<Entity<StorageComponent>> _openStorages = new();
|
private Dictionary<EntityUid, ItemStorageLocation> _oldStoredItems = new();
|
||||||
public int OpenStorageAmount => _openStorages.Count;
|
|
||||||
|
|
||||||
public event Action<Entity<StorageComponent>>? StorageUpdated;
|
|
||||||
public event Action<Entity<StorageComponent>?>? StorageOrderChanged;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<StorageComponent, ComponentShutdown>(OnShutdown);
|
SubscribeLocalEvent<StorageComponent, ComponentHandleState>(OnStorageHandleState);
|
||||||
SubscribeNetworkEvent<PickupAnimationEvent>(HandlePickupAnimation);
|
SubscribeNetworkEvent<PickupAnimationEvent>(HandlePickupAnimation);
|
||||||
SubscribeAllEvent<AnimateInsertingEntitiesEvent>(HandleAnimatingInsertingEntities);
|
SubscribeAllEvent<AnimateInsertingEntitiesEvent>(HandleAnimatingInsertingEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateUI(Entity<StorageComponent?> entity)
|
private void OnStorageHandleState(EntityUid uid, StorageComponent component, ref ComponentHandleState args)
|
||||||
{
|
{
|
||||||
if (Resolve(entity.Owner, ref entity.Comp))
|
if (args.Current is not StorageComponentState state)
|
||||||
StorageUpdated?.Invoke((entity, entity.Comp));
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
public void OpenStorageWindow(Entity<StorageComponent> entity)
|
component.Grid.Clear();
|
||||||
{
|
component.Grid.AddRange(state.Grid);
|
||||||
if (_openStorages.Contains(entity))
|
component.MaxItemSize = state.MaxItemSize;
|
||||||
|
component.Whitelist = state.Whitelist;
|
||||||
|
component.Blacklist = state.Blacklist;
|
||||||
|
|
||||||
|
_oldStoredItems.Clear();
|
||||||
|
|
||||||
|
foreach (var item in component.StoredItems)
|
||||||
{
|
{
|
||||||
if (_openStorages.LastOrDefault() == entity)
|
_oldStoredItems.Add(item.Key, item.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
component.StoredItems.Clear();
|
||||||
|
|
||||||
|
foreach (var (nent, location) in state.StoredItems)
|
||||||
|
{
|
||||||
|
var ent = EnsureEntity<StorageComponent>(nent, uid);
|
||||||
|
component.StoredItems[ent] = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
component.SavedLocations.Clear();
|
||||||
|
|
||||||
|
foreach (var loc in state.SavedLocations)
|
||||||
|
{
|
||||||
|
component.SavedLocations[loc.Key] = new(loc.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var uiDirty = !component.StoredItems.SequenceEqual(_oldStoredItems);
|
||||||
|
|
||||||
|
if (uiDirty && UI.TryGetOpenUi<StorageBoundUserInterface>(uid, StorageComponent.StorageUiKey.Key, out var storageBui))
|
||||||
|
{
|
||||||
|
storageBui.Refresh();
|
||||||
|
// Make sure nesting still updated.
|
||||||
|
var player = _player.LocalEntity;
|
||||||
|
|
||||||
|
if (NestedStorage && player != null && ContainerSystem.TryGetContainingContainer((uid, null, null), out var container) &&
|
||||||
|
UI.TryGetOpenUi<StorageBoundUserInterface>(container.Owner, StorageComponent.StorageUiKey.Key, out var containerBui))
|
||||||
{
|
{
|
||||||
CloseStorageWindow((entity, entity.Comp));
|
containerBui.Hide();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var storages = new ValueList<Entity<StorageComponent>>(_openStorages);
|
storageBui.Show();
|
||||||
var reverseStorages = storages.Reverse();
|
|
||||||
|
|
||||||
foreach (var storageEnt in reverseStorages)
|
|
||||||
{
|
|
||||||
if (storageEnt == entity)
|
|
||||||
break;
|
|
||||||
|
|
||||||
CloseStorageBoundUserInterface(storageEnt.Owner);
|
|
||||||
_openStorages.Remove(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearNonParentStorages(entity);
|
|
||||||
_openStorages.Add(entity);
|
|
||||||
Entity<StorageComponent>? last = _openStorages.LastOrDefault();
|
|
||||||
StorageOrderChanged?.Invoke(last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseStorageWindow(Entity<StorageComponent?> entity)
|
public override void UpdateUI(Entity<StorageComponent?> entity)
|
||||||
{
|
{
|
||||||
if (!Resolve(entity, ref entity.Comp, false))
|
if (UI.TryGetOpenUi<StorageBoundUserInterface>(entity.Owner, StorageComponent.StorageUiKey.Key, out var sBui))
|
||||||
return;
|
|
||||||
|
|
||||||
if (!_openStorages.Contains((entity, entity.Comp)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var storages = new ValueList<Entity<StorageComponent>>(_openStorages);
|
|
||||||
var reverseStorages = storages.Reverse();
|
|
||||||
|
|
||||||
foreach (var storage in reverseStorages)
|
|
||||||
{
|
{
|
||||||
CloseStorageBoundUserInterface(storage.Owner);
|
sBui.Refresh();
|
||||||
_openStorages.Remove(storage);
|
|
||||||
if (storage.Owner == entity.Owner)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity<StorageComponent>? last = null;
|
|
||||||
if (_openStorages.Any())
|
|
||||||
last = _openStorages.LastOrDefault();
|
|
||||||
StorageOrderChanged?.Invoke(last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearNonParentStorages(EntityUid uid)
|
protected override void HideStorageWindow(EntityUid uid, EntityUid actor)
|
||||||
{
|
{
|
||||||
var storages = new ValueList<Entity<StorageComponent>>(_openStorages);
|
if (UI.TryGetOpenUi<StorageBoundUserInterface>(uid, StorageComponent.StorageUiKey.Key, out var storageBui))
|
||||||
var reverseStorages = storages.Reverse();
|
|
||||||
|
|
||||||
foreach (var storage in reverseStorages)
|
|
||||||
{
|
{
|
||||||
if (storage.Comp.Container.Contains(uid))
|
storageBui.Hide();
|
||||||
break;
|
|
||||||
|
|
||||||
CloseStorageBoundUserInterface(storage.Owner);
|
|
||||||
_openStorages.Remove(storage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseStorageBoundUserInterface(Entity<UserInterfaceComponent?> entity)
|
protected override void ShowStorageWindow(EntityUid uid, EntityUid actor)
|
||||||
{
|
{
|
||||||
if (!Resolve(entity, ref entity.Comp, false))
|
if (UI.TryGetOpenUi<StorageBoundUserInterface>(uid, StorageComponent.StorageUiKey.Key, out var storageBui))
|
||||||
return;
|
{
|
||||||
|
storageBui.Show();
|
||||||
if (entity.Comp.ClientOpenInterfaces.GetValueOrDefault(StorageComponent.StorageUiKey.Key) is not { } bui)
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
bui.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnShutdown(Entity<StorageComponent> ent, ref ComponentShutdown args)
|
|
||||||
{
|
|
||||||
CloseStorageWindow((ent, ent.Comp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -142,7 +124,7 @@ public sealed class StorageSystem : SharedStorageSystem
|
|||||||
{
|
{
|
||||||
if (!_timing.IsFirstTimePredicted)
|
if (!_timing.IsFirstTimePredicted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TransformSystem.InRange(finalCoords, initialCoords, 0.1f) ||
|
if (TransformSystem.InRange(finalCoords, initialCoords, 0.1f) ||
|
||||||
!Exists(initialCoords.EntityId) || !Exists(finalCoords.EntityId))
|
!Exists(initialCoords.EntityId) || !Exists(finalCoords.EntityId))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,13 +31,12 @@ public sealed class HotbarUIController : UIController
|
|||||||
ReloadHotbar();
|
ReloadHotbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup(HandsContainer handsContainer, StorageContainer storageContainer)
|
public void Setup(HandsContainer handsContainer)
|
||||||
{
|
{
|
||||||
_inventory = UIManager.GetUIController<InventoryUIController>();
|
_inventory = UIManager.GetUIController<InventoryUIController>();
|
||||||
_hands = UIManager.GetUIController<HandsUIController>();
|
_hands = UIManager.GetUIController<HandsUIController>();
|
||||||
_storage = UIManager.GetUIController<StorageUIController>();
|
_storage = UIManager.GetUIController<StorageUIController>();
|
||||||
_hands.RegisterHandContainer(handsContainer);
|
_hands.RegisterHandContainer(handsContainer);
|
||||||
_storage.RegisterStorageContainer(storageContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadHotbar()
|
public void ReloadHotbar()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<widgets:HotbarGui
|
<widgets:HotbarGui
|
||||||
xmlns="https://spacestation14.io"
|
xmlns="https://spacestation14.io"
|
||||||
xmlns:inventory="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Controls"
|
xmlns:inventory="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Controls"
|
||||||
xmlns:storage="clr-namespace:Content.Client.UserInterface.Systems.Storage.Controls"
|
|
||||||
xmlns:hands="clr-namespace:Content.Client.UserInterface.Systems.Hands.Controls"
|
xmlns:hands="clr-namespace:Content.Client.UserInterface.Systems.Hands.Controls"
|
||||||
xmlns:widgets="clr-namespace:Content.Client.UserInterface.Systems.Hotbar.Widgets"
|
xmlns:widgets="clr-namespace:Content.Client.UserInterface.Systems.Hotbar.Widgets"
|
||||||
Name="HotbarInterface"
|
Name="HotbarInterface"
|
||||||
@@ -13,10 +12,8 @@
|
|||||||
<BoxContainer Name="StorageContainer"
|
<BoxContainer Name="StorageContainer"
|
||||||
Access="Public"
|
Access="Public"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
HorizontalExpand="True"
|
||||||
Margin="10">
|
Margin="10">
|
||||||
<storage:StorageContainer
|
|
||||||
Name="StoragePanel"
|
|
||||||
Visible="False"/>
|
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<BoxContainer Orientation="Horizontal" Name="Hotbar" HorizontalAlignment="Center">
|
<BoxContainer Orientation="Horizontal" Name="Hotbar" HorizontalAlignment="Center">
|
||||||
<inventory:ItemSlotButtonContainer
|
<inventory:ItemSlotButtonContainer
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public sealed partial class HotbarGui : UIWidget
|
|||||||
StatusPanelLeft.SetSide(HandUILocation.Left);
|
StatusPanelLeft.SetSide(HandUILocation.Left);
|
||||||
var hotbarController = UserInterfaceManager.GetUIController<HotbarUIController>();
|
var hotbarController = UserInterfaceManager.GetUIController<HotbarUIController>();
|
||||||
|
|
||||||
hotbarController.Setup(HandContainer, StoragePanel);
|
hotbarController.Setup(HandContainer);
|
||||||
LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin);
|
LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public sealed class ItemGridPiece : Control, IEntityControl
|
|||||||
Location = location;
|
Location = location;
|
||||||
|
|
||||||
Visible = true;
|
Visible = true;
|
||||||
MouseFilter = MouseFilterMode.Pass;
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
TooltipSupplier = SupplyTooltip;
|
TooltipSupplier = SupplyTooltip;
|
||||||
|
|
||||||
@@ -105,8 +105,11 @@ public sealed class ItemGridPiece : Control, IEntityControl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_storageController.IsDragging && _storageController.DraggingGhost?.Entity == Entity && _storageController.DraggingGhost != this)
|
if (_storageController.IsDragging && _storageController.DraggingGhost?.Entity == Entity &&
|
||||||
|
_storageController.DraggingGhost != this)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var adjustedShape = _entityManager.System<ItemSystem>().GetAdjustedItemShape((Entity, itemComponent), Location.Rotation, Vector2i.Zero);
|
var adjustedShape = _entityManager.System<ItemSystem>().GetAdjustedItemShape((Entity, itemComponent), Location.Rotation, Vector2i.Zero);
|
||||||
var boundingGrid = adjustedShape.GetBoundingBox();
|
var boundingGrid = adjustedShape.GetBoundingBox();
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ using System.Linq;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Hands.Systems;
|
using Content.Client.Hands.Systems;
|
||||||
using Content.Client.Items.Systems;
|
using Content.Client.Items.Systems;
|
||||||
|
using Content.Client.Storage;
|
||||||
using Content.Client.Storage.Systems;
|
using Content.Client.Storage.Systems;
|
||||||
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
using Content.Shared.Storage;
|
using Content.Shared.Storage;
|
||||||
@@ -11,12 +13,14 @@ using Robust.Client.Graphics;
|
|||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.UserInterface.Systems.Storage.Controls;
|
namespace Content.Client.UserInterface.Systems.Storage.Controls;
|
||||||
|
|
||||||
public sealed class StorageContainer : BaseWindow
|
public sealed class StorageWindow : BaseWindow
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entity = default!;
|
[Dependency] private readonly IEntityManager _entity = default!;
|
||||||
private readonly StorageUIController _storageController;
|
private readonly StorageUIController _storageController;
|
||||||
@@ -27,6 +31,20 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
private readonly GridContainer _backgroundGrid;
|
private readonly GridContainer _backgroundGrid;
|
||||||
private readonly GridContainer _sidebar;
|
private readonly GridContainer _sidebar;
|
||||||
|
|
||||||
|
private Control _titleContainer;
|
||||||
|
private Label _titleLabel;
|
||||||
|
|
||||||
|
// Needs to be nullable in case a piece is in default spot.
|
||||||
|
private readonly Dictionary<EntityUid, (ItemStorageLocation? Loc, ItemGridPiece Control)> _pieces = new();
|
||||||
|
private readonly List<Control> _controlGrid = new();
|
||||||
|
|
||||||
|
private ValueList<EntityUid> _contained = new();
|
||||||
|
private ValueList<EntityUid> _toRemove = new();
|
||||||
|
|
||||||
|
private TextureButton? _backButton;
|
||||||
|
|
||||||
|
private bool _isDirty;
|
||||||
|
|
||||||
public event Action<GUIBoundKeyEventArgs, ItemGridPiece>? OnPiecePressed;
|
public event Action<GUIBoundKeyEventArgs, ItemGridPiece>? OnPiecePressed;
|
||||||
public event Action<GUIBoundKeyEventArgs, ItemGridPiece>? OnPieceUnpressed;
|
public event Action<GUIBoundKeyEventArgs, ItemGridPiece>? OnPieceUnpressed;
|
||||||
|
|
||||||
@@ -51,9 +69,10 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
private readonly string _sidebarFatTexturePath = "Storage/sidebar_fat";
|
private readonly string _sidebarFatTexturePath = "Storage/sidebar_fat";
|
||||||
private Texture? _sidebarFatTexture;
|
private Texture? _sidebarFatTexture;
|
||||||
|
|
||||||
public StorageContainer()
|
public StorageWindow()
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
Resizable = false;
|
||||||
|
|
||||||
_storageController = UserInterfaceManager.GetUIController<StorageUIController>();
|
_storageController = UserInterfaceManager.GetUIController<StorageUIController>();
|
||||||
|
|
||||||
@@ -63,6 +82,7 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
|
|
||||||
_sidebar = new GridContainer
|
_sidebar = new GridContainer
|
||||||
{
|
{
|
||||||
|
Name = "SideBar",
|
||||||
HSeparationOverride = 0,
|
HSeparationOverride = 0,
|
||||||
VSeparationOverride = 0,
|
VSeparationOverride = 0,
|
||||||
Columns = 1
|
Columns = 1
|
||||||
@@ -70,21 +90,48 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
|
|
||||||
_pieceGrid = new GridContainer
|
_pieceGrid = new GridContainer
|
||||||
{
|
{
|
||||||
|
Name = "PieceGrid",
|
||||||
HSeparationOverride = 0,
|
HSeparationOverride = 0,
|
||||||
VSeparationOverride = 0
|
VSeparationOverride = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
_backgroundGrid = new GridContainer
|
_backgroundGrid = new GridContainer
|
||||||
{
|
{
|
||||||
|
Name = "BackgroundGrid",
|
||||||
HSeparationOverride = 0,
|
HSeparationOverride = 0,
|
||||||
VSeparationOverride = 0
|
VSeparationOverride = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_titleLabel = new Label()
|
||||||
|
{
|
||||||
|
HorizontalExpand = true,
|
||||||
|
Name = "StorageLabel",
|
||||||
|
ClipText = true,
|
||||||
|
Text = "Dummy",
|
||||||
|
StyleClasses =
|
||||||
|
{
|
||||||
|
"FancyWindowTitle",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_titleContainer = new PanelContainer()
|
||||||
|
{
|
||||||
|
StyleClasses =
|
||||||
|
{
|
||||||
|
"WindowHeadingBackground"
|
||||||
|
},
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
_titleLabel
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var container = new BoxContainer
|
var container = new BoxContainer
|
||||||
{
|
{
|
||||||
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
|
_titleContainer,
|
||||||
new BoxContainer
|
new BoxContainer
|
||||||
{
|
{
|
||||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||||
@@ -130,12 +177,22 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
if (entity == null)
|
if (entity == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (UserInterfaceManager.GetUIController<StorageUIController>().WindowTitle)
|
||||||
|
{
|
||||||
|
_titleLabel.Text = Identity.Name(entity.Value, _entity);
|
||||||
|
_titleContainer.Visible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_titleContainer.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
BuildGridRepresentation();
|
BuildGridRepresentation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildGridRepresentation()
|
private void BuildGridRepresentation()
|
||||||
{
|
{
|
||||||
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var comp) || !comp.Grid.Any())
|
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var comp) || comp.Grid.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var boundingGrid = comp.Grid.GetBoundingBox();
|
var boundingGrid = comp.Grid.GetBoundingBox();
|
||||||
@@ -144,12 +201,13 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
|
|
||||||
#region Sidebar
|
#region Sidebar
|
||||||
_sidebar.Children.Clear();
|
_sidebar.Children.Clear();
|
||||||
_sidebar.Rows = boundingGrid.Height + 1;
|
var rows = boundingGrid.Height + 1;
|
||||||
|
_sidebar.Rows = rows;
|
||||||
|
|
||||||
var exitButton = new TextureButton
|
var exitButton = new TextureButton
|
||||||
{
|
{
|
||||||
TextureNormal = _entity.System<StorageSystem>().OpenStorageAmount == 1
|
Name = "ExitButton",
|
||||||
?_exitTexture
|
TextureNormal = _exitTexture,
|
||||||
: _backTexture,
|
|
||||||
Scale = new Vector2(2, 2),
|
Scale = new Vector2(2, 2),
|
||||||
};
|
};
|
||||||
exitButton.OnPressed += _ =>
|
exitButton.OnPressed += _ =>
|
||||||
@@ -165,8 +223,10 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var exitContainer = new BoxContainer
|
var exitContainer = new BoxContainer
|
||||||
{
|
{
|
||||||
|
Name = "ExitContainer",
|
||||||
Children =
|
Children =
|
||||||
{
|
{
|
||||||
new TextureRect
|
new TextureRect
|
||||||
@@ -182,28 +242,70 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_sidebar.AddChild(exitContainer);
|
_sidebar.AddChild(exitContainer);
|
||||||
for (var i = 0; i < boundingGrid.Height - 1; i++)
|
var offset = 2;
|
||||||
|
|
||||||
|
if (_entity.System<StorageSystem>().NestedStorage && rows > 0)
|
||||||
{
|
{
|
||||||
_sidebar.AddChild(new TextureRect
|
_backButton = new TextureButton
|
||||||
{
|
{
|
||||||
Texture = _sidebarMiddleTexture,
|
TextureNormal = _backTexture,
|
||||||
TextureScale = new Vector2(2, 2),
|
Scale = new Vector2(2, 2),
|
||||||
});
|
};
|
||||||
|
_backButton.OnPressed += _ =>
|
||||||
|
{
|
||||||
|
var containerSystem = _entity.System<SharedContainerSystem>();
|
||||||
|
|
||||||
|
if (containerSystem.TryGetContainingContainer(StorageEntity.Value, out var container) &&
|
||||||
|
_entity.TryGetComponent(container.Owner, out StorageComponent? storage))
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if (_entity.System<SharedUserInterfaceSystem>()
|
||||||
|
.TryGetOpenUi<StorageBoundUserInterface>(container.Owner,
|
||||||
|
StorageComponent.StorageUiKey.Key,
|
||||||
|
out var parentBui))
|
||||||
|
{
|
||||||
|
parentBui.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var backContainer = new BoxContainer
|
||||||
|
{
|
||||||
|
Name = "ExitContainer",
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new TextureRect
|
||||||
|
{
|
||||||
|
Texture = rows > 2 ? _sidebarMiddleTexture : _sidebarBottomTexture,
|
||||||
|
TextureScale = new Vector2(2, 2),
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
_backButton,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_sidebar.AddChild(backContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boundingGrid.Height > 0)
|
var fillerRows = rows - offset;
|
||||||
|
|
||||||
|
for (var i = 0; i < fillerRows; i++)
|
||||||
{
|
{
|
||||||
_sidebar.AddChild(new TextureRect
|
_sidebar.AddChild(new TextureRect
|
||||||
{
|
{
|
||||||
Texture = _sidebarBottomTexture,
|
Texture = i != (fillerRows - 1) ? _sidebarMiddleTexture : _sidebarBottomTexture,
|
||||||
TextureScale = new Vector2(2, 2),
|
TextureScale = new Vector2(2, 2),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
BuildItemPieces();
|
FlagDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BuildBackground()
|
public void BuildBackground()
|
||||||
@@ -240,70 +342,127 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Reclaim(ItemStorageLocation location, ItemGridPiece draggingGhost)
|
||||||
|
{
|
||||||
|
draggingGhost.OnPiecePressed += OnPiecePressed;
|
||||||
|
draggingGhost.OnPieceUnpressed += OnPieceUnpressed;
|
||||||
|
_pieces[draggingGhost.Entity] = (location, draggingGhost);
|
||||||
|
draggingGhost.Location = location;
|
||||||
|
var controlIndex = GetGridIndex(draggingGhost);
|
||||||
|
_controlGrid[controlIndex].AddChild(draggingGhost);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetGridIndex(ItemGridPiece piece)
|
||||||
|
{
|
||||||
|
return piece.Location.Position.X + piece.Location.Position.Y * _pieceGrid.Columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FlagDirty()
|
||||||
|
{
|
||||||
|
_isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveGrid(ItemGridPiece control)
|
||||||
|
{
|
||||||
|
control.Orphan();
|
||||||
|
_pieces.Remove(control.Entity);
|
||||||
|
control.OnPiecePressed -= OnPiecePressed;
|
||||||
|
control.OnPieceUnpressed -= OnPieceUnpressed;
|
||||||
|
}
|
||||||
|
|
||||||
public void BuildItemPieces()
|
public void BuildItemPieces()
|
||||||
{
|
{
|
||||||
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var storageComp))
|
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var storageComp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!storageComp.Grid.Any())
|
if (storageComp.Grid.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var boundingGrid = storageComp.Grid.GetBoundingBox();
|
var boundingGrid = storageComp.Grid.GetBoundingBox();
|
||||||
var size = _emptyTexture!.Size * 2;
|
var size = _emptyTexture!.Size * 2;
|
||||||
var containedEntities = storageComp.Container.ContainedEntities.Reverse().ToArray();
|
_contained.Clear();
|
||||||
|
_contained.AddRange(storageComp.Container.ContainedEntities.Reverse());
|
||||||
|
|
||||||
//todo. at some point, we may want to only rebuild the pieces that have actually received new data.
|
// Build the grid representation
|
||||||
|
if (_pieceGrid.Rows - 1 != boundingGrid.Height || _pieceGrid.Columns - 1 != boundingGrid.Width)
|
||||||
_pieceGrid.RemoveAllChildren();
|
|
||||||
_pieceGrid.Rows = boundingGrid.Height + 1;
|
|
||||||
_pieceGrid.Columns = boundingGrid.Width + 1;
|
|
||||||
for (var y = boundingGrid.Bottom; y <= boundingGrid.Top; y++)
|
|
||||||
{
|
{
|
||||||
for (var x = boundingGrid.Left; x <= boundingGrid.Right; x++)
|
_pieceGrid.Rows = boundingGrid.Height + 1;
|
||||||
|
_pieceGrid.Columns = boundingGrid.Width + 1;
|
||||||
|
_controlGrid.Clear();
|
||||||
|
|
||||||
|
for (var y = boundingGrid.Bottom; y <= boundingGrid.Top; y++)
|
||||||
{
|
{
|
||||||
var control = new Control
|
for (var x = boundingGrid.Left; x <= boundingGrid.Right; x++)
|
||||||
{
|
{
|
||||||
MinSize = size
|
var control = new Control
|
||||||
};
|
|
||||||
|
|
||||||
var currentPosition = new Vector2i(x, y);
|
|
||||||
|
|
||||||
foreach (var (itemEnt, itemPos) in storageComp.StoredItems)
|
|
||||||
{
|
|
||||||
if (itemPos.Position != currentPosition)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (_entity.TryGetComponent<ItemComponent>(itemEnt, out var itemEntComponent))
|
|
||||||
{
|
{
|
||||||
ItemGridPiece gridPiece;
|
MinSize = size
|
||||||
|
};
|
||||||
|
|
||||||
if (_storageController.CurrentlyDragging?.Entity is { } dragging
|
_controlGrid.Add(control);
|
||||||
&& dragging == itemEnt)
|
_pieceGrid.AddChild(control);
|
||||||
{
|
}
|
||||||
_storageController.CurrentlyDragging.Orphan();
|
}
|
||||||
gridPiece = _storageController.CurrentlyDragging;
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gridPiece = new ItemGridPiece((itemEnt, itemEntComponent), itemPos, _entity)
|
|
||||||
{
|
|
||||||
MinSize = size,
|
|
||||||
Marked = Array.IndexOf(containedEntities, itemEnt) switch
|
|
||||||
{
|
|
||||||
0 => ItemGridPieceMarks.First,
|
|
||||||
1 => ItemGridPieceMarks.Second,
|
|
||||||
_ => null,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
gridPiece.OnPiecePressed += OnPiecePressed;
|
|
||||||
gridPiece.OnPieceUnpressed += OnPieceUnpressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
control.AddChild(gridPiece);
|
_toRemove.Clear();
|
||||||
}
|
|
||||||
|
// Remove entities no longer relevant / Update existing ones
|
||||||
|
foreach (var (ent, data) in _pieces)
|
||||||
|
{
|
||||||
|
if (storageComp.StoredItems.TryGetValue(ent, out var updated))
|
||||||
|
{
|
||||||
|
if (data.Loc.Equals(updated))
|
||||||
|
{
|
||||||
|
DebugTools.Assert(data.Control.Location == updated);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pieceGrid.AddChild(control);
|
// Update
|
||||||
|
data.Control.Location = updated;
|
||||||
|
var index = GetGridIndex(data.Control);
|
||||||
|
data.Control.Orphan();
|
||||||
|
_controlGrid[index].AddChild(data.Control);
|
||||||
|
_pieces[ent] = (updated, data.Control);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_toRemove.Add(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ent in _toRemove)
|
||||||
|
{
|
||||||
|
_pieces.Remove(ent, out var data);
|
||||||
|
data.Control.Orphan();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new ones
|
||||||
|
foreach (var (ent, loc) in storageComp.StoredItems)
|
||||||
|
{
|
||||||
|
if (_pieces.TryGetValue(ent, out var existing))
|
||||||
|
{
|
||||||
|
DebugTools.Assert(existing.Loc == loc);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_entity.TryGetComponent<ItemComponent>(ent, out var itemEntComponent))
|
||||||
|
{
|
||||||
|
var gridPiece = new ItemGridPiece((ent, itemEntComponent), loc, _entity)
|
||||||
|
{
|
||||||
|
MinSize = size,
|
||||||
|
Marked = _contained.IndexOf(ent) switch
|
||||||
|
{
|
||||||
|
0 => ItemGridPieceMarks.First,
|
||||||
|
1 => ItemGridPieceMarks.Second,
|
||||||
|
_ => null,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gridPiece.OnPiecePressed += OnPiecePressed;
|
||||||
|
gridPiece.OnPieceUnpressed += OnPieceUnpressed;
|
||||||
|
var controlIndex = loc.Position.X + loc.Position.Y * (boundingGrid.Width + 1);
|
||||||
|
|
||||||
|
_controlGrid[controlIndex].AddChild(gridPiece);
|
||||||
|
_pieces[ent] = (loc, gridPiece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,6 +474,35 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
if (!IsOpen)
|
if (!IsOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_isDirty)
|
||||||
|
{
|
||||||
|
_isDirty = false;
|
||||||
|
BuildItemPieces();
|
||||||
|
}
|
||||||
|
|
||||||
|
var containerSystem = _entity.System<SharedContainerSystem>();
|
||||||
|
|
||||||
|
if (_backButton != null)
|
||||||
|
{
|
||||||
|
if (StorageEntity != null && _entity.System<StorageSystem>().NestedStorage)
|
||||||
|
{
|
||||||
|
if (containerSystem.TryGetContainingContainer(StorageEntity.Value, out var container) &&
|
||||||
|
_entity.HasComponent<StorageComponent>(container.Owner))
|
||||||
|
{
|
||||||
|
_backButton.Visible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_backButton.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Hide the button.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_backButton.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var itemSystem = _entity.System<ItemSystem>();
|
var itemSystem = _entity.System<ItemSystem>();
|
||||||
var storageSystem = _entity.System<StorageSystem>();
|
var storageSystem = _entity.System<StorageSystem>();
|
||||||
var handsSystem = _entity.System<HandsSystem>();
|
var handsSystem = _entity.System<HandsSystem>();
|
||||||
@@ -324,7 +512,7 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
child.ModulateSelfOverride = Color.FromHex("#222222");
|
child.ModulateSelfOverride = Color.FromHex("#222222");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UserInterfaceManager.CurrentlyHovered is StorageContainer con && con != this)
|
if (UserInterfaceManager.CurrentlyHovered is StorageWindow con && con != this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var storageComponent))
|
if (!_entity.TryGetComponent<StorageComponent>(StorageEntity, out var storageComponent))
|
||||||
@@ -373,7 +561,7 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float spot = 0;
|
float spot = 0;
|
||||||
var marked = new List<Control>();
|
var marked = new ValueList<Control>();
|
||||||
|
|
||||||
foreach (var location in locations.Value)
|
foreach (var location in locations.Value)
|
||||||
{
|
{
|
||||||
@@ -500,14 +688,4 @@ public sealed class StorageContainer : BaseWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
|
||||||
{
|
|
||||||
base.Close();
|
|
||||||
|
|
||||||
if (StorageEntity == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_entity.System<StorageSystem>().CloseStorageWindow(StorageEntity.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using System.Numerics;
|
|||||||
using Content.Client.Examine;
|
using Content.Client.Examine;
|
||||||
using Content.Client.Hands.Systems;
|
using Content.Client.Hands.Systems;
|
||||||
using Content.Client.Interaction;
|
using Content.Client.Interaction;
|
||||||
|
using Content.Client.Storage;
|
||||||
using Content.Client.Storage.Systems;
|
using Content.Client.Storage.Systems;
|
||||||
using Content.Client.UserInterface.Systems.Hotbar.Widgets;
|
using Content.Client.UserInterface.Systems.Hotbar.Widgets;
|
||||||
using Content.Client.UserInterface.Systems.Storage.Controls;
|
using Content.Client.UserInterface.Systems.Storage.Controls;
|
||||||
@@ -9,9 +10,9 @@ using Content.Client.Verbs.UI;
|
|||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Item;
|
|
||||||
using Content.Shared.Storage;
|
using Content.Shared.Storage;
|
||||||
using Robust.Client.Input;
|
using Robust.Client.Input;
|
||||||
|
using Robust.Client.Player;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controllers;
|
using Robust.Client.UserInterface.Controllers;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
@@ -23,19 +24,23 @@ namespace Content.Client.UserInterface.Systems.Storage;
|
|||||||
|
|
||||||
public sealed class StorageUIController : UIController, IOnSystemChanged<StorageSystem>
|
public sealed class StorageUIController : UIController, IOnSystemChanged<StorageSystem>
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Things are a bit over the shop but essentially
|
||||||
|
* - Clicking into storagewindow is handled via storagewindow
|
||||||
|
* - Clicking out of it is via ItemGridPiece
|
||||||
|
* - Dragging around is handled here
|
||||||
|
* - Drawing is handled via ItemGridPiece
|
||||||
|
* - StorageSystem handles any sim stuff around open windows.
|
||||||
|
*/
|
||||||
|
|
||||||
[Dependency] private readonly IConfigurationManager _configuration = default!;
|
[Dependency] private readonly IConfigurationManager _configuration = default!;
|
||||||
[Dependency] private readonly IEntityManager _entity = default!;
|
|
||||||
[Dependency] private readonly IInputManager _input = default!;
|
[Dependency] private readonly IInputManager _input = default!;
|
||||||
[Dependency] private readonly IUserInterfaceManager _ui = default!;
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
|
[UISystemDependency] private readonly StorageSystem _storage = default!;
|
||||||
|
|
||||||
private readonly DragDropHelper<ItemGridPiece> _menuDragHelper;
|
private readonly DragDropHelper<ItemGridPiece> _menuDragHelper;
|
||||||
private StorageContainer? _container;
|
|
||||||
|
|
||||||
private Vector2? _lastContainerPosition;
|
public ItemGridPiece? DraggingGhost => _menuDragHelper.Dragged;
|
||||||
|
|
||||||
private HotbarGui? Hotbar => UIManager.GetActiveUIWidgetOrNull<HotbarGui>();
|
|
||||||
|
|
||||||
public ItemGridPiece? DraggingGhost;
|
|
||||||
public Angle DraggingRotation = Angle.Zero;
|
public Angle DraggingRotation = Angle.Zero;
|
||||||
public bool StaticStorageUIEnabled;
|
public bool StaticStorageUIEnabled;
|
||||||
public bool OpaqueStorageWindow;
|
public bool OpaqueStorageWindow;
|
||||||
@@ -43,6 +48,8 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
public bool IsDragging => _menuDragHelper.IsDragging;
|
public bool IsDragging => _menuDragHelper.IsDragging;
|
||||||
public ItemGridPiece? CurrentlyDragging => _menuDragHelper.Dragged;
|
public ItemGridPiece? CurrentlyDragging => _menuDragHelper.Dragged;
|
||||||
|
|
||||||
|
public bool WindowTitle { get; private set; } = false;
|
||||||
|
|
||||||
public StorageUIController()
|
public StorageUIController()
|
||||||
{
|
{
|
||||||
_menuDragHelper = new DragDropHelper<ItemGridPiece>(OnMenuBeginDrag, OnMenuContinueDrag, OnMenuEndDrag);
|
_menuDragHelper = new DragDropHelper<ItemGridPiece>(OnMenuBeginDrag, OnMenuContinueDrag, OnMenuEndDrag);
|
||||||
@@ -52,106 +59,88 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
UIManager.OnScreenChanged += OnScreenChange;
|
||||||
|
|
||||||
_configuration.OnValueChanged(CCVars.StaticStorageUI, OnStaticStorageChanged, true);
|
_configuration.OnValueChanged(CCVars.StaticStorageUI, OnStaticStorageChanged, true);
|
||||||
_configuration.OnValueChanged(CCVars.OpaqueStorageWindow, OnOpaqueWindowChanged, true);
|
_configuration.OnValueChanged(CCVars.OpaqueStorageWindow, OnOpaqueWindowChanged, true);
|
||||||
|
_configuration.OnValueChanged(CCVars.StorageWindowTitle, OnStorageWindowTitle, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScreenChange((UIScreen? Old, UIScreen? New) obj)
|
||||||
|
{
|
||||||
|
// Handle reconnects with hotbargui.
|
||||||
|
|
||||||
|
// Essentially HotbarGui / the screen gets loaded AFTER gamestates at the moment (because clientgameticker manually changes it via event)
|
||||||
|
// and changing this may be a massive change.
|
||||||
|
// So instead we'll just manually reload it for now.
|
||||||
|
if (!StaticStorageUIEnabled ||
|
||||||
|
obj.New == null ||
|
||||||
|
!EntityManager.TryGetComponent(_player.LocalEntity, out UserInterfaceUserComponent? userComp))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UISystemDependency not injected at this point so do it the old fashion way, I love ordering issues.
|
||||||
|
var uiSystem = EntityManager.System<SharedUserInterfaceSystem>();
|
||||||
|
|
||||||
|
foreach (var bui in uiSystem.GetActorUis((_player.LocalEntity.Value, userComp)))
|
||||||
|
{
|
||||||
|
if (!uiSystem.TryGetOpenUi<StorageBoundUserInterface>(bui.Entity, StorageComponent.StorageUiKey.Key, out var storageBui))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
storageBui.ReOpen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStorageWindowTitle(bool obj)
|
||||||
|
{
|
||||||
|
WindowTitle = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOpaqueWindowChanged(bool obj)
|
||||||
|
{
|
||||||
|
OpaqueStorageWindow = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStaticStorageChanged(bool obj)
|
||||||
|
{
|
||||||
|
StaticStorageUIEnabled = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageWindow CreateStorageWindow(EntityUid uid)
|
||||||
|
{
|
||||||
|
var window = new StorageWindow();
|
||||||
|
window.MouseFilter = Control.MouseFilterMode.Pass;
|
||||||
|
|
||||||
|
window.OnPiecePressed += (args, piece) =>
|
||||||
|
{
|
||||||
|
OnPiecePressed(args, window, piece);
|
||||||
|
};
|
||||||
|
window.OnPieceUnpressed += (args, piece) =>
|
||||||
|
{
|
||||||
|
OnPieceUnpressed(args, window, piece);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (StaticStorageUIEnabled)
|
||||||
|
{
|
||||||
|
UIManager.GetActiveUIWidgetOrNull<HotbarGui>()?.StorageContainer.AddChild(window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.OpenCenteredLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSystemLoaded(StorageSystem system)
|
public void OnSystemLoaded(StorageSystem system)
|
||||||
{
|
{
|
||||||
_input.FirstChanceOnKeyEvent += OnMiddleMouse;
|
_input.FirstChanceOnKeyEvent += OnMiddleMouse;
|
||||||
system.StorageUpdated += OnStorageUpdated;
|
|
||||||
system.StorageOrderChanged += OnStorageOrderChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSystemUnloaded(StorageSystem system)
|
public void OnSystemUnloaded(StorageSystem system)
|
||||||
{
|
{
|
||||||
_input.FirstChanceOnKeyEvent -= OnMiddleMouse;
|
_input.FirstChanceOnKeyEvent -= OnMiddleMouse;
|
||||||
system.StorageUpdated -= OnStorageUpdated;
|
|
||||||
system.StorageOrderChanged -= OnStorageOrderChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnStorageOrderChanged(Entity<StorageComponent>? nullEnt)
|
|
||||||
{
|
|
||||||
if (_container == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (IsDragging)
|
|
||||||
_menuDragHelper.EndDrag();
|
|
||||||
|
|
||||||
_container.UpdateContainer(nullEnt);
|
|
||||||
|
|
||||||
if (nullEnt is not null)
|
|
||||||
{
|
|
||||||
// center it if we knock it off screen somehow.
|
|
||||||
if (!StaticStorageUIEnabled &&
|
|
||||||
(_lastContainerPosition == null ||
|
|
||||||
_lastContainerPosition.Value.X < 0 ||
|
|
||||||
_lastContainerPosition.Value.Y < 0 ||
|
|
||||||
_lastContainerPosition.Value.X > _ui.WindowRoot.Width ||
|
|
||||||
_lastContainerPosition.Value.Y > _ui.WindowRoot.Height))
|
|
||||||
{
|
|
||||||
_container.OpenCenteredAt(new Vector2(0.5f, 0.75f));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_container.Open();
|
|
||||||
|
|
||||||
var pos = !StaticStorageUIEnabled && _lastContainerPosition != null
|
|
||||||
? _lastContainerPosition.Value
|
|
||||||
: Vector2.Zero;
|
|
||||||
|
|
||||||
LayoutContainer.SetPosition(_container, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StaticStorageUIEnabled)
|
|
||||||
{
|
|
||||||
// we have to orphan it here because Open() sets the parent.
|
|
||||||
_container.Orphan();
|
|
||||||
Hotbar?.StorageContainer.AddChild(_container);
|
|
||||||
}
|
|
||||||
_lastContainerPosition = _container.GlobalPosition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_lastContainerPosition = _container.GlobalPosition;
|
|
||||||
_container.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnStaticStorageChanged(bool obj)
|
|
||||||
{
|
|
||||||
if (StaticStorageUIEnabled == obj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
StaticStorageUIEnabled = obj;
|
|
||||||
_lastContainerPosition = null;
|
|
||||||
|
|
||||||
if (_container == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!_container.IsOpen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_container.Orphan();
|
|
||||||
if (StaticStorageUIEnabled)
|
|
||||||
{
|
|
||||||
Hotbar?.StorageContainer.AddChild(_container);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_ui.WindowRoot.AddChild(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_entity.TryGetComponent<StorageComponent>(_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?
|
/// One might ask, Hey Emo, why are you parsing raw keyboard input just to rotate a rectangle?
|
||||||
@@ -190,7 +179,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
binding.Mod3 == Keyboard.Key.Control))
|
binding.Mod3 == Keyboard.Key.Control))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!IsDragging && _entity.System<HandsSystem>().GetActiveHandEntity() == null)
|
if (!IsDragging && EntityManager.System<HandsSystem>().GetActiveHandEntity() == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//clamp it to a cardinal.
|
//clamp it to a cardinal.
|
||||||
@@ -198,43 +187,18 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
if (DraggingGhost != null)
|
if (DraggingGhost != null)
|
||||||
DraggingGhost.Location.Rotation = DraggingRotation;
|
DraggingGhost.Location.Rotation = DraggingRotation;
|
||||||
|
|
||||||
if (IsDragging || (_container != null && UIManager.CurrentlyHovered == _container))
|
if (IsDragging || UIManager.CurrentlyHovered is StorageWindow)
|
||||||
keyEvent.Handle();
|
keyEvent.Handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStorageUpdated(Entity<StorageComponent> uid)
|
private void OnPiecePressed(GUIBoundKeyEventArgs args, StorageWindow window, ItemGridPiece control)
|
||||||
{
|
{
|
||||||
if (_container?.StorageEntity != uid)
|
if (IsDragging || !window.IsOpen)
|
||||||
return;
|
|
||||||
|
|
||||||
_container.BuildItemPieces();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterStorageContainer(StorageContainer container)
|
|
||||||
{
|
|
||||||
if (_container != null)
|
|
||||||
{
|
|
||||||
container.OnPiecePressed -= OnPiecePressed;
|
|
||||||
container.OnPieceUnpressed -= OnPieceUnpressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
_container = container;
|
|
||||||
container.OnPiecePressed += OnPiecePressed;
|
|
||||||
container.OnPieceUnpressed += OnPieceUnpressed;
|
|
||||||
|
|
||||||
if (!StaticStorageUIEnabled)
|
|
||||||
_container.Orphan();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPiecePressed(GUIBoundKeyEventArgs args, ItemGridPiece control)
|
|
||||||
{
|
|
||||||
if (IsDragging || !_container?.IsOpen == true)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (args.Function == ContentKeyFunctions.MoveStoredItem)
|
if (args.Function == ContentKeyFunctions.MoveStoredItem)
|
||||||
{
|
{
|
||||||
DraggingRotation = control.Location.Rotation;
|
DraggingRotation = control.Location.Rotation;
|
||||||
|
|
||||||
_menuDragHelper.MouseDown(control);
|
_menuDragHelper.MouseDown(control);
|
||||||
_menuDragHelper.Update(0f);
|
_menuDragHelper.Update(0f);
|
||||||
|
|
||||||
@@ -242,17 +206,17 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
}
|
}
|
||||||
else if (args.Function == ContentKeyFunctions.SaveItemLocation)
|
else if (args.Function == ContentKeyFunctions.SaveItemLocation)
|
||||||
{
|
{
|
||||||
if (_container?.StorageEntity is not {} storage)
|
if (window.StorageEntity is not {} storage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_entity.RaisePredictiveEvent(new StorageSaveItemLocationEvent(
|
EntityManager.RaisePredictiveEvent(new StorageSaveItemLocationEvent(
|
||||||
_entity.GetNetEntity(control.Entity),
|
EntityManager.GetNetEntity(control.Entity),
|
||||||
_entity.GetNetEntity(storage)));
|
EntityManager.GetNetEntity(storage)));
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
else if (args.Function == ContentKeyFunctions.ExamineEntity)
|
else if (args.Function == ContentKeyFunctions.ExamineEntity)
|
||||||
{
|
{
|
||||||
_entity.System<ExamineSystem>().DoExamine(control.Entity);
|
EntityManager.System<ExamineSystem>().DoExamine(control.Entity);
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
else if (args.Function == EngineKeyFunctions.UseSecondary)
|
else if (args.Function == EngineKeyFunctions.UseSecondary)
|
||||||
@@ -262,62 +226,102 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
}
|
}
|
||||||
else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
|
else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
|
||||||
{
|
{
|
||||||
_entity.RaisePredictiveEvent(
|
EntityManager.RaisePredictiveEvent(
|
||||||
new InteractInventorySlotEvent(_entity.GetNetEntity(control.Entity), altInteract: false));
|
new InteractInventorySlotEvent(EntityManager.GetNetEntity(control.Entity), altInteract: false));
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
else if (args.Function == ContentKeyFunctions.AltActivateItemInWorld)
|
else if (args.Function == ContentKeyFunctions.AltActivateItemInWorld)
|
||||||
{
|
{
|
||||||
_entity.RaisePredictiveEvent(new InteractInventorySlotEvent(_entity.GetNetEntity(control.Entity), altInteract: true));
|
EntityManager.RaisePredictiveEvent(new InteractInventorySlotEvent(EntityManager.GetNetEntity(control.Entity), altInteract: true));
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.FlagDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPieceUnpressed(GUIBoundKeyEventArgs args, ItemGridPiece control)
|
private void OnPieceUnpressed(GUIBoundKeyEventArgs args, StorageWindow window, ItemGridPiece control)
|
||||||
{
|
{
|
||||||
if (args.Function != ContentKeyFunctions.MoveStoredItem)
|
if (args.Function != ContentKeyFunctions.MoveStoredItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_container?.StorageEntity is not { } storageEnt|| !_entity.TryGetComponent<StorageComponent>(storageEnt, out var storageComp))
|
// Want to get the control under the dragged control.
|
||||||
return;
|
// This means we can drag the original control around (and not hide the original).
|
||||||
|
control.MouseFilter = Control.MouseFilterMode.Ignore;
|
||||||
|
var targetControl = UIManager.MouseGetControl(args.PointerLocation);
|
||||||
|
var targetStorage = targetControl as StorageWindow;
|
||||||
|
control.MouseFilter = Control.MouseFilterMode.Pass;
|
||||||
|
|
||||||
if (DraggingGhost is { } draggingGhost)
|
var localPlayer = _player.LocalEntity;
|
||||||
|
window.RemoveGrid(control);
|
||||||
|
window.FlagDirty();
|
||||||
|
|
||||||
|
// If we tried to drag it on top of another grid piece then cancel out.
|
||||||
|
if (targetControl is ItemGridPiece || window.StorageEntity is not { } sourceStorage || localPlayer == null)
|
||||||
|
{
|
||||||
|
window.Reclaim(control.Location, control);
|
||||||
|
args.Handle();
|
||||||
|
_menuDragHelper.EndDrag();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_menuDragHelper.IsDragging && DraggingGhost is { } draggingGhost)
|
||||||
{
|
{
|
||||||
var dragEnt = draggingGhost.Entity;
|
var dragEnt = draggingGhost.Entity;
|
||||||
var dragLoc = draggingGhost.Location;
|
var dragLoc = draggingGhost.Location;
|
||||||
var itemSys = _entity.System<SharedItemSystem>();
|
|
||||||
|
|
||||||
var position = _container.GetMouseGridPieceLocation(dragEnt, dragLoc);
|
// Dragging in the same storage
|
||||||
var itemBounding = itemSys.GetAdjustedItemShape(dragEnt, dragLoc).GetBoundingBox();
|
// The existing ItemGridPiece just stops rendering but still exists so check if it's hovered.
|
||||||
var gridBounding = storageComp.Grid.GetBoundingBox();
|
if (targetStorage == window)
|
||||||
|
|
||||||
// The extended bounding box for if this is out of the window is the grid bounding box dimensions combined
|
|
||||||
// with the item shape bounding box dimensions. Plus 1 on the left for the sidebar. This makes it so that.
|
|
||||||
// dropping an item on the floor requires dragging it all the way out of the window.
|
|
||||||
var left = gridBounding.Left - itemBounding.Width - 1;
|
|
||||||
var bottom = gridBounding.Bottom - itemBounding.Height;
|
|
||||||
var top = gridBounding.Top;
|
|
||||||
var right = gridBounding.Right;
|
|
||||||
var lenientBounding = new Box2i(left, bottom, right, top);
|
|
||||||
|
|
||||||
if (lenientBounding.Contains(position))
|
|
||||||
{
|
{
|
||||||
_entity.RaisePredictiveEvent(new StorageSetItemLocationEvent(
|
var position = targetStorage.GetMouseGridPieceLocation(dragEnt, dragLoc);
|
||||||
_entity.GetNetEntity(draggingGhost.Entity),
|
var newLocation = new ItemStorageLocation(DraggingRotation, position);
|
||||||
_entity.GetNetEntity(storageEnt),
|
|
||||||
new ItemStorageLocation(DraggingRotation, position)));
|
EntityManager.RaisePredictiveEvent(new StorageSetItemLocationEvent(
|
||||||
|
EntityManager.GetNetEntity(draggingGhost.Entity),
|
||||||
|
EntityManager.GetNetEntity(sourceStorage),
|
||||||
|
newLocation));
|
||||||
|
|
||||||
|
window.Reclaim(newLocation, control);
|
||||||
|
}
|
||||||
|
// Dragging to new storage
|
||||||
|
else if (targetStorage?.StorageEntity != null && targetStorage != window)
|
||||||
|
{
|
||||||
|
var position = targetStorage.GetMouseGridPieceLocation(dragEnt, dragLoc);
|
||||||
|
var newLocation = new ItemStorageLocation(DraggingRotation, position);
|
||||||
|
|
||||||
|
// Check it fits and we can move to hand (no free transfers).
|
||||||
|
if (_storage.ItemFitsInGridLocation(
|
||||||
|
(dragEnt, null),
|
||||||
|
(targetStorage.StorageEntity.Value, null),
|
||||||
|
newLocation))
|
||||||
|
{
|
||||||
|
// Can drop and move.
|
||||||
|
EntityManager.RaisePredictiveEvent(new StorageTransferItemEvent(
|
||||||
|
EntityManager.GetNetEntity(dragEnt),
|
||||||
|
EntityManager.GetNetEntity(targetStorage.StorageEntity.Value),
|
||||||
|
newLocation));
|
||||||
|
|
||||||
|
targetStorage.Reclaim(newLocation, control);
|
||||||
|
DraggingRotation = Angle.Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Cancel it (rather than dropping).
|
||||||
|
window.Reclaim(dragLoc, control);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_menuDragHelper.EndDrag();
|
targetStorage?.FlagDirty();
|
||||||
_container?.BuildItemPieces();
|
|
||||||
}
|
}
|
||||||
else //if we just clicked, then take it out of the bag.
|
// If we just clicked, then take it out of the bag.
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_menuDragHelper.EndDrag();
|
EntityManager.RaisePredictiveEvent(new StorageInteractWithItemEvent(
|
||||||
_entity.RaisePredictiveEvent(new StorageInteractWithItemEvent(
|
EntityManager.GetNetEntity(control.Entity),
|
||||||
_entity.GetNetEntity(control.Entity),
|
EntityManager.GetNetEntity(sourceStorage)));
|
||||||
_entity.GetNetEntity(storageEnt)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_menuDragHelper.EndDrag();
|
||||||
args.Handle();
|
args.Handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,14 +330,8 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
if (_menuDragHelper.Dragged is not { } dragged)
|
if (_menuDragHelper.Dragged is not { } dragged)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
DraggingGhost!.Orphan();
|
||||||
DraggingRotation = dragged.Location.Rotation;
|
DraggingRotation = dragged.Location.Rotation;
|
||||||
DraggingGhost = new ItemGridPiece(
|
|
||||||
(dragged.Entity, _entity.GetComponent<ItemComponent>(dragged.Entity)),
|
|
||||||
dragged.Location,
|
|
||||||
_entity);
|
|
||||||
DraggingGhost.MouseFilter = Control.MouseFilterMode.Ignore;
|
|
||||||
DraggingGhost.Visible = true;
|
|
||||||
DraggingGhost.Orphan();
|
|
||||||
|
|
||||||
UIManager.PopupRoot.AddChild(DraggingGhost);
|
UIManager.PopupRoot.AddChild(DraggingGhost);
|
||||||
SetDraggingRotation();
|
SetDraggingRotation();
|
||||||
@@ -344,6 +342,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
{
|
{
|
||||||
if (DraggingGhost == null)
|
if (DraggingGhost == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SetDraggingRotation();
|
SetDraggingRotation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -356,7 +355,7 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
var offset = ItemGridPiece.GetCenterOffset(
|
var offset = ItemGridPiece.GetCenterOffset(
|
||||||
(DraggingGhost.Entity, null),
|
(DraggingGhost.Entity, null),
|
||||||
new ItemStorageLocation(DraggingRotation, Vector2i.Zero),
|
new ItemStorageLocation(DraggingRotation, Vector2i.Zero),
|
||||||
_entity);
|
EntityManager);
|
||||||
|
|
||||||
// I don't know why it divides the position by 2. Hope this helps! -emo
|
// I don't know why it divides the position by 2. Hope this helps! -emo
|
||||||
LayoutContainer.SetPosition(DraggingGhost, UIManager.MousePositionScaled.Position / 2 - offset );
|
LayoutContainer.SetPosition(DraggingGhost, UIManager.MousePositionScaled.Position / 2 - offset );
|
||||||
@@ -366,18 +365,13 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
|||||||
{
|
{
|
||||||
if (DraggingGhost == null)
|
if (DraggingGhost == null)
|
||||||
return;
|
return;
|
||||||
DraggingGhost.Visible = false;
|
|
||||||
DraggingGhost = null;
|
|
||||||
DraggingRotation = Angle.Zero;
|
DraggingRotation = Angle.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FrameUpdate(FrameEventArgs args)
|
public override void FrameUpdate(FrameEventArgs args)
|
||||||
{
|
{
|
||||||
base.FrameUpdate(args);
|
base.FrameUpdate(args);
|
||||||
|
|
||||||
_menuDragHelper.Update(args.DeltaSeconds);
|
_menuDragHelper.Update(args.DeltaSeconds);
|
||||||
|
|
||||||
if (!StaticStorageUIEnabled && _container?.Parent != null && _lastContainerPosition != null)
|
|
||||||
_lastContainerPosition = _container.GlobalPosition;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace Content.Client.Viewport
|
|||||||
_inputManager.ViewportKeyEvent(this, args);
|
_inputManager.ViewportKeyEvent(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Draw(DrawingHandleScreen handle)
|
protected override void Draw(IRenderHandle handle)
|
||||||
{
|
{
|
||||||
EnsureViewportCreated();
|
EnsureViewportCreated();
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ namespace Content.Client.Viewport
|
|||||||
var drawBox = GetDrawBox();
|
var drawBox = GetDrawBox();
|
||||||
var drawBoxGlobal = drawBox.Translated(GlobalPixelPosition);
|
var drawBoxGlobal = drawBox.Translated(GlobalPixelPosition);
|
||||||
_viewport.RenderScreenOverlaysBelow(handle, this, drawBoxGlobal);
|
_viewport.RenderScreenOverlaysBelow(handle, this, drawBoxGlobal);
|
||||||
handle.DrawTextureRect(_viewport.RenderTarget.Texture, drawBox);
|
handle.DrawingHandleScreen.DrawTextureRect(_viewport.RenderTarget.Texture, drawBox);
|
||||||
_viewport.RenderScreenOverlaysAbove(handle, this, drawBoxGlobal);
|
_viewport.RenderScreenOverlaysAbove(handle, this, drawBoxGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,23 @@ public sealed partial class CCVars
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<bool> OpaqueStorageWindow =
|
public static readonly CVarDef<bool> OpaqueStorageWindow =
|
||||||
CVarDef.Create("control.opaque_storage_background", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
CVarDef.Create("control.opaque_storage_background", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not the storage window has a title of the entity name.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> StorageWindowTitle =
|
||||||
|
CVarDef.Create("control.storage_window_title", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many storage windows are allowed to be open at once.
|
||||||
|
/// Recommended that you utilise this in conjunction with <see cref="StaticStorageUI"/>
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<int> StorageLimit =
|
||||||
|
CVarDef.Create("control.storage_limit", 1, CVar.REPLICATED | CVar.SERVER);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether or not storage can be opened recursively.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> NestedStorage =
|
||||||
|
CVarDef.Create("control.nested_storage", true, CVar.REPLICATED | CVar.SERVER);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Administration.Logs;
|
using Content.Shared.Administration.Logs;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Destructible;
|
using Content.Shared.Destructible;
|
||||||
@@ -27,6 +28,7 @@ using Content.Shared.Verbs;
|
|||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
@@ -35,36 +37,46 @@ using Robust.Shared.Player;
|
|||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Storage.EntitySystems;
|
namespace Content.Shared.Storage.EntitySystems;
|
||||||
|
|
||||||
public abstract class SharedStorageSystem : EntitySystem
|
public abstract class SharedStorageSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||||
|
[Dependency] protected readonly IGameTiming Timing = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
[Dependency] protected readonly IRobustRandom Random = default!;
|
[Dependency] protected readonly IRobustRandom Random = default!;
|
||||||
|
[Dependency] private readonly ISharedAdminLogManager _adminLog = default!;
|
||||||
|
|
||||||
[Dependency] protected readonly ActionBlockerSystem ActionBlocker = default!;
|
[Dependency] protected readonly ActionBlockerSystem ActionBlocker = default!;
|
||||||
[Dependency] private readonly EntityLookupSystem _entityLookupSystem = default!;
|
[Dependency] private readonly EntityLookupSystem _entityLookupSystem = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||||
|
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||||
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
[Dependency] protected readonly SharedContainerSystem ContainerSystem = default!;
|
||||||
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||||
[Dependency] protected readonly SharedEntityStorageSystem EntityStorage = default!;
|
[Dependency] protected readonly SharedEntityStorageSystem EntityStorage = default!;
|
||||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
|
||||||
[Dependency] protected readonly SharedItemSystem ItemSystem = default!;
|
[Dependency] protected readonly SharedItemSystem ItemSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
|
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
|
||||||
[Dependency] private readonly SharedStackSystem _stack = default!;
|
[Dependency] private readonly SharedStackSystem _stack = default!;
|
||||||
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
|
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
|
||||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
[Dependency] protected readonly SharedUserInterfaceSystem UI = default!;
|
||||||
[Dependency] protected readonly UseDelaySystem UseDelay = default!;
|
[Dependency] protected readonly UseDelaySystem UseDelay = default!;
|
||||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLog = default!;
|
|
||||||
|
|
||||||
private EntityQuery<ItemComponent> _itemQuery;
|
private EntityQuery<ItemComponent> _itemQuery;
|
||||||
private EntityQuery<StackComponent> _stackQuery;
|
private EntityQuery<StackComponent> _stackQuery;
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
private EntityQuery<TransformComponent> _xformQuery;
|
||||||
|
private EntityQuery<UserInterfaceUserComponent> _userQuery;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether we're allowed to go up-down storage via UI.
|
||||||
|
/// </summary>
|
||||||
|
public bool NestedStorage = true;
|
||||||
|
|
||||||
[ValidatePrototypeId<ItemSizePrototype>]
|
[ValidatePrototypeId<ItemSizePrototype>]
|
||||||
public const string DefaultStorageMaxItemSize = "Normal";
|
public const string DefaultStorageMaxItemSize = "Normal";
|
||||||
@@ -76,10 +88,15 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
private ItemSizePrototype _defaultStorageMaxItemSize = default!;
|
private ItemSizePrototype _defaultStorageMaxItemSize = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flag for whether we're checking for nested storage interactions.
|
||||||
|
/// </summary>
|
||||||
|
private bool _nestedCheck;
|
||||||
|
|
||||||
public bool CheckingCanInsert;
|
public bool CheckingCanInsert;
|
||||||
|
|
||||||
private List<EntityUid> _entList = new();
|
private readonly List<EntityUid> _entList = new();
|
||||||
private HashSet<EntityUid> _entSet = new();
|
private readonly HashSet<EntityUid> _entSet = new();
|
||||||
|
|
||||||
private readonly List<ItemSizePrototype> _sortedSizes = new();
|
private readonly List<ItemSizePrototype> _sortedSizes = new();
|
||||||
private FrozenDictionary<string, ItemSizePrototype> _nextSmallest = FrozenDictionary<string, ItemSizePrototype>.Empty;
|
private FrozenDictionary<string, ItemSizePrototype> _nextSmallest = FrozenDictionary<string, ItemSizePrototype>.Empty;
|
||||||
@@ -87,6 +104,11 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
private const string QuickInsertUseDelayID = "quickInsert";
|
private const string QuickInsertUseDelayID = "quickInsert";
|
||||||
private const string OpenUiUseDelayID = "storage";
|
private const string OpenUiUseDelayID = "storage";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many storage windows are allowed to be open at once.
|
||||||
|
/// </summary>
|
||||||
|
private int _openStorageLimit = -1;
|
||||||
|
|
||||||
protected readonly List<string> CantFillReasons = [];
|
protected readonly List<string> CantFillReasons = [];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -97,8 +119,11 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
_itemQuery = GetEntityQuery<ItemComponent>();
|
_itemQuery = GetEntityQuery<ItemComponent>();
|
||||||
_stackQuery = GetEntityQuery<StackComponent>();
|
_stackQuery = GetEntityQuery<StackComponent>();
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
_userQuery = GetEntityQuery<UserInterfaceUserComponent>();
|
||||||
_prototype.PrototypesReloaded += OnPrototypesReloaded;
|
_prototype.PrototypesReloaded += OnPrototypesReloaded;
|
||||||
|
|
||||||
|
Subs.CVar(_cfg, CCVars.StorageLimit, OnStorageLimitChanged, true);
|
||||||
|
|
||||||
Subs.BuiEvents<StorageComponent>(StorageComponent.StorageUiKey.Key, subs =>
|
Subs.BuiEvents<StorageComponent>(StorageComponent.StorageUiKey.Key, subs =>
|
||||||
{
|
{
|
||||||
subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
|
subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
|
||||||
@@ -108,7 +133,6 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<StorageComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<StorageComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<StorageComponent, GetVerbsEvent<ActivationVerb>>(AddUiVerb);
|
SubscribeLocalEvent<StorageComponent, GetVerbsEvent<ActivationVerb>>(AddUiVerb);
|
||||||
SubscribeLocalEvent<StorageComponent, ComponentGetState>(OnStorageGetState);
|
SubscribeLocalEvent<StorageComponent, ComponentGetState>(OnStorageGetState);
|
||||||
SubscribeLocalEvent<StorageComponent, ComponentHandleState>(OnStorageHandleState);
|
|
||||||
SubscribeLocalEvent<StorageComponent, ComponentInit>(OnComponentInit, before: new[] { typeof(SharedContainerSystem) });
|
SubscribeLocalEvent<StorageComponent, ComponentInit>(OnComponentInit, before: new[] { typeof(SharedContainerSystem) });
|
||||||
SubscribeLocalEvent<StorageComponent, GetVerbsEvent<UtilityVerb>>(AddTransferVerbs);
|
SubscribeLocalEvent<StorageComponent, GetVerbsEvent<UtilityVerb>>(AddTransferVerbs);
|
||||||
SubscribeLocalEvent<StorageComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(ItemSlotsSystem) });
|
SubscribeLocalEvent<StorageComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(ItemSlotsSystem) });
|
||||||
@@ -116,6 +140,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<StorageComponent, OpenStorageImplantEvent>(OnImplantActivate);
|
SubscribeLocalEvent<StorageComponent, OpenStorageImplantEvent>(OnImplantActivate);
|
||||||
SubscribeLocalEvent<StorageComponent, AfterInteractEvent>(AfterInteract);
|
SubscribeLocalEvent<StorageComponent, AfterInteractEvent>(AfterInteract);
|
||||||
SubscribeLocalEvent<StorageComponent, DestructionEventArgs>(OnDestroy);
|
SubscribeLocalEvent<StorageComponent, DestructionEventArgs>(OnDestroy);
|
||||||
|
SubscribeLocalEvent<BoundUserInterfaceMessageAttempt>(OnBoundUIAttempt);
|
||||||
SubscribeLocalEvent<StorageComponent, BoundUIOpenedEvent>(OnBoundUIOpen);
|
SubscribeLocalEvent<StorageComponent, BoundUIOpenedEvent>(OnBoundUIOpen);
|
||||||
SubscribeLocalEvent<StorageComponent, LockToggledEvent>(OnLockToggled);
|
SubscribeLocalEvent<StorageComponent, LockToggledEvent>(OnLockToggled);
|
||||||
SubscribeLocalEvent<MetaDataComponent, StackCountChangedEvent>(OnStackCountChanged);
|
SubscribeLocalEvent<MetaDataComponent, StackCountChangedEvent>(OnStackCountChanged);
|
||||||
@@ -126,6 +151,8 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<StorageComponent, AreaPickupDoAfterEvent>(OnDoAfter);
|
SubscribeLocalEvent<StorageComponent, AreaPickupDoAfterEvent>(OnDoAfter);
|
||||||
|
|
||||||
|
SubscribeAllEvent<OpenNestedStorageEvent>(OnStorageNested);
|
||||||
|
SubscribeAllEvent<StorageTransferItemEvent>(OnStorageTransfer);
|
||||||
SubscribeAllEvent<StorageInteractWithItemEvent>(OnInteractWithItem);
|
SubscribeAllEvent<StorageInteractWithItemEvent>(OnInteractWithItem);
|
||||||
SubscribeAllEvent<StorageSetItemLocationEvent>(OnSetItemLocation);
|
SubscribeAllEvent<StorageSetItemLocationEvent>(OnSetItemLocation);
|
||||||
SubscribeAllEvent<StorageInsertItemIntoLocationEvent>(OnInsertItemIntoLocation);
|
SubscribeAllEvent<StorageInsertItemIntoLocationEvent>(OnInsertItemIntoLocation);
|
||||||
@@ -138,12 +165,24 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
.Bind(ContentKeyFunctions.OpenBelt, InputCmdHandler.FromDelegate(HandleOpenBelt, handle: false))
|
.Bind(ContentKeyFunctions.OpenBelt, InputCmdHandler.FromDelegate(HandleOpenBelt, handle: false))
|
||||||
.Register<SharedStorageSystem>();
|
.Register<SharedStorageSystem>();
|
||||||
|
|
||||||
|
Subs.CVar(_cfg, CCVars.NestedStorage, OnNestedStorageCvar, true);
|
||||||
|
|
||||||
UpdatePrototypeCache();
|
UpdatePrototypeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnNestedStorageCvar(bool obj)
|
||||||
|
{
|
||||||
|
NestedStorage = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStorageLimitChanged(int obj)
|
||||||
|
{
|
||||||
|
_openStorageLimit = obj;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnRemove(Entity<StorageComponent> entity, ref ComponentRemove args)
|
private void OnRemove(Entity<StorageComponent> entity, ref ComponentRemove args)
|
||||||
{
|
{
|
||||||
_ui.CloseUi(entity.Owner, StorageComponent.StorageUiKey.Key);
|
UI.CloseUi(entity.Owner, StorageComponent.StorageUiKey.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(Entity<StorageComponent> entity, ref MapInitEvent args)
|
private void OnMapInit(Entity<StorageComponent> entity, ref MapInitEvent args)
|
||||||
@@ -172,28 +211,6 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStorageHandleState(EntityUid uid, StorageComponent component, ref ComponentHandleState args)
|
|
||||||
{
|
|
||||||
if (args.Current is not StorageComponentState state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
component.Grid.Clear();
|
|
||||||
component.Grid.AddRange(state.Grid);
|
|
||||||
component.MaxItemSize = state.MaxItemSize;
|
|
||||||
component.Whitelist = state.Whitelist;
|
|
||||||
component.Blacklist = state.Blacklist;
|
|
||||||
|
|
||||||
component.StoredItems.Clear();
|
|
||||||
|
|
||||||
foreach (var (nent, location) in state.StoredItems)
|
|
||||||
{
|
|
||||||
var ent = EnsureEntity<StorageComponent>(nent, uid);
|
|
||||||
component.StoredItems[ent] = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
component.SavedLocations = state.SavedLocations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
_prototype.PrototypesReloaded -= OnPrototypesReloaded;
|
_prototype.PrototypesReloaded -= OnPrototypesReloaded;
|
||||||
@@ -228,7 +245,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnComponentInit(EntityUid uid, StorageComponent storageComp, ComponentInit args)
|
private void OnComponentInit(EntityUid uid, StorageComponent storageComp, ComponentInit args)
|
||||||
{
|
{
|
||||||
storageComp.Container = _containerSystem.EnsureContainer<Container>(uid, StorageComponent.ContainerId);
|
storageComp.Container = ContainerSystem.EnsureContainer<Container>(uid, StorageComponent.ContainerId);
|
||||||
UpdateAppearance((uid, storageComp, null));
|
UpdateAppearance((uid, storageComp, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +264,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
// close ui
|
// close ui
|
||||||
foreach (var entity in storageComp.Container.ContainedEntities)
|
foreach (var entity in storageComp.Container.ContainedEntities)
|
||||||
{
|
{
|
||||||
_ui.CloseUis(entity, actor);
|
UI.CloseUis(entity, actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +273,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
CloseNestedInterfaces(uid, args.Actor, storageComp);
|
CloseNestedInterfaces(uid, args.Actor, storageComp);
|
||||||
|
|
||||||
// If UI is closed for everyone
|
// If UI is closed for everyone
|
||||||
if (!_ui.IsUiOpen(uid, args.UiKey))
|
if (!UI.IsUiOpen(uid, args.UiKey))
|
||||||
{
|
{
|
||||||
UpdateAppearance((uid, storageComp, null));
|
UpdateAppearance((uid, storageComp, null));
|
||||||
Audio.PlayPredicted(storageComp.StorageCloseSound, uid, args.Actor);
|
Audio.PlayPredicted(storageComp.StorageCloseSound, uid, args.Actor);
|
||||||
@@ -269,7 +286,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Does this player currently have the storage UI open?
|
// Does this player currently have the storage UI open?
|
||||||
var uiOpen = _ui.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.User);
|
var uiOpen = UI.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.User);
|
||||||
|
|
||||||
ActivationVerb verb = new()
|
ActivationVerb verb = new()
|
||||||
{
|
{
|
||||||
@@ -277,7 +294,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (uiOpen)
|
if (uiOpen)
|
||||||
{
|
{
|
||||||
_ui.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.User);
|
UI.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.User);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -315,16 +332,16 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
if (!CanInteract(entity, (uid, storageComp), silent: silent))
|
if (!CanInteract(entity, (uid, storageComp), silent: silent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!UI.TryOpenUi(uid, StorageComponent.StorageUiKey.Key, entity))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
if (!_ui.IsUiOpen(uid, StorageComponent.StorageUiKey.Key))
|
Audio.PlayPredicted(storageComp.StorageOpenSound, uid, entity);
|
||||||
Audio.PlayPredicted(storageComp.StorageOpenSound, uid, entity);
|
|
||||||
|
|
||||||
if (useDelay != null)
|
if (useDelay != null)
|
||||||
UseDelay.TryResetDelay((uid, useDelay), id: OpenUiUseDelayID);
|
UseDelay.TryResetDelay((uid, useDelay), id: OpenUiUseDelayID);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ui.OpenUi(uid, StorageComponent.StorageUiKey.Key, entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UpdateUI(Entity<StorageComponent?> entity) {}
|
public virtual void UpdateUI(Entity<StorageComponent?> entity) {}
|
||||||
@@ -384,18 +401,43 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Toggle
|
// Toggle
|
||||||
if (_ui.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.User))
|
if (UI.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.User))
|
||||||
{
|
{
|
||||||
_ui.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.User);
|
UI.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.User);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OpenStorageUI(uid, args.User, storageComp, false);
|
// Handle recursively opening nested storages.
|
||||||
|
if (ContainerSystem.TryGetContainingContainer((args.Target, null, null), out var container) &&
|
||||||
|
UI.IsUiOpen(container.Owner, StorageComponent.StorageUiKey.Key, args.User))
|
||||||
|
{
|
||||||
|
_nestedCheck = true;
|
||||||
|
HideStorageWindow(container.Owner, args.User);
|
||||||
|
OpenStorageUI(uid, args.User, storageComp, silent: true);
|
||||||
|
_nestedCheck = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If you need something more sophisticated for multi-UI you'll need to code some smarter
|
||||||
|
// interactions.
|
||||||
|
if (_openStorageLimit == 1)
|
||||||
|
UI.CloseUserUis<StorageComponent.StorageUiKey>(args.User);
|
||||||
|
|
||||||
|
OpenStorageUI(uid, args.User, storageComp, silent: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void HideStorageWindow(EntityUid uid, EntityUid actor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void ShowStorageWindow(EntityUid uid, EntityUid actor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Specifically for storage implants.
|
/// Specifically for storage implants.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -404,10 +446,10 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
if (args.Handled)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var uiOpen = _ui.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.Performer);
|
var uiOpen = UI.IsUiOpen(uid, StorageComponent.StorageUiKey.Key, args.Performer);
|
||||||
|
|
||||||
if (uiOpen)
|
if (uiOpen)
|
||||||
_ui.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.Performer);
|
UI.CloseUi(uid, StorageComponent.StorageUiKey.Key, args.Performer);
|
||||||
else
|
else
|
||||||
OpenStorageUI(uid, args.Performer, storageComp, false);
|
OpenStorageUI(uid, args.Performer, storageComp, false);
|
||||||
|
|
||||||
@@ -474,7 +516,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
if (args.Target is not { Valid: true } target)
|
if (args.Target is not { Valid: true } target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_containerSystem.IsEntityInContainer(target)
|
if (ContainerSystem.IsEntityInContainer(target)
|
||||||
|| target == args.User
|
|| target == args.User
|
||||||
|| !_itemQuery.HasComponent(target))
|
|| !_itemQuery.HasComponent(target))
|
||||||
{
|
{
|
||||||
@@ -525,7 +567,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
var entity = GetEntity(args.Entities[i]);
|
var entity = GetEntity(args.Entities[i]);
|
||||||
|
|
||||||
// Check again, situation may have changed for some entities, but we'll still pick up any that are valid
|
// Check again, situation may have changed for some entities, but we'll still pick up any that are valid
|
||||||
if (_containerSystem.IsEntityInContainer(entity)
|
if (ContainerSystem.IsEntityInContainer(entity)
|
||||||
|| entity == args.Args.User
|
|| entity == args.Args.User
|
||||||
|| !_itemQuery.HasComponent(entity))
|
|| !_itemQuery.HasComponent(entity))
|
||||||
{
|
{
|
||||||
@@ -570,7 +612,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnReclaimed(EntityUid uid, StorageComponent storageComp, GotReclaimedEvent args)
|
private void OnReclaimed(EntityUid uid, StorageComponent storageComp, GotReclaimedEvent args)
|
||||||
{
|
{
|
||||||
_containerSystem.EmptyContainer(storageComp.Container, destination: args.ReclaimerCoordinates);
|
ContainerSystem.EmptyContainer(storageComp.Container, destination: args.ReclaimerCoordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy(EntityUid uid, StorageComponent storageComp, DestructionEventArgs args)
|
private void OnDestroy(EntityUid uid, StorageComponent storageComp, DestructionEventArgs args)
|
||||||
@@ -578,7 +620,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
var coordinates = TransformSystem.GetMoverCoordinates(uid);
|
var coordinates = TransformSystem.GetMoverCoordinates(uid);
|
||||||
|
|
||||||
// Being destroyed so need to recalculate.
|
// Being destroyed so need to recalculate.
|
||||||
_containerSystem.EmptyContainer(storageComp.Container, destination: coordinates);
|
ContainerSystem.EmptyContainer(storageComp.Container, destination: coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -638,6 +680,54 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
TrySetItemStorageLocation(item!, storage!, msg.Location);
|
TrySetItemStorageLocation(item!, storage!, msg.Location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnStorageNested(OpenNestedStorageEvent msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
if (!NestedStorage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryGetEntity(msg.InteractedItemUid, out var itemEnt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_nestedCheck = true;
|
||||||
|
|
||||||
|
var result = ValidateInput(args,
|
||||||
|
msg.StorageUid,
|
||||||
|
msg.InteractedItemUid,
|
||||||
|
out var player,
|
||||||
|
out var storage,
|
||||||
|
out var item);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
_nestedCheck = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HideStorageWindow(storage.Owner, player.Owner);
|
||||||
|
OpenStorageUI(item.Owner, player.Owner, silent: true);
|
||||||
|
_nestedCheck = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStorageTransfer(StorageTransferItemEvent msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
if (!TryGetEntity(msg.ItemEnt, out var itemEnt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var localPlayer = args.SenderSession.AttachedEntity;
|
||||||
|
|
||||||
|
if (!TryComp(localPlayer, out HandsComponent? handsComp) || !_sharedHandsSystem.TryPickup(localPlayer.Value, itemEnt.Value, handsComp: handsComp, animate: false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ValidateInput(args, msg.StorageEnt, msg.ItemEnt, out var player, out var storage, out var item, held: true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_adminLog.Add(
|
||||||
|
LogType.Storage,
|
||||||
|
LogImpact.Low,
|
||||||
|
$"{ToPrettyString(player):player} is inserting {ToPrettyString(item):item} into {ToPrettyString(storage):storage}");
|
||||||
|
InsertAt(storage!, item!, msg.Location, out _, player, stackAutomatically: false);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnInsertItemIntoLocation(StorageInsertItemIntoLocationEvent msg, EntitySessionEventArgs args)
|
private void OnInsertItemIntoLocation(StorageInsertItemIntoLocationEvent msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (!ValidateInput(args, msg.StorageEnt, msg.ItemEnt, out var player, out var storage, out var item, held: true))
|
if (!ValidateInput(args, msg.StorageEnt, msg.ItemEnt, out var player, out var storage, out var item, held: true))
|
||||||
@@ -658,9 +748,46 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
SaveItemLocation(storage!, item.Owner);
|
SaveItemLocation(storage!, item.Owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBoundUIOpen(EntityUid uid, StorageComponent storageComp, BoundUIOpenedEvent args)
|
private void OnBoundUIOpen(Entity<StorageComponent> ent, ref BoundUIOpenedEvent args)
|
||||||
{
|
{
|
||||||
UpdateAppearance((uid, storageComp, null));
|
UpdateAppearance((ent.Owner, ent.Comp, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBoundUIAttempt(BoundUserInterfaceMessageAttempt args)
|
||||||
|
{
|
||||||
|
if (args.UiKey is not StorageComponent.StorageUiKey.Key ||
|
||||||
|
_openStorageLimit == -1 ||
|
||||||
|
_nestedCheck ||
|
||||||
|
args.Message is not OpenBoundInterfaceMessage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var uid = args.Target;
|
||||||
|
var actor = args.Actor;
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
if (_userQuery.TryComp(actor, out var userComp))
|
||||||
|
{
|
||||||
|
foreach (var (ui, keys) in userComp.OpenInterfaces)
|
||||||
|
{
|
||||||
|
if (ui == uid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var key in keys)
|
||||||
|
{
|
||||||
|
if (key is not StorageComponent.StorageUiKey)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count >= _openStorageLimit)
|
||||||
|
{
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEntInserted(Entity<StorageComponent> entity, ref EntInsertedIntoContainerMessage args)
|
private void OnEntInserted(Entity<StorageComponent> entity, ref EntInsertedIntoContainerMessage args)
|
||||||
@@ -676,7 +803,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (!TryGetAvailableGridSpace((entity.Owner, entity.Comp), (args.Entity, null), out var location))
|
if (!TryGetAvailableGridSpace((entity.Owner, entity.Comp), (args.Entity, null), out var location))
|
||||||
{
|
{
|
||||||
_containerSystem.Remove(args.Entity, args.Container, force: true);
|
ContainerSystem.Remove(args.Entity, args.Container, force: true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +865,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
var capacity = storage.Grid.GetArea();
|
var capacity = storage.Grid.GetArea();
|
||||||
var used = GetCumulativeItemAreas((uid, storage));
|
var used = GetCumulativeItemAreas((uid, storage));
|
||||||
|
|
||||||
var isOpen = _ui.IsUiOpen(entity.Owner, StorageComponent.StorageUiKey.Key);
|
var isOpen = UI.IsUiOpen(entity.Owner, StorageComponent.StorageUiKey.Key);
|
||||||
|
|
||||||
_appearance.SetData(uid, StorageVisuals.StorageUsed, used, appearance);
|
_appearance.SetData(uid, StorageVisuals.StorageUsed, used, appearance);
|
||||||
_appearance.SetData(uid, StorageVisuals.Capacity, capacity, appearance);
|
_appearance.SetData(uid, StorageVisuals.Capacity, capacity, appearance);
|
||||||
@@ -848,7 +975,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckingCanInsert = true;
|
CheckingCanInsert = true;
|
||||||
if (!_containerSystem.CanInsert(insertEnt, storageComp.Container))
|
if (!ContainerSystem.CanInsert(insertEnt, storageComp.Container))
|
||||||
{
|
{
|
||||||
CheckingCanInsert = false;
|
CheckingCanInsert = false;
|
||||||
reason = null;
|
reason = null;
|
||||||
@@ -949,7 +1076,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
if (!stackAutomatically || !_stackQuery.TryGetComponent(insertEnt, out var insertStack))
|
if (!stackAutomatically || !_stackQuery.TryGetComponent(insertEnt, out var insertStack))
|
||||||
{
|
{
|
||||||
if (!_containerSystem.Insert(insertEnt, storageComp.Container))
|
if (!ContainerSystem.Insert(insertEnt, storageComp.Container))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (playSound)
|
if (playSound)
|
||||||
@@ -975,7 +1102,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
|
|
||||||
// Still stackable remaining
|
// Still stackable remaining
|
||||||
if (insertStack.Count > 0
|
if (insertStack.Count > 0
|
||||||
&& !_containerSystem.Insert(insertEnt, storageComp.Container)
|
&& !ContainerSystem.Insert(insertEnt, storageComp.Container)
|
||||||
&& toInsertCount == insertStack.Count)
|
&& toInsertCount == insertStack.Count)
|
||||||
{
|
{
|
||||||
// Failed to insert anything.
|
// Failed to insert anything.
|
||||||
@@ -1054,6 +1181,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
storageEnt.Comp.StoredItems[itemEnt] = location;
|
storageEnt.Comp.StoredItems[itemEnt] = location;
|
||||||
|
UpdateUI(storageEnt);
|
||||||
Dirty(storageEnt, storageEnt.Comp);
|
Dirty(storageEnt, storageEnt.Comp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1186,6 +1314,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
Dirty(ent, ent.Comp);
|
Dirty(ent, ent.Comp);
|
||||||
|
UpdateUI((ent.Owner, ent.Comp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1357,16 +1486,16 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Gets everyone looking at the UI
|
// Gets everyone looking at the UI
|
||||||
foreach (var actor in _ui.GetActors(uid, StorageComponent.StorageUiKey.Key).ToList())
|
foreach (var actor in UI.GetActors(uid, StorageComponent.StorageUiKey.Key).ToList())
|
||||||
{
|
{
|
||||||
if (!CanInteract(actor, (uid, component)))
|
if (!CanInteract(actor, (uid, component)))
|
||||||
_ui.CloseUi(uid, StorageComponent.StorageUiKey.Key, actor);
|
UI.CloseUi(uid, StorageComponent.StorageUiKey.Key, actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStackCountChanged(EntityUid uid, MetaDataComponent component, StackCountChangedEvent args)
|
private void OnStackCountChanged(EntityUid uid, MetaDataComponent component, StackCountChangedEvent args)
|
||||||
{
|
{
|
||||||
if (_containerSystem.TryGetContainingContainer((uid, null, component), out var container) &&
|
if (ContainerSystem.TryGetContainingContainer((uid, null, component), out var container) &&
|
||||||
container.ID == StorageComponent.ContainerId)
|
container.ID == StorageComponent.ContainerId)
|
||||||
{
|
{
|
||||||
UpdateAppearance(container.Owner);
|
UpdateAppearance(container.Owner);
|
||||||
@@ -1398,13 +1527,13 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
if (!ActionBlocker.CanInteract(playerEnt, storageEnt))
|
if (!ActionBlocker.CanInteract(playerEnt, storageEnt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_ui.IsUiOpen(storageEnt.Value, StorageComponent.StorageUiKey.Key, playerEnt))
|
if (!UI.IsUiOpen(storageEnt.Value, StorageComponent.StorageUiKey.Key, playerEnt))
|
||||||
{
|
{
|
||||||
OpenStorageUI(storageEnt.Value, playerEnt, silent: false);
|
OpenStorageUI(storageEnt.Value, playerEnt, silent: false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ui.CloseUi(storageEnt.Value, StorageComponent.StorageUiKey.Key, playerEnt);
|
UI.CloseUi(storageEnt.Value, StorageComponent.StorageUiKey.Key, playerEnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1459,7 +1588,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
// TODO STORAGE use BUI events
|
// TODO STORAGE use BUI events
|
||||||
// This would automatically validate that the UI is open & that the user can interact.
|
// This would automatically validate that the UI is open & that the user can interact.
|
||||||
// However, we still need to manually validate that items being used are in the users hands or in the storage.
|
// However, we still need to manually validate that items being used are in the users hands or in the storage.
|
||||||
if (!_ui.IsUiOpen(storageUid.Value, StorageComponent.StorageUiKey.Key, playerUid))
|
if (!UI.IsUiOpen(storageUid.Value, StorageComponent.StorageUiKey.Key, playerUid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ActionBlocker.CanInteract(playerUid, storageUid))
|
if (!ActionBlocker.CanInteract(playerUid, storageUid))
|
||||||
|
|||||||
@@ -148,6 +148,19 @@ namespace Content.Shared.Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class OpenNestedStorageEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public readonly NetEntity InteractedItemUid;
|
||||||
|
public readonly NetEntity StorageUid;
|
||||||
|
|
||||||
|
public OpenNestedStorageEvent(NetEntity interactedItemUid, NetEntity storageUid)
|
||||||
|
{
|
||||||
|
InteractedItemUid = interactedItemUid;
|
||||||
|
StorageUid = storageUid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class StorageInteractWithItemEvent : EntityEventArgs
|
public sealed class StorageInteractWithItemEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
@@ -179,6 +192,26 @@ namespace Content.Shared.Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class StorageTransferItemEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public readonly NetEntity ItemEnt;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target storage to receive the transfer.
|
||||||
|
/// </summary>
|
||||||
|
public readonly NetEntity StorageEnt;
|
||||||
|
|
||||||
|
public readonly ItemStorageLocation Location;
|
||||||
|
|
||||||
|
public StorageTransferItemEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location)
|
||||||
|
{
|
||||||
|
ItemEnt = itemEnt;
|
||||||
|
StorageEnt = storageEnt;
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs
|
public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
|
|||||||
Submodule RobustToolbox updated: ee906af16e...c4a5752c2a
Reference in New Issue
Block a user