Skip to content

Commit 6cd17d7

Browse files
Revert Bad "SS13" Action Bar (#1333)
# Description Simple-Station/Parkstation-Friendly-Chainsaw#2 space-wizards/space-station-14#21352 --- <details><summary><h1>Media</h1></summary> <p> <!-- https://github.com/user-attachments/assets/701512ce-1bf2-4020-a2eb-ba1e35b18669 --> https://github.com/user-attachments/assets/d01f01b9-dae7-4d05-91db-ac6e3de30e9f </p> </details> --- # Changelog :cl: - tweak: Added back support for the action bar to have "loadouts" or quick layouts of actions (man, how many things are called loadouts?)
1 parent fc3c43e commit 6cd17d7

File tree

8 files changed

+238
-82
lines changed

8 files changed

+238
-82
lines changed

Content.Client/Input/ContentContexts.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ public static void SetupContexts(IInputContextContainer contexts)
9797
common.AddFunction(ContentKeyFunctions.OpenActionsMenu);
9898

9999
foreach (var boundKey in ContentKeyFunctions.GetHotbarBoundKeys())
100-
{
101100
common.AddFunction(boundKey);
102-
}
101+
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
102+
common.AddFunction(boundKey);
103103

104104
var aghost = contexts.New("aghost", "common");
105105
aghost.AddFunction(EngineKeyFunctions.MoveUp);

Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,9 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
271271

272272
AddHeader("ui-options-header-hotbar");
273273
foreach (var boundKey in ContentKeyFunctions.GetHotbarBoundKeys())
274-
{
275274
AddButton(boundKey);
276-
}
275+
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
276+
AddButton(boundKey);
277277

278278
AddHeader("ui-options-header-shuttle");
279279
AddButton(ContentKeyFunctions.ShuttleStrafeUp);

Content.Client/UserInterface/Systems/Actions/ActionUIController.cs

+150-47
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Linq;
22
using System.Numerics;
3+
using System.Runtime.InteropServices;
34
using Content.Client.Actions;
45
using Content.Client.Construction;
56
using Content.Client.Gameplay;
@@ -50,14 +51,17 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
5051
[UISystemDependency] private readonly TargetOutlineSystem? _targetOutline = default;
5152
[UISystemDependency] private readonly SpriteSystem _spriteSystem = default!;
5253

54+
private const int DefaultPageIndex = 0;
5355
private ActionButtonContainer? _container;
54-
private readonly List<EntityUid?> _actions = new();
56+
private readonly List<ActionPage> _pages = new();
57+
private int _currentPageIndex = DefaultPageIndex;
5558
private readonly DragDropHelper<ActionButton> _menuDragHelper;
5659
private readonly TextureRect _dragShadow;
5760
private ActionsWindow? _window;
5861

5962
private ActionsBar? ActionsBar => UIManager.GetActiveUIWidgetOrNull<ActionsBar>();
6063
private MenuButton? ActionButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.ActionButton;
64+
private ActionPage CurrentPage => _pages[_currentPageIndex];
6165

6266
public bool IsDragging => _menuDragHelper.IsDragging;
6367

@@ -75,8 +79,13 @@ public ActionUIController()
7579
Stretch = StretchMode.Scale,
7680
Visible = false,
7781
SetSize = new Vector2(64, 64),
78-
MouseFilter = MouseFilterMode.Ignore
82+
MouseFilter = MouseFilterMode.Ignore,
7983
};
84+
85+
var pageCount = ContentKeyFunctions.GetLoadoutBoundKeys().Length;
86+
var buttonCount = ContentKeyFunctions.GetHotbarBoundKeys().Length;
87+
for (var i = 0; i < pageCount; i++)
88+
_pages.Add(new ActionPage(buttonCount));
8089
}
8190

8291
public override void Initialize()
@@ -129,6 +138,15 @@ public void OnStateEntered(GameplayState state)
129138
}, false, true));
130139
}
131140

141+
var loadoutKeys = ContentKeyFunctions.GetLoadoutBoundKeys();
142+
for (var i = 0; i < loadoutKeys.Length; i++)
143+
{
144+
var boundId = i; // This is needed, because the lambda captures it.
145+
var boundKey = loadoutKeys[i];
146+
builder = builder.Bind(boundKey,
147+
InputCmdHandler.FromDelegate(_ => ChangePage(boundId)));
148+
}
149+
132150
builder
133151
.Bind(ContentKeyFunctions.OpenActionsMenu,
134152
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
@@ -315,34 +333,80 @@ public void OnStateExited(GameplayState state)
315333
private void TriggerAction(int index)
316334
{
317335
if (_actionsSystem == null ||
318-
!_actions.TryGetValue(index, out var actionId) ||
336+
CurrentPage[index] is not { } actionId ||
319337
!_actionsSystem.TryGetActionData(actionId, out var baseAction))
320-
{
321338
return;
322-
}
323339

324340
if (baseAction is BaseTargetActionComponent action)
325-
ToggleTargeting(actionId.Value, action);
341+
ToggleTargeting(actionId, action);
326342
else
327-
_actionsSystem?.TriggerAction(actionId.Value, baseAction);
343+
_actionsSystem?.TriggerAction(actionId, baseAction);
344+
}
345+
346+
private void ChangePage(int index)
347+
{
348+
if (_actionsSystem == null)
349+
return;
350+
351+
var lastPage = _pages.Count - 1;
352+
if (index < 0)
353+
index = lastPage;
354+
else if (index > lastPage)
355+
index = 0;
356+
357+
_currentPageIndex = index;
358+
var page = _pages[_currentPageIndex];
359+
_container?.SetActionData(_actionsSystem, page);
360+
361+
ActionsBar!.PageButtons.Label.Text = $"{_currentPageIndex + 1}";
362+
}
363+
364+
private void OnLeftArrowPressed(ButtonEventArgs args) => ChangePage(_currentPageIndex - 1);
365+
366+
private void OnRightArrowPressed(ButtonEventArgs args) => ChangePage(_currentPageIndex + 1);
367+
368+
private void AppendAction(EntityUid action)
369+
{
370+
if (_container == null)
371+
return;
372+
373+
foreach (var button in _container.GetButtons())
374+
{
375+
if (button.ActionId != null)
376+
continue;
377+
378+
SetAction(button, action);
379+
return;
380+
}
381+
382+
foreach (var page in _pages)
383+
for (var i = 0; i < page.Size; i++)
384+
{
385+
var pageAction = page[i];
386+
if (pageAction != null)
387+
continue;
388+
389+
page[i] = action;
390+
return;
391+
}
328392
}
329393

330394
private void OnActionAdded(EntityUid actionId)
331395
{
332396
if (_actionsSystem == null ||
333397
!_actionsSystem.TryGetActionData(actionId, out var action))
334-
{
335398
return;
336-
}
337399

338400
// if the action is toggled when we add it, start targeting
339401
if (action is BaseTargetActionComponent targetAction && action.Toggled)
340402
StartTargeting(actionId, targetAction);
341403

342-
if (_actions.Contains(actionId))
343-
return;
404+
foreach (var page in _pages)
405+
for (var i = 0; i < page.Size; i++)
406+
if (page[i] == actionId)
407+
return;
344408

345-
_actions.Add(actionId);
409+
AppendAction(actionId);
346410
}
347411

348412
private void OnActionRemoved(EntityUid actionId)
@@ -353,19 +417,24 @@ private void OnActionRemoved(EntityUid actionId)
353417
if (actionId == SelectingTargetFor)
354418
StopTargeting();
355419

356-
_actions.RemoveAll(x => x == actionId);
420+
foreach (var page in _pages)
421+
for (var i = 0; i < page.Size; i++)
422+
if (page[i] == actionId)
423+
page[i] = null;
357424
}
358425

359426
private void OnActionsUpdated()
360427
{
361428
QueueWindowUpdate();
429+
if (_container == null)
430+
return;
362431

363432
// TODO ACTIONS allow buttons to persist across state applications
364433
// Then we don't have to interrupt drags any time the buttons get rebuilt.
365434
_menuDragHelper.EndDrag();
366435

367436
if (_actionsSystem != null)
368-
_container?.SetActionData(_actionsSystem, _actions.ToArray());
437+
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
369438
}
370439

371440
private void ActionButtonPressed(ButtonEventArgs args)
@@ -512,7 +581,7 @@ private void SearchAndDisplay()
512581
PopulateActions(actions);
513582
}
514583

515-
private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlots = true)
584+
private void SetAction(ActionButton button, EntityUid? actionId)
516585
{
517586
if (_actionsSystem == null)
518587
return;
@@ -523,27 +592,28 @@ private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlot
523592
{
524593
button.ClearData();
525594
if (_container?.TryGetButtonIndex(button, out position) ?? false)
526-
{
527-
if (_actions.Count > position && position >= 0)
528-
_actions.RemoveAt(position);
529-
}
595+
CurrentPage[position] = null;
530596
}
531597
else if (button.TryReplaceWith(actionId.Value, _actionsSystem) &&
532598
_container != null &&
533599
_container.TryGetButtonIndex(button, out position))
534-
{
535-
if (position >= _actions.Count)
536-
{
537-
_actions.Add(actionId);
538-
}
600+
if (position >= 0 && position < CurrentPage.Size)
601+
CurrentPage[position] = actionId;
539602
else
540603
{
541-
_actions[position] = actionId;
604+
if (_pages.Count <= _currentPageIndex)
605+
return;
606+
// Add the button to the next page if there's no space on the current one
607+
var nextPage = _pages[_currentPageIndex + 1];
608+
int i;
609+
for (i = 0; i < nextPage.Size; i++)
610+
if (nextPage[i] == null)
611+
{
612+
nextPage[i] = actionId;
613+
break;
614+
}
615+
ChangePage(_currentPageIndex + 1); //TODO: Make this a client config?
542616
}
543-
}
544-
545-
if (updateSlots)
546-
_container?.SetActionData(_actionsSystem, _actions.ToArray());
547617
}
548618

549619
private void DragAction()
@@ -559,14 +629,14 @@ private void DragAction()
559629
if (currentlyHovered is ActionButton button)
560630
{
561631
swapAction = button.ActionId;
562-
SetAction(button, action, false);
632+
SetAction(button, action);
563633
}
564634

565635
if (dragged.Parent is ActionButtonContainer)
566-
SetAction(dragged, swapAction, false);
636+
SetAction(dragged, swapAction);
567637

568638
if (_actionsSystem != null)
569-
_container?.SetActionData(_actionsSystem, _actions.ToArray());
639+
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
570640

571641
_menuDragHelper.EndDrag();
572642
}
@@ -717,9 +787,10 @@ private void UnloadGui()
717787
_actionsSystem?.UnlinkAllActions();
718788

719789
if (ActionsBar == null)
720-
{
721790
return;
722-
}
791+
792+
ActionsBar.PageButtons.LeftArrow.OnPressed -= OnLeftArrowPressed;
793+
ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed;
723794

724795
if (_window != null)
725796
{
@@ -747,9 +818,10 @@ private void LoadGui()
747818
_window.FilterButton.OnItemSelected += OnFilterSelected;
748819

749820
if (ActionsBar == null)
750-
{
751821
return;
752-
}
822+
823+
ActionsBar.PageButtons.LeftArrow.OnPressed += OnLeftArrowPressed;
824+
ActionsBar.PageButtons.RightArrow.OnPressed += OnRightArrowPressed;
753825

754826
RegisterActionContainer(ActionsBar.ActionsContainer);
755827

@@ -779,13 +851,10 @@ private void AssignSlots(List<SlotAssignment> assignments)
779851
if (_actionsSystem == null)
780852
return;
781853

782-
_actions.Clear();
783-
foreach (var assign in assignments)
784-
{
785-
_actions.Add(assign.ActionId);
786-
}
854+
foreach (ref var assignment in CollectionsMarshal.AsSpan(assignments))
855+
_pages[assignment.Hotbar][assignment.Slot] = assignment.ActionId;
787856

788-
_container?.SetActionData(_actionsSystem, _actions.ToArray());
857+
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
789858
}
790859

791860
public void RemoveActionContainer()
@@ -822,7 +891,7 @@ private void OnComponentLinked(ActionsComponent component)
822891
return;
823892

824893
LoadDefaultActions();
825-
_container?.SetActionData(_actionsSystem, _actions.ToArray());
894+
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
826895
QueueWindowUpdate();
827896
}
828897

@@ -841,11 +910,27 @@ private void LoadDefaultActions()
841910
var actions = _actionsSystem.GetClientActions().Where(action => action.Comp.AutoPopulate).ToList();
842911
actions.Sort(ActionComparer);
843912

844-
_actions.Clear();
845-
foreach (var (action, _) in actions)
913+
var offset = 0;
914+
var totalPages = _pages.Count;
915+
var pagesLeft = totalPages;
916+
var currentPage = DefaultPageIndex;
917+
while (pagesLeft > 0)
846918
{
847-
if (!_actions.Contains(action))
848-
_actions.Add(action);
919+
var page = _pages[currentPage];
920+
var pageSize = page.Size;
921+
922+
for (var slot = 0; slot < pageSize; slot++)
923+
if (slot + offset < actions.Count)
924+
page[slot] = actions[slot + offset].Id;
925+
else
926+
page[slot] = null;
927+
928+
offset += pageSize;
929+
currentPage++;
930+
if (currentPage == totalPages)
931+
currentPage = 0;
932+
933+
pagesLeft--;
849934
}
850935
}
851936

@@ -956,4 +1041,22 @@ private void StopTargeting()
9561041
handOverlay.IconOverride = null;
9571042
handOverlay.EntityOverride = null;
9581043
}
1044+
1045+
//TODO: Serialize this shit
1046+
private sealed class ActionPage(int size)
1047+
{
1048+
public readonly EntityUid?[] Data = new EntityUid?[size];
1049+
1050+
public EntityUid? this[int index]
1051+
{
1052+
get => Data[index];
1053+
set => Data[index] = value;
1054+
}
1055+
1056+
public static implicit operator EntityUid?[](ActionPage p) => p.Data.ToArray();
1057+
1058+
public void Clear() => Array.Fill(Data, null);
1059+
1060+
public int Size => Data.Length;
1061+
}
9591062
}

0 commit comments

Comments
 (0)