The druid secondary mana bar (shown while shapeshifted into a form that
uses energy/rage) lived in nampower.lua and read base mana through
nampower's GetUnitField. Extract it into the unit frame proper and drive
it with ClassicAPI instead:
- Create pfDruidMana_<unit> as f.druidmana in CreateUnitFrame (player and
target), lay it out in UpdateConfig from the existing C.unitframes.druidmana*
keys, and update it in a new pfUI.uf:UpdateDruidMana driven by the frame's
own base-refresh pass (UNIT_MANA / UNIT_DISPLAYPOWER). No separate event
frames, no nampower dependency.
- Read mana via UnitPower(unit, 0) / UnitPowerMax(unit, 0), the ClassicAPI
slot getters that return the mana pool regardless of the active power, so
it works while in Cat/Bear form.
- Add a "Show Druid Mana Bar Text" toggle (druidmanatext) so the current/max
readout can be hidden while keeping the bar; config default, GUI checkbox,
and locale stubs.
- Remove the now-dead block from nampower.lua.
- selfinraid now gates on `not IsInGroup()`, so "show self in raid frames"
applies only when truly solo (both party and raid suppress it), matching
the option's actual behavior.
- Hide the redundant group frames when a party is promoted to the raid grid
(raidforgroup + hide_in_raid), not just in an actual raid. A shared
hide_group local drives both the party-member and self branches; the
party-member branch is scoped to cache_raid == 0 so the raidforgroup-mapped
raid frames (which themselves carry label "party") aren't hidden too.
- Rename "Always Show Self In Raid Frames" to "Show Self In Raid Frames When
Solo" in gui.lua and all locale files; the four previously-translated
strings are reset to nil stubs since the meaning changed.
commit f19d7402810637fc32460864104cb792ac5af863
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Wed Jul 22 01:05:52 2026 -0500
remove comment
commit 60f4968f06d19d42bdc6347f98ff4d5a34785e97
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Wed Jul 22 01:05:06 2026 -0500
Bump ClassicAPI minimum version to 10705
Update the minimum required ClassicAPI version from 10704 (1.7.4) to 10705 (1.7.5).
commit 088dba4c23f4aa7ce98b9ce9d75bc5892cd40520
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Wed Jul 22 01:04:04 2026 -0500
Add raid-pet frames: an independent, roster-driven pet grid
New "raidpet" unitframe type that shows raid members' pets (raidpet1..40)
in their own movable block (pfRaidPetCluster), off by default. It's a
flat pool of frames laid out by pfUI.uf.raid:LayoutPets straight from the
raid roster -- cell N shows raidpet<N> -- so it's fully decoupled from how
the raid grid arranges its own slots.
Layout is independent of the raid grid: raidpet carries its own
width/height plus a Layout section (raidlayout / raidpadding / raidfill),
and its own Collapse Empty Slots toggle that packs only the pets that
exist into the leading cells. The raid grid gets the same collapse option
(sequential slot assignment in AddUnitToGroup instead of by subgroup).
Collapsed pets re-pack on roster changes and on UNIT_PET so summons and
dismisses track live without polling.
Also:
- unitframes: a "raidpet" branch in UpdateVisibility (hide when the pet is
out of range or its raid<N> owner is gone), and fix cache_raid so the
"pfRaid" prefix check doesn't misread pfRaidPet<n> frames (char 7 is
non-numeric -> nil compare crash).
- New "Owner Name" text option: on any pet frame (raidpet/partypet/pet) it
shows the owner's class-colored name so you can tell whose pet it is.
- unlock: a pfRaidPet drag cluster, a numeric-suffix guard so pfRaid no
longer matches (and crashes on) pet frames, and RaidPet config mappings.
- config/gui/translations for all of the above.
commit 52f02c8963fe7ec90f36100ebe069c7807529301
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Mon Jul 20 23:09:06 2026 -0500
Enumerate chat bubbles via ClassicAPI instead of scanning WorldFrame
ClassicAPI's C_ChatBubbles.GetAllChatBubbles() walks the engine's own
bubble list and returns the exact set of live bubble frames, with real
GetRegions(), so the decoration idiom works unchanged. Replace the
WorldFrame:GetChildren() sweep and drop the IsBubble heuristic (unnamed
frame whose first region is the ChatBubble-Background texture) -- the API
only ever hands back bubbles, so that guess is both redundant and more
fragile than the engine list. Cheaper too: it iterates only live bubbles
rather than every world child on each chat event.
Add a Left Click / Right Click hint to the totem icon tooltip via
AddDoubleLine, matching the panel.lua convention. Reuses the existing
"Left Click" / "Right Click" strings and adds "Recast Totem" /
"Target Totem" as new translation keys (stubbed across all locales; they
fall back to English until translated).
Also drop the now-orphaned "Range Check Interval" string from every
locale manifest -- the setting was removed when librange stopped
scanning, but its translation stubs were left behind.
ClassicAPI now ships GetTotemInfo/GetTotemTimeLeft/GetTotemDuration/
TargetTotem plus a native PLAYER_TOTEM_UPDATE event, backed by a
data-driven tracker (slot from the Spell.dbc summon effect, duration from
SpellDuration.dbc, and object-manager death detection). That's exactly
what libtotem hand-rolled -- and better -- so delete the library outright:
its spellid/icon tables, the CastSpellByName/CastSpell/UseAction hooks,
the SPELL_GO commit path, and the active-totem bookkeeping.
modules/totems.lua becomes a thin consumer of the native API:
- Driven by PLAYER_TOTEM_UPDATE; drop the shaman tick-poller that only
existed because vanilla had no totem event.
- Fix the GetTotemInfo call sites: the native 1st return is tool presence,
not "summoned", so key active state on name/start instead.
- Right-click a totem icon to TargetTotem it; tooltip shows remaining time
via GetTotemTimeLeft.
modules/turtle-wow.lua: drop the Totemic Recall handler that poked
libtotem:Clean() -- the native tracker detects the totems despawning and
clears the slots itself. Also clean up the now-orphaned translation string
and a stale libtotem mention in libdebuff's comment.
Mirror the druid-stealth page switch for priests: swap to the auto page
(8) while in Shadowform, back to the default page when it drops. Driven
by UPDATE_SHAPESHIFT_FORM (form ID 28), which fully covers shadowform on
its own -- no prowl-style stealth substate to chase.
Fold the new state into the existing prowl machinery instead of
duplicating it: prowl/shadowform are mutually exclusive by class, so one
shared `formpaging` flag and one page constant serve both, and the
OnUpdate switch collapses to a single class-gated block.
New module built on ClassicAPI's C_NewItems + BAG_NEW_ITEMS_UPDATED.
Glows bag slots (bags 0-4) holding items acquired since login, keyed on
item GUID so the flag survives rearranging. Hovering an item
acknowledges it (RemoveNewItem); closing the bags clears the rest via
ClearAll. Glow is UI-ActionButton-Border, sized off the slot width so it
tracks the icon_size config.
To stay decoupled from the bag frames, the bag module now broadcasts a
reusable "bag:closed" event through pfUI.events from its OnHide (carrying
the container so subscribers can tell backpack from bank), guarded so the
initial setup Hide() doesn't fire a phantom close.
Config: appearance.bags.newitem + newitem_color, with GUI toggles.
A pfUI-native group-loot roll history window built on ClassicAPI's
C_LootHistory backport, adapted from the anniversary Blizzard reference.
- Movable/scrollable window (ESC-closable, Clear button) listing rolled
items; each row expands to per-player rolls.
- Item icon/name/quality rendered via the !!!ClassicAPI Item mixin
(Item:CreateFromItemLink + ContinueOnItemLoad), so uncached items load
asynchronously and repaint their row.
- Winner shown on the collapsed row (name/roll/roll-type) and marked in the
expanded list with a checkmark left of the name (matches the reference).
- Expansion state keys on the stable rollID; events (FULL_UPDATE /
ROLL_CHANGED / ROLL_COMPLETE) drive a rebuild while shown, and re-attach
the scroll child so a growing list scrolls without a /reload.
- Toggle via /loothistory or /lh; optional auto-show on new rolls behind
loothistory.autoshow (default off).
Add display of required and optional addon dependencies to the addons tooltip. Introduce AddDependencyLines helper in modules/addons.lua which lists dependencies with color coding: green for loaded, yellow for present but unloaded, and red for missing (uses new T["Missing"]). Store dependency arrays on addon frames (adeps / aoptdeps) using GetAddOnDependencies and C_AddOns.GetAddOnOptionalDependencies. Add translation keys 'Dependencies', 'Optional Dependencies', and 'Missing' to env/translations_enUS.lua.
commit d63057474083aa67fda2aa28ee6301334ffc4fdf
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Mon Jul 6 00:59:17 2026 -0500
Use C_Map.GetMapOverlays instead of hardcoded pfMapOverlayData
ClassicAPI's C_Map.GetMapOverlays reads WorldMapOverlay.dbc directly and
returns the full overlay list for a zone (explored + unexplored) — the
data vanilla's GetMapOverlayInfo withholds. mapreveal now iterates it
straight (named fields: textureName/texturePath/width/height/offsets),
dropping unpack_hash and the pfMapOverlayData tables entirely.
Also fixes the explored-check: it compared the full texture path against
GetMapOverlayInfo's bare-name keys, so the magnifying glass never
suppressed on explored overlays. Now matches on the bare name.
Removes ~870 lines of hand-measured overlay data (base + Turtle).
commit ad12c8209a80cd1211fe08e83f7013d24b5efd2d
Author: Brues <5278969+brues-code@users.noreply.github.com>
Date: Sun Jul 5 23:45:09 2026 -0500
utilize HookScript from ClassicAPI
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.
Both sub-tables carried per-locale strings only so pfUI's own code could
match against localized text. ClassicAPI's numeric item APIs replace
both:
- GetBagFamily now reads classID/subClassID from C_Item.GetItemInfoInstant
and switches on the numbers (class 1 = Container, class 11 = Quiver).
- eqcompare pulls the itemID from GameTooltip:GetItem(), fetches the
numeric invType via C_Item.GetItemInventoryTypeByID, and looks up the
destination slot(s) in a numeric slotTable keyed by Enum.InventoryType.
Pair-slot invtypes (finger / trinket / one-hand weapon) list both
destinations directly, so the "_other" string-concat hack is gone.
Removes the setglobal INVTYPE_* injection, the tooltip text scan, and
the itemtypes + bagtypes locale sub-tables across all 7 files.
Audited every consumer of pfUI_locale[*][key] across the codebase. Four
sub-tables have no non-locale-file readers left:
- hunterpaging — old auto-page trigger removed
- interrupts — replaced by Nampower SPELL_INTERRUPTED events
- spells — replaced by ClassicAPI Spell.dbc lookups
- icons — replaced by ClassicAPI C_Spell.GetSpellName / icon path
Removed the entries from all 7 locale files. ~18k dead lines gone,
~70% shrink per file.
Switches the addon-message prefix to "pfUI-brues" so we don't share an
inbound queue with upstream pfUI installs at all — they don't register
a listener for this prefix, so our broadcasts get dropped at the engine
level instead of needing branch-string filtering on their end. The
"main" branch tag stays as a tiebreaker for any future fork variant
sharing this prefix.
Source/dev installs leave the toc Version as "@project-version@" until
release tooling substitutes it. pfUI.lua now stamps those as "dev" with
major/minor/fix=0 instead of silently falling back to 1.2.0, and
updatenotify short-circuits on pfUI.version.string == "dev" before
broadcasting so dev installs don't ship a stale low version to everyone
in guild/raid. Single source of truth — the dev marker lives in pfUI.lua.
URLs centralize via the toc's X-Website. updatenotify and firstrun read
it via GetAddOnMetadata + string.format("%s"), and all eight translation
files swap their hardcoded shagu.org references for the same %s slot.
Drive-bys: groupsize math uses ClassicAPI's IsInRaid/IsInGroup; toc
Author typo "modfied" → "modified".
* 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>
Each pfSellData entry was a "sell,buy" string. The sell price duplicates
what C_Item.GetItemSellPriceByID returns from the engine's item DBC, so
it's redundant in our table — only the buy price (curated from real
vendor encounters, not a static item property) needs to live here.
Transformed every [id]="X,Y" entry across env/tables.lua, compat/tbc.lua,
and modules/turtle-wow.lua to [id]=Y via sed. Format is now itemid →
buyPrice (number, copper).
sellvalue.lua: reads sell from C_Item.GetItemSellPriceByID(id), reads
buy from pfSellData[id]. Items that have only a sell price (not in
pfSellData) now display sell-only — previously they got no tooltip
addition because the lookup gated on table membership. Items with
buy-only (sell == 0 in old data) still display buy correctly.
autovendor.lua: replaces the pfSellData[id] gate (which only checked
table membership and unused the parsed sell/buy) with a direct
C_Item.GetItemSellPriceByID > 0 check — the engine's canonical
"is this item sellable to a vendor" answer.
env/tables.lua — Updated pfMapOverlayData to current Turtle WoW WorldMapOverlay.dbc (53 zones, 707 overlays — added 12 new zones, ~40 new exploration areas)
modules/mapreveal.lua — Use separate texture pool to prevent conflicts with Blizzard overlay rendering; removed legacy errata and unused hash logic