# v12.0.7 (2026-04-05)

## New Features

### Multi-Class Support Framework
- Added dynamic class detection system mirroring Nem: Pet Alerts architecture
- Options panel UI now themes dynamically per class — all section headers, borders, title, slider inputs, font label, and version footer update on every panel open
- **Class theme colors:** Druid `#FF7C0A`, Priest `#FFFFFF`, Evoker `#33937F`, Shaman `#0070DD`, Monk `#00FF98`, Paladin `#F48CBA`, unsupported default `#00CCFF`
- **Three-tier class overlay:**
  - Unsupported classes see a full blackout with "Class Not Supported" and a list of supported classes (Druid, Evoker, Monk, Paladin, Priest, Shaman)
  - Supported healers without implementation see "Class Support Coming Soon" in their class color
  - Druid gets the full working options panel
- Slash commands (`on`, `off`, `toggle`, `test`, `lock`, `unlock`, `reset`) are blocked for non-implemented classes with a contextual message
- Updated subtitle to "Important Healer Procs, and Heal Over Time alerts" to reflect multi-class scope

## Changes

- Removed "Functionality disabled — character is not a Druid" chat message on login for non-Druid characters
- Panel brand color changed from static Nem orange (`#FF8000`) to per-class theme colors (Nem orange preserved for drag border and chat messages)

---

# v12.0.6 (2026-04-05)

## Bug Fixes

- **Fixed crash in M+ / rated content** — `GetSpellCooldown` was removed from the global namespace in WoW 12.0; replaced with `C_Spell.GetSpellCooldown` which returns a table (`startTime`, `duration`) instead of bare values. This caused a nil call error on every `Evaluate()` tick when the Wild Growth alert was enabled in combat. The secret-value fallback and all downstream CD logic are unchanged.

---

# v12.0.5 (2026-04-04)

## New Features

### Wild Growth Ready Alert
- Displays `* WILD GROWTH READY *` when Wild Growth (48438) is off cooldown
- **Combat-only** — alert is hidden outside of combat since WG is nearly always ready when idle
- Alert stays visible during GCD from other spells — only hides when WG is actually on its real 10s cooldown
- Sound fires only when coming off a real cooldown, not when a GCD from another spell briefly flips the state
- Secret-value combat fallback — when `GetSpellCooldown` returns restricted values in M+/rated combat, falls back to `UNIT_SPELLCAST_SUCCEEDED` cast-time tracking with a 10.1s fallback timer
- Configurable sound (default: Lamp) with Preview button
- Color customizable via Alerts panel swatch (default: `#A6E22E` lime)

### Reforestation / Tree of Life Alert
- Displays `* TREE OF LIFE NEXT SWIFTMEND *` after 3 Swiftmend casts since the last Tree of Life proc
- Tracked via `UNIT_SPELLCAST_SUCCEEDED` cast counting — does not rely on aura API (which proved unreliable for stack counts in combat)
- Counter increments on each Swiftmend cast, resets automatically on the 4th cast when Tree of Life procs
- **Talent-gated via C_Traits API** — `C_Traits.GetNodeInfo` with node ID 82069 checks `ranksPurchased` and `activeRank`. Alert auto-disables immediately when talent is unspecced and re-enables on a 0.5s delayed re-check after respec. Listens to `PLAYER_TALENT_UPDATE`, `PLAYER_SPECIALIZATION_CHANGED`, and `TRAIT_CONFIG_UPDATED`
- **Swiftmend count sync** — `SyncSwiftmendCount()` reads actual Reforestation buff stacks via `GetAuraDataBySpellID` on zone transitions, combat exit, talent changes, and login to correct any desync from secret values or instance changes
- Configurable sound (default: Redfox) with Preview button
- Color customizable via Alerts panel swatch (default: `#3498DB` blue)

### Empowered Regrowth Glow
- Glows the Regrowth buff icon on any raid/party/target/focus frame when Regrowth was cast while Soul of the Forest was active
- Glow color matches the SOTF alert color swatch — all empowered spells (Rejuv, Germination, Regrowth) share one configurable color
- Detected via aura instance ID tagging in `EvaluateFrameGlow` hook, with `ScanForEmpoweredRegrowth` delayed-scan fallback (0.1s, 0.3s, 0.5s) using the global `_G.C_UnitAuras` API to bypass localization issues
- Supports empowered Regrowth spread — 0.75s tagging window captures all spread copies from a single cast while preventing false tags on subsequent manual casts (minimum 1.2s cast time)
- Glow clears when a non-empowered Regrowth is cast (wipes all empowered Regrowth state synchronously in `UNIT_SPELLCAST_SUCCEEDED`)
- Operates independently of the SOTF text alert toggle

### Alert Order Redesign
- Alert display order flipped top-to-bottom: Tree of Life (top), Wild Growth, Soul of the Forest, Lifebloom (bottom)
- Same total span and inter-alert spacing as before

### SOTF Alert Text
- Changed from `* CAST REJUV *` to `* SOUL OF THE FOREST *`

## New Sounds
- **Lamp.ogg** — new bundled sound, default for Wild Growth Ready
- **Redfox.ogg** — new bundled sound, default for Tree of Life Ready
- Total bundled sounds: 15

## New Default Colors
- Lifebloom Expiring: `#24A148` (green)
- Soul of the Forest: `#00E5C0` (teal)
- Wild Growth Ready: `#A6E22E` (lime)
- Tree of Life Ready: `#3498DB` (blue)

## Options Panel Redesign

- **Alerts section** restructured to 2 rows: LB + Wild Growth (left/right), SOTF + Tree of Life (left/right)
- All four alerts now have individual color swatches
- **Show Timer** toggles moved from Alerts section into the Display section right column
- **Empowered Regrowth Glow** toggle moved into Display section right column
- Sounds section expanded to 4 rows covering all four alerts
- Buttons raised ~85px — panel no longer overflows the options window

## Slash Commands
- `/nha debug` — diagnostic output for empowered Regrowth glow state, API availability, and target frame aura data
- `/nha trace` — one-shot live trace that prints diagnostics at the moment of the next empowered Regrowth cast

## Bug Fixes

### Wild Growth combat reliability
- **`GetSpellCooldown` secret-value crash** — `start` and `dur` return values are now guarded with `issecretvalue()` before any comparison. Falls back to `wgCastTime`-based elapsed-time tracking when the API is restricted. This was the root cause of 1600+ Lua errors per session and cascading failures in all downstream Evaluate logic (Reforestation, rising-edge sounds, state updates)
- **Wild Growth alert not clearing after cast** — `GetSpellCooldown` briefly returns the GCD before the real 10s CD registers. Sets `wgJustCast` flag and synchronous `state.wgReady = false` in `UNIT_SPELLCAST_SUCCEEDED` for immediate OnUpdate hide
- **Wild Growth sound not playing in combat** — secret-value fallback path was clearing `wgOnRealCD` before the sound handler could fire. Now keeps `wgOnRealCD = true` until `PlayWGSound()` runs, then the sound handler clears it
- **Wild Growth sound re-triggering on GCD** — `wgOnRealCD` flag gates sound to only play when coming off an actual >1.5s cooldown

### Reforestation reliability
- **Talent gate not catching unspec** — `IsPlayerSpell(392356)` returns true even after unspeccing passive talents. Replaced with `C_Traits.GetNodeInfo(configID, 82069)` checking `ranksPurchased`/`activeRank`. Immediate reset on talent change events with delayed 0.5s re-check
- **Swiftmend count desync leaving instances** — counter drifted when entering/leaving dungeons. `SyncSwiftmendCount()` now reads actual buff stacks on zone transitions (`PLAYER_ENTERING_WORLD`), combat exit (`PLAYER_REGEN_ENABLED`), talent changes, and login
- **`SyncSwiftmendCount` crash** — `C_UnitAuras.GetAuraDataBySpellID` was nil on the localized reference. Added API availability guard and `"HELPFUL"` filter argument matching existing code patterns
- **Reforestation alert stuck after 4th Swiftmend** — `state.refoActive = false` now set synchronously in `UNIT_SPELLCAST_SUCCEEDED` when count resets, so OnUpdate hides the alert immediately

### Empowered Regrowth glow
- **Glow never firing** — `db` variable in `UNIT_SPELLCAST_SUCCEEDED` handler was undefined (only declared as `local db = NHA.db` inside `Evaluate()`, not in the event handler). The check `db and db.empRegrowthEnabled` always short-circuited to nil. Fixed: `db` → `NHA.db`
- **Glow color bleeding between Rejuv and Regrowth** — empowered Rejuv path now clears `regrowthGlowFrames[buffFrame]` when taking over a frame, matching the existing LB crossover cleanup pattern
- **Glow persisting when overwritten by non-empowered Regrowth** — WoW does not re-fire `CompactUnitFrame_UtilSetBuff` when Regrowth replaces Regrowth (same spell ID, instance updated in place). Non-empowered Regrowth casts now synchronously wipe all empowered Regrowth state in `UNIT_SPELLCAST_SUCCEEDED`. Additionally, `UNIT_AURA` `removedAuraInstanceIDs` processing now scans `regrowthGlowFrames` for matching instances and hides the visual glow
- **Hook pre-check skipping tracked Regrowth frames** — `regrowthGlowFrames[buffFrame]` added to the `CompactUnitFrame_UtilSetBuff` fast-reject check alongside `lbGlowFrames` and `rejuvGlowFrames`
- **`empRegrowthPending` set on every Regrowth cast** — now only fires when `state.sotfActive or state.sotfProcPending` is true, preventing false-positive glows on non-empowered Regrowths

### General
- **`PLAYER_DEAD` incomplete reset** — now clears all WG, Reforestation, and empowered Regrowth state: `wgReady`, `wgWasReady`, `wgOnRealCD`, `wgJustCast`, `wgCDTimerSet`, `wgCastTime`, `refoActive`, `refoWasActive`, `swiftmendCount`, `empRegrowthPending`, `empRegrowthDeadline`
- **All Display section checkbox labels invisible** — `labelAnchor` variable intended for `MakeAlertRow` was accidentally applied to `MakeCheckbox`. Fixed
- **`MakeAlertRow` crash with nil colorKey** — color swatch creation is now guarded and skipped when `colorKey` is nil
- **Test mode not showing WG / Refo alerts** — test mode block now sets `wgReady` and `refoActive` so all four alerts display during test

---

# v12.0.4 (2026-04-02)

## Bug Fixes

- **Test mode timers not showing** — `OnUpdate` was hiding both countdown timers every frame during test mode, fighting against `Evaluate`'s cycling values. Timers now display correctly alongside alert text in test mode
- **Options panel spacing** — Sounds section and Alerts section now pixel-perfect with Nem: Pet Alerts layout

---

# v12.0.3 (2026-04-02)

## Performance

### CPU optimization — large group content
Significant reduction in CPU usage in raid and battleground environments:

- **`UNIT_AURA` updateInfo filtering** — handler now reads the `updateInfo` payload to skip irrelevant aura changes entirely. For the tracked LB target, only evaluates when LB's specific instance ID is added, updated, or removed. For the player, skips duration-only refreshes. For untracked units, only scans when auras are added
- **`CompactUnitFrame_UtilSetBuff` pre-check** — hook now fast-rejects untracked frames with non-player auras before calling `EvaluateFrameGlow`. In a 40-man raid this fires hundreds of times per second; the pre-check eliminates the vast majority of calls at near-zero cost
- **`EvaluateFrameGlow` fast-reject** — untracked frames with nil, secret, or non-player auras now return immediately without touching any tables
- **Cached group unit list** — `GetGroupUnits()` now rebuilds only on `GROUP_ROSTER_UPDATE`, `PLAYER_ENTERING_WORLD`, `PLAYER_TARGET_CHANGED`, and `PLAYER_FOCUS_CHANGED`. Previously allocated a new 40-entry table on every `FullScanForLB` call
- **`UNIT_AURA` debounce** — player aura events now debounced to 0.1s. In a BG, player aura changes (procs, HoTs, debuffs) were firing dozens of Evaluate calls per second
- **`GROUP_ROSTER_UPDATE` debounce** — fires 5–10 times per player join. A 0.5s debounce collapses the entire join burst into a single Evaluate, eliminating heavy stuttering during the initial fill of a 40-man raid
- **Coalescing `ScheduleEvaluate` helper** — multiple events firing in the same frame each previously queued their own `C_Timer.After(0, Evaluate)`. A single pending flag now collapses them into one
- **`ShowProcGlow` table allocation** — eliminated two heap allocations per glow activation by reusing a module-level cached options table
- **Duplicate `issecretvalue` check removed** — was being called twice on the same value in `EvaluateFrameGlow`

## Bug Fixes

- **SOTF alert stuck in combat when proc expires naturally** — if the Soul of the Forest proc ran out without casting Rejuv or Regrowth, `sotfProcPending` stayed `true` indefinitely. Alert now clears correctly when `sotfExpire` passes
- **LB icon glow not firing when targeting an enemy** — compact raid frames only fire `CompactUnitFrame_UtilSetBuff` when an aura changes, not while it silently ticks. Entries were being removed from `lbGlowFrames` when outside the panic window, leaving `RefreshLBGlows` with nothing to monitor. Entries are now retained while the aura is active so the ticker catches the threshold crossing regardless of hook activity
- **`lbTicker` not stopped when addon disabled** — ticker continued firing `Evaluate()` every 0.25s indefinitely when the addon was turned off. Now calls `StopLBTicker()` + `ClearLBState()` on the disabled path
- **`state.sotfActive` not cleared when SOTF alert disabled** — if `db.sotfEnabled` became false mid-session, `state.sotfActive` was never written, keeping the alert visible. `state.sotfActive` is now always assigned after the SOTF check block
- **`ClearLBState` Lua forward-reference crash** — added glow table cleanup to `ClearLBState` which is defined before `lbGlowFrames`/`rejuvGlowFrames` are declared. Lua closures capture variable slots at definition time — the function always held `nil`. Extracted into a separate `ClearAllGlows()` function defined after the table declarations. This was causing a `bad argument #1 to 'pairs' (table expected, got nil)` error that climbed rapidly in combat
- **Alerts not cleared on player death** — `PLAYER_DEAD` and `PLAYER_ALIVE` events now registered. Death wipes all active state immediately; resurrect triggers a fresh Evaluate
- **SOTF alert not clearing immediately on Rejuv cast** — `state.sotfActive`, `state.sotfExpire`, and `state.sotfWasActive` are now cleared synchronously in `UNIT_SPELLCAST_SUCCEEDED` before the deferred Evaluate, closing a race condition window
- **Sound defaults not working without LibSharedMedia** — `Bell` and `Ping` were missing from `BUNDLED_SOUNDS` despite the files being present. Both are now registered and work standalone

---

# v12.0.2 (2026-04-01)

## Bug Fixes

### Combat reliability — complete overhaul
WoW 12.0's secret-value system restricts aura data reads in M+/rated combat. All alert and sound failures in combat have been resolved through three complementary approaches:

- **All event-driven `Evaluate()` calls are now deferred** via `C_Timer.After(0, ...)`. Direct calls from events like `PLAYER_TARGET_CHANGED` inherited taint from secure frame operations, causing `aura.spellId` to be flagged as "tainted by NemHotAlerts" and throw on the next read. Deferring breaks the taint chain
- **`issecretvalue()` is now the first gate** in all aura evaluation paths, checked before any field access. This mirrors LifebloomGlow's pattern and is more robust than per-field guards — one check at the top, all fields safe below it
- **SOTF detection now uses spell-cast tracking as a combat fallback.** `GetAuraDataBySpellID` returns a restricted placeholder in combat. The addon now also tracks SOTF via `UNIT_SPELLCAST_SUCCEEDED`: Swiftmend sets a `sotfProcPending` flag, and casting Rejuvenation/Germination/Regrowth clears it. This event is not subject to secret-value restrictions
- **SOTF timer now starts immediately** when Swiftmend is cast, seeded from `GetTime()`, rather than waiting for a successful aura query
- **SOTF alert now persists when entering combat** with the proc already active. `PLAYER_REGEN_DISABLED` carries forward the pending state so the combat fallback path keeps the alert alive
- **`PLAYER_REGEN_DISABLED` and `PLAYER_REGEN_ENABLED` now registered** to re-evaluate on combat transitions

### Other fixes
- Lifebloom scan switched to `GetAuraDataBySpellID`, bypassing secret-value comparison failures
- All `C_UnitAuras` API calls use the module-level localized table reference, consistent with LifebloomGlow

## Options Panel
- Sounds section height corrected to match Nem: Pet Alerts exactly
- Alert rows and buttons repositioned to match Nem: Pet Alerts spacing

## Slash Commands
Added missing commands to match Nem: Pet Alerts parity:
- `/nha on` / `/nha off` / `/nha toggle`
- `/nha status` — show enabled state, test mode, and per-alert status
- `/nha version` — show addon version
- `/nha reset` — wipe saved variables and reload UI
- `/nha unlock` — unlock frame
- All commands available via `/hotalerts` alias

---

# v12.0.1 (2026-03-31)

Initial release of **Nem: HoT Alerts**. Part of the Nem addon suite.

---

## Overview

Nem: HoT Alerts is a Restoration Druid addon that provides text alerts, countdown timers, and icon proc glows for Lifebloom pandemic tracking and Soul of the Forest proc consumption. Built as a standalone, self-contained addon with full options panel, configurable sounds, and font customization — matching the Nem suite visual style.

---

## Text Alerts

- **Lifebloom Expiring** — displays `* LIFEBLOOM EXPIRING *` when Lifebloom enters its pandemic window (last 4.5 seconds of base duration). Anchored to a fixed 4.5s window so Swiftmend extensions never change the trigger timing
- **Soul of the Forest** — displays `* CAST REJUV *` when the Soul of the Forest proc buff is active on the player
- Both alerts support configurable text colors, flash animation, and independent enable/disable toggles
- Alert position is draggable and saved per session

## Countdown Timers

- **Lifebloom timer** — live per-frame countdown displayed beneath the LB alert text, color-coded by urgency:
  - `4.5s – 2.1s` → `#aaff00` yellow-green
  - `2.0s – 1.1s` → `#ffd000` gold
  - `1.0s and below` → `#ff6600` deep orange
- **Soul of the Forest timer** — live per-frame countdown displayed beneath the SOTF alert text, color-coded by urgency:
  - `15s – 10.1s` → `#aaff00` yellow-green
  - `10s – 5.1s` → `#ffd000` gold
  - `5.0s and below` → `#ff6600` deep orange
- Both timers are anchored to their respective alert rows and move together when the frame is repositioned
- Timer font, scale, and size all scale proportionally with the alert font settings
- Each timer has an independent **Show Timer** toggle in the options panel (checked by default)

## Icon Glow

- Attaches a LibCustomGlow-1.0 `ProcGlow` border glow directly to buff frame icons in the game UI
- **Lifebloom** icons glow in the configured LB color when inside the pandemic window
- **Empowered Rejuvenation / Germination** icons glow in the configured SOTF color when the Soul of the Forest proc was consumed into the cast (detected via icon ID change)
- Glow operates independently of text alert toggles
- Compatible with Compact unit frames (party, raid), Target frame, and Focus frame
- Toggle on/off via the **Icon Glow** option in the Display section

## Sounds

- Configurable sound alert for **Lifebloom Expiring** and **Soul of the Forest**
- 13 bundled sounds in `Media\` folder
- LibSharedMedia-3.0 support for additional sounds from other addons

## Options Panel

- Display, Sounds, and Alerts sections matching Nem: Pet Alerts layout
- Test mode with live cycling countdowns through all color tiers
- Font dropdown (46 bundled fonts), scale and size sliders, color pickers

## Technical

- Single-file build, self-contained with bundled Fonts, Media, and Libs
- MIT licensed — Copyright (c) 2026 Nemreaper
- Slash commands: `/nha`, `/hotalerts`
- Addon compartment button support
