diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 0a8e5d35b5..1e13b105c6 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -103,9 +103,9 @@ public static void SetupContexts(IInputContextContainer contexts) common.AddFunction(ContentKeyFunctions.OpenActionsMenu); foreach (var boundKey in ContentKeyFunctions.GetHotbarBoundKeys()) + { common.AddFunction(boundKey); - foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys()) - common.AddFunction(boundKey); + } var aghost = contexts.New("aghost", "common"); aghost.AddFunction(EngineKeyFunctions.MoveUp); diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index f97c3b6f26..43affd7293 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -274,9 +274,9 @@ void AddCheckBox(string checkBoxName, bool currentState, Action _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,13 +75,8 @@ public ActionUIController() Stretch = StretchMode.Scale, Visible = false, SetSize = new Vector2(64, 64), - MouseFilter = MouseFilterMode.Ignore, + MouseFilter = MouseFilterMode.Ignore }; - - var pageCount = ContentKeyFunctions.GetLoadoutBoundKeys().Length; - var buttonCount = ContentKeyFunctions.GetHotbarBoundKeys().Length; - for (var i = 0; i < pageCount; i++) - _pages.Add(new ActionPage(buttonCount)); } public override void Initialize() @@ -138,15 +129,6 @@ public void OnStateEntered(GameplayState state) }, false, true)); } - var loadoutKeys = ContentKeyFunctions.GetLoadoutBoundKeys(); - for (var i = 0; i < loadoutKeys.Length; i++) - { - var boundId = i; // This is needed, because the lambda captures it. - var boundKey = loadoutKeys[i]; - builder = builder.Bind(boundKey, - InputCmdHandler.FromDelegate(_ => ChangePage(boundId))); - } - builder .Bind(ContentKeyFunctions.OpenActionsMenu, InputCmdHandler.FromDelegate(_ => ToggleWindow())) @@ -367,80 +349,34 @@ public void OnStateExited(GameplayState state) private void TriggerAction(int index) { if (_actionsSystem == null || - CurrentPage[index] is not { } actionId || + !_actions.TryGetValue(index, out var actionId) || !_actionsSystem.TryGetActionData(actionId, out var baseAction)) - return; - - if (baseAction is BaseTargetActionComponent action) - ToggleTargeting(actionId, action); - else - _actionsSystem?.TriggerAction(actionId, baseAction); - } - - private void ChangePage(int index) - { - if (_actionsSystem == null) - return; - - var lastPage = _pages.Count - 1; - if (index < 0) - index = lastPage; - else if (index > 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; - } + if (baseAction is BaseTargetActionComponent action) + ToggleTargeting(actionId.Value, action); + else + _actionsSystem?.TriggerAction(actionId.Value, baseAction); } private void OnActionAdded(EntityUid actionId) { if (_actionsSystem == null || !_actionsSystem.TryGetActionData(actionId, out var action)) + { return; + } // if the action is toggled when we add it, start targeting if (action is BaseTargetActionComponent targetAction && action.Toggled) StartTargeting(actionId, targetAction); - foreach (var page in _pages) - for (var i = 0; i < page.Size; i++) - if (page[i] == actionId) - return; + if (_actions.Contains(actionId)) + return; - AppendAction(actionId); + _actions.Add(actionId); } private void OnActionRemoved(EntityUid actionId) @@ -451,24 +387,19 @@ private void OnActionRemoved(EntityUid actionId) if (actionId == SelectingTargetFor) StopTargeting(); - foreach (var page in _pages) - for (var i = 0; i < page.Size; i++) - if (page[i] == actionId) - page[i] = null; + _actions.RemoveAll(x => x == actionId); } private void OnActionsUpdated() { QueueWindowUpdate(); - if (_container == null) - return; // TODO ACTIONS allow buttons to persist across state applications // Then we don't have to interrupt drags any time the buttons get rebuilt. _menuDragHelper.EndDrag(); if (_actionsSystem != null) - _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); + _container?.SetActionData(_actionsSystem, _actions.ToArray()); } private void ActionButtonPressed(ButtonEventArgs args) @@ -615,7 +546,7 @@ private void SearchAndDisplay() PopulateActions(actions); } - private void SetAction(ActionButton button, EntityUid? actionId) + private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlots = true) { if (_actionsSystem == null) return; @@ -626,28 +557,27 @@ private void SetAction(ActionButton button, EntityUid? actionId) { button.ClearData(); if (_container?.TryGetButtonIndex(button, out position) ?? false) - CurrentPage[position] = null; + { + if (_actions.Count > position && position >= 0) + _actions.RemoveAt(position); + } } else if (button.TryReplaceWith(actionId.Value, _actionsSystem) && _container != null && _container.TryGetButtonIndex(button, out position)) - if (position >= 0 && position < CurrentPage.Size) - CurrentPage[position] = actionId; + { + if (position >= _actions.Count) + { + _actions.Add(actionId); + } else { - if (_pages.Count <= _currentPageIndex) - return; - // Add the button to the next page if there's no space on the current one - var nextPage = _pages[_currentPageIndex + 1]; - int i; - for (i = 0; i < nextPage.Size; i++) - if (nextPage[i] == null) - { - nextPage[i] = actionId; - break; - } - ChangePage(_currentPageIndex + 1); //TODO: Make this a client config? + _actions[position] = actionId; } + } + + if (updateSlots) + _container?.SetActionData(_actionsSystem, _actions.ToArray()); } private void DragAction() @@ -663,14 +593,14 @@ private void DragAction() if (currentlyHovered is ActionButton button) { swapAction = button.ActionId; - SetAction(button, action); + SetAction(button, action, false); } if (dragged.Parent is ActionButtonContainer) - SetAction(dragged, swapAction); + SetAction(dragged, swapAction, false); if (_actionsSystem != null) - _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); + _container?.SetActionData(_actionsSystem, _actions.ToArray()); _menuDragHelper.EndDrag(); } @@ -815,10 +745,9 @@ private void UnloadGui() _actionsSystem?.UnlinkAllActions(); if (ActionsBar == null) + { return; - - ActionsBar.PageButtons.LeftArrow.OnPressed -= OnLeftArrowPressed; - ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed; + } if (_window != null) { @@ -846,10 +775,9 @@ private void LoadGui() _window.FilterButton.OnItemSelected += OnFilterSelected; if (ActionsBar == null) + { return; - - ActionsBar.PageButtons.LeftArrow.OnPressed += OnLeftArrowPressed; - ActionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed; + } RegisterActionContainer(ActionsBar.ActionsContainer); @@ -879,10 +807,13 @@ private void AssignSlots(List assignments) if (_actionsSystem == null) return; - foreach (ref var assignment in CollectionsMarshal.AsSpan(assignments)) - _pages[assignment.Hotbar][assignment.Slot] = assignment.ActionId; + _actions.Clear(); + foreach (var assign in assignments) + { + _actions.Add(assign.ActionId); + } - _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); + _container?.SetActionData(_actionsSystem, _actions.ToArray()); } public void RemoveActionContainer() => @@ -917,7 +848,7 @@ private void OnComponentLinked(ActionsComponent component) return; LoadDefaultActions(); - _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); + _container?.SetActionData(_actionsSystem, _actions.ToArray()); QueueWindowUpdate(); } @@ -936,27 +867,11 @@ private void LoadDefaultActions() var actions = _actionsSystem.GetClientActions().Where(action => 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++) - if (slot + offset < 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); } } @@ -1067,22 +982,4 @@ private void StopTargeting() handOverlay.IconOverride = null; handOverlay.EntityOverride = null; } - - //TODO: Serialize this shit - private sealed class ActionPage(int size) - { - public readonly EntityUid?[] Data = new EntityUid?[size]; - - public EntityUid? this[int index] - { - get => Data[index]; - set => Data[index] = value; - } - - public static implicit operator EntityUid?[](ActionPage p) => p.Data.ToArray(); - - public void Clear() => Array.Fill(Data, null); - - public int Size => Data.Length; - } } diff --git a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs index c028e2a76d..c5f8adbdea 100644 --- a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs +++ b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs @@ -18,18 +18,25 @@ public class ActionButtonContainer : GridContainer public event Action? ActionUnpressed; public event Action? ActionFocusExited; - public ActionButtonContainer() => IoCManager.InjectDependencies(this); + public ActionButtonContainer() + { + IoCManager.InjectDependencies(this); + } - public ActionButton this[int index] => (ActionButton) GetChild(index); + public ActionButton this[int index] + { + get => (ActionButton) GetChild(index); + } private void BuildActionButtons(int count) { var keys = ContentKeyFunctions.GetHotbarBoundKeys(); Children.Clear(); - for (var i = 0; i < count; i++) - AddChild(MakeButton(i)); - return; + for (var index = 0; index < count; index++) + { + Children.Add(MakeButton(index)); + } ActionButton MakeButton(int index) { @@ -40,7 +47,9 @@ ActionButton MakeButton(int index) button.KeyBind = boundKey; if (_input.TryGetKeyBinding(boundKey, out var binding)) + { button.Label.Text = binding.GetKeyString(); + } return button; } @@ -48,7 +57,7 @@ ActionButton MakeButton(int index) public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) { - var uniqueCount = Math.Max(ContentKeyFunctions.GetHotbarBoundKeys().Length, actionTypes.Length + 1); + var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1); if (ChildCount != uniqueCount) BuildActionButtons(uniqueCount); @@ -63,7 +72,9 @@ public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) public void ClearActionData() { foreach (var button in Children) + { ((ActionButton) button).ClearData(); + } } protected override void ChildAdded(Control newChild) @@ -103,9 +114,14 @@ public bool TryGetButtonIndex(ActionButton button, out int position) public IEnumerable GetButtons() { foreach (var control in Children) + { if (control is ActionButton button) yield return button; + } } - ~ActionButtonContainer() => UserInterfaceManager.GetUIController().RemoveActionContainer(); + ~ActionButtonContainer() + { + UserInterfaceManager.GetUIController().RemoveActionContainer(); + } } diff --git a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml index 961f720925..1d317f6155 100644 --- a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml +++ b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml @@ -14,7 +14,6 @@ MaxSize="64 9999" Name="ActionsContainer" Access="Public" - Rows="1" /> - + 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 b11357cf8e..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,26 +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 e51c392a80..d4d75b179b 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -100,21 +100,12 @@ public static class ContentKeyFunctions public static readonly BoundKeyFunction Hotbar7 = "Hotbar7"; public static readonly BoundKeyFunction Hotbar8 = "Hotbar8"; public static readonly BoundKeyFunction Hotbar9 = "Hotbar9"; - public static BoundKeyFunction[] GetHotbarBoundKeys() => - new[] { 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 BoundKeyFunction[] GetHotbarBoundKeys() => + new[] + { + Hotbar1, Hotbar2, Hotbar3, Hotbar4, Hotbar5, Hotbar6, Hotbar7, Hotbar8, Hotbar9, Hotbar0 + }; public static readonly BoundKeyFunction Vote0 = "Vote0"; public static readonly BoundKeyFunction Vote1 = "Vote1"; diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index ee83563ba6..eca4568c7a 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -550,46 +550,6 @@ 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 - function: LookUp type: State key: Space