Hook DoTradeSkill to capture the requested count, then on the first
SPELLCAST_START of an isTradeskill cast stretch endTime to span all
crafts so the player bar fills continuously across the chain. Mid-chain
SPELLCAST_START / SPELL_START_SELF events refresh the "(N)" remaining
label and reset a per-craft spark that crosses the bar once per craft.
SPELL_GO_SELF counts completions; SPELLCAST_STOP no-ops while merged.
Gated by a new C.castbar.player.mergetradeskill knob (default on).
Drive the cast bar from cast lifecycle events instead of polling C_Spell
every frame. OnUpdate now only animates a stamped start/end and fades out;
all state transitions come from events:
- player: vanilla SPELLCAST_START / _STOP / _FAILED / _INTERRUPTED /
_CHANNEL_START / _CHANNEL_STOP, plus nampower SPELL_START_SELF (the only
signal for a chained same-spell recast, which never runs the client cast
path) and SPELL_DELAYED_SELF for pushback (applied from its delayMs arg).
- non-player (target/focus): nampower SPELL_START_OTHER / SPELL_FAILED_OTHER
+ PLAYER_TARGET_CHANGED / PLAYER_FOCUS_CHANGED.
Data comes from ClassicAPI's C_Spell.UnitCastingInfo / UnitChannelInfo
(player exact; other units from the SMSG_SPELL_START cache). SPELL_START_*
re-polls are deferred one frame so ClassicAPI's packet co-hook has stamped
before the read. SPELLCAST_CHANNEL_STOP only clears when a channel is shown,
so a lagged channel-stop doesn't wipe a following cast's bar.
Remove the now-unused CASTBAR_EVENT_* constants from compat/vanilla.lua.
ClassicAPI's recent C_Spell additions cover remote-unit casts natively
(SMSG_SPELL_START co-hook caching per caster GUID), so the two parallel
cast trackers pfUI was running — libcast.lua and the libdebuff_casts
table inside libdebuff.lua — can both retire.
Migrations:
- modules/castbar.lua: focus/player cast-info gathering reads
C_Spell.UnitCastingInfo / UnitChannelInfo directly. Fallback ladder
(libdebuff_casts → pfGetCastInfo → pfGetChannelInfo) collapses into a
single call. Pushback handlers stop writing back into a non-existent
cache; the local this.endTime is the source of truth.
- modules/nameplates.lua: GetCastInfo(guid) now resolves to a unit token
via UnitTokenFromGUID and queries C_Spell, returning the same compact
struct shape downstream code expected. UpdateCastbar collapses from a
three-branch hierarchy (dead IterDebuffs / libdebuff_casts / libcast)
to one C_Spell read.
- modules/afkcam.lua: pfGetCastInfo+pfGetChannelInfo round-trip becomes
a single C_Spell.UnitCastingInfo("player") or UnitChannelInfo fallback.
- libs/libpredict.lua: HealComm timing uses C_Spell on the sender's unit
token after a small group-roster walk to resolve the sender's name.
Deletions:
- libs/libcast.lua entirely (-571 lines) plus its init/libs.xml entry.
- libdebuff_casts / libdebuff_item_icons tables and their write sites
in libs/libdebuff.lua (the SPELL_START_*, SPELL_GO_*, SPELL_FAILED_*
event handlers stop maintaining them but keep firing the
libdebuff_*_hooks broadcast surface for actionbar / swingtimer /
libtotem). SPELLCAST_CHANNEL_STOP now reads the active channel from
C_Spell.ChannelInfo.
- modules/superwow.lua's supercast block — UNIT_CASTEVENT writes into
libcast.db are redundant now that C_Spell co-hooks the same packet.
- The cast-bar item-icon override that swapped in a potion/trinket
icon for item-triggered casts. Spell icon stays; the item-icon
metadata path (libdebuff_item_icons) went with libdebuff_casts.
Steady Shot synthetic cast bar — Turtle WoW-specific:
- castbar.lua gains a pfUI.synthetic_casts[unit] fallback that fires
only when C_Spell returns nil, so abilities the engine treats as
instant but which have a meaningful wait window can still render a
cast bar.
- modules/turtle-wow.lua replaces the old libcast.customcast block with
a Nampower SPELL_QUEUE_EVENT subscriber. ON_SWING_QUEUED matching
the localized "Steady Shot" name writes a 1.4s synthetic entry;
ON_SWING_QUEUE_POPPED clears it; castbar's endMs guard self-expires
the entry as a safety net. Note: haste scaling (libcast.ApplyShotHaste)
is gone — bar may finish slightly early under +ranged haste buffs.
Net: 152 insertions, 972 deletions.
Routes player and nameplate castbar progress through
PixelUtil.SetStatusBarValue so a 1.4s cast on a narrow bar no longer
shimmers across fractional pixels as it ticks. Adds GetMinMaxValues /
GetValue handlers to pfUI's custom StatusBar so PixelUtil can read the
current range.
* focus: migrate to FocusUnit / "focus" token / PLAYER_FOCUS_CHANGED
ClassicAPI now polyfills modern WoW's focus system: FocusUnit / ClearFocus
+ "focus" / "focustarget" unit tokens accepted by every UnitX function +
PLAYER_FOCUS_CHANGED event. Drop pfUI's GUID-juggling pseudo-frame.
- env/tables.lua: add "focus" and "focustarget" to pfValidUnits — the
focus frames now follow the standard event-driven CreateUnitFrame path
with f.label = "focus"
- modules/focus.lua: rewrite. Slash commands use FocusUnit / ClearFocus
directly; no more manual frame.label/unitname/id manipulation. /focus
<name> still does a target-swap to resolve names → units, then
FocusUnit("target") captures the GUID before the target is restored.
PLAYER_FOCUS_CHANGED triggers immediate frame refresh on assign/clear.
- api/unitframes.lua: delete the pseudo-focus block (per-tick "scan all
units for matching name" loop) and the "focus"/"focustarget" special-
case in the visibility branch — "focus" is now a real token.
- modules/castbar.lua: bind the focus castbar to unitstr = "focus" once;
drop the OnUpdate that synced pfUI.castbar.focus from
pfUI.uf.focus.label/unitname. UnitGUID("focus") resolves at read time.
- Drop C_Minimap.SetFocusByGUID / SetFocusByName / ClearFocus calls —
C_Minimap subscribes to PLAYER_FOCUS_CHANGED on its own.
Net -183 lines. Focus stops being a pfUI-special pseudo-frame and
becomes "just another unit token" — same treatment as target/player.
* add nameplate to valid units
---------
Co-authored-by: Brues <5278969+brues-code@users.noreply.github.com>
Drop the now-vestigial expansion plumbing.
- Delete modules/thirdparty-tbc.lua + its xml Include
- Strip 10 tbc-tagged CreateConfig calls in modules/gui.lua
- Drop the expansion arg from CreateConfig() signature + the disabled-
entry rendering path that depended on it
- Drop the showdisabled GUI toggle + its default
- Simplify pfUI:RegisterModule / pfUI:RegisterSkin to (name, func) only
- Strip the leading version arg ("vanilla:tbc", etc.) from all 114
Register call sites
- Delete the pfUI.expansion variable
- 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
Problem:
Since a recent Turtle-WoW update, nameplates would show the same castbar on all mobs sharing a name (e.g. multiple "Defias Rogue Wizard"). Additionally, a targeted mob that was not casting would incorrectly display the castbar of a nearby mob with the same name.
Changes:
**`modules/nameplates.lua`**
- Removed `hasNampower` version-sniffing entirely. Nampower is a hard requirement for pfUI; all related guards have been removed and the code runs unconditionally.
- Castbar lookup now always uses `nameplate.cachedGuid` directly — never `GetUnitGUID("target")` or a unit name string.
- Removed dead fallback block using `UnitCastingInfo("target")`.
- Restored fallback via `pfGetCastInfo(cachedGuid)` / `pfGetChannelInfo(cachedGuid)` (see libcast changes below) for casts not tracked by libdebuff (e.g. already-in-progress casts on login).
**`libs/libcast.lua`**
- Renamed `UnitCastingInfo` → `pfGetCastInfo` and `UnitChannelInfo` → `pfGetChannelInfo` to avoid confusion with the Blizzard API of the same name, which does not exist in Vanilla.
- Name-based fallback lookup (`libcast.db[unitName]`) is now skipped when a GUID is available. This prevents cast bleed between mobs that share a name.
**`libs/libpredict.lua`, `modules/castbar.lua`, `modules/afkcam.lua`**
- Updated all call sites to use the renamed `pfGetCastInfo` / `pfGetChannelInfo`.
Removed SuperWoW dependency from castbar and nameplate cast detection. Cast interrupts (sidestep, spell failed) now correctly stop the castbar by setting event = "FAIL" / event = "CAST" on the libdebuff cache entry instead of nil-ing it — preventing stale local references from keeping the castbar alive. UnitCastingInfo fallback is retained for non-Nampower environments but no longer overrides Nampower cast state.
Bugfixes:
- Fixed 40-yard range check not working for raid/party frames
- Fixed aggro indicator not displaying properly on raid/party frames
- Improved aggro cache to only cache positive results for instant detection
- Fixed HP/Mana not updating with "Use Raid Frames for group" enabled
- Added SuperWoW nil-check for SpellInfo
- Added missing events: PARTY_MEMBER_ENABLE, PARTY_MEMBER_DISABLE, PLAYER_UPDATE_RESTING
UI Improvements:
- Share/Hoverbind buttons now show warning when module is disabled