Tidy up for 0.9.3: Shagu overlap warning, readme rewrite
- Warn once in chat when ShaguTweaks Debuff Timer draws on target debuffs. - Use STANDARD_TEXT_FONT for timers and stack counts. - Clean up comments and dead code; add .gitattributes and .gitignore. - Rewrite README (ClassicAPI version table, ShaguTweaks compatibility); move history to CHANGELOG.md. - Tests: 19 scenarios, no machine-specific paths. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019W3rwutyoLNHxXPycYWSMc
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.zip
|
||||
@@ -0,0 +1,31 @@
|
||||
# Changelog
|
||||
|
||||
## 0.9.3
|
||||
|
||||
- Warn once in chat when ShaguTweaks Debuff Timer is drawing on target debuffs.
|
||||
- Use the client font (`STANDARD_TEXT_FONT`) for timers and stack counts.
|
||||
- Tidy source comments; add `.gitattributes` (LF) and `.gitignore`.
|
||||
- Rewrite the README: ClassicAPI version table (1.17.11+ recommended for the
|
||||
reverse-sweep fix) and a ShaguTweaks compatibility table.
|
||||
- Tests: 19 scenarios; no machine-specific paths.
|
||||
|
||||
## 0.9.2
|
||||
|
||||
- ClassicAPI 1.17.10+: use `UNIT_AURA_DELTA`; no periodic polling. The displayed
|
||||
snapshot is rebuilt to keep filtered ordering and tooltip indices aligned.
|
||||
- Older ClassicAPI keeps the 0.5-second fallback.
|
||||
- Hide native cooldown numbers on our sweeps; disable the expiration flash and
|
||||
clear removed sweeps where supported.
|
||||
- Spellbook and player-pet changes refresh capability-dependent presentation.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
- Refresh on target change and target aura events, with a 0.5-second fallback.
|
||||
- Update only active countdowns every 0.2 s from cached expirations.
|
||||
- Use `GetAuraSlots` / `UnitAuraBySlot` with reusable buffers; positional
|
||||
`UnitAura` fallback for older ClassicAPI.
|
||||
- Stack counts for buffs and overflow debuffs; debuff-type borders.
|
||||
- Gold borders on enemy buffs you or your pet can remove.
|
||||
- Optional reverse cooldown sweeps.
|
||||
- Saved settings, an AddOn Options panel and `/tfb` commands.
|
||||
- Guard against an aura vanishing just before its tooltip opens.
|
||||
@@ -1,71 +1,72 @@
|
||||
# TargetFrameBuff v0.9.2
|
||||
# TargetFrameBuff
|
||||
|
||||
Shows up to 32 upper-row icons and 16 lower-row debuffs on the default target frame.
|
||||
The existing 5-11-11-5 buff layout and 4-4-8 debuff layout are preserved.
|
||||
With ClassicAPI, harmful auras beyond the first 16 use available upper-row icons.
|
||||
Shows up to **32 buffs** and **16 debuffs** on the default target frame of a
|
||||
1.12 client (tested target: Turtle WoW 1.18.1). Buffs sit above the frame in
|
||||
rows of 5-11-11-5, debuffs below it in rows of 4-4-8.
|
||||
|
||||
With the optional [ClassicAPI](https://github.com/brues-code/ClassicAPI) client
|
||||
mod it also adds countdown text, stack counts, debuff-type borders, a gold
|
||||
border on enemy buffs you can remove, optional cooldown sweeps, and accurate
|
||||
tooltips. Without ClassicAPI it behaves like the original: more icons, no timers.
|
||||
|
||||
## Installation
|
||||
|
||||
Back up your existing TargetFrameBuff folder, then replace it with the TargetFrameBuff
|
||||
folder from the ZIP under Interface/AddOns. Restart the client or reload the UI.
|
||||
ClassicAPI is optional; version 1.17.3 was reviewed for this update.
|
||||
For working reverse sweeps and edges, use ClassicAPI 1.17.1 or newer.
|
||||
1. Copy the `TargetFrameBuff` folder into `Interface/AddOns`, replacing any older copy.
|
||||
2. Restart the client (or `/reload`).
|
||||
3. Optional: install ClassicAPI.
|
||||
|
||||
## Changes in v0.9.2
|
||||
## ClassicAPI
|
||||
|
||||
- ClassicAPI 1.17.10+: use UNIT_AURA_DELTA for applications, removals, stack changes
|
||||
and timing-only refreshes; no periodic aura polling on this path. Rebuild the
|
||||
displayed snapshot to preserve filtered ordering and tooltip index alignment.
|
||||
- Older ClassicAPI retains the 0.5-second fallback below.
|
||||
- Hide native cooldown numbers on our sweeps to prevent duplicate text when
|
||||
countdownForCooldowns is enabled; retain TargetFrameBuff's text controls.
|
||||
- Disable the sweep expiration flash and clear removed/disabled sweeps where supported.
|
||||
- Spellbook and player-pet changes refresh capability-dependent aura presentation.
|
||||
| Version | What you get |
|
||||
| --- | --- |
|
||||
| none | 32 buffs and 16 debuffs, no timers, borders or sweeps |
|
||||
| 1.17.x | Timers, stack counts, borders; auras are re-read every 0.5 s |
|
||||
| 1.17.10+ | Event-driven updates (`UNIT_AURA_DELTA`), no polling |
|
||||
| 1.17.11+ | **Recommended.** Fixes the reverse sweep briefly showing a bright icon just before an aura ends |
|
||||
|
||||
## Earlier changes (v0.9.1)
|
||||
|
||||
- Refresh auras on target changes and target aura events, with a 0.5-second fallback.
|
||||
- Update only active countdowns every 0.2 seconds using cached expiration; stop
|
||||
countdown work when none remain. Silent timing changes can take up to 0.5 seconds to appear.
|
||||
- Use GetAuraSlots with reusable buffers and UnitAuraBySlot where available; retain
|
||||
the positional UnitAura fallback for older ClassicAPI. Slot IDs never survive a scan.
|
||||
- Display stack counts for upper-row buffs and overflow debuffs, with debuff-type borders.
|
||||
- Gold borders identify enemy buffs ClassicAPI says you or your pet can remove.
|
||||
- Optional reverse cooldown sweeps; countdown and stack text draw above the sweep.
|
||||
- Saved settings, a ClassicAPI AddOn Options panel, and vanilla-compatible slash commands.
|
||||
- Guard against an aura disappearing immediately before its tooltip opens.
|
||||
Harmful auras beyond the first 16 use free buff-row slots. ClassicAPI decides
|
||||
aura order and lists your own auras first.
|
||||
|
||||
## Settings
|
||||
|
||||
Run /tfb to open AddOn Options when available, or show command help otherwise.
|
||||
`/tfb` opens the AddOn Options panel (or prints help if the client has none).
|
||||
|
||||
| Command | Action |
|
||||
| --- | --- |
|
||||
| /tfb timers on or off | Toggle countdown text (default on) |
|
||||
| /tfb highlight on or off | Toggle removable-buff borders (default on) |
|
||||
| /tfb sweeps on or off | Toggle cooldown sweeps (default off) |
|
||||
| /tfb size 6-20 | Set countdown font size (default 9) |
|
||||
| /tfb warning 0-30 | Seconds remaining at which text turns red (default 5) |
|
||||
| /tfb reset | Restore defaults |
|
||||
| Command | Action | Default |
|
||||
| --- | --- | --- |
|
||||
| `/tfb timers [on\|off]` | Countdown text | on |
|
||||
| `/tfb highlight [on\|off]` | Gold border on removable enemy buffs | on |
|
||||
| `/tfb sweeps [on\|off]` | Reverse cooldown sweeps | off |
|
||||
| `/tfb size 6-20` | Countdown font size | 9 |
|
||||
| `/tfb warning 0-30` | Seconds left at which text turns red | 5 |
|
||||
| `/tfb reset` | Restore defaults | |
|
||||
|
||||
Without ClassicAPI the original native aura display remains available without timers,
|
||||
highlighting or sweeps. Settings are retained for use when ClassicAPI is installed.
|
||||
Settings are saved and kept even while ClassicAPI is absent.
|
||||
|
||||
## Timing limitations
|
||||
## Compatibility with ShaguTweaks
|
||||
|
||||
ClassicAPI timings are best-effort. Unobserved applications and certain max-stack
|
||||
refreshes can have unknown expiration. Unknown or expired timers hide their text
|
||||
and sweep; the icon stays visible while the aura remains listed by the API.
|
||||
ClassicAPI controls aura ordering and puts your own auras first.
|
||||
Checked against the upstream [ShaguTweaks](https://github.com/shagu/ShaguTweaks) source.
|
||||
|
||||
## Validation
|
||||
| ShaguTweaks option | Effect | What to do |
|
||||
| --- | --- | --- |
|
||||
| **Unit Frames > Debuff Timer** | Conflict. Adds its own timer text, sweep and green stack count to debuffs 1-16, on top of ours. It ignores overflow debuffs in the buff row. | Disable it. TargetFrameBuff prints a warning in chat if it detects it. Alternatively use `/tfb timers off` and `/tfb sweeps off`. |
|
||||
| Cooldown Numbers | No conflict found. It only hooks `CooldownFrame_SetTimer`; our sweeps use `SetCooldown`. | Keep. |
|
||||
| Dark UI Elements | Adds a dark border to every `TargetFrameBuff*` button. Ours draws above it, so the gold removable-buff border should stay visible. | Not verified in-game. |
|
||||
| Target Castbar | Positions the castbar from debuff 7 and 11 being shown. With the 4-4-8 layout it can sit over the second and third debuff rows. | Disable it or move the castbar if it overlaps. |
|
||||
| Move Unit Frames | Buff and debuff buttons are children of `TargetFrame`, so they follow it. | Keep. |
|
||||
|
||||
17 automated scenarios passed using Lua 5.1 with a simulated WoW API; XML parses.
|
||||
This is not a live WoW 1.12/1.18.1 test or an exact Lua 5.0 runtime test.
|
||||
See VALIDATION.md for remaining in-game checks.
|
||||
## Notes
|
||||
|
||||
Based on https://wow.curseforge.com/projects/project-949
|
||||
Original author: lua@lumpn.de (modified).
|
||||
- Timings from ClassicAPI are best effort. Unobserved applications and some
|
||||
max-stack refreshes have unknown expiration; their timer and sweep stay hidden
|
||||
while the icon remains.
|
||||
- This is not a live WoW test. See [VALIDATION.md](VALIDATION.md) for what was
|
||||
simulated and what to check in-game, and [CHANGELOG.md](CHANGELOG.md) for history.
|
||||
|
||||
## Development
|
||||
|
||||
Disable ShaguTweaks Unit Frames > Debuff Timer to prevent duplicate countdown text.
|
||||
Tests simulate the WoW API under Lua 5.1: `pip install lupa`, then `python3 tests/test_addon.py`.
|
||||
|
||||
## Credits
|
||||
|
||||
Based on [project-949](https://wow.curseforge.com/projects/project-949).
|
||||
Original author lua@lumpn.de; modified.
|
||||
|
||||
+25
-17
@@ -1,14 +1,14 @@
|
||||
|
||||
-- Title: TargetFrameBuff v0.9.2
|
||||
-- Notes: Shows up to 32 Buffs & 16 Debuffs on a Target (Buffs above, Debuffs below),
|
||||
-- with remaining-time countdowns when ClassicAPI is installed
|
||||
-- Author: lua@lumpn.de (modified)
|
||||
|
||||
-- TargetFrameBuff: up to 32 buffs above and 16 debuffs below the default target
|
||||
-- frame. With ClassicAPI it also adds countdowns, stack counts, removable-buff
|
||||
-- highlights and optional cooldown sweeps. Version and author live in the .toc.
|
||||
|
||||
local lOriginal_TargetDebuffButton_Update = nil;
|
||||
local TARGETFRAMEBUFF_MAX_TARGET_DEBUFFS = 16;
|
||||
local TARGETFRAMEBUFF_MAX_TARGET_BUFFS = 32;
|
||||
|
||||
-- Follow the client font so localized clients keep readable glyphs.
|
||||
local TARGETFRAMEBUFF_FONT = STANDARD_TEXT_FONT or "Fonts\\FRIZQT__.TTF";
|
||||
|
||||
-- How often the countdowns refresh, in seconds.
|
||||
local TARGETFRAMEBUFF_TIMER_INTERVAL = 0.2;
|
||||
|
||||
@@ -62,13 +62,13 @@ local function TargetFrameBuff_AddTimer(button)
|
||||
holder:SetFrameLevel(button:GetFrameLevel() + 2);
|
||||
|
||||
local timer = holder:CreateFontString(nil, "OVERLAY");
|
||||
timer:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE");
|
||||
timer:SetFont(TARGETFRAMEBUFF_FONT, 9, "OUTLINE");
|
||||
timer:SetPoint("CENTER", button, "CENTER", 0, 0);
|
||||
timer:Hide();
|
||||
|
||||
if (not button.auraCount) then
|
||||
button.auraCount = holder:CreateFontString(nil, "OVERLAY");
|
||||
button.auraCount:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE");
|
||||
button.auraCount:SetFont(TARGETFRAMEBUFF_FONT, 9, "OUTLINE");
|
||||
button.auraCount:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 1, -1);
|
||||
button.auraCount:Hide();
|
||||
local stockCount = getglobal(button:GetName().."Count");
|
||||
@@ -90,7 +90,7 @@ function TargetFrameBuff_OnLoad()
|
||||
overlay:SetAllPoints(button);
|
||||
overlay:SetFrameLevel(button:GetFrameLevel() + 2);
|
||||
button.auraCount = overlay:CreateFontString(nil, "OVERLAY");
|
||||
button.auraCount:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE");
|
||||
button.auraCount:SetFont(TARGETFRAMEBUFF_FONT, 9, "OUTLINE");
|
||||
button.auraCount:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 1, -1);
|
||||
button.auraCount:Hide();
|
||||
button.auraBorder = overlay:CreateTexture(nil, "OVERLAY");
|
||||
@@ -148,6 +148,18 @@ function TargetFrameBuff_OnLoad()
|
||||
end
|
||||
|
||||
|
||||
-- ShaguTweaks "Debuff Timer" wraps TargetDebuffButton_Update and adds its own
|
||||
-- cooldown (button.cd), timer text and stack count to every debuff button. On
|
||||
-- top of ours that doubles the timers, sweeps and stack numbers. Its field is
|
||||
-- named cd (ours is cooldown), so seeing it is a locale-proof way to notice.
|
||||
local lWarnedShagu = false;
|
||||
local function TargetFrameBuff_CheckShagu()
|
||||
if (lDebuffButtons[1] and lDebuffButtons[1].cd and lDebuffButtons[1].timer) then
|
||||
lWarnedShagu = true;
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffd100TargetFrameBuff:|r ShaguTweaks Debuff Timer is also drawing timers, sweeps and stack counts on target debuffs, so they overlap. Disable it under ShaguTweaks > Unit Frames, or use /tfb timers off and /tfb sweeps off.");
|
||||
end
|
||||
end
|
||||
|
||||
-- use extended update-function (original code from FrameXML/TargetFrame.lua)
|
||||
function TargetFrameBuff_Update()
|
||||
if (TargetFrameBuff_HasClassicAPI() and lBuffButtons[1] and lBuffButtons[1].timer) then
|
||||
@@ -156,6 +168,7 @@ function TargetFrameBuff_Update()
|
||||
TargetFrameBuff_UpdateNative();
|
||||
end
|
||||
TargetFrameBuff_Layout();
|
||||
if (not lWarnedShagu) then TargetFrameBuff_CheckShagu(); end
|
||||
-- Draw countdowns right away instead of waiting for the next tick.
|
||||
lTimerElapsed = TARGETFRAMEBUFF_TIMER_INTERVAL;
|
||||
end
|
||||
@@ -372,13 +385,8 @@ function TargetFrameBuff_Layout()
|
||||
TargetFrameBuff1:ClearAllPoints();
|
||||
TargetFrameBuff1:SetPoint("BOTTOMLEFT", "TargetFrame", "TOPLEFT", 5, -10);
|
||||
|
||||
-- Position debuffs below target frame using default positioning (no gap)
|
||||
-- Layout: 4-4-8 (three rows: 4 debuffs, 4 debuffs, 8 debuffs)
|
||||
-- Debuff 1 uses default WoW positioning to avoid gap with target frame
|
||||
-- TargetFrameDebuff1:ClearAllPoints();
|
||||
-- TargetFrameDebuff1:SetPoint("TOPLEFT", "TargetFrame", "BOTTOMLEFT", 5, 0);
|
||||
|
||||
-- Position remaining buttons in 4-4-8 layout
|
||||
-- Debuff 1 keeps the stock anchor so it sits flush under the target frame.
|
||||
-- Remaining debuffs use a 4-4-8 layout (three rows).
|
||||
for i=2, TARGETFRAMEBUFF_MAX_TARGET_DEBUFFS do
|
||||
button = lDebuffButtons[i];
|
||||
if button then
|
||||
@@ -417,7 +425,7 @@ TargetFrameBuff_UpdateTimer = function(button, now)
|
||||
|
||||
local size = TargetFrameBuff_Setting("timerSize");
|
||||
if (button.timerSize ~= size) then
|
||||
button.timer:SetFont("Fonts\\FRIZQT__.TTF", size, "OUTLINE");
|
||||
button.timer:SetFont(TARGETFRAMEBUFF_FONT, size, "OUTLINE");
|
||||
button.timerSize = size;
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
## Interface: 1700
|
||||
## Title: TargetFrameBuff v0.9.2
|
||||
## Title: TargetFrameBuff v0.9.3
|
||||
## Notes: Shows up to 32 Buffs & 16 Debuffs on a Target, with countdowns when ClassicAPI is installed
|
||||
## Author: lua@lumpn.de (modified)
|
||||
## SavedVariables: TargetFrameBuffDB
|
||||
|
||||
+5
-4
@@ -1,8 +1,8 @@
|
||||
# TargetFrameBuff v0.9.2 validation
|
||||
# TargetFrameBuff v0.9.3 validation
|
||||
|
||||
17 simulated Lua 5.1 regression scenarios passed, plus XML parsing. These cover
|
||||
19 simulated Lua 5.1 regression scenarios passed, plus XML parsing. These cover
|
||||
old/native clients, aura reordering, overflow, settings, sweep lifecycle, delta
|
||||
refreshes and full updates, target/pet/spellbook changes, reused delta payloads,
|
||||
refreshes and full updates, the Debuff Timer overlap warning, target/pet/spellbook changes, reused delta payloads,
|
||||
no polling in delta mode, and native-number/flash suppression.
|
||||
|
||||
ClassicAPI 1.17.10+ is detected through GetAuraDataByAuraInstanceID, introduced with
|
||||
@@ -16,4 +16,5 @@ New Clear and SetDrawBling methods are optional, preserving older versions.
|
||||
|
||||
Not tested inside a running WoW client. Verify recasts, target switches, auras
|
||||
expiring, and sweeps with countdownForCooldowns enabled. Keep ShaguTweaks Debuff
|
||||
Timer disabled to prevent overlapping addon countdowns. No FPS gain is claimed.
|
||||
Timer disabled to prevent overlapping addon countdowns (a chat warning appears
|
||||
if it is detected). No FPS gain is claimed.
|
||||
|
||||
+13
-1
@@ -1,7 +1,6 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import xml.etree.ElementTree as ET
|
||||
sys.path.insert(0, str(Path("work/pythonlibs").resolve()))
|
||||
from lupa.lua51 import LuaRuntime
|
||||
|
||||
addon = Path(__file__).resolve().parents[1]
|
||||
@@ -214,6 +213,19 @@ SlashCmdList.TARGETFRAMEBUFF("sweeps off"); assert(cd.cleared and not cd:IsShown
|
||||
SlashCmdList.TARGETFRAMEBUFF("sweeps on"); cd.cleared=false
|
||||
auras.HELPFUL={}; Tick(); assert(cd.cleared and not cd:IsShown())
|
||||
''')
|
||||
run("ShaguTweaks Debuff Timer overlap warns once, only with ClassicAPI", 'InstallAPI(true); auras.HELPFUL={Aura("A")}', '''
|
||||
Tick(); assert(#messages==0)
|
||||
TargetFrameDebuff1.cd={readable={}}
|
||||
Tick(); Tick()
|
||||
local n=0
|
||||
for _,m in ipairs(messages) do if string.find(m,"Debuff Timer",1,true) then n=n+1 end end
|
||||
assert(n==1)
|
||||
''')
|
||||
run("no warning on the native path", 'nativeBuffs={"Native"}; nativeDebuffs={}', '''
|
||||
TargetFrameDebuff1.cd={readable={}}
|
||||
Tick(); Tick()
|
||||
for _,m in ipairs(messages) do assert(not string.find(m,"Debuff Timer",1,true)) end
|
||||
''')
|
||||
ET.parse(addon/"TargetFrameBuff.xml")
|
||||
print("PASS XML parsing")
|
||||
print(f"{passed} Lua regression scenarios passed; XML parsed.")
|
||||
|
||||
Reference in New Issue
Block a user