Adds per-unit (player/target/focus) dropdowns to align the castbar
spell name (left text) and cast timer (right text) Left/Center/Right.
Both share a castbaralign dropdown; defaults preserve current behavior
(name LEFT, timer RIGHT). Applied at castbar creation, so takes effect
on /reload like the other castbar options.
The unlock preview drives the bar via alpha: the OnUpdate forces alpha=1
while the drag handle is shown. On lock, with no active cast (endTime nil)
and no fadeout, the idle branch returned early and left the empty bar
stuck at alpha 1. Reset leftover alpha to 0 in that branch so the preview
clears once the drag handle hides. Fixes#16.
pfUI's Lua hooksecurefunc lived in pfUI.env and shadowed ClassicAPI's C
global for all pfUI code. Replace it with a thin pfUI.hooksecurefunc shim
that keeps the missing-target no-op our call sites rely on (ClassicAPI
errors on a nil target) and delegates the actual hook to _G.hooksecurefunc.
Migrated all 70 internal call sites (modules/libs/skins) to
pfUI.hooksecurefunc; bare hooksecurefunc now resolves to ClassicAPI's C
version everywhere. Dropped the unused prepend path and the orphaned
pfUI.hooks table.
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