feat: Controller hotbars with cross layout, separate storage, and sync with game
- Add controller hotbars: 8 cross bars (L2/R2 style), separate from normal hotbars 1-8 - Controller bar slot data stored in config (not game StandardHotbars) so layouts can differ per mode - Drag-and-drop on controller bars: from game, shift+drag rearrange, release outside to clear - Independent controller bar keybinds with modifier+trigger combinations (e.g. L2+South) - Optional 'Sync bar mode with game client': follow Character Config Mouse/Gamepad toggle (PadMode) - Clone/copy actions: normal hotbars ↔ controller bars - Restore controller bar layout button; deploy to devPlugins on Release build Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.ClientState.GamePad;
|
||||
using Dalamud.Plugin.Services;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
||||
using HSUI.Interface.GeneralElements;
|
||||
|
||||
namespace HSUI.Helpers
|
||||
{
|
||||
/// <summary>Provides current cross hotbar trigger state (L2/R2) and game controller-mode detection for sync with game client.</summary>
|
||||
public static class ControllerHotbarHelper
|
||||
{
|
||||
private static IGamepadState? _gamepadState;
|
||||
|
||||
public static void SetGamepadState(IGamepadState? gamepadState)
|
||||
{
|
||||
_gamepadState = gamepadState;
|
||||
}
|
||||
|
||||
/// <summary>True when the game's Character Configuration has controller (gamepad) mode enabled. Reads the PadMode config option so bar mode follows the toggle and does not switch on input.</summary>
|
||||
public static unsafe bool IsGameInControllerMode()
|
||||
{
|
||||
try
|
||||
{
|
||||
Framework* framework = Framework.Instance();
|
||||
if (framework == null) return false;
|
||||
int option = (int)ConfigOption.PadMode;
|
||||
if (framework->SystemConfig.SystemConfigBase.UiConfig.ConfigCount <= option)
|
||||
return false;
|
||||
uint value = framework->SystemConfig.SystemConfigBase.UiConfig.ConfigEntry[option].Value.UInt;
|
||||
// PadMode: 0 = keyboard/mouse, 1 = gamepad
|
||||
return value != 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns the current trigger combo for which cross bar should be visible. Uses L2/R2 from gamepad.</summary>
|
||||
public static CrossBarTrigger GetCurrentTrigger()
|
||||
{
|
||||
if (_gamepadState == null)
|
||||
return CrossBarTrigger.None;
|
||||
|
||||
try
|
||||
{
|
||||
// Raw returns float (analog); treat as pressed when > 0.5
|
||||
bool l2 = _gamepadState.Raw(GamepadButtons.L2) > 0.5f;
|
||||
bool r2 = _gamepadState.Raw(GamepadButtons.R2) > 0.5f;
|
||||
|
||||
if (l2 && r2)
|
||||
{
|
||||
// Both held - could distinguish L2 then R2 vs R2 then L2 by order; for now use L2R2
|
||||
return CrossBarTrigger.L2R2;
|
||||
}
|
||||
if (l2) return CrossBarTrigger.L2;
|
||||
if (r2) return CrossBarTrigger.R2;
|
||||
return CrossBarTrigger.None;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return CrossBarTrigger.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user