Update for WoW 12.0.0 (Midnight) Compatibility#461
Update for WoW 12.0.0 (Midnight) Compatibility#461Amadeus- wants to merge 58 commits intoLuxocracy:masterfrom
Conversation
- Implement native StatusBar for health/power bars to handle secret values - Add SafeNumber, SafeHealthPercent, SafeIsDamaged helpers for safe comparisons - Store safe cached values (healthSafe, powermaxSafe, etc.) in unit table - Handle secret values in aura data (issecretvalue checks before table keys) - Disable COMBAT_LOG_EVENT_UNFILTERED (restricted to damage meters in 12.0.0) - Update all TOC files to Interface 120000 with multi-version support - Remove 67 legacy version-specific TOC files (Classic, BCC, Cata, etc.) - Add SetGradient compatibility wrapper (replaces deprecated SetGradientAlpha) - Add C_SpellBook.IsSpellKnown and C_NamePlate.SetNamePlateSize wrappers
Follow-up: Additional WoW 12.0 Secret Value FixesTested on retail 12.0 against normal mobs in the open world. Not tested on classic servers or boss encounters. SummaryThis follow-up commit addresses additional Secret Value issues discovered during live testing that weren't covered in the initial PR:
Fix 1: Raid Target Icons (Skull, X, Moon, etc.)Problem:
Solution:
Files Changed:
Fix 2: Aura/Debuff DisplayProblem: Solution:
Files Changed:
Fix 3: Aura Duration TimersProblem: Solution: local durationObject = C_UnitAuras.GetAuraDuration(unitToken, auraInstanceID)
cooldown:SetCooldownFromDurationObject(durationObject)
cooldown:SetHideCountdownNumbers(false) -- Enable built-in countdown
Behavior:
Files Changed:
Bonus: Debug SystemAdded a debug window system for future troubleshooting (disabled by default): Commands:
Files Changed:
Secret Value API ReferenceAPIs that ACCEPT secret values (
APIs that DO NOT accept secret values:
Detection: if issecretvalue(value) then
-- Value is secret, cannot use in comparisons
end |
- Guard all UnitIsUnit/UnitName/UnitClass calls against secret values in NeatPlatesCore.lua, NeatPlatesUtility.lua, and Text.lua - Remove old PolledHideIn-based TimeLeft timer from aura icons - Standardize on Blizzard's built-in CooldownFrame countdown numbers
- Pass raw GetAuraApplicationDisplayCount value directly to SetText instead of SafeValue stripping secret values during combat - Remove SetUseAuraDisplayTime from durationObject path to prevent conflict with SetCooldownFromDurationObject's internal aura timing - Fix legacy fallback: enable SetUseAuraDisplayTime and remove +0.25 hack
- Use native SetTimerDuration API for C++-level smooth bar animation instead of Lua OnUpdate with raw epoch-millisecond timestamps - Normalize min/max to (0, durationSeconds) for pre-12.0 fallback - Root cause: float precision loss with 13-digit ms timestamps in StatusBar's internal fill fraction computation
- Show standard Blizzard spell tooltip on aura icon mouseover - Use SetUnitAuraByAuraInstanceID with SetSpellByID fallback - Enable mouse hover but pass clicks through to nameplate - Dismiss tooltip when aura expires mid-hover - Add toggle setting in aura options (enabled by default)
- Display interrupter name inline as "Interrupted (NAME)" with class color on the cast bar. - Uses dedicated interrupterName FontString with SetFormattedText and C_ClassColor.GetClassColor to handle secret values at the C++ level. - Left-aligned when name is known, centered when showing only "Interrupted". - Please note that, as of WoW 12.0.0, only the names of those in your group or raid will appear as an "interruptor". If someone outside the group or raid does the interruption, their name will not appear. It will just say "Interrupted".
- Filters nameplate auras to only those Blizzard flags as important (via INCLUDE_NAME_PLATE_ONLY), matching Platynator's behavior. Enabled by default. Located under "Buffs and Debuffs" in settings.
Blizzard's 12.0 Secret Values system makes all aura data (name, spellId, icon, etc.) unreadable during combat, breaking custom aura list matching (Exclude, Mine Only, All). Only auraInstanceID remains non-secret but is per-instance, not per-spell. - Hide Additional Auras UI on 12.0+ with explanatory notice - Short-circuit GetPrefixPriority() on 12.0+ clients - Preserve saved aura list data for pre-12.0 client compatibility - Add /npdebug secrettest diagnostic command
- Add missing GameTooltip:Show() call to OnEnter scripts in NeatPlatesCheckButtonTemplate, NeatPlatesColorButtonTemplate, and NeatPlatesPanelTipTemplate in NeatPlates.xml. - Extend tooltip hover area to include labels for all widget types (checkboxes, sliders, dropdowns, color pickers) in NeatPlatesUtility.lua. Clicking checkbox labels now also toggles the checkbox.
- Blizzard added ADVENTURER and TRAVELER tokens to RAID_CLASS_COLORS in 11.2.x. NeatPlates copies all keys from that table but lacked locale entries for these new tokens, causing 25+ AceLocale warnings on load.
- Add nil checks for activetheme.SetSubText, activetheme.SetScale, activetheme.SetUnitName, and NeatPlatesHubFunctions.SetStyleNamed calls in NeatPlatesCore.lua. These Hub delegate functions may not be present in the activetheme table during initialization or when NeatPlatesHub hasn't fully loaded. Also guard activetheme.Default.hitbox access in UpdateNameplateSize timer callback.
- Guard all uses of unit.guid as table keys in RangeWidget.lua with issecretvalue() checks to comply with WoW 12.0.0 secret values API. Falls back safely when guids are secret during combat.
- Move ShowImportantAurasOnly declaration before function definition to fix Lua upvalue capture (variable was always nil) - Remove duplicate declaration so SetAuraOptions updates correct variable - Re-register UNIT_AURA on Blizzard UnitFrame after UnregisterAllEvents so Blizzard's AurasFrame continues processing auras internally - Add GetBlizzardImportantAuras() to read Blizzard's filtered aura whitelist and filter NeatPlates auras against it
- Guard color.r/g/b comparisons with issecretvalue() check to handle WoW 12.0.0+ secret values during combat. Skips quest objective detection when colors are protected instead of erroring.
- Guard all table lookups using UnitName() results with issecretvalue() checks in HealerTrack, Color, and RangeWidget to prevent crashes when unit names are restricted during combat.
* Enforce minimum hitbox width based on active theme's visual elements so Blizzard's HitTestFrame fully covers the NeatPlates healthbar/castbar/borders. Uses Blizzard's own anchor math: effective click width = SetNamePlateSize(W) - 4. * Disable mouse on NeatPlates StatusBar frames (EnableMouse(false)) so clicks pass through to Blizzard's HitTestFrame for proper unit targeting. * Add /npdebug hitbox command with color-coded visual overlays, mouse-focus tracker, and detailed frame size reporting for diagnosing click issues.
- Guard against WoW 12.0.0 secret table values in NeatPlatesUtility.lua by checking issecretvalue(color) before indexing color.r/g/b fields. Add issecretvalue guard for unit.name comparison in Color.lua.
…alth-based coloring is impossible with secret values in 12.0.0+. The plain "Percent Health" option remains and works correctly
…oW 12.0.0) - Add issecretvalue() guards to prevent errors from secret number/table values returned by WoW APIs during combat: - NeatPlatesUtility.lua: Guard tempThreat and playerThreat comparisons in GetGroupThreatLeader() and GetRelativeThreat() (threat functions) - NeatPlatesUtility.lua: Guard secret tooltip line data (leftColor, leftText, lineType) in quest objective parsing to prevent indexing secret tables - Add nil-safety for lastQuestTitle when earlier lines are skipped```
…tibility - Hub Core.lua/Alpha.lua: Guard bare issecretvalue() calls with existence check to prevent crashes on pre-12.0 clients - NeatPlatesPanel.lua: Add C_SpecializationInfo.GetSpecialization wrapper for 12.0.0+ where the global was removed, fixing profile switching
…bat safety - Hub Color.lua: Fix unguarded UnitIsUnit() calls in threat color and warning border functions (reuse existing guarded var, restructure elseif) - Hub Core.lua: Guard UnitIsUnit() in ThreatExceptions fixate detection - ComboPointWidget: Guard UnitGUID table keys and UnitPower/UnitPowerMax comparisons to prevent combat errors - ResourceWidget: Guard UnitPower/UnitPowerMax in all class GetPower functions (Druid, Rogue, Paladin, Default) - TankTrack: Guard 3 UnitIsUnit boolean tests and 7 UnitGUID table key usages across Classic and Retail code paths - HealerTrack: Guard unit.guid before WidgetList table operations
- NeatPlatesCore: Guard UnitThreatSituation before ThreatReference table key lookup, UnitIsFriend/UnitIsEnemy before boolean tests in target toggle, UnitSelectionColor before arithmetic with cached reaction fallback - NeatPlatesUtility: Guard valueToString against secret value arithmetic - ArenaWidget: Guard unit.rawName before GetArenaIndex in PvP combat
…ellInfo - NeatPlatesCore.lua: Pass 'spellidentifier' (the function parameter) to C_Spell.GetSpellInfo instead of 'spellname' (undefined, always nil)
- Replace GUID-based target detection with UnitIsUnit() in ResourceWidget to handle WoW 12.0.0+ secret values returned by UnitGUID() during combat.
- Add threat percentage widget debug instrumentation with [Threat] and [ThreatInit] output categories, toggled via /npdebug threat. Add pause/resume toggle button to the debug output window for easier copy-paste of debug logs.
- Hide "Show Tug-o-Threat Indicator" and "Show Threat Percentage" settings on 12.0.0+ since UnitDetailedThreatSituation no longer returns usable data from addon code. - Add combat detection fallback for remaining threat features when UnitThreatSituation returns nil, using target-chain heuristics
…n type green. (The original file is left remaining for those who might prefer it.)
…onal Resource Display - Add "Show Power Bar" checkbox that displays a thin light cyan StatusBar showing the player's power (mana/energy/rage) on the target's nameplate, below the class resource icons - Power bar uses pcall-wrapped UnitPower/UnitPowerMax with native StatusBar secret value handling for 12.0.0+ compatibility - Add "Refill Brightness (%)" slider (0-100%, default 80%) to control the brightness of cooldown swipe texture during resource refilling - Remove " Profile" suffix from profile names in settings panel - Remove "(BETA)" label from Personal Resource Display heading - Remove erroneous SetFont(1, .8, 0) call in dropdown highlight code - Add missing ItemTooltip:Hide() after SetOwner in settings tooltips - Remove unnecessary global names from nameplate carrier frames
- Add "Refill Brightness (%)" slider (0-100%, default 80%) to control cooldown swipe brightness during resource refilling - Fix power bar vertical position (was too far below resource icons) - Fix "Show Power Bar" checkbox left-alignment with "Show On:" - Push cast bar and all casting elements down 10px on target nameplate when power bar is visible to prevent overlap - Fix cast bar offset scoping across do blocks (forward declaration) - Fix non-target plates retaining target's cast bar offset
Please note that I have not tested this version on the classic servers. I tested it as much as I could on retail against normal mobs in the open world, but not bosses or special encounters.
Summary
This update brings full compatibility with World of Warcraft 12.0.0 (Midnight), addressing the major API changes introduced in the Midnight expansion's secret value system and combat log restrictions.
Key changes:
Technical Details: Secret Value Handling
In WoW 12.0.0+, certain unit information (health, power, aura details) returns "secret values" during combat. These values cannot be:
health / healthmaxwill error)health < healthmaxwill error)Solution Approach
Native StatusBar for Health/Power Bars: The core solution uses WoW's native
StatusBarwidget, which hasSecretArguments = "AllowedWhenTainted"at the C++ level. This allowsSetValue()andSetMinMaxValues()to accept secret values directly without Lua ever needing to read them back.Safe Value Caching: The unit table now includes "safe" versions of health/power values:
unit.healthSafe/unit.healthmaxSafeunit.powerSafe/unit.powermaxSafeThese are populated with the numeric value when available, or a fallback when the value is secret.
Helper Functions: New helper functions in
NeatPlatesHubHelpers:SafeNumber(value, fallback)- Returns numeric value or fallback if secretSafeHealthPercent(unit)- Safe health percentage calculationSafeIsDamaged(unit)- Safe "health < healthmax" comparisonSafeHasHealth(unit)- Safe "health > 0" checkAura Data Handling: Direct field access from
C_UnitAuras.GetAuraDataByIndex()instead ofAuraUtil.UnpackAuraData()which fails on secret values. All aura field usages now checkissecretvalue()before comparisons or table key operations.Combat Log Restriction
COMBAT_LOG_EVENT_UNFILTEREDis no longer available to addons only in 12.0.0+. This addon now:UNIT_SPELLCAST_INTERRUPTEDeventsAPI Migrations
C_SpellBook.IsSpellKnownreplaces deprecatedIsSpellKnownC_NamePlate.SetNamePlateSizereplaces separate friendly/enemy size functionsSetGradientwith ColorMixin replaces deprecatedSetGradientAlphaC_CombatLog.GetCurrentEventInforeplacesCombatLogGetCurrentEventInfoTesting Notes
Breaking Changes
Files Modified
Core Files (Secret Value Handling)
NeatPlates/NeatPlatesCore.lua- Version detection, safe value helpers, secret-aware unit updatesNeatPlates/NeatPlatesStatusbar.lua- Complete rewrite with native StatusBar for 12.0.0+NeatPlates/NeatPlatesUtility.lua- Minor updatesNeatPlatesHub/Helpers.lua- New SafeNumber, SafeHealthPercent, SafeIsDamaged, SafeHasHealth helpersHub Functions (Safe Comparisons)
NeatPlatesHub/functions/Alpha.lua- Use safe helpers for health-based alphaNeatPlatesHub/functions/Color.lua- Use safe helpers for health-based coloringNeatPlatesHub/functions/Core.lua- Safe value compatibilityNeatPlatesHub/functions/Filter.lua- Safe value compatibilityNeatPlatesHub/functions/Scale.lua- Use safe helpers for health-based scalingNeatPlatesHub/functions/Style.lua- Safe value compatibilityNeatPlatesHub/functions/Text.lua- Use safe helpers for health text displayNeatPlatesHub/functions/Widgets.lua- Safe value compatibilityWidgets (Aura Secret Handling)
NeatPlatesWidgets/AuraWidget.lua- Direct aura field access, issecretvalue checksNeatPlatesWidgets/ComboPointWidget.lua- API compatibilityNeatPlatesWidgets/HealerTrack.lua- API compatibilityNeatPlatesWidgets/ResourceWidget.lua- API compatibilityNeatPlatesWidgets/TankTrack.lua- API compatibilityTOC Files Updated (Interface 120000)
NeatPlates/NeatPlates.tocNeatPlatesHub/NeatPlatesHub.tocNeatPlatesWidgets/NeatPlatesWidgets.tocNeatPlates_Alvara/NeatPlates_Alvara.tocNeatPlates_BlizzardPlates/NeatPlates_BlizzardPlates.tocNeatPlates_ClassicPlates/NeatPlates_ClassicPlates.tocNeatPlates_Graphite/NeatPlates_Graphite.tocNeatPlates_Grey/NeatPlates_Grey.tocNeatPlates_Neon/NeatPlates_Neon.tocNeatPlates_Quatre/NeatPlates_Quatre.tocNeatPlates_Renaitre/NeatPlates_Renaitre.tocNeatPlates_Roth/NeatPlates_Roth.tocNeatPlates_Simple/NeatPlates_Simple.tocNeatPlates_Slim_Horizontal/NeatPlates_Slim_Horizontal.tocNeatPlates_Slim_Vertical/NeatPlates_Slim_Vertical.tocDeleted Files (Legacy TOC files)
NeatPlates_Renaitre/Fonts/._RobotoCondensed-Bold.ttf(macOS metadata file)