Files
benilla-octo/crates/benilla-app/assets/ui/GroupLootFrame.xml
T
SamandClaude Fable 5 cf581aa2ac the auction house opens, the Honor tab lands, and a day of fixes
- the auction house end to end: right-clicking an auctioneer opens Browse/Bids/Auctions on the server's reply — search, the category tree from your own DBCs, the reference's 50-a-page pager, multi-key sorting (directions corrected at the bytes), bid/buyout, the sell slot with deposit and duration, cancel with its fee popup; prices sit on the reference's own money-frame kit in lined-up columns, the twenty auction messages split refusals-red / outcomes-to-chat, and a won or sold auction reads as a proper mail receipt — the window's Lua re-worded in our own terms after the overlap ratchet caught the first cut leaning on the reference's text
- the PvP honor system whole: the Honor tab and the inspect page over a real wire model, with current rank and highest-ever rank correctly two different fields
- a day of reported fixes: WASD survives a /logout re-entry, addon settings save on a window close and Cmd+Q (exactly once — a mac close could fire the tail twice), clams open again, random-enchant items name themselves on every surface, the loot window's rows hold their seats with legible counts, idle players stop sinking through building floors, the shooter re-pulls between Auto Shots, portraits loosen ~19% to the client's own aspect-1.0 matrix, and big creatures thump the camera off the CameraShakes table
- character select clicks like 1.12 — captions whiten on hover, buttons fire on release, Humans face straight ahead off the stage bone's real yaw, the facing is per-character, and hunter/warlock pets stand beside you at their family-ramp size with their own emitters (the imp's flames), the Voidwalker's sequence-hidden shackles culled
- the smaller player-facing set: nameplate on/off rows in Options with the CanAttack category gate (emissaries stop plating), the bonus bar slides up with igBonusBarOpen, the camera's framing height glides on a shapeshift, the open letter evicts the centre seat, the far-band fog hull stops printing a pale horizon stripe at low view distance, the guide arrow is gold with per-source rim art, error text fades through its shadow too, and /convertraid converts the party
- README: the auction house and PvP honor move out of "not built yet"

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 19:04:27 +07:00

546 lines
32 KiB
XML

<Ui>
<!--
benilla's group-loot roll window (decision 0591) — the Need/Greed/Pass dialog: four stacked
`GroupLootFrame`s, re-expressed from the real 1.12 client (`LootFrame.xml` l.243-533,
`LootFrame.lua` l.246-296, `UIParent.lua` l.513-515/1577 — all extracted, scratchpad
`WoW/_extracted_framexml/`). Geometry, art paths, and behavior below are QUOTED from those
(line citations inline); the Lua is re-expressed logic turned onto our own `loot_roll` engine
seam (`benilla-ui/src/script/loot_roll.rs`, decision 0591) and its app feed
(`crates/benilla/src/ui_loot_roll.rs`).
FOUR STACKED POPUPS, NOT A UIPANEL. Unlike LootFrame.xml, this window is a real 1.12
`frameStrata="DIALOG"`/`toplevel="true"` popup family — never registered in UiPanels.xml, no
pushable slot. `GroupLootFrame1` sits at the ref's own hardcoded anchor (BOTTOM,
+0,60 — ref l.498-506); frames 2-4 each stack on the PREVIOUS frame's TOP +15 (ref l.507-533).
`GroupLootFrame_OpenNewFrame` (ref LootFrame.lua l.246-258) claims the first currently-hidden
of the four on every `START_LOOT_ROLL`, so up to 4 concurrent rolls each get their own frame,
stacking upward; a 5th simultaneous roll finds none free and is silently dropped — the
reference's own ceiling (`NUM_GROUP_LOOT_FRAMES = 4`, LootFrame.lua l.2), not a benilla gap.
THE FOUR INSTANCES KEEP THE REFERENCE'S BARE NAMES (`GroupLootFrame1`..`4`), deliberately —
the one place the house `Benilla`-prefix convention is NOT applied, for the same reason
`CastingBarFrame` keeps its bare name (CastingBar.xml's POSITION note). `UIParent.xml` (l.70)
already carries the ref's `UIPARENT_MANAGED_FRAME_POSITIONS["GroupLootFrame1"]` row (baseY 60,
+42 for a shown bottom multibar, +42 for the pet/stance bar, +9 for the rep watch bar), and
`UIParent_ManageFramePositions` finds its frames by a literal `getglobal(name)` — no prefix
awareness. UIParent.xml's own comment lists `GroupLootFrame1` among the rows that "no-op
through the ref's own `if ( frame )` guard and self-activate if the frames later land": this
file is that landing, so the bare name is what makes the row engage.
It matters concretely, not theoretically: with benilla's always-on bottom multibars the
managed pass puts frame 1 at y=102 (and y=144 while the stance bar shows). Under a prefixed
name the row would never fire and the roll dialogs would sit permanently at y=60 — squarely on
top of the action bars. Bare names are also what a real 1.12 addon expects to find (0068's
Era-addon target), so this costs nothing elsewhere. The template, the driver, and this file's
own Lua functions stay `Benilla`-prefixed: nothing in the reference keys on those.
NO CENTRAL UIParent EVENT ROUTER. The reference's `START_LOOT_ROLL` dispatch (`UIParent.lua`
l.513-515: `GroupLootFrame_OpenNewFrame(arg1, arg2)`) rides the monolithic `UIParent_OnEvent`
this engine doesn't ship (`UIParent.xml`'s own note: "not ours to ship - no consumer yet").
Rather than claim UIParent's single OnEvent slot (which a later, more general router would then
have to fight over) or special-case ONE of the four peer frames, a small dedicated hidden
driver frame (`BenillaGroupLootFrameDriver`, below — the same shape as `DeathFrame.xml`'s
`BenillaDeathDriver`) owns exactly this one registration, keeping all four
`BenillaGroupLootFrame`s byte-identical instances of the same template (each registers only
`CANCEL_LOOT_ROLL` on itself, ref l.487-489/493-495, verbatim).
THE DRESSING-ROOM / CHAT-LINK CLICK LANDED (decisions 1059/1060 — this note used to read "no
dressing room exists", which was true until the room did). The ref icon button's Ctrl-click
`DressUpItemLink`/Shift-click `ChatFrameEditBox:Insert` (ref l.353-361) are re-expressed in
`BenillaGroupLootFrame_Icon_OnClick` below, over the `GetLootRollItemLink(rollID)` binding the
same arc added to `loot_roll.rs`. Still dropped: the ref's `this.hasItem = 1` OnLoad flag
(ref l.338-340) and its `CursorUpdate()`/`ResetCursor()`/`CursorOnUpdate()` hover-cursor calls
(ref l.344,348,351) — the flag exists only to feed those, and they are the Ctrl-hover
MAGNIFIER, a separate affordance (`ShowInspectCursor`, which the bags and the vendor rows do
wire) that this button has never had. LootFrame.xml's own row template
(`BenillaLootButtonTemplate`) carries the same hover-cursor omission.
THE ITEM TOOLTIP uses `GameTooltip:SetLootRollItem(rollID)` — the reference's own binding
(decision 1547; it replaced a `SetItemById` that could not see the drop's random-suffix
roll and so printed `<Random enchantment>` on every rolled item). The `itemId` guard stays:
it is the benilla-extension 6th return of `GetLootRollItemInfo` (see `loot_roll.rs`),
always populated once a roll is known — unlike name/texture/quality, which may be `nil`
while the item template is still in flight. `GetLootRollItemLink` (decision 1059) is the
click's, not the hover's: the tooltip wants the roll, not the markup.
`toplevel="true"` (ref l.243) IS STILL OMITTED, but for a NEW reason — the old one ("`SetToplevel`
isn't in the v1 object model yet ... trivially re-added the day `SetToplevel` lands") has expired.
`SetToplevel` landed: the loader calls the real method and the raise law — occlusion-gated,
confined to this frame's own stratum — is `script::object::toplevel` (wow-re
`ui/scratch/toplevel-raise.md`).
What adding it back does, measured rather than guessed: `GroupLootFrame1`'s rect
(390.5,60)-(633.5,144) overlaps `ExhaustionTick` — `ActionBar.xml` l.1111, `frameStrata="DIALOG"`
transcribed verbatim from ref-MainMenuBar.xml l.415-442 — in a ~2.5 px band, so showing roll
frame 1 raises its whole subtree to DIALOG level 3 while frame 2 (which overlaps nothing, the
four stack with a 15 px gap) stays at level 0. That is exactly what the reference does, and the
only pixels it moves are the sliver where the roll frame meets the tick. It does, however, break
`group_loot_tests::start_loot_roll_claims_frames_in_order_and_paints_the_roll`, whose
`quad_center("UI-GroupLoot-Dice-Up")` picks the FIRST dice quad in painter order as a stand-in
for "frame 1's Need button" — an unstated assumption that declaration order is draw order among
the four, which the raise legitimately ends. That is a fixture proxy, not the test's assertion
(the BoP-confirm gate it proves is untouched), so re-adding the attribute is one word plus a
two-line fix to that helper — a director's call on the look, not a blocked mechanism.
NAMED FONT OBJECTS ARE SUPPORTED on this branch (the loader's top-level `<Font>` handling,
`loader/mod.rs`'s `do_font`, plus the full `Fonts.xml` transcription, both landed since
LootFrame.xml's own "not implemented yet" caveat was written) — `$parentName`'s
`inherits="GameFontNormalSmall"` below resolves for real; no stale caveat needed here.
IN-FLIGHT ITEMS: `GetLootRollItemInfo`'s `name`/`texture`/`quality` are `nil` while the item
template query hasn't landed yet (`loot_roll.rs`). `GroupLootFrame_OnShow` falls back to
`BENILLA_FALLBACK_ICON` / an empty name / common (quality 1) — the same fallback shape
`LootFrame_Update` uses for an in-flight loot row.
The Era API this drives (`benilla-ui/src/script/loot_roll.rs`, decision 0591):
`GetLootRollItemInfo(rollID)` -> texture,name,count,quality,bindOnPickUp,itemID;
`GetLootRollItemLink(rollID)` -> the item's link (the icon click's two arms, decision 1059);
`GetLootRollTimeLeft(rollID)` -> ms remaining; `RollOnLoot(rollID, rollType)` (0 Pass / 1 Need /
2 Greed). Events: `START_LOOT_ROLL(rollID, rollTime)` claims a frame; `CANCEL_LOOT_ROLL(rollID)`
hides the one that owns it (`crates/benilla/src/ui_loot_roll.rs` fires both).
-->
<Script><![CDATA[
-- LootFrame.lua l.2's NUM_GROUP_LOOT_FRAMES, under the REFERENCE's own name.
--
-- It carried the house `BENILLA_` prefix until an addon died on the bare one:
-- `Bongos_RollBar/bar.lua:85` is `for i=1, NUM_GROUP_LOOT_FRAMES do` and got a nil limit.
-- That is 1222's shadowed-global class again — the fifth instance — and the rule it
-- settled applies to a CONSTANT an addon reads exactly as it does to a frame: our name for
-- a global is as load-bearing as our name for a function. The prefix is right only where
-- the reference has no counterpart; here it has one, with the same value (4) counting the
-- same four frames, which already carry the reference's bare names two paragraphs down.
NUM_GROUP_LOOT_FRAMES = 4
-- The bind-on-pickup confirm (ref StaticPopup.lua l.1371-1382, verbatim bar the TEXT()
-- indirection this house dialect drops). Need/Greed on a BoP roll never reaches the wire
-- directly: the seam diverts it to CONFIRM_LOOT_ROLL, the driver below raises this popup,
-- and only OnAccept's ConfirmLootRoll re-enters past the gate (decision 0594, VERIFIED in
-- the 5875 binary — the gate lives in the C RollOnLoot, not in the Lua). Keyed BARE, like
-- every other StaticPopupDialogs entry: the key is the StaticPopup_Show argument, not a
-- frame name. `id`/`rollType` arrive as the dialog's data/data2.
-- The three strings quoted verbatim from the real 1.12 GlobalStrings.lua (patch-2.MPQ,
-- Interface\FrameXML\GlobalStrings.lua l.2612/2818/465), following UiPanels.xml's
-- DELETE_ITEM idiom rather than reading the globals: GlobalStrings is loaded from the
-- PATCH CHAIN at runtime, so a bare global is nil under test and any format() over it
-- errors — and an error here aborts the whole chunk, taking every function in this file
-- with it.
local LOOT_NO_DROP_TEXT = "Looting this item will bind it to you." -- LOOT_NO_DROP
local OKAY_TEXT = "Okay" -- OKAY
local CANCEL_TEXT = "Cancel" -- CANCEL
StaticPopupDialogs["CONFIRM_LOOT_ROLL"] = {
text = LOOT_NO_DROP_TEXT,
button1 = OKAY_TEXT,
button2 = CANCEL_TEXT,
OnAccept = function(id, rollType)
ConfirmLootRoll(id, rollType)
end,
timeout = 0,
whileDead = 1,
exclusive = 1,
hideOnEscape = 1
}
-- GroupLootFrame_OpenNewFrame (ref LootFrame.lua l.246-258): claim the first currently-hidden
-- of the four frames for a freshly opened roll, seed its rollID/rollTime, and prime the
-- Timer StatusBar's max before showing it (fields set BEFORE Show(), so OnShow below can
-- already read frame.rollID).
function GroupLootFrame_OpenNewFrame(rollId, rollTime)
for i = 1, NUM_GROUP_LOOT_FRAMES do
local frame = getglobal("GroupLootFrame" .. i)
if frame and not frame:IsVisible() then
frame.rollID = rollId
frame.rollTime = rollTime
getglobal(frame:GetName() .. "Timer"):SetMinMaxValues(0, rollTime)
frame:Show()
return
end
end
-- All 4 already claimed: the reference has no overflow handling either (a 5th
-- simultaneous roll simply finds no free frame) — its own ceiling, not a benilla gap.
end
-- GroupLootFrame_OnShow's body (ref l.260-277): resolve the roll's display fields and paint
-- the icon/name/backdrop. name/texture/quality may be nil while the item template query is
-- still in flight (loot_roll.rs) — fall back to the fallback icon / blank name / common (1)
-- quality rather than erroring, the same fallback shape LootFrame_Update uses for an
-- in-flight loot row (LootFrame.xml).
--
-- SPLIT OUT OF OnShow, unlike the reference, because it must be re-runnable: the ref's
-- `GetLootRollItemInfo` reads live C state that is already populated when START_LOOT_ROLL
-- fires, whereas ours reads a *pushed snapshot* that by construction does not yet contain a
-- roll opening this frame (loot_roll.rs `feed_loot_rolls`, and the late item template on top
-- of that). `UPDATE_LOOT_ROLL` re-enters here; the paint is idempotent.
function BenillaGroupLootFrame_Paint(frame)
local texture, name, count, quality, bindOnPickUp, itemId = GetLootRollItemInfo(frame.rollID)
frame.itemId = itemId
if bindOnPickUp then
frame:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
})
getglobal(frame:GetName() .. "Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Gold-Corner")
getglobal(frame:GetName() .. "Decoration"):Show()
else
frame:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
})
getglobal(frame:GetName() .. "Corner"):SetTexture("Interface\\DialogFrame\\UI-DialogBox-Corner")
getglobal(frame:GetName() .. "Decoration"):Hide()
end
getglobal(frame:GetName() .. "IconFrameIcon"):SetTexture(texture or BENILLA_FALLBACK_ICON)
local nameText = getglobal(frame:GetName() .. "Name")
nameText:SetText(name or "")
local color = ITEM_QUALITY_COLORS[quality] or ITEM_QUALITY_COLORS[1]
nameText:SetVertexColor(color.r, color.g, color.b)
end
function GroupLootFrame_OnShow()
local frame = this
BenillaGroupLootFrame_Paint(frame)
end
-- Per-instance CANCEL_LOOT_ROLL (ref l.487-489 OnLoad, l.279-285/493-495 OnEvent): each of the
-- four frames registers and checks its OWN rollID, hiding only itself. UPDATE_LOOT_ROLL is
-- the benilla extension alongside it (see BenillaGroupLootFrame_Paint) and takes the same
-- per-instance shape: arg1 is the rollID whose display identity changed.
function BenillaGroupLootFrame_OnLoad(frame)
frame:RegisterEvent("CANCEL_LOOT_ROLL")
frame:RegisterEvent("UPDATE_LOOT_ROLL")
end
function GroupLootFrame_OnEvent()
local frame = this
if arg1 ~= frame.rollID then
return
end
if event == "CANCEL_LOOT_ROLL" then
frame:Hide()
elseif event == "UPDATE_LOOT_ROLL" then
BenillaGroupLootFrame_Paint(frame)
end
end
-- GroupLootFrame_OnUpdate (ref l.287-296): poll the remaining time each tick, clamped to the
-- bar's own [min,max] exactly as the reference does (an out-of-range read — e.g. an unknown
-- rollID's 0 — clamps to min rather than erroring). Bound to the Timer bar itself so
-- `bar:IsVisible()` follows its (hidden) parent frame, matching the ref's `this:IsVisible()`.
function BenillaGroupLootFrame_Timer_OnUpdate(bar)
if bar:IsVisible() then
local left = GetLootRollTimeLeft(bar:GetParent().rollID)
local min, max = bar:GetMinMaxValues()
if left < min or left > max then
left = min
end
bar:SetValue(left)
end
end
-- Pass/Need/Greed (ref $parentPassButton/$parentRollButton/$parentGreedButton OnClick,
-- l.374/398/425): one shared handler, rollType 0 Pass / 1 Need / 2 Greed.
function BenillaGroupLootFrame_Roll_OnClick(button, rollType)
RollOnLoot(button:GetParent().rollID, rollType)
end
function BenillaGroupLootFrame_Roll_OnEnter(button, text)
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
GameTooltip:SetText(text)
end
function BenillaGroupLootFrame_Roll_OnLeave()
GameTooltip:Hide()
end
-- The item icon's hover tooltip (ref $parentIconFrame OnEnter/OnLeave, l.341-349, minus the
-- CursorUpdate/ResetCursor calls this engine has no counterpart for — see the header).
-- SetLootRollItem, the reference's own binding: the ROLL is the source, so the hover sees
-- the drop's random-suffix roll (through SetItemById it showed `<Random enchantment>` —
-- decision 1547).
function BenillaGroupLootFrame_Icon_OnEnter(button)
local frame = button:GetParent()
GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
local _, name, _, quality, _, itemId = GetLootRollItemInfo(frame.rollID)
if itemId then
GameTooltip:SetLootRollItem(frame.rollID)
end
end
function BenillaGroupLootFrame_Icon_OnLeave()
GameTooltip:Hide()
end
-- The item icon's click (ref $parentIconFrame OnClick, LootFrame.xml l.353-361, re-expressed
-- whole): CTRL previews the rolled item in the dressing room (decision 1060), SHIFT posts
-- its link into an open chat edit box (decision 1059) — "link me that" being most of what a
-- roll popup gets asked. Both read `GetLootRollItemLink(rollID)`, the binding this arc added
-- (loot_roll.rs); it answers nil while the item template is still in flight, and both arms
-- drop that nil — the ctrl one inside DressUpItemLink (DressUpFrame.lua l.10-16), the shift
-- one inside BenillaChatEdit_InsertLink.
--
-- Nothing else happens on this button, exactly as in the reference: the vote lives on the
-- Pass/Need/Greed buttons and the icon is a preview/link affordance only. The ref's
-- `this.hasItem = 1` OnLoad flag (l.338-340) stays dropped — it exists solely for the
-- CursorUpdate/CursorOnUpdate ctrl-hover magnifier (l.344/351), which this button still does
-- not wire (see the header). No RegisterForClicks either, also as in the reference: a Button
-- is registered for LeftButtonUp by default (widget/kinds/mod.rs), which is the whole set
-- this handler wants.
function BenillaGroupLootFrame_Icon_OnClick(button)
local rollId = button:GetParent().rollID
if IsControlKeyDown() then
DressUpItemLink(GetLootRollItemLink(rollId)) -- ref l.354-355
elseif IsShiftKeyDown() then
-- ref l.356-359, through the shared helper (UIParent.xml): it carries the ref's own
-- edit-box-visible guard AND our nil-link one, which this popup needs routinely —
-- the frame is up the instant START_LOOT_ROLL fires, well before the item template
-- answers, and until it does there is no link to post.
BenillaChatEdit_InsertLink(GetLootRollItemLink(rollId))
end
end
]]></Script>
<!--
The template (ref GroupLootFrameTemplate, l.243-497): 243x84, DIALOG strata, toplevel, hidden
by default. Geometry/art below is QUOTED verbatim, INCLUDING dropping the stray `d` character
inside ref l.292's `<Anchor point="TOPLEFT">d` (a typo in Blizzard's own shipped file — not
transcribed).
-->
<!--
THE REFERENCE'S OWN NAME, deliberately un-prefixed (decision 1254).
This was `BenillaGroupLootFrameTemplate`. The `Benilla` prefix marks things WE invented, so
that nothing we made up can collide with a name an addon expects; this template is the
opposite of that — a line-by-line transcription of 1.12's `GroupLootFrameTemplate`, and
addons inherit it BY THAT NAME. Bongos_RollBar builds its four roll frames with
`CreateFrame("Frame", "BRollBarFrame"..i, bar, "GroupLootFrameTemplate")`, which resolves on
the real client and missed here for no reason but our prefix.
-->
<Frame name="GroupLootFrameTemplate" frameStrata="DIALOG" hidden="true" virtual="true">
<Size><AbsDimension x="243" y="84"/></Size>
<Layers>
<Layer level="ARTWORK">
<!-- The item slot plate (ref l.249-260). -->
<Texture name="$parentSlotTexture" file="Interface\Buttons\UI-EmptySlot">
<Size><AbsDimension x="64" y="64"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="3" y="-3"/></Offset></Anchor>
</Anchors>
</Texture>
<!-- The parchment name plate (ref l.261-272). -->
<Texture name="$parentNameFrame" file="Interface\MerchantFrame\UI-Merchant-LabelSlots">
<Size><AbsDimension x="128" y="64"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSlotTexture" relativePoint="RIGHT">
<Offset><AbsDimension x="-9" y="-10"/></Offset>
</Anchor>
</Anchors>
</Texture>
<!-- The item name (ref l.273-284): GameFontNormalSmall, LEFT. -->
<FontString name="$parentName" inherits="GameFontNormalSmall" text="Item Name" justifyH="LEFT">
<Size><AbsDimension x="90" y="30"/></Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parentSlotTexture" relativePoint="RIGHT">
<Offset><AbsDimension x="-5" y="5"/></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level="OVERLAY">
<!-- The gold BoP dragon flourish (ref l.287-298): hidden by default, shown only for a
bind-on-pickup roll (GroupLootFrame_OnShow). -->
<Texture name="$parentDecoration" file="Interface\DialogFrame\UI-DialogBox-Gold-Dragon" hidden="true">
<Size><AbsDimension x="120" y="120"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="-30" y="15"/></Offset></Anchor>
</Anchors>
</Texture>
<!-- The dialog-box corner (ref l.299-310): swapped plain/gold in OnShow. -->
<Texture name="$parentCorner" file="Interface\DialogFrame\UI-DialogBox-Corner">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-6" y="-7"/></Offset></Anchor>
</Anchors>
</Texture>
</Layer>
</Layers>
<Frames>
<!-- The item icon (ref $parentIconFrame, l.314-363): hover tooltip + the ref's own
Ctrl/Shift dressing-room/chat-link click (l.353-361, landed — decision 1059/1060);
only the hasItem OnLoad flag stays dropped (header). -->
<Button name="$parentIconFrame" enableMouse="true">
<Size><AbsDimension x="34" y="34"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentSlotTexture">
<Offset><AbsDimension x="15" y="-15"/></Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="OVERLAY">
<Texture name="$parentIcon">
<Size><AbsDimension x="34" y="34"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnEnter>BenillaGroupLootFrame_Icon_OnEnter(self)</OnEnter>
<OnLeave>BenillaGroupLootFrame_Icon_OnLeave()</OnLeave>
<OnClick>BenillaGroupLootFrame_Icon_OnClick(self)</OnClick>
</Scripts>
</Button>
<!-- Pass (ref $parentPassButton, l.364-384): the ref inherits UIPanelCloseButton, which
this engine ships no template for — reconstructed on the same minimize-button art
LootFrame's own close button uses (LootFrame.xml's identical "no
UIPanelCloseButton template ships" precedent), at the ref's own 32x32/position. -->
<Button name="$parentPassButton">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors>
<Anchor point="TOPRIGHT" relativeTo="$parentCorner" relativePoint="TOPRIGHT">
<Offset><AbsDimension x="5" y="5"/></Offset>
</Anchor>
</Anchors>
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
<Scripts>
<OnClick>BenillaGroupLootFrame_Roll_OnClick(self, 0)</OnClick>
<OnEnter>BenillaGroupLootFrame_Roll_OnEnter(self, PASS)</OnEnter>
<OnLeave>BenillaGroupLootFrame_Roll_OnLeave()</OnLeave>
</Scripts>
</Button>
<!-- Need (the dice, ref $parentRollButton, l.385-411). -->
<Button name="$parentRollButton">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="-37" y="-14"/></Offset></Anchor>
</Anchors>
<NormalTexture file="Interface\Buttons\UI-GroupLoot-Dice-Up"/>
<HighlightTexture file="Interface\Buttons\UI-GroupLoot-Dice-Highlight" alphaMode="ADD"/>
<PushedTexture file="Interface\Buttons\UI-GroupLoot-Dice-Down"/>
<Scripts>
<OnClick>BenillaGroupLootFrame_Roll_OnClick(self, 1)</OnClick>
<OnEnter>BenillaGroupLootFrame_Roll_OnEnter(self, NEED)</OnEnter>
<OnLeave>BenillaGroupLootFrame_Roll_OnLeave()</OnLeave>
</Scripts>
</Button>
<!-- Greed (the coin, ref $parentGreedButton, l.412-438). -->
<Button name="$parentGreedButton">
<Size><AbsDimension x="32" y="32"/></Size>
<Anchors>
<Anchor point="TOP" relativeTo="$parentRollButton" relativePoint="BOTTOM">
<Offset><AbsDimension x="-2" y="2"/></Offset>
</Anchor>
</Anchors>
<NormalTexture file="Interface\Buttons\UI-GroupLoot-Coin-Up"/>
<HighlightTexture file="Interface\Buttons\UI-GroupLoot-Coin-Highlight" alphaMode="ADD"/>
<PushedTexture file="Interface\Buttons\UI-GroupLoot-Coin-Down"/>
<Scripts>
<OnClick>BenillaGroupLootFrame_Roll_OnClick(self, 2)</OnClick>
<OnEnter>BenillaGroupLootFrame_Roll_OnEnter(self, GREED)</OnEnter>
<OnLeave>BenillaGroupLootFrame_Roll_OnLeave()</OnLeave>
</Scripts>
</Button>
<!-- The 1-minute countdown bar (ref $parentTimer, l.439-473): 152x10, [0,60000] ms,
yellow UI-Character-Skills-Bar fill + its border overlay. -->
<StatusBar name="$parentTimer" drawLayer="BACKGROUND" minValue="0" maxValue="60000" defaultValue="0">
<Size><AbsDimension x="152" y="10"/></Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parentSlotTexture" relativePoint="BOTTOMLEFT">
<Offset><AbsDimension x="13" y="10"/></Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="OVERLAY">
<Texture file="Interface\PaperDollInfoFrame\UI-Character-Skills-BarBorder">
<Size><AbsDimension x="156" y="20"/></Size>
<Anchors>
<Anchor point="TOP"><Offset><AbsDimension x="0" y="5"/></Offset></Anchor>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnUpdate>BenillaGroupLootFrame_Timer_OnUpdate(self)</OnUpdate>
</Scripts>
<BarTexture name="$parentBar" file="Interface\PaperDollInfoFrame\UI-Character-Skills-Bar"/>
<BarColor r="1.0" g="1.0" b="0"/>
</StatusBar>
</Frames>
<!-- The plain dialog plate (ref l.475-485); swapped to the gold variant in OnShow for a BoP
roll. -->
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<BackgroundInsets><AbsInset left="11" right="12" top="12" bottom="11"/></BackgroundInsets>
<TileSize><AbsValue val="32"/></TileSize>
<EdgeSize><AbsValue val="32"/></EdgeSize>
</Backdrop>
<Scripts>
<OnLoad>BenillaGroupLootFrame_OnLoad(self)</OnLoad>
<OnShow>GroupLootFrame_OnShow()</OnShow>
<OnEvent>GroupLootFrame_OnEvent()</OnEvent>
</Scripts>
</Frame>
<!-- The four instances (ref l.498-533): frame 1 at the ref's own hardcoded BOTTOM+60; each next
frame stacks on the previous one's TOP+15. -->
<Frame name="GroupLootFrame1" inherits="GroupLootFrameTemplate" id="1">
<Anchors>
<Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="60"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame2" inherits="GroupLootFrameTemplate" id="2">
<Anchors>
<Anchor point="BOTTOM" relativeTo="GroupLootFrame1" relativePoint="TOP">
<Offset><AbsDimension x="0" y="15"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame3" inherits="GroupLootFrameTemplate" id="3">
<Anchors>
<Anchor point="BOTTOM" relativeTo="GroupLootFrame2" relativePoint="TOP">
<Offset><AbsDimension x="0" y="15"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame4" inherits="GroupLootFrameTemplate" id="4">
<Anchors>
<Anchor point="BOTTOM" relativeTo="GroupLootFrame3" relativePoint="TOP">
<Offset><AbsDimension x="0" y="15"/></Offset>
</Anchor>
</Anchors>
</Frame>
<!-- The START_LOOT_ROLL driver (header, "NO CENTRAL UIParent EVENT ROUTER"): the same shape as
DeathFrame.xml's BenillaDeathDriver — a tiny hidden frame whose sole job is owning the
registrations none of the four peer GroupLootFrames should have to special-case. -->
<Frame name="BenillaGroupLootFrameDriver" hidden="true">
<Size><AbsDimension x="1" y="1"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<Scripts>
<OnLoad>
self:RegisterEvent("START_LOOT_ROLL")
self:RegisterEvent("CONFIRM_LOOT_ROLL")
</OnLoad>
<OnEvent>
if event == "START_LOOT_ROLL" then
GroupLootFrame_OpenNewFrame(arg1, arg2)
elseif event == "CONFIRM_LOOT_ROLL" then
-- Ref UIParent.lua:517-524 verbatim, minus the central router: a Need/Greed on a
-- BIND-ON-PICKUP roll sends nothing and asks first (decision 0594). arg1 = rollID,
-- arg2 = rollType; both ride the dialog so OnAccept can re-enter ConfirmLootRoll.
local dialog = StaticPopup_Show("CONFIRM_LOOT_ROLL")
if dialog then
dialog.data = arg1
dialog.data2 = arg2
end
end
</OnEvent>
</Scripts>
</Frame>
</Ui>