Refactor(Player Aura Bars): render weapon enchants inside the AuraContainer - #2086
Merged
EllesmereGaming merged 5 commits intoSep 18, 2026
Merged
EllesmereGaming merged 5 commits into
EllesmereGaming merged 5 commits into
Conversation
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
force-pushed
the
fix/pab-centered-enchant-anchor
branch
from
September 18, 2026 05:26
b548175 to
46de40b
Compare
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.luais 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 gainsAddItemEnchantmentsToContainerplus 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.ApplyFlowLayoutagainst 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
Checklist
HookScript/hooksecurefunconly, neverSetScripton Blizzard frames - decoration goes through the engine's owninitializeFramecallback and AuraKit's weak-keyed button table