diff --git a/Enums/ElementKind.cs b/Enums/ElementKind.cs index aa8a0a2..996c52d 100644 --- a/Enums/ElementKind.cs +++ b/Enums/ElementKind.cs @@ -2,37 +2,86 @@ using System; namespace HSUI.Enums; -// Hashes from HUD layout (AddonNameHash). Sources: HSUI, HUDManager plugin +/// +/// HUD layout AddonNameHash values. Uses CRC32 of "AddonName_a". +/// Source: https://github.com/zacharied/FFXIV-Plugin-HudManager/blob/testing/HUDManager/Structs/ElementKind.cs +/// public enum ElementKind : uint { - Hotbar1 = 0xC48D3605, // _ActionBar_a - Hotbar2 = 0xFB7B6E1E, // _ActionBar01_a - Hotbar3 = 0xF93DD047, // _ActionBar02_a - Hotbar4 = 0xF8FFBA70, // _ActionBar03_a - Hotbar5 = 0xFDB0ACF5, // _ActionBar04_a - Hotbar6 = 0xFC72C6C2, // _ActionBar05_a - Hotbar7 = 0xFE34789B, // _ActionBar06_a - Hotbar8 = 0xFFF612AC, // _ActionBar07_a - Hotbar9 = 0xF4AA5591, // _ActionBar08_a - Hotbar10 = 0xF5683FA6, // _ActionBar09_a - PetHotbar = 0xD8D188FF, // _ActionBarEx_a - CrossHotbar = 0xBA81E8D1, // _ActionCross_a - LeftWCrossHotbar = 0x6665735D, // _ActionDoubleCrossL_a - RightWCrossHotbar = 0x70DDFD27, // _ActionDoubleCrossR_a - ParameterBar = 0x9818E23E, // _ParameterWidget - player HP/MP - TargetBar = 0x9139E9FD, // target info - FocusTargetBar = 0xC28E7D1F, - ProgressBar = 0xECB1E391, // cast bar - ExperienceBar = 0x21E32D4E, - LimitGauge = 0xC7A40A8A, - StatusEffects = 0x4A5B6A16, // player buffs/debuffs - StatusInfoEnhancements = 0x1F320624, - StatusInfoEnfeeblements = 0x1E7A7A83, - TargetInfoHp = 0xBD411F17, - TargetInfoProgressBar = 0xCB5BCCCF, - TargetInfoStatus = 0x070F4E6B, - PartyList = 0x3D3B34F9, - EnemyList = 0xB8C30AC5, + // Hotbars + Hotbar1 = 0xC48D3605, // _ActionBar_a + Hotbar2 = 0xFB7B6E1E, // _ActionBar01_a + Hotbar3 = 0xF93DD047, // _ActionBar02_a + Hotbar4 = 0xF8FFBA70, // _ActionBar03_a + Hotbar5 = 0xFDB0ACF5, // _ActionBar04_a + Hotbar6 = 0xFC72C6C2, // _ActionBar05_a + Hotbar7 = 0xFE34789B, // _ActionBar06_a + Hotbar8 = 0xFFF612AC, // _ActionBar07_a + Hotbar9 = 0xF4AA5591, // _ActionBar08_a + Hotbar10 = 0xF5683FA6, // _ActionBar09_a + PetHotbar = 0xD8D188FF, // _ActionBarEx_a + CrossHotbar = 0xBA81E8D1, // _ActionCross_a + LeftWCrossHotbar = 0x6665735D, + RightWCrossHotbar = 0x70DDFD27, + + // Player & target + ParameterBar = 0x981EC49E, // _ParameterWidget_a (player HP/MP) + ProgressBar = 0xECB29811, // _CastBar_a + TargetBar = 0x913EC97D, // _TargetInfo_a + TargetInfoHp = 0xBD128377, // _TargetInfoMainTarget_a + TargetInfoProgressBar = 0xCB54A2EF, // _TargetInfoCastBar_a + TargetInfoStatus = 0x076F596B, // _TargetInfoBuffDebuff_a + FocusTargetBar = 0xC292F05F, // _FocusTargetInfo_a + + // Party & lists + PartyList = 0x3D425039, // _PartyList_a + AllianceList1 = 0x2943729A, + AllianceList2 = 0x2B05CCC3, + EnemyList = 0xB8BD6685, // _EnemyList_a + + // Misc HUD + ExperienceBar = 0x21E53CCE, // _Exp_a + LimitGauge = 0xC79F450A, // _LimitBreak_a + StatusEffects = 0x4A569616, // _Status_a + StatusInfoEnhancements = 0x1F4230B4, // _StatusCustom0_a + StatusInfoEnfeeblements = 0x1E805A83, // _StatusCustom1_a + StatusInfoOther = 0x1CC6E4DA, // _StatusCustom2_a + StatusInfoConditionalEnhancements = 0x1D048EED, // _StatusCustom3_a + + // Job gauges (PLD, WAR, DRK, GNB, WHM, SCH, AST, SGE, MNK, DRG, NIN, SAM, RPR, VPR, BRD, MCH, DNC, BLM, SMN, RDM, PCT) + OathGauge = 0xEFBAFE40, // JobHudPLD0 + BeastGauge = 0x7F5D020A, // JobHudWAR0 + BloodGauge = 0xF04E8778, // JobHudDRK0 + DarksideGauge = 0xF18CED4F, // JobHudDRK1 + PowderGauge = 0xAEC2C0DF, // JobHudGNB0 + HealingGauge = 0x7A3727B2, // JobHudWHM0 + AetherflowGaugeSch = 0xCADD58CB, // JobHudACN0 + FaerieGauge = 0xA1A8A487, // JobHudSCH0 + ArcanaGauge = 0x959978B2, // JobHudAST0 + EukrasiaGauge = 0x11D01C49, // JobHudGFF0 (SGE) + AddersgallGauge = 0x1012767E, // JobHudGFF1 (SGE) + MastersGauge = 0x7251AC33, // JobHudMNK0 + ChakraGauge = 0x7393C604, // JobHudMNK1 + DragonGauge = 0xBA9838C0, // JobHudDRG0 + NinkiGauge = 0x713BF2BF, // JobHudNIN0 + Kazematoi = 0x6CD4313E, // JobHudNIN1v70 (NIN) + KenkiGauge = 0xECB607D5, // JobHudSAM0 + SenGauge = 0xED746DE2, // JobHudSAM1 + SoulGauge = 0xA2D9B660, // JobHudRRP0 (RPR) + DeathGauge = 0xA31BDC57, // JobHudRRP1 (RPR) + Vipersight = 0xB7694B56, // JobHudRDB0 (VIP) + SerpentOfferingsGauge = 0xB6AB2161, // JobHudRDB1 (VIP) + SongGauge = 0x7E747433, // JobHudBRD0 + HeatGauge = 0x9874C76C, // JobHudMCH0 + StepGauge = 0x90EAD514, // JobHudDNC0 + FourfoldFeathers = 0x9128BF23, // JobHudDNC1 + ElementalGauge = 0xDCAC125A, // JobHudBLM0 + AstralGauge = 0xDD6E786D, // JobHudBLM1 + AetherflowGaugeSmn = 0x3BF3453A, // JobHudSMN0 + TranceGauge = 0x3A312F0D, // JobHudSMN1 + BalanceGauge = 0xEF0A5B00, // JobHudRDM0 + Canvases = 0x7A6A6A42, // JobHudRPM0 (PCT) + PaletteGauge = 0x7BA80075, // JobHudRPM1 (PCT) } public static class ElementKindHelper @@ -55,4 +104,34 @@ public static class ElementKindHelper _ => throw new ArgumentOutOfRangeException(nameof(hotBarId)) }; } -} \ No newline at end of file + + /// Returns ElementKind hashes for the current job's gauges (0-4 gauges per job). + public static ElementKind[] GetJobGaugeElementKinds(uint jobId) + { + return jobId switch + { + 19 => new[] { ElementKind.OathGauge }, // PLD + 21 => new[] { ElementKind.MastersGauge, ElementKind.ChakraGauge }, // MNK + 22 => new[] { ElementKind.BeastGauge }, // WAR + 23 => new[] { ElementKind.DragonGauge }, // DRG + 24 => new[] { ElementKind.SongGauge }, // BRD + 25 => new[] { ElementKind.HealingGauge }, // WHM + 27 => new[] { ElementKind.ElementalGauge, ElementKind.AstralGauge }, // BLM + 28 => new[] { ElementKind.AetherflowGaugeSmn, ElementKind.TranceGauge }, // SMN + 29 => new[] { ElementKind.AetherflowGaugeSch, ElementKind.FaerieGauge }, // SCH + 30 => new[] { ElementKind.NinkiGauge, ElementKind.Kazematoi }, // NIN + 31 => new[] { ElementKind.HeatGauge }, // MCH + 32 => new[] { ElementKind.BloodGauge, ElementKind.DarksideGauge }, // DRK + 33 => new[] { ElementKind.ArcanaGauge }, // AST + 34 => new[] { ElementKind.KenkiGauge, ElementKind.SenGauge }, // SAM + 35 => new[] { ElementKind.BalanceGauge }, // RDM + 37 => new[] { ElementKind.PowderGauge }, // GNB + 38 => new[] { ElementKind.StepGauge, ElementKind.FourfoldFeathers }, // DNC + 39 => new[] { ElementKind.SoulGauge, ElementKind.DeathGauge }, // RPR + 40 => new[] { ElementKind.EukrasiaGauge, ElementKind.AddersgallGauge }, // SGE + 41 => new[] { ElementKind.Vipersight, ElementKind.SerpentOfferingsGauge },// VPR + 42 => new[] { ElementKind.Canvases, ElementKind.PaletteGauge }, // PCT + _ => Array.Empty() + }; + } +} diff --git a/HSUI.csproj b/HSUI.csproj index 29baf89..561ec70 100644 --- a/HSUI.csproj +++ b/HSUI.csproj @@ -9,9 +9,9 @@ HSUI - 1.0.2.3 - 1.0.2.3 - 1.0.2.3 + 1.0.2.4 + 1.0.2.4 + 1.0.2.4 diff --git a/HSUI.json b/HSUI.json index e78ead6..5dfd083 100644 --- a/HSUI.json +++ b/HSUI.json @@ -2,7 +2,7 @@ "Author": "Knack117", "Name": "HSUI", "InternalName": "HSUI", - "AssemblyVersion": "1.0.2.3", + "AssemblyVersion": "1.0.2.4", "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", "RepoUrl": "https://github.com/Knack117/HSUI", diff --git a/Interface/HudHelper.cs b/Interface/HudHelper.cs index 5151472..02ef2f4 100644 --- a/Interface/HudHelper.cs +++ b/Interface/HudHelper.cs @@ -2,6 +2,7 @@ using Dalamud.Game.Addon.Lifecycle; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects.SubKinds; using HSUI.Config; +using HSUI.Enums; using HSUI.Helpers; using HSUI.Interface.EnemyList; using HSUI.Interface.GeneralElements; @@ -194,70 +195,66 @@ namespace HSUI.Interface } var hashesToHide = new List(); - void AddHashes(params string[] addonNames) + void AddElements(params ElementKind[] elements) { - foreach (var name in addonNames) - { - var h = HudLayoutHashHelper.GetHash(name); - if (h != 0) - hashesToHide.Add(h); - } + foreach (var e in elements) + hashesToHide.Add((uint)e); } + // Use ElementKind hashes (HUD Layout config) — the proper way per DelvUI. Source: HUDManager ElementKind.cs var hotbarsConfig = ConfigurationManager.Instance?.GetConfigObject(); - if (hotbarsConfig?.Enabled == true) + if (hotbarsConfig?.Enabled == true && AnyHotbarEnabled()) { - AddHashes("_ActionBar", "_ActionBar01", "_ActionBar02", "_ActionBar03", "_ActionBar04", - "_ActionBar05", "_ActionBar06", "_ActionBar07", "_ActionBar08", "_ActionBar09", "_ActionCross"); + AddElements(ElementKind.Hotbar1, ElementKind.Hotbar2, ElementKind.Hotbar3, ElementKind.Hotbar4, ElementKind.Hotbar5, + ElementKind.Hotbar6, ElementKind.Hotbar7, ElementKind.Hotbar8, ElementKind.Hotbar9, ElementKind.Hotbar10, ElementKind.CrossHotbar); } var playerUnitFrame = ConfigurationManager.Instance?.GetConfigObject(); if (playerUnitFrame?.Enabled == true) - AddHashes("_ParameterWidget"); + AddElements(ElementKind.ParameterBar); var targetUnitFrame = ConfigurationManager.Instance?.GetConfigObject(); if (targetUnitFrame?.Enabled == true) - AddHashes("_TargetInfo", "_TargetInfoMainTarget", "_TargetInfoCastBar", "_TargetInfoBuffDebuff"); + AddElements(ElementKind.TargetBar, ElementKind.TargetInfoHp, ElementKind.TargetInfoProgressBar, ElementKind.TargetInfoStatus); var focusUnitFrame = ConfigurationManager.Instance?.GetConfigObject(); if (focusUnitFrame?.Enabled == true) - AddHashes("_FocusTargetInfo"); + AddElements(ElementKind.FocusTargetBar); var playerCastbar = ConfigurationManager.Instance?.GetConfigObject(); if (playerCastbar?.Enabled == true) - AddHashes("_CastBar"); + AddElements(ElementKind.ProgressBar); var expBar = ConfigurationManager.Instance?.GetConfigObject(); if (expBar?.Enabled == true) - AddHashes("_Exp"); + AddElements(ElementKind.ExperienceBar); var limitBreak = ConfigurationManager.Instance?.GetConfigObject(); if (limitBreak?.Enabled == true) - AddHashes("_LimitBreak"); + AddElements(ElementKind.LimitGauge); var playerBuffs = ConfigurationManager.Instance?.GetConfigObject(); var playerDebuffs = ConfigurationManager.Instance?.GetConfigObject(); if (playerBuffs?.Enabled == true || playerDebuffs?.Enabled == true) - AddHashes("_Status", "_StatusCustom0", "_StatusCustom1", "_StatusCustom2", "_StatusCustom3"); + AddElements(ElementKind.StatusEffects, ElementKind.StatusInfoEnhancements, ElementKind.StatusInfoEnfeeblements, ElementKind.StatusInfoOther, ElementKind.StatusInfoConditionalEnhancements); var partyFrames = ConfigurationManager.Instance?.GetConfigObject(); if (partyFrames?.Enabled == true) - AddHashes("_PartyList"); + AddElements(ElementKind.PartyList); var enemyList = ConfigurationManager.Instance?.GetConfigObject(); if (enemyList?.Enabled == true) - AddHashes("_EnemyList"); - - // Hide NamePlate when HSUI nameplates are enabled. We read icon IDs from the addon (still updated when hidden) - // and draw our own quest icons (! ? above NPCs) via NPC nameplate IconConfig. - var nameplatesConfig = ConfigurationManager.Instance?.GetConfigObject(); - if (nameplatesConfig?.Enabled == true) - AddHashes("NamePlate"); + AddElements(ElementKind.EnemyList); + // NamePlate is not in HUD Layout config; use UpdateDefaultNameplates (IsVisible) for that if (IsCurrentJobHudEnabled()) { - foreach (var name in GetCurrentJobGaugeAddonNames()) - AddHashes(name); + var player = Plugin.ObjectTable.LocalPlayer; + if (player != null) + { + foreach (var ek in ElementKindHelper.GetJobGaugeElementKinds(player.ClassJob.RowId)) + hashesToHide.Add((uint)ek); + } } SetGameHudElementsHidden(hashesToHide.ToArray(), false); diff --git a/changelog.md b/changelog.md index f99a3b6..8da6be1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +# 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. + # 1.0.2.3 - **Hotbars**: Keypress flash indicator — slots flash when you press their keybind (or click). Toggle in Hotbars → per-hotbar "Show Keypress Flash". diff --git a/pluginmaster.json b/pluginmaster.json index 71b205f..ed90456 100644 --- a/pluginmaster.json +++ b/pluginmaster.json @@ -4,9 +4,9 @@ "Name": "HSUI", "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.", - "Changelog": "Hotbars: Keypress flash indicator when pressing slot keybinds. Toggle per hotbar.", + "Changelog": "HUD Layout: Use proper HUD config instead of memory reads. ElementKind hashes from HUDManager for hiding default elements.", "InternalName": "HSUI", - "AssemblyVersion": "1.0.2.3", + "AssemblyVersion": "1.0.2.4", "RepoUrl": "https://github.com/Knack117/HSUI", "ApplicableVersion": "any", "Tags": ["UI", "HUD", "Unit Frames", "Nameplates", "Party Frames", "Hotbars"], @@ -14,10 +14,10 @@ "DalamudApiLevel": 14, "IconUrl": "https://raw.githubusercontent.com/Knack117/HSUI/main/Media/Images/icon.png", "ImageUrls": [], - "DownloadLinkInstall": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.3/latest.zip", + "DownloadLinkInstall": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip", "IsHide": false, "IsTestingExclusive": false, - "DownloadLinkTesting": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.3/latest.zip", - "DownloadLinkUpdate": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.3/latest.zip" + "DownloadLinkTesting": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip", + "DownloadLinkUpdate": "https://github.com/Knack117/HSUI/releases/download/v1.0.2.4/latest.zip" } ]