GetActionInfo + GetMacroSpell resolve each action slot to a spell name
(or skip if it's an item / empty / non-resolvable macro). The names to
match against come from C_Spell.GetSpellName on the canonical rank-1
spellIDs (78 = Heroic Strike, 845 = Cleave) so the comparison is
locale-independent without hardcoding all ranks: every rank of Heroic
Strike returns the same localized name.
Replaces the old two-path scan (texture string match + hardcoded
English name match against "heroic strike" / "hs" / "cleave"). Closes
two correctness holes the old logic had: macros that cast HS/Cleave
with a custom icon now match correctly, and macros merely *named* "HS"
without actually casting HS no longer false-match.
Drops the legacy pfUI.api.GetItemCount wrapper (name-based bag walk +
GetItemInfo per slot) entirely — both call sites switch to direct
C_Item.GetItemCount(itemID) calls.
actionbar reagent counter: drops the SPELL_REAGENTS tooltip-scan +
libtipscan dependency. UpdateSlot now does GetActionInfo(slot) →
spellID → C_Spell.GetSpellReagents → reagent itemID, stored per slot.
Counts update via C_Item.GetItemCount(itemID). reagent_counts is
keyed by itemID instead of localized name string. Multi-reagent
spells now resolve cleanly (only first reagent counted, matching old
single-name behavior). Macro and bag-item actions skip cleanly.
questitem: switches to hooksecurefunc("SetItemRef", ...) + the
modern GameTooltip:HasItem / :GetItem pair instead of monkey-patching
_G.SetItemRef and string.find-parsing the "item:NNN" out of the link.
Drops the libtooltip indirection for the regular tooltip path —
GameTooltip:GetItem returns name + itemID directly. AddTooltip
extended to accept the itemID (both callers already had it and were
discarding it).
Replaces the Phase 1 buff-slot loop + tooltip-scanned mount-string match
with a single Dismount() call. The implementation in ClassicAPI scans
for SPELL_AURA_MOUNTED on the player's auras and sends the cancel
packet itself, so we don't have to maintain a localized list of mount
tooltip patterns ("Increases speed by X%", "Erhöht Tempo um X%", etc.).
Drops pfUI.autoshift.mounts (the 20-line localized-string table) and
pfUI.autoshift.scanner (its only consumer). Module is down to ~50 lines
from ~150 at session start.
Replaces autoshift's Phase 2 (form-ID → texture lookup → buff iteration →
CancelPlayerBuff(bid)) with a single CancelShapeshiftForm() call. The
implementation in ClassicAPI walks the buff slots and matches via
Spell.dbc effect arrays itself, so we don't have to maintain a form-ID
→ texture map on the Lua side.
Drops pfUI.autoshift.shapeshifts entirely (no longer consulted) and the
turtle-wow.lua block that conditionally appended Tree of Life / Stag
Form textures — Turtle's added DBC rows (form IDs 9 and 11) are handled
natively by the same scan.
actionbar.lua: pageswitch now listens to UPDATE_SHAPESHIFT_FORM as the
authoritative form-change signal. PLAYER_AURAS_CHANGED becomes a
narrowly-scoped prowl-detection trigger that runs after form state is
already known. The Nampower SPELL_GO_SELF hook drops its Cat Form
(spellID 768) branch — UPDATE_SHAPESHIFT_FORM covers form changes
without per-spellID watchlists. Prowl IDs stay hooked for zero-latency
detection that PLAYER_AURAS_CHANGED can't match.
autoshift.lua: the texture-list shapeshift detection becomes a form-ID-
keyed map. GetShapeshiftFormID returns the active form directly so we
don't have to texture-match against every possible form pattern. The
moonkin_scan frame disappears entirely — its talent-conditional was a
workaround for the agility buff sharing Moonkin's icon, which form ID
makes irrelevant (form 31 is only reported when the player is genuinely
in Moonkin Form). Loop also splits into two phases for clarity: mount
priority pass, then form cancel.
Drops the C_UnitAuras helpful-aura iteration in favor of a direct engine
state read. GetShapeshiftFormID returns vanilla 1.12.1's stable per-form
DBC ID (Cat = 1), so the helper collapses to a one-liner that's
locale-independent, talent-independent, and works without scanning any
buff list.
FullScan/HasProwlBuff stop iterating GetPlayerBuffTexture(0..31) for the
prowl buff — that's exactly what ClassicAPI's IsStealthed() returns,
locale-independent and zero allocations. Cat-form detection still needs
the icon (GetShapeshiftForm's index varies by talents/learned forms) but
moves to one C_UnitAuras.GetUnitAuras iteration over populated auras via
the new HasCatForm helper.
The inline cat-form recheck after a prowl ends collapses to one
HasCatForm() call. HasProwlBuff is inlined to IsStealthed() at its
single call site.
The three customcast handlers (Aimed Shot, Multi-Shot, Steady Shot) each
iterated 1..32 UnitBuff slots checking the same four icon paths for
haste-providing buffs. Lifted into libcast.ApplyShotHaste which iterates
the populated auras once via C_UnitAuras.GetUnitAuras and reads from a
single SHOT_HASTE lookup table. Three loop copies collapse to one helper.
Kept texture-keyed matching (rather than spellID) because the Naxx
trinket and Quick Shots procs have spell-ID variants across server
flavors but stable icons.
Player branch in GetBuffData now reads from C_UnitAuras.GetAuraDataByIndex
directly, dropping the GetPlayerBuff chain plus the tooltip-scan for the
buff name. Lazy bid resolution for CancelPlayerBuff. All four tooltip
calls (SetPlayerBuff/SetUnitBuff/SetUnitDebuff x2) collapse to the unified
GameTooltip:SetUnitAura. UnitDebuff dispel-color lookup at line 312 reads
aura.dispelName instead. libdebuff path preserved for non-player units
that still need caster correlation.
- This module will call in group/raid and battleground if you innervated yourself or someone else.
- The module will inform your group/raid/battleground if innervate is ready again.
- Decouple OnValueChanged from OnDataChanged to prevent expensive
full updates on every HP tick
- Replace UnitAffectingCombat(guid) with GetUnitField(flags) bitcheck
and add 0.2s per-GUID throttle cache for GetCombatStateColor
- Gate HP bar SetMinMaxValues/SetValue and text formatting behind
hp/hpmax change detection
- Inline castbar update into per-plate OnUpdate loop, remove dedicated
castbarFrame overhead
- Switch debuff slot cache from name-keyed to slot-index-keyed to fix
timer reset bug when debuffs shift after expiry
- Add raidGuidCache (rebuilt on RAID_ROSTER_UPDATE/PARTY_MEMBERS_CHANGED)
for O(1) offtank target-name lookup
- Add UNIT_FLAGS_GUID event support for instant combat flag notification
(Nampower)
- Extract RebuildOfftanks() to ensure offtanks table is populated at
startup, not only on config change
- Reuse childs table across scan ticks to reduce GC pressure
- Add zoominstant config option to skip zoom animation
- Add combatColorCache cleanup on plate hide and combat leave
Please report any bugs that appear after this change, since it is a huge change.
Fix stale debuff icons/tooltips on target frame after target swap
Fix debuffs not showing on nameplates for timer-less spells (e.g. Hurricane)
Fix buffwatch timer visually speeding up when another debuff fades
Remove 50ms aura cache (slotMapCache/auraFC) - caused stale debuff data
Remove "Show Only Own Debuffs" from unitframes and nameplates GUI
Force selfdebuff=0 for unitframes/nameplates on login to reset old SavedVariables
- use SPELL_DELAYED_SELF (nampower) for cast pushback instead of pfGetCastInfo
- use SPELLCAST_CHANNEL_UPDATE remaining time for channel pushback
- move SetMinMaxValues outside endTime guard so bar visually extends on pushback
Master and experiment users no longer cross-notify each other about updates. The version message now includes a branch tag (master or exp) derived from the toc version string at runtime — only players on the same branch trigger the update notification. No config needed, works automatically.