# Changelog

All notable changes to TotemBar are documented here.

## v0.4.0 — 2026-08-30

### Added
- **Destroyed totems can now be detected while SuperWoW is present (verified against captured
  event log 2026-08-20, live eviction pending retest).** A totem killed before its timer ran
  out used to keep counting down as if it were still standing — both TotemBar's own tracking
  and pfUI's libtotem are blind, duration-only timers, and neither ever checked whether the
  totem itself was still alive (pfUI's `GetTotemInfo` was previously assumed to cover this
  case; checked against its source — it does not). A live event tap against the real client
  (2026-08-20) captured totem spawn/pulse/death lines and found the original mechanism could
  never have fired at all: the spawn/pulse latch paths compared totem names for *exact*
  equality, but the live client hands back a *ranked* name ("Searing Totem VI"), never the bare
  book name; and the pulse-cast latch mapped through the pulse *spell's* name ("Searing Bolt"),
  which is not the totem's own name either. Both are now fixed, and a third, GUID-free signal
  was added as the primary path:
  1. **Primary — `CHAT_MSG_COMBAT_FRIENDLY_DEATH`** (native 1.12, needs no SuperWoW/nampower):
     TurtleWoW emits a totem's own death as `"<Name> (<Owner>) is destroyed."` verbatim; parsed
     and evicted once the owner resolves to the player and the name rank-tolerantly matches a
     tracked totem. The generic vanilla `"<Name> dies."` form is accepted as a second, stricter
     shape — since it carries no owner, it only evicts a candidate that already has a latched
     GUID, confirmed via a live `UnitExists`/`UnitHealth`/`UnitIsDeadOrGhost` read.
  2. **`UNIT_CASTEVENT`** (SuperWoW), for totems that periodically cast their own pulse — now
     keyed off `UnitName(casterGUID)` (the totem unit's own, rank-tolerant name) instead of the
     pulse spell's name; covers only pulsing totems (Searing/Magma/Fire Nova/Mana Spring/
     Healing Stream/Mana Tide/the Cleansing totems), gated on the caster's resolved owner
     matching the player.
  3. **`UNIT_MODEL_CHANGED`** (native 1.12), for totems that never cast anything visible — now
     rank-tolerant instead of an exact name compare.
  4. **`UNIT_DIED`** (nampower), extended with a GUID-free fallback: when no GUID was ever
     latched, a rank-tolerant name + owner match at the death instant (both resolve reliably
     there per the captured log) still evicts.

  A totem confirmed destroyed is evicted immediately and tombstoned for the remainder of its
  own natural duration, so pfUI's libtotem — itself just another blind timer — cannot
  resurrect the countdown/ring/pulse a moment later; a real re-cast on that element clears the
  tombstone right away. This clears the countdown, duration ring, pulse animation and
  out-of-range tint together, since all four already derive from the same tracking record. On
  a client without SuperWoW, only the primary `CHAT_MSG_COMBAT_FRIENDLY_DEATH` signal is
  active; without either SuperWoW or TurtleWoW's own death-line wording, behaviour is
  byte-for-byte unchanged from before this feature. The decision logic (name matching, line
  parsing, eviction gating) is fully offline-tested against the captured fixture lines (95
  assertions in `tools/luatests/test_destroy.lua`); a live totem-kill retest with the addon
  in the loop is still pending — `/tb tdump` prints each totem's latched `guid`, the raw
  `UnitExists`/`UnitHealth`/`UnitIsDeadOrGhost` reads, and (for an evicted slot) its tombstone
  status, for that verification.

### Fixed
- **A totem's countdown no longer starts when the cast was refused for lack of mana.** The
  pre-cast mana gate stood down completely while Clearcasting (Elemental Focus) was up, on the
  assumption that it zeroes the next cast's price. Elemental Focus covers the shaman's damage
  spells, not totem summons -- so a totem costs full mana while Clearcasting is up, and since
  totems are the only thing this addon casts, that exemption disabled the mana gate outright.
  The client then refused the cast while the timer had already been recorded, leaving a
  countdown running for a totem that was never placed. The exemption is gone from the cast
  gate, the out-of-mana dim and the flyout tint alike; the unverified buff-icon constant it
  relied on went with it. The gate still accepts (and ignores) the old sixth argument, so no
  stale caller can quietly reinstate it.

- **A Totemic Recall the server refuses no longer wipes your totem timers.**
  Recall already checked whether the cast could go out *before* touching the
  tracking, but a press that passes that check can still be refused after the
  fact — moving at the wrong moment, a stun or silence landing first, or plain
  latency. The tracking was cleared unconditionally the instant the cast was
  issued, so a refused Recall left the addon believing nothing was out while a
  full set kept standing — the same phantom-state bug class the totem casts'
  own two-layer guard already closed, mirrored. The recall paths now remember
  what they cleared, and the same failure signals that take back a refused
  totem's countdown (the exact per-spell one with nampower, the error-message
  fallback without it) put the timers back. The restore follows the same
  narrow rules as the totem-cast revoke: only when the Recall itself was the
  last cast attempted, only within a short window afterward, and never over a
  slot a new cast has already refilled — when attribution is uncertain it
  stays silent, since here a *wrongly restored* timer would be the phantom.
  Covers the Recall button, its keybind, and the DropSet keybind's recall
  stroke alike.

## v0.3.0 — 2026-08-15

### Added
- **Totems you cannot afford are dimmed.** Element buttons and the hover flyout
  grey out while your mana is below the totem's cost, so the bar shows what is
  actually castable instead of only what is chosen. The cost is the real one for
  your highest known rank, including cost talents, and the dim composes with the
  out-of-range tint rather than replacing it — an out-of-range totem you also
  cannot afford still reads as red, just darker. Clearcasting suspends it, since
  the next spell is free while it is up.

### Fixed
- **A refused cast no longer starts a countdown, and one that already started
  can now be taken back.** Pressing a totem without the mana for it (or while
  it is genuinely on cooldown) used to start a full timer for a totem that was
  never placed — which also made Totemic Recall believe something was out and
  burn its 6s cooldown on an empty board. The cast's chances are now checked
  *before* it leaves, so an attempt that cannot have gone through is never
  tracked in the first place. A second layer catches what the pre-check
  cannot predict — movement, another action already in progress, a stun, or a
  server-side refusal — by watching the client's own "cast failed" signal
  (the exact one with nampower, an error-message fallback without it) and
  undoing the countdown after the fact. That revoke is filtered narrowly on
  purpose: it only fires for the totem cast just attempted, only within a
  short window afterward, and only for messages the client is known to use
  for a refused cast, so it stays silent whenever it cannot be sure — a
  refused *repeat* press restores the original timer rather than clearing it.
  In every case where attribution is uncertain, this fails **closed**: no
  revoke happens, and the existing timer is left standing, because a missing
  timer is worse than a phantom one.
- **Totemic Recall no longer wipes your totem timers on a press that could not
  have gone out.** Recall's own 6s cooldown or the global cooldown could
  refuse a manual Recall press while the button and keybind still cleared the
  addon's totem tracking as if it had fired — after which the addon believed
  nothing was out and refused every further Recall press until something
  re-armed it. Recall now checks whether the cast can actually go out before
  it touches the tracking, and a press that cannot keeps it intact.
- **Totemic Recall no longer wastes its cooldown on a no-op moments after your
  totems expire.** The check for "is anything even out" relied on the totem
  tracking table staying occupied, but that table is emptied the instant each
  totem's own timer runs out — so within a fraction of a second of the last
  totem expiring, Recall forgot it had ever cast anything and let a needless
  press through, burning the cooldown on an empty board. A separate flag now
  answers "did we cast this session", so the check survives normal timer
  expiry as intended.
- **The Recall button and its keybind can no longer sweep away a set you just
  redeployed.** Both issued a plain Totemic Recall cast, which nampower
  queues behind the global cooldown — so pressing Recall during a GCD could
  fire it *after* you had already placed your totems again, recalling the
  set you had just dropped. Both now share the same queue-safe cast the
  automatic recall paths already used, so a GCD-blocked press is skipped
  instead of firing late.
- **A totem you have not learned no longer starts a countdown.** The saved
  totem set is account-wide and not checked against the spellbook, so a set
  carried over from another character could land on one that never learned
  those totems. Casting it was a guaranteed no-op, but it still started a
  full phantom timer and made Totemic Recall think something was out.
- **Sentry Totem's timer no longer expires 180 seconds early.** It was
  missing its own duration entry and silently fell back to a generic
  120-second default, well short of the totem's real 5-minute duration.
- **The seventh Air totem is no longer dropped from the hover flyout.** The
  flyout's icon pool was sized for six totems, but Air offers seven — with
  the Air slot left empty, the last entry could neither be cast nor be set
  as the slot's new default from the bar.
- **Windwall Totem no longer reads permanently in-range once you are also
  carrying Strength of Earth Totem.** The range check matched buff icons by
  an unanchored substring, and Strength of Earth Totem's icon name happens to
  start with Windwall's, so carrying one made the other's out-of-range tint
  never trigger.
- **A totem pulse from another shaman can no longer drag your own pulse ring
  backward.** The periodic self-heal/self-mana messages TotemBar reads to
  time the pulse ring carry no caster information, so an identically worded
  tick from someone else's totem re-anchored the phase and made the ring
  visibly jump. Anchoring is now limited to at most once per pulse interval.
- **The out-of-range tint no longer skips most of a freshly-placed set when
  pfUI is loaded.** pfUI's own totem tracking commits at most one totem per
  cast, so dropping a full four-totem set left three slots with no
  information from it at all — and those slots were treated as "known to be
  in range" instead of falling back to TotemBar's own tracking, so most of
  the set never turned red out of range or pulsed the Recall button.
- **The duration ring no longer counts down, jumps back up, and counts down
  again with Totemic Mastery talented.** TotemBar's own tracking stores the
  Mastery-inflated duration while pfUI's totem data reports the shorter flat
  spellbook value; the display preferred pfUI's number until it ran out, then
  jumped back up to the correct remaining time. Both sources now agree on the
  same, Mastery-scaled endpoint.

## v0.2.5 — 2026-07-25

### Added
- **New option: "Show drop-all button".** The drop-all-totems button can now be
  hidden from the bar, for anyone who drives it purely from a keybind or a macro
  and would rather not spend the slot on it. On by default, so nothing changes
  unless you turn it off.
  - **The keybind keeps working while the button is hidden.** It is bound to the
    cast function, not to the frame, and the entry stays listed in the Esc key
    bindings menu — otherwise you could never assign it again.
  - **The bar resizes instead of leaving a gap.** In the 1×6 layout it shrinks by
    one slot. In 2×3 and 3×2 the frame keeps its size on purpose: Recall still
    needs the last column, and shrinking there would break up the 2×2 block of
    the four element totems. What remains is one empty grid cell in the trailing
    corner — invisible, and it simply adds drag area.

## v0.2.4 — 2026-07-14

### Fixed
- **Totemic Recall no longer refuses to fire after a /reload.** The "no totems
  out — not recalling" guard could block a legitimate recall: TotemBar tracks
  which totems you've dropped in memory only, and a `/reload` wipes that memory.
  On 1.12 there is no `GetTotemInfo` / totem unit-id to re-detect a totem that
  was placed before the reload, so the addon wrongly concluded nothing was out
  and refused to recall. The guard now blocks **only** when it is certain nothing
  is out (it tracked totems this session and they've all expired); after a
  /reload the state is unknown, so it fails open and lets the recall through.
  Worst case is one needless recall right after a reload — far better than a
  blocked one.

## v0.2.3 — 2026-07-13

### Fixed
- **Totemic Recall no longer sweeps away a freshly-placed set (nampower).**
  With nampower installed, dropping your set while the global cooldown was
  active could make the new totems appear and then instantly vanish: nampower
  queued Totemic Recall behind the GCD, so it fired *after* the (off-GCD)
  totems were placed and pulled them right back down. TotemBar now casts
  Recall via `CastSpellByNameNoQueue` when nampower provides it, so a
  GCD-blocked Recall is skipped for that press instead of firing late. No
  effect for setups without nampower.

### Changed
- **The drop-set keybind now recalls on key-down and places on key-release.**
  This keeps the recall and the totem placements as separate hardware events;
  for a normal tap the difference is imperceptible.

## v0.2.2 — 2026-07-10

### Added
- **"Button spacing" slider** in the options panel (10–30 px) — adjusts the
  gap between bar buttons live, including the flyout and assignment panel.

### Fixed
- **Keybind casts now start TotemBar's own duration/pulse timers.**
  Per-totem and element key bindings call the same tracking as click-casts.
  Previously, setups without pfUI got no timer/ring/pulse feedback for
  keybind-cast totems, and even with pfUI the spawn ripple and out-of-range
  tint were missing for them.

### Removed
- **Dead `pulseGlow` setting** — the anticipation glow is part of "Show
  pulse waves"; stale saved values are cleaned up automatically.

## v0.2.1 — 2026-07-10

### Fixed
- **Tooltips showed rank 1 instead of your highest rank.** Both totem
  tooltips (element buttons and the flyout) resolved the spell by its first
  spellbook match — which is rank 1 — so mana cost, damage and duration read
  far too low. Display-only: the actual cast is name-based and always used
  your highest rank. Tooltips now resolve to the highest known rank **and
  show the rank** next to the spell name (vanilla's tooltip omits it).

## v0.2.0 — 2026-07-10

**The Pulse UI release** — a complete visual rework of the bar around one idea:
you should see at a glance *how long* each totem still stands and *when* it
pulses next.

### Added
- **Round floating slots.** Buttons are free-floating round icons in a subtle
  shadow-rim frame — the square boxes and backdrops are gone. Flyout, Recall
  and drop-set share the round look (round hover/pressed states included).
- **Duration ring (time traffic light).** The outer ring drains with the
  totem's remaining lifetime and blends green → yellow → orange → red as time
  runs out.
- **Pulse ring.** A thin inner arc in the totem's element color fills toward
  the next pulse and resets when it fires — animated per frame, no stutter.
- **Server-accurate pulse timing.** Intervals and first-tick behavior come
  from TurtleWoW server data, not guesswork: e.g. Tremor pulses every **4s**
  (not the commonly cited 3s) and ticks **immediately** on placement, while
  Magma/Healing Stream/Mana Spring first pulse one full interval after
  placement. Water totems additionally re-anchor on the real observed
  mana/heal ticks.
- **Pulse waves & anticipation glow.** An expanding ripple in the element
  color marks each pulse; a soft halo builds around the ring during the last
  stretch before it. A spawn ripple confirms every placement.
- **Bar layouts.** Cycle between 1×6, 2×3 (elements grouped as a 2×2 block)
  and 3×2 in the options panel.
- **Custom art set.** Element glyphs for empty slots (no more question
  marks), a four-element drop-set icon, a minimap glyph, a custom options
  panel skin with rounded corners, and grounding shadow plates under the
  slots. All art is generated by scripts in `tools/` — reproducible, no
  binary-only assets.
- **New options:** Show duration ring · Show pulse ring · Show pulse waves ·
  Show countdown text · Layout.
- **`/tb pulsecal` (dev aid):** captures pulse-timing telemetry to
  `imports\totembar_pulsecal.txt` (SuperWoW) for verifying timings in-game.

### Changed
- Button spacing widened (4 → 10 px) to give the ring frames air; multi-row
  layouts use the same tight pitch vertically.
- Options panel restyled with the custom skin and section dividers.
- The remaining-time countdown text is now optional (on by default).

## v0.1.3 — 2026-07-09

### Fixed
- **Totemic Recall no longer wastes its 6-second cooldown.** Recall — via the
  button, its keybinding, or the "Totems" macro's auto-recall — now only fires
  when you actually have totems out. Casting it with nothing down put Recall on
  its 6s cooldown, so a set placed right after couldn't be recalled for 6
  seconds. With nothing out, TotemBar now skips the cast (with a brief note).

## v0.1.2 — 2026-07-09

### Added
- **Mana cost on the drop-set tooltip** — hovering the drop-set button (and the
  "Totems" macro action) shows the total mana to drop your four chosen totems.
- **Refund on the Totemic Recall tooltip** — shows the mana you'll get back,
  computed live from the totems currently out (expired ones are excluded) and a
  refund percentage that is learned from your real recall mana-gain (defaults to
  25% until learned).
- **Totemic Mastery duration** — when the talent is skilled, helpful totems'
  own-tracked timers get the +20% duration so they no longer read short.
- `/tb manadump` dev aid — writes the raw mana-cost scan (resolved rank, tooltip
  lines, parsed cost) to `imports\totembar_manadump.txt`.

### Fixed
- Totem mana costs were read from **rank 1** instead of the highest rank you
  actually cast, so the displayed mana was far too low. The scan now resolves
  the highest known rank.

## v0.1.1 — 2026-07-09

### Added
- **Drop-set button** on the bar (right of the Totemic Recall button): one
  left-click casts all four chosen totems (the same action as the "Totems"
  macro, with the 2-second double-press guard).
- **Key bindings** — a **TotemBar** section in the Esc → Key Bindings menu:
  Drop all totems, Totemic Recall, Toggle bar, Toggle options, Toggle key-bind
  mode, Cast *element* totem (chosen, one per element), and — under per-element
  sub-sections — a binding to cast **every individual totem** (Cast Searing
  Totem, Cast Windfury Totem, …).
- **Hover-bind mode** (`/tb bind`, or the options panel's "Key bind mode"
  button): hover any bar button or a flyout totem and press a key to bind it
  (a button binds its action; a flyout totem binds that specific totem). ESC
  over a button clears its key; ESC over empty space (or the options button)
  exits. A "Key-Bind Mode ACTIVE" box is shown while active. The
  currently-bound key is displayed on each button at all times (abbreviated,
  e.g. `N7` for Num Pad 7). Bindings are saved by the game and persist.

### Notes
- Totemic Recall cast **deliberately** (the Recall button, or its keybinding)
  is never guarded — only the Totems macro's built-in recall respects the 2s
  double-press guard.

## v0.1.0 — 2026-07-09

Initial public release.

### Added
- Totem bar: four element buttons + a Totemic Recall button. Left-click an
  element casts its chosen totem; right-click clears the slot. Hover an element
  for a flyout of the element's other known totems (left-click to cast once,
  right-click to set as the new default).
- One-press "Totems" macro (`TotemBar.recallAndCastAll()`) with a 2-second
  double-press recall guard (a rapid second press won't recall the totems you
  just dropped).
- Native cooldown swipes + OmniCC-style duration timers; out-of-range red tint
  (buff-presence based); the Recall button pulses when a totem is out of range.
- Real in-game spell tooltips on the element buttons and the flyout.
- Minimap button (orbit-draggable; left-click = options, right-click = toggle
  bar); pfUI-safe, with `/tb options` as a fallback.
- Options panel: lock bar, auto-recall, show bar, recall guard, cycle-reset
  gap, UI size (scales the bar, anchored top-left), reset position, create
  "Totems" macro, and per-setting tooltips. Adopts pfUI's look when pfUI is
  installed, a clean Blizzard look otherwise.
- Assignment-receiver API (`TotemBar.ReceiveAssignment`) for a future raid
  totem-assignment addon — see [`docs/API.md`](docs/API.md).
