Skip to content

Refactor(Player Aura Bars): render weapon enchants inside the AuraContainer - #2086

Merged
EllesmereGaming merged 5 commits into
EllesmereGaming:mainfrom
JuJuFX-dev:fix/pab-centered-enchant-anchor
Sep 18, 2026
Merged

EllesmereGaming merged 5 commits into
EllesmereGaming:mainfrom
JuJuFX-dev:fix/pab-centered-enchant-anchor

Conversation

@JuJuFX-dev

@JuJuFX-dev JuJuFX-dev commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Weapon oils and imbues on the Player Aura Bars buffs bar and on the player unit frame's buffs are now rendered by the game's own item-enchantment display source instead of by hand-built icons inside the addon. For the player that means the cells sit in the run with exactly the same spacing as the buffs next to them (the seam between the last oil and the first buff used to be twice as wide), they keep following the run while you are in combat instead of freezing in place until it ends, they work in the Centered Horizontal and Centered Vertical grow directions, and they pick up border, font, icon shape, duration text and profile changes with the rest of the bar.

The centered grow directions previously threw "Anchoring disallowed as dependent object would inherit forbidden aspects: UntrustedLayoutScriptExecution" whenever an oil was active: those modes need the cells to hug the moving edge of the aura run, and 12.1 refuses to anchor anything to an aura container. Nothing is anchored to a container any more, so that error class is gone.

Two behaviour changes are worth calling out. With the Weapon Enchants row enabled the cells count against the bar's own Max Icons, so a bar set to 32 shows 32 icons in total no matter how many oils are up, and a weapon slot without a temporary enchant reserves nothing; the bar's frame keeps exactly the same size whether the row is on or off. On the player unit frame the cells now follow the buff display itself rather than its Show All Buffs / Has Duration content mode, and they can be right-click cancelled like the buffs beside them.

One more spacing fix rides along: when a buffs bar shows both its catch-all group and its spell selection on the same line, the gap between the two blocks was also twice the icon spacing, because the engine already trails every icon with that spacing and the addon added the same amount again on top. Both are now one gap.

Internally EUI_UnitFrames_WeaponEnchants.lua is deleted: the slot-fixed SecureActionButton trio, the second style pipeline, the duration ticker, the weapon-enchant event registration and the container cell shift all move to the engine. AuraKit gains AddItemEnchantmentsToContainer plus the layout and sort setters for that source.

How was it tested?

Tested in game on the live client.

The spacing, budget and box arithmetic was additionally verified outside the client by replaying the game's own AnchorUtil.ApplyFlowLayout against the layout tables this code builds: every gap stays uniform including the group seam, no grid configuration renders outside the bar's frame, the rendered icon count equals Max Icons for every number of active enchants, and toggling the Weapon Enchants row leaves the geometry untouched (17280 grid configurations, 2160 toggle pairs, 90 spacing cases).

Screenshots

grafik

Checklist

  • New settings default OFF (no behavior change without opt-in) - N/A, no new settings; the existing Weapon Enchants row keeps its default-off state, and the behaviour changes above are listed for review
  • Zero cost while disabled: no events registered, no polling, no hooks doing work, no frames built - with the row off nothing is declared at all, and the removed module's event registrations and shared 0.5s ticker are gone with it
  • Cheap while enabled: event-driven (no polling, no timer-based logic, no per-frame allocations) - the engine owns refresh and layout; the addon declares the source once per container and re-applies the icon budget on WEAPON_ENCHANT_CHANGED / WEAPON_SLOT_CHANGED, guarded on the enchant count so a charge tick does nothing
  • No writes onto Blizzard-owned frames (weak-table pattern used); HookScript/hooksecurefunc only, never SetScript on Blizzard frames - decoration goes through the engine's own initializeFrame callback and AuraKit's weak-keyed button table
  • Tested in-game on live; no version gates or pre-Midnight APIs added

Weapon oils and imbues never reach an aura container through aura parsing
(they carry an enchantID, not a spell ID), so the display was hand-built: a
SecureActionButton trio per host, a duplicate style pipeline, its own tooltip,
duration ticker and event registration, a cell shift on the container and an
alpha-only combat model. 12.1 renders them natively instead
(AuraContainer:AddItemEnchantment), and it also made the old design illegal:
the centered grow directions had the enchant host ride the container's rect,
which now errors with "Anchoring disallowed as dependent object would inherit
forbidden aspects: UntrustedLayoutScriptExecution" for any dependent, secure
or not.

AuraKit gains AddItemEnchantmentsToContainer, SetContainerItemEnchantmentLayout,
SetContainerItemEnchantmentSort and HasItemEnchantments. The declared slots are
tracked in containerData (HasItemEnchantment is engine-private and a second
declaration for the same slot asserts), and ReleaseContainer untracks the
returned frames from the restyle registry.

Player Aura Bars declares the enchants on the Buffs container as a leading
layout group, so the engine flows them ahead of the aura run in every grow
direction, keeps doing so in combat, and styles them from the bar's live style;
icon, item tooltip and the protected CancelTemporaryEnchantment click are
engine-side (the last via style.cancelButtons). The row has no addon-facing
unregister, so showWeaponEnchants is folded into the buffs content signature
and a flip rides the existing release and rebuild lane. Unit Frames declare the
same group on the player buff container; their cells now follow that
container's visibility instead of the old All Buffs / Has Duration gate, since
UF has no container swap lane. groupSpacing is the gap before the group that
continues the line, so the distance to the first aura sits on the aura groups'
layout, set in UF only where enchants are actually declared.

The options preview models one uniform flow now (enchants as leading members
of the same line) instead of the retired wholesale container shift, and
EUI_UnitFrames_WeaponEnchants.lua is gone with its toc entry.
The gap between the weapon-enchant cells and the first buff was twice the gap
between two buffs. Blizzard's flow layout trails EVERY element with
elementSpacing, the last one of a group included, and groupSpacing is added on
top of that, so a group boundary carried both. Both consumers hold groupSpacing
at 0 now, which also halves the seam between the catch-all and the spells group.

The cells share the line with the auras, so they come out of the grid the three
sliders describe instead of being added on top: the aura cap drops by the
declared enchant slots while the row is on, and the bar's box is identical with
the row on or off. Reserving an extra row instead made the bar jump when the row
was toggled. A grid smaller than three cells declares only as many slots as it
can hold (main hand first, new maxSlots option), and that count rides the buffs
content signature so a shrunk grid rebuilds the container. Enchants-only bars
keep their full cap, their grid was auto-sized for exactly these cells.

Checked against Blizzard's own AnchorUtil.ApplyFlowLayout rather than by eye:
17280 grid configurations render inside their box, 2160 toggle pairs leave the
geometry untouched, 90 spacing cases keep every gap uniform including the seam.

Also from an independent review of the migration: ApplyEnchants no longer runs
on the container ApplyLiveConfig is about to retire (three engine frames leaked
per toggle), CreateBars retires the previous containers before replacing them (a
second build left orphans that rendered every icon twice), PAB_ProfileResync
reconciles the buffs content signature so a profile swap picks up a changed
spell set or enchant row, AddItemEnchantment is pcall'd and the sort setter
requires both halves because the engine validates before it defaults, the
options preview draws the cells in the live order, and the Filters tooltip no
longer describes the retired grid shift.
Max Icons is the whole bar's budget, so only the cells actually showing take a
slot from it: a bar set to 32 renders 32 icons whether no oil, one or two are
up, and a slot without a temporary enchant reserves nothing. The previous pass
subtracted all three engine slots statically, which cost three buffs even with
nothing enchanted (32 icons over 3 rows of 11 showed 29, and 32 over a single
row of 6 showed 4 with one oil up).

The cap follows WEAPON_ENCHANT_CHANGED and WEAPON_SLOT_CHANGED, registered only
while the row is on and guarded on the count, so a charge tick re-applies
nothing. Reading the three inventory slots is equipment state, not aura data, so
it stays legal in restricted combat. The declaration cap is unchanged: a grid
under three cells still declares only as many slots as it can hold, so the cells
can never spill out of the bar, and the box geometry stays identical with the
row on or off.

The options preview follows the same rule, drawing its enchant cells out of the
same budget, and the Filters tooltip is cut back to what the row does now that
nothing is shifted.
…imit

Rebased onto upstream/main, whose new chunk-level locals pushed the file past Lua 5.1's 200-locals-per-chunk limit together with the weapon-enchant helpers. The count and event helpers now live in a do...end block; only BuffAuraMax and SyncEnchantEvents stay chunk-level.
@JuJuFX-dev
JuJuFX-dev force-pushed the fix/pab-centered-enchant-anchor branch from b548175 to 46de40b Compare September 18, 2026 05:26
upstream/main carries 800 keys in the body of EllesmereUILocales/_keys.txt but still says 791 in the header, left behind when two branches that both added keys were merged. The Locale keys up to date check regenerates the file and fails on that single line for every PR that touches Lua. Only the count changes; the key list is untouched.
@EllesmereGaming
EllesmereGaming merged commit a984858 into EllesmereGaming:main Sep 18, 2026
1 check passed
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.

2 participants