Skip to content

feat(qol): add standalone movable gear durability display - #1635

Open
apainter2 wants to merge 6 commits into
EllesmereGaming:mainfrom
apainter2:feature/qol-durability-display
Open

apainter2 wants to merge 6 commits into
EllesmereGaming:mainfrom
apainter2:feature/qol-durability-display

Conversation

@apainter2

@apainter2 apainter2 commented Aug 21, 2026

Copy link
Copy Markdown

Add an optional Quality of Life feature that shows a compact, independently movable "[icon] 87%" style readout of the lowest durability percent across equipped repairable gear, making it obvious when to repair.

  • Event driven only (UPDATE_INVENTORY_DURABILITY, PLAYER_ENTERING_WORLD); no OnUpdate, ticker or polling.
  • Zero cost unless enabled: default off, builds no frame and registers no events until first enabled; getFrame never creates so login-time ApplySavedPositions stays free while disabled.
  • Reuses house systems: Lite.NewDB (own gearDurability slice on EllesmereUIQoLDB, other QoL data untouched), GetFontPath/SlugFlag fonts, MakeUnlockElement/Unlock Mode for movement and persistence, ShowWidgetTooltip for a per-slot breakdown, DualRow/DependentSetValue options widgets.
  • Durability maths and white->red warning gradient mirror the DataBars durability block; reuses the DataBars forge glyph.

What does this PR do?

Adds an optional Quality of Life feature: a compact, independently movable gear durability display that shows the lowest durability percent across equipped repairable gear, so it's obvious at a glance when to repair.

  • Renders as [forge icon] 87% (icon and percentage each toggleable).
  • Lives under Quality of Life -> Keys, Logs & Brez, in a new GEAR DURABILITY
    section alongside the BattleRes / Bloodlust trackers.
  • Movable via the existing Unlock Mode; position persists per profile.
  • Hover shows a per-slot breakdown through the house widget tooltip.
  • Optional dynamic white -> red warning colour (mirrors the DataBars durability
    block), a static colour when dynamic is off, and an optional "hide at full".

It reuses the existing durability maths and white->red gradient from the DataBars durability block (so the two readouts always agree) and reuses the DataBars forge glyph. It does not modify or replace the DataBars block; the differentiator is that this is standalone and independently movable without requiring DataBars.

How was it tested?

Tested in-game on live (Retail/Midnight 12.1), no Lua errors:

  • Enable/disable via the section dropdown; sub-rows appear only when enabled.
  • Toggled Show Icon / Show Percentage / Dynamic Colour / Hide at Full; adjusted Font Size.
  • Dragged in Unlock Mode; /reload restores position; survives profile switch.
  • Verified updates are event-driven (damage at a dummy / vendor repair) with no OnUpdate or polling.
  • Confirmed nothing is built and no events are registered while the feature is off.

Also validated all touched Lua files with lua-language-server --check (zero diagnostics); ASCII-only, Lua 5.1, no goto.

Screenshots

Before addon activation:
before-activation

After activation:
after-activation

Unlock Mode:
unlock mode

Durability Addon displayed:
durability

Detailed - When hovered over:
hover-detailed

Checklist

  • New settings default OFF (no behavior change without opt-in) -- visibility defaults to NEVER
  • Zero cost while disabled: no events registered, no polling, no hooks doing work, no frames built -- Apply() builds nothing while off, and getFrame never creates (so login-time ApplySavedPositions stays free)
  • Cheap while enabled: event-driven (no polling, no timer-based logic, no per-frame allocations) -- only UPDATE_INVENTORY_DURABILITY + PLAYER_ENTERING_WORLD
  • No writes onto Blizzard-owned frames -- the feature only creates its own UIParent child; no SetScript on Blizzard frames
  • Tested in-game on live; no version gates or pre-Midnight APIs added

Changelog

  • 12e5cce feat(qol): add standalone movable gear durability display

    • New Quality of Life feature: compact, independently movable [icon] 87%
      readout of the lowest durability across equipped repairable gear.
    • Options under QoL -> Keys, Logs & Brez (Enable, Show Icon, Show Percentage,
      Dynamic Colour, static Text Colour, Hide at Full, Font Size).
    • Movable via Unlock Mode with per-profile position; per-slot hover tooltip.
    • Reuses the DataBars durability maths + white->red gradient and forge glyph.
    • Default OFF; zero cost while disabled.
  • fdd93c1 fix(qol): refresh on all durability-change edges

    • On-screen number was stale after damage until /reload; now re-samples on
      UPDATE_INVENTORY_DURABILITY, PLAYER_REGEN_ENABLED, PLAYER_UNGHOST,
      PLAYER_EQUIPMENT_CHANGED, MERCHANT_CLOSED and PLAYER_ENTERING_WORLD (still
      event-driven, no polling).

Quick note on timing: I know CONTRIBUTING.md currently pauses feature requests until a few weeks after the 12.1 launch, with only bug fixes accepted in the meantime. I'm opening this now mainly for visibility and early feedback on the approach rather than to jump the queue.

I'm completely happy to:

  • leave it sitting until the freeze lifts,
  • close and re-open it later if you'd prefer, or
  • adjust the design first if a standalone display isn't the direction you want.

For context, I deliberately kept it self-contained and reused the existing DataBars durability maths, the white->red colour model, the forge glyph, Unlock Mode, the house tooltip, and the DualRow options widgets, so it should sit naturally within the existing conventions and stay zero-cost while disabled. If you'd rather see this as a small extension of the DataBars durability block instead of a separate QoL element, I'm glad to rework it that way.

No rush at all on review, and thanks for the great addon.

apainter2 and others added 2 commits August 21, 2026 11:43
Add an optional Quality of Life feature that shows a compact, independently
movable "[icon] 87%" style readout of the lowest durability percent across
equipped repairable gear, making it obvious when to repair.

- Event driven only (UPDATE_INVENTORY_DURABILITY, PLAYER_ENTERING_WORLD); no
  OnUpdate, ticker or polling.
- Zero cost unless enabled: default off, builds no frame and registers no
  events until first enabled; getFrame never creates so login-time
  ApplySavedPositions stays free while disabled.
- Reuses house systems: Lite.NewDB (own gearDurability slice on
  EllesmereUIQoLDB, other QoL data untouched), GetFontPath/SlugFlag fonts,
  MakeUnlockElement/Unlock Mode for movement and persistence,
  ShowWidgetTooltip for a per-slot breakdown, DualRow/DependentSetValue
  options widgets.
- Durability maths and white->red warning gradient mirror the DataBars
  durability block; reuses the DataBars forge glyph.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The on-screen readout only refreshed on UPDATE_INVENTORY_DURABILITY and
PLAYER_ENTERING_WORLD, so after gear was damaged the number stayed stale until
a /reload (the hover tooltip samples live, which is why it showed the true
values). UPDATE_INVENTORY_DURABILITY alone is unreliable for a standalone
readout: durability is lost in combat / on death, where the event can fire
before the value settles, and the DataBars block only stays current because a
co-located time-driven block drives its shared 1s ticker.

Re-sample on the concrete durability-change edges instead (still event-driven,
no polling): add PLAYER_EQUIPMENT_CHANGED, PLAYER_REGEN_ENABLED, PLAYER_UNGHOST
and MERCHANT_CLOSED alongside the existing two events.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@apainter2

Copy link
Copy Markdown
Author

Pushed a follow-up fix (fdd93c1): the on-screen readout wasn't refreshing after
gear took damage -- it stayed at the last value until a /reload.

Root cause: it only re-sampled on UPDATE_INVENTORY_DURABILITY and
PLAYER_ENTERING_WORLD. On its own that first event is unreliable for a
standalone readout -- durability is lost in combat / on death, where it can fire
before the value has settled -- and unlike the DataBars durability block there's
no co-located time-driven block driving a shared 1s ticker to paper over it. (The
hover tooltip always looked correct because it samples live on each hover, which
is what made the staleness obvious.)

Fix: re-sample on the concrete durability-change edges instead, still fully
event-driven with no polling or OnUpdate:

  • UPDATE_INVENTORY_DURABILITY - repair / damage edges
  • PLAYER_REGEN_ENABLED - leaving combat (catches durability lost in combat / on death once settled)
  • PLAYER_UNGHOST - durability applied after a corpse resurrect
  • PLAYER_EQUIPMENT_CHANGED - gear swaps changing the lowest item
  • MERCHANT_CLOSED - after a vendor repair
  • PLAYER_ENTERING_WORLD - login / reload / zone

Retested in-game: the number now updates without a manual reload (most visibly
right as you leave combat), and it stays zero-cost while the feature is disabled.

@apainter2

Copy link
Copy Markdown
Author

Hi there,

Is there any news or updates on when QoL feature requests such as the above may or may not be included in the main release? Just wondering if I should convert this into a QoL Addon depending on timescales.

apainter2 and others added 4 commits August 31, 2026 15:57
Add an optional Quality of Life feature that shows a compact, independently
movable "[icon] 87%" style readout of the lowest durability percent across
equipped repairable gear, making it obvious when to repair.

- Event driven only (UPDATE_INVENTORY_DURABILITY, PLAYER_ENTERING_WORLD); no
  OnUpdate, ticker or polling.
- Zero cost unless enabled: default off, builds no frame and registers no
  events until first enabled; getFrame never creates so login-time
  ApplySavedPositions stays free while disabled.
- Reuses house systems: Lite.NewDB (own gearDurability slice on
  EllesmereUIQoLDB, other QoL data untouched), GetFontPath/SlugFlag fonts,
  MakeUnlockElement/Unlock Mode for movement and persistence,
  ShowWidgetTooltip for a per-slot breakdown, DualRow/DependentSetValue
  options widgets.
- Durability maths and white->red warning gradient mirror the DataBars
  durability block; reuses the DataBars forge glyph.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The on-screen readout only refreshed on UPDATE_INVENTORY_DURABILITY and
PLAYER_ENTERING_WORLD, so after gear was damaged the number stayed stale until
a /reload (the hover tooltip samples live, which is why it showed the true
values). UPDATE_INVENTORY_DURABILITY alone is unreliable for a standalone
readout: durability is lost in combat / on death, where the event can fire
before the value settles, and the DataBars block only stays current because a
co-located time-driven block drives its shared 1s ticker.

Re-sample on the concrete durability-change edges instead (still event-driven,
no polling): add PLAYER_EQUIPMENT_CHANGED, PLAYER_REGEN_ENABLED, PLAYER_UNGHOST
and MERCHANT_CLOSED alongside the existing two events.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nter2/EllesmereUI into feature/qol-durability-display
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant