Files
benilla-octo/crates/benilla-app/assets/ui/GroupLootFrame.xml
T
SamandClaude Fable 5 d99ad8bc7d the dressing room opens, and the pet gets its paper doll
- ctrl-click an item to try it on: the dressing room dresses your double, and shift-click posts the item link to chat
- the pet tab lands in the character window: paper doll stats, family and diet, the right-click menu, and dropping food on the pet feeds it
- water-only spells refuse on dry land: aquatic form gates to swimming, client-side like the real one
- the macro icon picker's white squares get their art back, and option rows explain themselves on hover

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 16:02:21 +07:00

513 lines
30 KiB
XML

<Ui>
<!--
benilla's group-loot roll window (decision 0591) — the Need/Greed/Pass dialog: four stacked
`GroupLootFrame`s, transcribed 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 transcribed 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 transcribed 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:SetItemById(itemId, name, quality)` (LootFrame.xml's own
`BenillaLootItem_OnEnter` idiom), not the reference's `SetLootRollItem` (no such tooltip
method here) — `itemId` 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` DOES exist now
(decision 1059) but is the click's, not the hover's: the tooltip wants the id, not the markup.
`toplevel="true"` (ref l.243) IS OMITTED — `SetToplevel` isn't in the v1 object model yet
(`loader/geometry.rs`'s `apply_attrs`: a warn-once "gap", same as `movable`/`resizable`); other
benilla toplevel popups (BuffFrame.xml, CastingBar.xml) carry the attribute anyway and simply
eat the warning, but it has ZERO engine effect either way today, so keeping this file's own
load warning-free (this assignment's own bar) costs nothing real — trivially re-added the day
`SetToplevel` lands.
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`). `BenillaGroupLootFrame_OnShow` falls back to
`BENILLA_FALLBACK_ICON` / an empty name / common (quality 1) — the same fallback shape
`BenillaLootFrame_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, renamed to the house BENILLA_ prefix (the same
-- treatment LootFrame.xml gave LOOTFRAME_NUMBUTTONS -> BENILLA_LOOT_NUMBUTTONS).
BENILLA_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 BenillaGroupLootFrame_OpenNewFrame(rollId, rollTime)
for i = 1, BENILLA_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 BenillaLootFrame_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 BenillaGroupLootFrame_OnShow(frame)
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 BenillaGroupLootFrame_OnEvent(frame)
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). Uses
-- the LootFrame.xml row idiom (SetItemById + the benilla itemId extension) rather than the
-- reference's SetLootRollItem, which doesn't exist here.
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:SetItemById(itemId, name, quality)
end
end
function BenillaGroupLootFrame_Icon_OnLeave()
GameTooltip:Hide()
end
-- The item icon's click (ref $parentIconFrame OnClick, LootFrame.xml l.353-361, transcribed
-- 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).
-->
<Frame name="BenillaGroupLootFrameTemplate" 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 (BenillaGroupLootFrame_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
BenillaLootFrame'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>BenillaGroupLootFrame_OnShow(self)</OnShow>
<OnEvent>BenillaGroupLootFrame_OnEvent(self)</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="BenillaGroupLootFrameTemplate" id="1">
<Anchors>
<Anchor point="BOTTOM"><Offset><AbsDimension x="0" y="60"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame2" inherits="BenillaGroupLootFrameTemplate" id="2">
<Anchors>
<Anchor point="BOTTOM" relativeTo="GroupLootFrame1" relativePoint="TOP">
<Offset><AbsDimension x="0" y="15"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame3" inherits="BenillaGroupLootFrameTemplate" id="3">
<Anchors>
<Anchor point="BOTTOM" relativeTo="GroupLootFrame2" relativePoint="TOP">
<Offset><AbsDimension x="0" y="15"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="GroupLootFrame4" inherits="BenillaGroupLootFrameTemplate" 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
BenillaGroupLootFrame_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>