Skip to content

Revert Bad "SS13" Action Bar #1333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,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);
Expand Down
4 changes: 2 additions & 2 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,9 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto

AddHeader("ui-options-header-hotbar");
foreach (var boundKey in ContentKeyFunctions.GetHotbarBoundKeys())
{
AddButton(boundKey);
}
foreach (var boundKey in ContentKeyFunctions.GetLoadoutBoundKeys())
AddButton(boundKey);

AddHeader("ui-options-header-shuttle");
AddButton(ContentKeyFunctions.ShuttleStrafeUp);
Expand Down
197 changes: 150 additions & 47 deletions Content.Client/UserInterface/Systems/Actions/ActionUIController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using Content.Client.Actions;
using Content.Client.Construction;
using Content.Client.Gameplay;
Expand Down Expand Up @@ -50,14 +51,17 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
[UISystemDependency] private readonly TargetOutlineSystem? _targetOutline = default;
[UISystemDependency] private readonly SpriteSystem _spriteSystem = default!;

private const int DefaultPageIndex = 0;
private ActionButtonContainer? _container;
private readonly List<EntityUid?> _actions = new();
private readonly List<ActionPage> _pages = new();
private int _currentPageIndex = DefaultPageIndex;
private readonly DragDropHelper<ActionButton> _menuDragHelper;
private readonly TextureRect _dragShadow;
private ActionsWindow? _window;

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

public bool IsDragging => _menuDragHelper.IsDragging;

Expand All @@ -75,8 +79,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()
Expand Down Expand Up @@ -129,6 +138,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()))
Expand Down Expand Up @@ -315,34 +333,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)
Expand All @@ -353,19 +417,24 @@ 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;

// 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, _actions.ToArray());
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
}

private void ActionButtonPressed(ButtonEventArgs args)
Expand Down Expand Up @@ -512,7 +581,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;
Expand All @@ -523,27 +592,28 @@ private void SetAction(ActionButton button, EntityUid? actionId, bool updateSlot
{
button.ClearData();
if (_container?.TryGetButtonIndex(button, out position) ?? false)
{
if (_actions.Count > position && position >= 0)
_actions.RemoveAt(position);
}
CurrentPage[position] = null;
}
else if (button.TryReplaceWith(actionId.Value, _actionsSystem) &&
_container != null &&
_container.TryGetButtonIndex(button, out position))
{
if (position >= _actions.Count)
{
_actions.Add(actionId);
}
if (position >= 0 && position < CurrentPage.Size)
CurrentPage[position] = actionId;
else
{
_actions[position] = actionId;
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?
}
}

if (updateSlots)
_container?.SetActionData(_actionsSystem, _actions.ToArray());
}

private void DragAction()
Expand All @@ -559,14 +629,14 @@ private void DragAction()
if (currentlyHovered is ActionButton button)
{
swapAction = button.ActionId;
SetAction(button, action, false);
SetAction(button, action);
}

if (dragged.Parent is ActionButtonContainer)
SetAction(dragged, swapAction, false);
SetAction(dragged, swapAction);

if (_actionsSystem != null)
_container?.SetActionData(_actionsSystem, _actions.ToArray());
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);

_menuDragHelper.EndDrag();
}
Expand Down Expand Up @@ -717,9 +787,10 @@ private void UnloadGui()
_actionsSystem?.UnlinkAllActions();

if (ActionsBar == null)
{
return;
}

ActionsBar.PageButtons.LeftArrow.OnPressed -= OnLeftArrowPressed;
ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed;

if (_window != null)
{
Expand Down Expand Up @@ -747,9 +818,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);

Expand Down Expand Up @@ -779,13 +851,10 @@ private void AssignSlots(List<SlotAssignment> 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()
Expand Down Expand Up @@ -822,7 +891,7 @@ private void OnComponentLinked(ActionsComponent component)
return;

LoadDefaultActions();
_container?.SetActionData(_actionsSystem, _actions.ToArray());
_container?.SetActionData(_actionsSystem, _pages[_currentPageIndex]);
QueueWindowUpdate();
}

Expand All @@ -841,11 +910,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--;
}
}

Expand Down Expand Up @@ -956,4 +1041,22 @@ 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;
}
}
Loading
Loading