v1.0.2.5: More accurate hotbar cooldowns (ActionManager), fix tooltip cast/recast display
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+3
-3
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>HSUI</AssemblyName>
|
<AssemblyName>HSUI</AssemblyName>
|
||||||
<AssemblyVersion>1.0.2.4</AssemblyVersion>
|
<AssemblyVersion>1.0.2.5</AssemblyVersion>
|
||||||
<FileVersion>1.0.2.4</FileVersion>
|
<FileVersion>1.0.2.5</FileVersion>
|
||||||
<InformationalVersion>1.0.2.4</InformationalVersion>
|
<InformationalVersion>1.0.2.5</InformationalVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"Author": "Knack117",
|
"Author": "Knack117",
|
||||||
"Name": "HSUI",
|
"Name": "HSUI",
|
||||||
"InternalName": "HSUI",
|
"InternalName": "HSUI",
|
||||||
"AssemblyVersion": "1.0.2.4",
|
"AssemblyVersion": "1.0.2.5",
|
||||||
"Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.",
|
"Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.",
|
||||||
"ApplicableVersion": "any",
|
"ApplicableVersion": "any",
|
||||||
"RepoUrl": "https://github.com/Knack117/HSUI",
|
"RepoUrl": "https://github.com/Knack117/HSUI",
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.String;
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
||||||
using KamiToolKit.Controllers;
|
using KamiToolKit.Controllers;
|
||||||
|
using static FFXIVClientStructs.FFXIV.Client.Game.ActionManager;
|
||||||
|
|
||||||
namespace HSUI.Helpers
|
namespace HSUI.Helpers
|
||||||
{
|
{
|
||||||
@@ -114,19 +116,72 @@ namespace HSUI.Helpers
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int secsLeft = 0;
|
|
||||||
int pct = slot->GetSlotActionCooldownPercentage(&secsLeft, 0);
|
|
||||||
bool usable = slot->IsSlotUsable(slot->ApparentSlotType, slot->ApparentActionId);
|
bool usable = slot->IsSlotUsable(slot->ApparentSlotType, slot->ApparentActionId);
|
||||||
uint iconId = slot->IconId;
|
uint iconId = slot->IconId;
|
||||||
uint actionId = slot->ApparentActionId;
|
uint actionId = slot->ApparentActionId;
|
||||||
var slotType = slot->ApparentSlotType;
|
var slotType = slot->ApparentSlotType;
|
||||||
|
|
||||||
|
(int pct, int secsLeft) = GetSlotCooldown(slot);
|
||||||
list.Add(new SlotInfo(iconId, false, usable, pct, secsLeft, actionId, slotType, keybind));
|
list.Add(new SlotInfo(iconId, false, usable, pct, secsLeft, actionId, slotType, keybind));
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets cooldown for a hotbar slot. For Action/GeneralAction/PetAction, uses ActionManager recast API
|
||||||
|
/// (more accurate for adjusted IDs, recast groups). Falls back to slot's GetSlotActionCooldownPercentage for Items/Macros.
|
||||||
|
/// </summary>
|
||||||
|
private static unsafe (int CooldownPercent, int SecondsLeft) GetSlotCooldown(RaptureHotbarModule.HotbarSlot* slot)
|
||||||
|
{
|
||||||
|
if (slot == null) return (0, 0);
|
||||||
|
|
||||||
|
var slotType = slot->ApparentSlotType;
|
||||||
|
uint actionId = slot->ApparentActionId;
|
||||||
|
if (actionId == 0) return GetSlotCooldownFromSlot(slot);
|
||||||
|
|
||||||
|
var actionManager = ActionManager.Instance();
|
||||||
|
if (actionManager == null) return GetSlotCooldownFromSlot(slot);
|
||||||
|
|
||||||
|
ActionType? actionType = slotType switch
|
||||||
|
{
|
||||||
|
RaptureHotbarModule.HotbarSlotType.Action => ActionType.Action,
|
||||||
|
RaptureHotbarModule.HotbarSlotType.GeneralAction => ActionType.GeneralAction,
|
||||||
|
RaptureHotbarModule.HotbarSlotType.PetAction => ActionType.PetAction,
|
||||||
|
RaptureHotbarModule.HotbarSlotType.CraftAction => ActionType.CraftAction,
|
||||||
|
RaptureHotbarModule.HotbarSlotType.Item => ActionType.Item,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (actionType.HasValue)
|
||||||
|
{
|
||||||
|
// GetAdjustedActionId resolves Continuation, Egi Assaults, etc. Only applies to Action type
|
||||||
|
uint effectiveId = actionType.Value == ActionType.Action
|
||||||
|
? actionManager->GetAdjustedActionId(actionId)
|
||||||
|
: actionId;
|
||||||
|
float total = actionManager->GetRecastTime(actionType.Value, effectiveId);
|
||||||
|
float elapsed = actionManager->GetRecastTimeElapsed(actionType.Value, effectiveId);
|
||||||
|
|
||||||
|
if (total > 0.001f && elapsed < total)
|
||||||
|
{
|
||||||
|
float remaining = total - elapsed;
|
||||||
|
int pct = (int)Math.Clamp((remaining / total) * 100f, 0, 100);
|
||||||
|
int secsLeft = (int)Math.Ceiling(remaining);
|
||||||
|
return (pct, secsLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetSlotCooldownFromSlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static unsafe (int CooldownPercent, int SecondsLeft) GetSlotCooldownFromSlot(RaptureHotbarModule.HotbarSlot* slot)
|
||||||
|
{
|
||||||
|
if (slot == null) return (0, 0);
|
||||||
|
int secsLeft = 0;
|
||||||
|
int pct = slot->GetSlotActionCooldownPercentage(&secsLeft, 0);
|
||||||
|
return (pct, secsLeft);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the default game keybind label for a hotbar slot (Hotbar 1: 1,2,...,0,-,=; Bar 2: Ctrl+1..12; etc.).
|
/// Returns the default game keybind label for a hotbar slot (Hotbar 1: 1,2,...,0,-,=; Bar 2: Ctrl+1..12; etc.).
|
||||||
/// hotbarIndex 1–10, slotIndex 0–11. Used to mirror the default hotbar keybind display.
|
/// hotbarIndex 1–10, slotIndex 0–11. Used to mirror the default hotbar keybind display.
|
||||||
|
|||||||
@@ -1378,8 +1378,8 @@ namespace HSUI.Interface.GeneralElements
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var parts = new List<string>();
|
var parts = new List<string>();
|
||||||
float castSec = action.Cast100ms / 100f;
|
float castSec = action.Cast100ms / 10f; // Cast100ms/Recast100ms are in 100ms units
|
||||||
float recastSec = action.Recast100ms / 100f;
|
float recastSec = action.Recast100ms / 10f;
|
||||||
if (castSec > 0)
|
if (castSec > 0)
|
||||||
parts.Add($"Cast: {castSec:F1}s");
|
parts.Add($"Cast: {castSec:F1}s");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
# 1.0.2.5
|
||||||
|
- **Hotbars**: More accurate cooldown tracking using ActionManager recast API (fixes actions like Continuation, Egi Assaults).
|
||||||
|
- **Tooltips**: Fixed cast/recast display (60s was showing as 6.0s; correct Cast100ms/Recast100ms divisor).
|
||||||
|
|
||||||
# 1.0.2.4
|
# 1.0.2.4
|
||||||
- **HUD Layout**: Switched to proper HUD Layout config (AddonConfig) instead of memory reads. Uses authoritative ElementKind hashes from HUDManager for hiding default elements. Job gauges now use layout hashes.
|
- **HUD Layout**: Switched to proper HUD Layout config (AddonConfig) instead of memory reads. Uses authoritative ElementKind hashes from HUDManager for hiding default elements. Job gauges now use layout hashes.
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -4,9 +4,9 @@
|
|||||||
"Name": "HSUI",
|
"Name": "HSUI",
|
||||||
"Punchline": "A modern HUD replacement built for customization.",
|
"Punchline": "A modern HUD replacement built for customization.",
|
||||||
"Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.",
|
"Description": "HSUI provides a highly configurable HUD replacement for FFXIV, recreated from DelvUI using KamiToolKit, FFXIVClientStructs, and Dalamud. Features unit frames, castbars, job gauges, nameplates, party frames, status effects, enemy list, configurable hotbars with drag-and-drop, and profiles.",
|
||||||
"Changelog": "HUD Layout: Use proper HUD config instead of memory reads. ElementKind hashes from HUDManager for hiding default elements.",
|
"Changelog": "Hotbars: More accurate cooldown tracking. Tooltips: Fixed cast/recast display (60s was showing as 6.0s).",
|
||||||
"InternalName": "HSUI",
|
"InternalName": "HSUI",
|
||||||
"AssemblyVersion": "1.0.2.4",
|
"AssemblyVersion": "1.0.2.5",
|
||||||
"RepoUrl": "https://github.com/Knack117/HSUI",
|
"RepoUrl": "https://github.com/Knack117/HSUI",
|
||||||
"ApplicableVersion": "any",
|
"ApplicableVersion": "any",
|
||||||
"Tags": ["UI", "HUD", "Unit Frames", "Nameplates", "Party Frames", "Hotbars"],
|
"Tags": ["UI", "HUD", "Unit Frames", "Nameplates", "Party Frames", "Hotbars"],
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
"DalamudApiLevel": 14,
|
"DalamudApiLevel": 14,
|
||||||
"IconUrl": "https://raw.githubusercontent.com/Knack117/HSUI/main/Media/Images/icon.png",
|
"IconUrl": "https://raw.githubusercontent.com/Knack117/HSUI/main/Media/Images/icon.png",
|
||||||
"ImageUrls": [],
|
"ImageUrls": [],
|
||||||
"DownloadLinkInstall": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip",
|
"DownloadLinkInstall": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.5/latest.zip",
|
||||||
"IsHide": false,
|
"IsHide": false,
|
||||||
"IsTestingExclusive": false,
|
"IsTestingExclusive": false,
|
||||||
"DownloadLinkTesting": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip",
|
"DownloadLinkTesting": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.5/latest.zip",
|
||||||
"DownloadLinkUpdate": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip"
|
"DownloadLinkUpdate": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.5/latest.zip"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user