diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs
index 8efd977b20..ba8b72788e 100644
--- a/Content.Client/Input/ContentContexts.cs
+++ b/Content.Client/Input/ContentContexts.cs
@@ -80,11 +80,6 @@ namespace Content.Client.Input
common.AddFunction(boundKey);
}
- foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
- {
- common.AddFunction(boundKey);
- }
-
var aghost = contexts.New("aghost", "common");
aghost.AddFunction(EngineKeyFunctions.MoveUp);
aghost.AddFunction(EngineKeyFunctions.MoveDown);
diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
index c68e7f3af9..87b1f10352 100644
--- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
+++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
@@ -224,10 +224,6 @@ namespace Content.Client.Options.UI.Tabs
{
AddButton(boundKey);
}
- foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
- {
- AddButton(boundKey);
- }
AddHeader("ui-options-header-shuttle");
AddButton(ContentKeyFunctions.ShuttleStrafeUp);
diff --git a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml
index 8b502515c9..5c09574005 100644
--- a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml
+++ b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml
@@ -22,10 +22,10 @@
+
-
diff --git a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs
index c35d831035..a8a53e83c7 100644
--- a/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs
+++ b/Content.Client/UserInterface/Screens/DefaultGameScreen.xaml.cs
@@ -17,7 +17,6 @@ public sealed partial class DefaultGameScreen : InGameScreen
SetAnchorPreset(MainViewport, LayoutPreset.Wide);
SetAnchorPreset(ViewportContainer, LayoutPreset.Wide);
SetAnchorAndMarginPreset(TopLeft, LayoutPreset.TopLeft, margin: 10);
- SetAnchorAndMarginPreset(Actions, LayoutPreset.BottomLeft, margin: 10);
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
SetAnchorAndMarginPreset(Chat, LayoutPreset.TopRight, margin: 10);
@@ -25,6 +24,7 @@ public sealed partial class DefaultGameScreen : InGameScreen
Chat.OnResized += ChatOnResized;
Chat.OnChatResizeFinish += ChatOnResizeFinish;
+ Actions.ActionsContainer.Columns = 1;
}
private void ChatOnResizeFinish(Vector2 _)
diff --git a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs
index 41c4a85e7e..e0c66b7a8b 100644
--- a/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs
+++ b/Content.Client/UserInterface/Screens/SeparatedChatGameScreen.xaml.cs
@@ -19,7 +19,7 @@ public sealed partial class SeparatedChatGameScreen : InGameScreen
SetAnchorPreset(ViewportContainer, LayoutPreset.Wide);
SetAnchorPreset(MainViewport, LayoutPreset.Wide);
SetAnchorAndMarginPreset(VoteMenu, LayoutPreset.TopLeft, margin: 10);
- SetAnchorAndMarginPreset(Actions, LayoutPreset.BottomLeft, margin: 10);
+ SetAnchorAndMarginPreset(Actions, LayoutPreset.TopLeft, margin: 10);
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10);
diff --git a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs
index 340aa5447d..5a992786a2 100644
--- a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs
+++ b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs
@@ -1,6 +1,5 @@
using System.Linq;
using System.Numerics;
-using System.Runtime.InteropServices;
using Content.Client.Actions;
using Content.Client.Construction;
using Content.Client.Gameplay;
@@ -49,17 +48,14 @@ public sealed class ActionUIController : UIController, IOnStateChanged _pages = new();
- private int _currentPageIndex = DefaultPageIndex;
+ private readonly List _actions = new();
private readonly DragDropHelper _menuDragHelper;
private readonly TextureRect _dragShadow;
private ActionsWindow? _window;
private ActionsBar? ActionsBar => UIManager.GetActiveUIWidgetOrNull();
private MenuButton? ActionButton => UIManager.GetActiveUIWidgetOrNull()?.ActionButton;
- private ActionPage CurrentPage => _pages[_currentPageIndex];
public bool IsDragging => _menuDragHelper.IsDragging;
@@ -79,14 +75,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged ChangePage(boundId)));
- }
-
builder
.Bind(ContentKeyFunctions.OpenActionsMenu,
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
@@ -178,7 +157,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged lastPage)
- {
- index = 0;
- }
-
- _currentPageIndex = index;
- var page = _pages[_currentPageIndex];
- _container?.SetActionData(_actionsSystem, page);
-
- ActionsBar!.PageButtons.Label.Text = $"{_currentPageIndex + 1}";
- }
-
- private void OnLeftArrowPressed(ButtonEventArgs args)
- {
- ChangePage(_currentPageIndex - 1);
- }
-
- private void OnRightArrowPressed(ButtonEventArgs args)
- {
- ChangePage(_currentPageIndex + 1);
- }
-
- private void AppendAction(EntityUid action)
- {
- if (_container == null)
- return;
-
- foreach (var button in _container.GetButtons())
- {
- if (button.ActionId != null)
- continue;
-
- SetAction(button, action);
- return;
- }
-
- foreach (var page in _pages)
- {
- for (var i = 0; i < page.Size; i++)
- {
- var pageAction = page[i];
- if (pageAction != null)
- continue;
-
- page[i] = action;
- return;
- }
- }
+ _actionsSystem?.TriggerAction(actionId.Value, baseAction);
}
private void OnActionAdded(EntityUid actionId)
@@ -416,18 +335,10 @@ public sealed class ActionUIController : UIController, IOnStateChanged x == actionId);
}
private void OnActionsUpdated()
{
QueueWindowUpdate();
- if (_container == null)
- return;
- foreach (var button in _container.GetButtons())
- {
- button.UpdateIcons();
- }
+ if (_actionsSystem != null)
+ _container?.SetActionData(_actionsSystem, _actions.ToArray());
}
private void ActionButtonPressed(ButtonEventArgs args)
@@ -512,8 +401,8 @@ public sealed class ActionUIController : UIController, IOnStateChanged action.Enabled,
- Filters.Item => action.Container != null && action.Container != _playerManager.LocalPlayer?.ControlledEntity,
- Filters.Innate => action.Container == null || action.Container == _playerManager.LocalPlayer?.ControlledEntity,
+ Filters.Item => action.Container != null && action.Container != _playerManager.LocalEntity,
+ Filters.Innate => action.Container == null || action.Container == _playerManager.LocalEntity,
Filters.Instant => action is InstantActionComponent,
Filters.Targeted => action is BaseTargetActionComponent,
_ => throw new ArgumentOutOfRangeException(nameof(filter), filter, null)
@@ -580,7 +469,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged= _actions.Count)
+ {
+ _actions.Add(actionId);
+ }
+ else
+ {
+ _actions[position] = actionId;
+ }
}
+
+ if (updateSlots)
+ _container?.SetActionData(_actionsSystem, _actions.ToArray());
}
private void DragAction()
{
+ EntityUid? swapAction = null;
if (UIManager.CurrentlyHovered is ActionButton button)
{
if (!_menuDragHelper.IsDragging || _menuDragHelper.Dragged?.ActionId is not { } type)
@@ -651,14 +548,18 @@ public sealed class ActionUIController : UIController, IOnStateChanged action.Comp.AutoPopulate).ToList();
actions.Sort(ActionComparer);
- var offset = 0;
- var totalPages = _pages.Count;
- var pagesLeft = totalPages;
- var currentPage = DefaultPageIndex;
- while (pagesLeft > 0)
+ _actions.Clear();
+ foreach (var (action, _) in actions)
{
- var page = _pages[currentPage];
- var pageSize = page.Size;
-
- for (var slot = 0; slot < pageSize; slot++)
- {
- var actionIndex = slot + offset;
- if (actionIndex < actions.Count)
- {
- page[slot] = actions[slot + offset].Id;
- }
- else
- {
- page[slot] = null;
- }
- }
-
- offset += pageSize;
- currentPage++;
- if (currentPage == totalPages)
- {
- currentPage = 0;
- }
-
- pagesLeft--;
+ if (!_actions.Contains(action))
+ _actions.Add(action);
}
}
@@ -1078,34 +943,4 @@ public sealed class ActionUIController : UIController, IOnStateChanged _data[index];
- set => _data[index] = value;
- }
-
- public static implicit operator EntityUid?[](ActionPage p)
- {
- return p._data.ToArray();
- }
-
- public void Clear()
- {
- Array.Fill(_data, null);
- }
-
- public int Size => _data.Length;
- }
}
diff --git a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs
index 31c5a28e52..6b2033e78c 100644
--- a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs
+++ b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs
@@ -49,6 +49,8 @@ public sealed class ActionButton : Control, IEntityControl
private readonly SpriteView _smallItemSpriteView;
private readonly SpriteView _bigItemSpriteView;
+ private Texture? _buttonBackgroundTexture;
+
public EntityUid? ActionId { get; private set; }
private BaseActionComponent? _action;
public bool Locked { get; set; }
@@ -138,9 +140,9 @@ public sealed class ActionButton : Control, IEntityControl
});
Cooldown = new CooldownGraphic {Visible = false};
+ AddChild(Button);
AddChild(_bigActionIcon);
AddChild(_bigItemSpriteView);
- AddChild(Button);
AddChild(HighlightRect);
AddChild(Label);
AddChild(Cooldown);
@@ -167,7 +169,7 @@ public sealed class ActionButton : Control, IEntityControl
protected override void OnThemeUpdated()
{
base.OnThemeUpdated();
- Button.Texture = Theme.ResolveTexture("SlotBackground");
+ _buttonBackgroundTexture = Theme.ResolveTexture("SlotBackground");
Label.FontColorOverride = Theme.ResolveColorOrSpecified("whiteText");
}
@@ -263,6 +265,7 @@ public sealed class ActionButton : Control, IEntityControl
public void UpdateIcons()
{
UpdateItemIcon();
+ UpdateBackground();
if (_action == null)
{
@@ -278,6 +281,18 @@ public sealed class ActionButton : Control, IEntityControl
SetActionIcon(_action.Icon != null ? _spriteSys.Frame0(_action.Icon) : null);
}
+ public void UpdateBackground()
+ {
+ if (_action == null)
+ {
+ Button.Texture = null;
+ }
+ else
+ {
+ Button.Texture = _buttonBackgroundTexture;
+ }
+ }
+
public bool TryReplaceWith(EntityUid actionId, ActionsSystem system)
{
if (Locked)
@@ -363,7 +378,8 @@ public sealed class ActionButton : Control, IEntityControl
public void DrawModeChanged()
{
- HighlightRect.Visible = _beingHovered;
+ _controller ??= UserInterfaceManager.GetUIController();
+ HighlightRect.Visible = _beingHovered && (_action != null || _controller.IsDragging);
// always show the normal empty button style if no action in this slot
if (_action == null)
@@ -373,8 +389,7 @@ public sealed class ActionButton : Control, IEntityControl
}
// show a hover only if the action is usable or another action is being dragged on top of this
- _controller ??= UserInterfaceManager.GetUIController();
- if (_beingHovered && (_controller.IsDragging || _action.Enabled))
+ if (_beingHovered && (_controller.IsDragging || _action!.Enabled))
{
SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassHover);
}
diff --git a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs
index 9986c61ad6..5e26c192d7 100644
--- a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs
+++ b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs
@@ -1,12 +1,19 @@
+using System.Linq;
using Content.Client.Actions;
+using Content.Shared.Input;
+using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Utility;
namespace Content.Client.UserInterface.Systems.Actions.Controls;
[Virtual]
public class ActionButtonContainer : GridContainer
{
+ [Dependency] private readonly IEntityManager _entity = default!;
+ [Dependency] private readonly IInputManager _input = default!;
+
public event Action? ActionPressed;
public event Action? ActionUnpressed;
public event Action? ActionFocusExited;
@@ -14,7 +21,6 @@ public class ActionButtonContainer : GridContainer
public ActionButtonContainer()
{
IoCManager.InjectDependencies(this);
- UserInterfaceManager.GetUIController().RegisterActionContainer(this);
}
public ActionButton this[int index]
@@ -22,17 +28,42 @@ public class ActionButtonContainer : GridContainer
get => (ActionButton) GetChild(index);
}
+ private void BuildActionButtons(int count)
+ {
+ var keys = ContentKeyFunctions.GetHotbarBoundKeys();
+
+ Children.Clear();
+ for (var index = 0; index < count; index++)
+ {
+ Children.Add(MakeButton(index));
+ }
+
+ ActionButton MakeButton(int index)
+ {
+ var button = new ActionButton(_entity);
+
+ if (keys.TryGetValue(index, out var boundKey))
+ {
+ button.KeyBind = boundKey;
+
+ var binding = _input.GetKeyBinding(boundKey);
+ button.Label.Text = binding.GetKeyString();
+ }
+
+ return button;
+ }
+ }
+
public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes)
{
- ClearActionData();
+ var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1);
+ BuildActionButtons(uniqueCount);
- for (var i = 0; i < actionTypes.Length; i++)
+ for (var i = 0; i < uniqueCount; i++)
{
- var action = actionTypes[i];
- if (action == null)
- continue;
-
- ((ActionButton) GetChild(i)).UpdateData(action.Value, system);
+ if (!actionTypes.TryGetValue(i, out var action))
+ action = null;
+ ((ActionButton) GetChild(i)).UpdateData(action, system);
}
}
diff --git a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml
index 7e4d60a057..1d317f6155 100644
--- a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml
+++ b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml
@@ -13,7 +13,7 @@
VerticalAlignment="Center"
MaxSize="64 9999"
Name="ActionsContainer"
- Access="Public"/>
-
+ Access="Public"
+ Rows="1"/>
diff --git a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs
index ff3c32cc0e..8e95992ff6 100644
--- a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs
+++ b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs
@@ -1,6 +1,4 @@
-using Content.Client.UserInterface.Systems.Actions.Controls;
-using Content.Shared.Input;
-using Robust.Client.AutoGenerated;
+using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
@@ -9,28 +7,9 @@ namespace Content.Client.UserInterface.Systems.Actions.Widgets;
[GenerateTypedNameReferences]
public sealed partial class ActionsBar : UIWidget
{
- [Dependency] private readonly IEntityManager _entity = default!;
-
public ActionsBar()
{
RobustXamlLoader.Load(this);
- IoCManager.InjectDependencies(this);
-
- var keys = ContentKeyFunctions.GetHotbarBoundKeys();
- for (var index = 1; index < keys.Length; index++)
- {
- ActionsContainer.Children.Add(MakeButton(index));
- }
- ActionsContainer.Children.Add(MakeButton(0));
-
- ActionButton MakeButton(int index)
- {
- var boundKey = keys[index];
- var button = new ActionButton(_entity);
- button.KeyBind = boundKey;
- button.Label.Text = index.ToString();
- return button;
- }
}
}
diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs
index 840320b0d3..f4307cd058 100644
--- a/Content.Shared/Input/ContentKeyFunctions.cs
+++ b/Content.Shared/Input/ContentKeyFunctions.cs
@@ -84,23 +84,6 @@ namespace Content.Shared.Input
Hotbar1, Hotbar2, Hotbar3, Hotbar4, Hotbar5, Hotbar6, Hotbar7, Hotbar8, Hotbar9, Hotbar0
};
- public static readonly BoundKeyFunction Loadout0 = "Loadout0";
- public static readonly BoundKeyFunction Loadout1 = "Loadout1";
- public static readonly BoundKeyFunction Loadout2 = "Loadout2";
- public static readonly BoundKeyFunction Loadout3 = "Loadout3";
- public static readonly BoundKeyFunction Loadout4 = "Loadout4";
- public static readonly BoundKeyFunction Loadout5 = "Loadout5";
- public static readonly BoundKeyFunction Loadout6 = "Loadout6";
- public static readonly BoundKeyFunction Loadout7 = "Loadout7";
- public static readonly BoundKeyFunction Loadout8 = "Loadout8";
- public static readonly BoundKeyFunction Loadout9 = "Loadout9";
-
- public static BoundKeyFunction[] GetLoadoutBoundKeys() =>
- new[]
- {
- Loadout1, Loadout2, Loadout3, Loadout4, Loadout5, Loadout6, Loadout7, Loadout8, Loadout9, Loadout0
- };
-
public static readonly BoundKeyFunction Vote0 = "Vote0";
public static readonly BoundKeyFunction Vote1 = "Vote1";
public static readonly BoundKeyFunction Vote2 = "Vote2";
diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml
index 1b82435861..b3ba05def2 100644
--- a/Resources/keybinds.yml
+++ b/Resources/keybinds.yml
@@ -510,43 +510,3 @@ binds:
- function: Hotbar9
type: State
key: Num9
-- function: Loadout0
- type: State
- key: Num0
- mod1: Shift
-- function: Loadout1
- type: State
- key: Num1
- mod1: Shift
-- function: Loadout2
- type: State
- key: Num2
- mod1: Shift
-- function: Loadout3
- type: State
- key: Num3
- mod1: Shift
-- function: Loadout4
- type: State
- key: Num4
- mod1: Shift
-- function: Loadout5
- type: State
- key: Num5
- mod1: Shift
-- function: Loadout6
- type: State
- key: Num6
- mod1: Shift
-- function: Loadout7
- type: State
- key: Num7
- mod1: Shift
-- function: Loadout8
- type: State
- key: Num8
- mod1: Shift
-- function: Loadout9
- type: State
- key: Num9
- mod1: Shift