From ecde5ed389a1d8e20a96221fb6ddaf98273b6b8e Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Tue, 10 Dec 2024 21:56:26 -0800 Subject: [PATCH 1/3] mostly working revert of shitctionbar --- Content.Client/Input/ContentContexts.cs | 4 +- .../Options/UI/Tabs/KeyRebindTab.xaml.cs | 4 +- .../Systems/Actions/ActionUIController.cs | 193 +++++++++++++----- .../Systems/Actions/Widgets/ActionsBar.xaml | 3 +- .../Actions/Widgets/ActionsBar.xaml.cs | 23 ++- Content.Shared/Input/ContentKeyFunctions.cs | 19 +- Resources/keybinds.yml | 40 ++++ 7 files changed, 219 insertions(+), 67 deletions(-) diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 503a9ac953b..d3656de8441 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -87,9 +87,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 198eb5e4fb0..ec29e54445c 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -242,9 +242,9 @@ void AddCheckBox(string checkBoxName, bool currentState, Action _actions = new(); + private readonly List _pages = new(); + private int _currentPageIndex = DefaultPageIndex; 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; @@ -73,8 +77,13 @@ 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() @@ -127,6 +136,15 @@ 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())) @@ -311,34 +329,80 @@ public void OnStateExited(GameplayState state) private void TriggerAction(int index) { if (_actionsSystem == null || - !_actions.TryGetValue(index, out var actionId) || + CurrentPage[index] is not { } actionId || !_actionsSystem.TryGetActionData(actionId, out var baseAction)) - { return; - } if (baseAction is BaseTargetActionComponent action) - ToggleTargeting(actionId.Value, action); + ToggleTargeting(actionId, action); else - _actionsSystem?.TriggerAction(actionId.Value, baseAction); + _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; + } } 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); - if (_actions.Contains(actionId)) - return; + foreach (var page in _pages) + for (var i = 0; i < page.Size; i++) + if (page[i] == actionId) + return; - _actions.Add(actionId); + AppendAction(actionId); } private void OnActionRemoved(EntityUid actionId) @@ -349,15 +413,20 @@ private void OnActionRemoved(EntityUid actionId) if (actionId == SelectingTargetFor) StopTargeting(); - _actions.RemoveAll(x => x == actionId); + foreach (var page in _pages) + for (var i = 0; i < page.Size; i++) + if (page[i] == actionId) + page[i] = null; } private void OnActionsUpdated() { QueueWindowUpdate(); + if (_container == null) + return; - if (_actionsSystem != null) - _container?.SetActionData(_actionsSystem, _actions.ToArray()); + foreach (var button in _container.GetButtons()) + button.UpdateIcons(); } private void ActionButtonPressed(ButtonEventArgs args) @@ -504,7 +573,7 @@ private void SearchAndDisplay() PopulateActions(actions); } - private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlots = true) + private void SetAction(ActionButton button, EntityUid? actionId) { if (_actionsSystem == null) return; @@ -515,26 +584,12 @@ private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlot { button.ClearData(); if (_container?.TryGetButtonIndex(button, out position) ?? false) - { - _actions.RemoveAt(position); - } + CurrentPage[position] = actionId; } else if (button.TryReplaceWith(actionId.Value, _actionsSystem) && _container != null && _container.TryGetButtonIndex(button, out position)) - { - if (position >= _actions.Count) - { - _actions.Add(actionId); - } - else - { - _actions[position] = actionId; - } - } - - if (updateSlots) - _container?.SetActionData(_actionsSystem, _actions.ToArray()); + CurrentPage[position] = actionId; } private void DragAction() @@ -549,16 +604,11 @@ private void DragAction() } swapAction = button.ActionId; - SetAction(button, type, false); + SetAction(button, type); } - if (_menuDragHelper.Dragged is {Parent: ActionButtonContainer} old) - { - SetAction(old, swapAction, false); - } - - if (_actionsSystem != null) - _container?.SetActionData(_actionsSystem, _actions.ToArray()); + if (_menuDragHelper.Dragged is { Parent: ActionButtonContainer } old) + SetAction(old, swapAction); _menuDragHelper.EndDrag(); } @@ -711,9 +761,10 @@ private void UnloadGui() _actionsSystem?.UnlinkAllActions(); if (ActionsBar == null) - { return; - } + + ActionsBar.PageButtons.LeftArrow.OnPressed -= OnLeftArrowPressed; + ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed; if (_window != null) { @@ -741,9 +792,10 @@ private void LoadGui() _window.FilterButton.OnItemSelected += OnFilterSelected; if (ActionsBar == null) - { return; - } + + ActionsBar.PageButtons.LeftArrow.OnPressed += OnLeftArrowPressed; + ActionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed; RegisterActionContainer(ActionsBar.ActionsContainer); @@ -773,13 +825,10 @@ private void AssignSlots(List assignments) if (_actionsSystem == null) return; - _actions.Clear(); - foreach (var assign in assignments) - { - _actions.Add(assign.ActionId); - } + foreach (ref var assignment in CollectionsMarshal.AsSpan(assignments)) + _pages[assignment.Hotbar][assignment.Slot] = assignment.ActionId; - _container?.SetActionData(_actionsSystem, _actions.ToArray()); + _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); } public void RemoveActionContainer() @@ -816,7 +865,7 @@ private void OnComponentLinked(ActionsComponent component) return; LoadDefaultActions(); - _container?.SetActionData(_actionsSystem, _actions.ToArray()); + _container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]); QueueWindowUpdate(); } @@ -835,11 +884,27 @@ private void LoadDefaultActions() var actions = _actionsSystem.GetClientActions().Where(action => action.Comp.AutoPopulate).ToList(); actions.Sort(ActionComparer); - _actions.Clear(); - foreach (var (action, _) in actions) + var offset = 0; + var totalPages = _pages.Count; + var pagesLeft = totalPages; + var currentPage = DefaultPageIndex; + while (pagesLeft > 0) { - if (!_actions.Contains(action)) - _actions.Add(action); + 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--; } } @@ -950,4 +1015,22 @@ private void StopTargeting() handOverlay.IconOverride = null; handOverlay.EntityOverride = null; } + + //TODO: Serialize this shit + private sealed class ActionPage(int size) + { + private 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/Widgets/ActionsBar.xaml b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml index 1d317f6155d..961f720925a 100644 --- a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml +++ b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml @@ -14,6 +14,7 @@ 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 8e95992ff64..b11357cf8eb 100644 --- a/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs +++ b/Content.Client/UserInterface/Systems/Actions/Widgets/ActionsBar.xaml.cs @@ -1,4 +1,6 @@ -using Robust.Client.AutoGenerated; +using Content.Client.UserInterface.Systems.Actions.Controls; +using Content.Shared.Input; +using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; @@ -7,9 +9,26 @@ 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 dac780783c7..927e1d73fcf 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -85,12 +85,21 @@ 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 - }; + 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 readonly BoundKeyFunction Vote0 = "Vote0"; public static readonly BoundKeyFunction Vote1 = "Vote1"; diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index 2cca749317a..233ad63d929 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -543,3 +543,43 @@ 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 From e1485f538246f19b34ab324f7e637d8697214c91 Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Tue, 10 Dec 2024 23:53:04 -0800 Subject: [PATCH 2/3] allow moving actions to bound slots --- .../Actions/Controls/ActionButtonContainer.cs | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs index c5f8adbdea3..c028e2a76db 100644 --- a/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs +++ b/Content.Client/UserInterface/Systems/Actions/Controls/ActionButtonContainer.cs @@ -18,25 +18,18 @@ 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] - { - get => (ActionButton) GetChild(index); - } + public ActionButton this[int index] => (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)); - } + for (var i = 0; i < count; i++) + AddChild(MakeButton(i)); + return; ActionButton MakeButton(int index) { @@ -47,9 +40,7 @@ ActionButton MakeButton(int index) button.KeyBind = boundKey; if (_input.TryGetKeyBinding(boundKey, out var binding)) - { button.Label.Text = binding.GetKeyString(); - } return button; } @@ -57,7 +48,7 @@ ActionButton MakeButton(int index) public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) { - var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1); + var uniqueCount = Math.Max(ContentKeyFunctions.GetHotbarBoundKeys().Length, actionTypes.Length + 1); if (ChildCount != uniqueCount) BuildActionButtons(uniqueCount); @@ -72,9 +63,7 @@ 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) @@ -114,14 +103,9 @@ 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(); } From 051739bec0570c504414caf4095637ff1104b4ac Mon Sep 17 00:00:00 2001 From: DEATHB4DEFEAT Date: Wed, 11 Dec 2024 18:58:56 -0800 Subject: [PATCH 3/3] fix index error --- .../Systems/Actions/ActionUIController.cs | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs index db7c556fd2f..42791521668 100644 --- a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs +++ b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs @@ -592,12 +592,28 @@ private void SetAction(ActionButton button, EntityUid? actionId) { button.ClearData(); if (_container?.TryGetButtonIndex(button, out position) ?? false) - CurrentPage[position] = actionId; + CurrentPage[position] = null; } else if (button.TryReplaceWith(actionId.Value, _actionsSystem) && _container != null && _container.TryGetButtonIndex(button, out position)) - CurrentPage[position] = actionId; + if (position >= 0 && position < CurrentPage.Size) + CurrentPage[position] = 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? + } } private void DragAction() @@ -1029,18 +1045,18 @@ private void StopTargeting() //TODO: Serialize this shit private sealed class ActionPage(int size) { - private readonly EntityUid?[] _data = new EntityUid?[size]; + public readonly EntityUid?[] Data = new EntityUid?[size]; public EntityUid? this[int index] { - get => _data[index]; - set => _data[index] = value; + get => Data[index]; + set => Data[index] = value; } - public static implicit operator EntityUid?[](ActionPage p) => p._data.ToArray(); + public static implicit operator EntityUid?[](ActionPage p) => p.Data.ToArray(); - public void Clear() => Array.Fill(_data, null); + public void Clear() => Array.Fill(Data, null); - public int Size => _data.Length; + public int Size => Data.Length; } }