- every build off macOS has been silent since the 09-02 snapshot (B356): the non-macOS device layer was a stub that opened nothing, and nothing had ever compiled the client for another target; that layer is now the same output stream over cpal — one seam, not two stacks: the ring, the render thread and the rebuild-on-device-change loop are one code on every platform, only the device file differs; the audio thread never allocates, a lost or changed default device is noticed at kira's own cadence, and realtime is `SCHED_FIFO` on unix and MMCSS "Pro Audio" on Windows, either refusable, the ring turning a refusal into a degradation; and the two instruments this bug says were missing exist — a Linux and Windows cross-compile under `clippy -D warnings`, and a live output test that opens the real device and asserts the ring never ran dry, because compiling is not sounding (1920) - an emote that requires standing still now refuses on the move: `CheckEmoteEligible`'s `0x4000` arm writes an out-param that `DoEmote` turns into a red "You can't do that while moving!" and aborts; 20 emotes of 78 can raise the line, read off the shipped `Emotes.dbc`; SWIMMING is not in the mask, so a swimmer holding still emotes fine, and `IsSelfControlled` is TRUE for an ordinary player, so a feared or confused player emotes away happily (1904); and the cast path gains its equipped-item rung — the button greyed and pressing it still sent: the reference short-circuits to "fits" on four gates, not one, the miss being a zero `EquippedItemSubClassMask`, which means no item required at all, and the rung sits above the crowd-control validator, so a player both stunned and missing the weapon is told about the weapon; that ladder has six arms, not three — CHARMED, FLEEING and CONFUSED join (1925) - the quest reward's money is the reference's own widget: the tail of the shared `QuestFrameItems_Update` drives `questState.."MoneyFrame"` through `MoneyFrame_Update`, and the two hand-built coin trios become one `MoneyFrameTemplate` instance each at the reference's anchors, which our coins already used; the progress panel stays on coins, being the required-money flow, not the reward one (1928); and the flight master's `!` joins the questgiver sweep, because the green `!` and the gold `!` are the SAME slot, `unit+0xb2c`, torn down once before both queries re-issue; the mouseover re-ask is refuted — the only taxi-status sender has one live caller — and the two queries are not symmetric: the questgiver's goes out on every sweep, the taxi one only when the unit's key moves or on a full sweep, as the wire shows at Dungar Longdrink: 68 questgiver status queries against 1 taxi-node one (1918) - `GetSpellTabInfo` out of range answers `nil, nil, 0, 0` — the reference returns four values on every path that returns (`0x4b3ce0`), and ours answered a single nil copied from another binding's shape; it matters because stock `SpellBookFrame_OnLoad` calls it unconditionally and then does `id > (offset + numSpells)`, which a nil raises on and (0+0) makes true, hiding every button on the page — the behaviour to match; the argument raises the reference's usage string when absent, and the index truncates toward zero THEN decrements (1931); the perf probe gains a `WOW_PROBE_UNCAP=vsync` arm, because the uncapped present mode is a request, not a schedule — measured, it taxes the number it was meant to pin (11.80 `cpu_ms` uncapped against 14.65 under it), so the default stays uncapped; and the last three test temp paths are keyed on the pid, after concurrent runs raced on one fixed shared file Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1360 lines
97 KiB
XML
1360 lines
97 KiB
XML
<Ui>
|
||
<!--
|
||
benilla's questgiver window (decision 0088; this geometry pass is the arc 0112 named as "the
|
||
giver windows still carry invented offsets... proposed as the immediate next arc" — see that
|
||
decision for the resolver-fixpoint/ScrollFrame engine work this pass builds on; its own decision
|
||
record, if any, is claimed at land time per `method.md`). Four REAL child panels now (greeting /
|
||
detail / progress / reward), mirroring the
|
||
real 1.12 `QuestFrame.xml`/`QuestFrameTemplates.xml` (scratchpad `ref-framexml/QuestFrame.*`;
|
||
`file:line` cites below are into those extracted files) structurally, not just its numbers:
|
||
|
||
QUEST_GREETING → QuestFrameGreetingPanel (SMSG_QUESTGIVER_QUEST_LIST): greeting text +
|
||
active/available quest title buttons (SelectActiveQuest/SelectAvailableQuest).
|
||
QUEST_DETAIL → QuestFrameDetailPanel (SMSG_QUESTGIVER_QUEST_DETAILS): title/description/
|
||
objectives + rewards on offer, Accept/Decline.
|
||
QUEST_PROGRESS → QuestFrameProgressPanel (SMSG_QUESTGIVER_REQUEST_ITEMS): title, request
|
||
text, required items/money, Continue (enabled iff completable)/Goodbye.
|
||
QUEST_COMPLETE → QuestFrameRewardPanel (SMSG_QUESTGIVER_OFFER_REWARD): title, reward text,
|
||
choose reward + fixed rewards + money, Complete Quest/Cancel.
|
||
QUEST_ITEM_UPDATE → in-place refresh of the visible panel's rows (async name landing).
|
||
QUEST_FINISHED → hide the window (turn-in result / interaction end).
|
||
|
||
WHY FOUR CHILD FRAMES NOW (reversing 0088 §2's "FLAT layout" finding): that finding — "a
|
||
child frame shown at runtime does not draw its own <Layers>/button-text regions" — was an
|
||
engine BUG (a bounded anchor-resolver budget silently dropping deep chains), not a real engine
|
||
constraint; the resolver now runs to a true change-driven fixpoint and a dedicated test
|
||
(`child_frame_layers_regions_render_after_the_fixpoint`, `benilla-ui`) pins that a shown child
|
||
frame's own Layers/buttons render correctly. So the ref's actual frame tree — one always-shown
|
||
`QuestFrame` chrome (portrait/name/close) hosting four independent child panels, each
|
||
shown/hidden by its own event, each carrying its own art + a real ScrollFrame — is expressible
|
||
again, and is what ships here. The reward/choice item grids still use a RUNTIME `SetPoint` chain
|
||
(not a static XML relativeTo chain) for the SAME reason the quest log's rewards do
|
||
(`QuestLogFrame.xml`'s `BenillaQuestLogRewards_Update`) — that IS the ref's own mechanism
|
||
(`QuestFrame.lua`'s shared `QuestFrameItems_Update`), now safe to port line-for-line because a
|
||
Button anchored to a chained region resolves correctly (the second half of 0112's fixpoint
|
||
finding — pinned by `long_region_chain_resolves_and_a_frame_binds_to_its_tail`).
|
||
|
||
Each panel's text pane sits on a REAL ScrollFrame (`benilla-ui` `script/scrollframe.rs`,
|
||
decision 0112's last structural gap): `SetScrollChild`/`SetVerticalScroll` pin + pan the child,
|
||
`GetVerticalScrollRange` is live off the resolved rects, and every quad in the child's subtree
|
||
clips to the ScrollFrame's rect (real "content clipped to the panel", not an overflow-and-hope).
|
||
Wheel-driven only (no scrollbar thumb widget exists in this engine yet — `Slider` is a named
|
||
FrameKind with no behavior behind it, same gap the quest log's own faux-scroll stood in for);
|
||
`<ScrollFrame>` takes the wheel by construction, same as `ScrollingMessageFrame`
|
||
(`widget/mod.rs`). The scroll child's `<Size>` is a GENEROUS FIXED budget (700px), not the
|
||
ref's own measured-to-content height (`QuestFrame_SetAsLastShown`'s real mechanism — moving a
|
||
spacer frame to the last-shown element and sizing the child off it): this engine has no
|
||
`GetBottom`/`GetTop` to read a chain's true extent back out, so a tight fit remains a documented
|
||
follow-up (the same class of gap 0088/0112 already named as "a measured layout reflow... is a
|
||
v1 dressing follow-up"); the budget only means the scroll RANGE is generous, never that content
|
||
is cut off — everything still resolves, scrolls, and clips correctly at whatever size it is.
|
||
|
||
Item row visuals (`QuestItemTemplate`) are UNCHANGED from before this pass — they were
|
||
already a capture-verified port of the quest log's own item row shape (ring-slot art), not the
|
||
ref's plainer inline `QuestItemTemplate` (`QuestFrameTemplates.xml` l.85-166) — kept for visual
|
||
consistency across the quest windows, not a fidelity regression introduced here.
|
||
|
||
Docks the left UIPanel slot (`pushable=0`, `UiPanels.xml`) exactly as before — untouched by this
|
||
pass. The window-sound convention (decision 0090/0095/0096) and the Lua seam
|
||
(`benilla-ui` `script/quest.rs`'s `GetTitleText`/`AcceptQuest`/`GetQuestReward`/… — untouched by
|
||
this pass, see that module's doc) live on the OUTER `QuestFrame` only, matching the ref's
|
||
own `QuestFrame_OnShow`/`OnHide` (l.284-295) — a panel switch never re-plays a kit, only the
|
||
window opening/closing does.
|
||
|
||
Deviations (each cited again at its own widget below):
|
||
- `QUEST_FADING_DISABLE` (the ref's "Instant Quest Text" option) is no longer a deviation:
|
||
1804 put it back on the reference's "0", so quest text writes on and the panels fade in
|
||
out of the box. The write-on machinery (0132) is ref-verbatim, and since decision 1136
|
||
the player can flip the flag on the Interface page.
|
||
- The material swap is BUILT but always Parchment: `QuestFramePanelTemplate` carries the
|
||
ref's four `$parentMaterial*` quadrants and `QuestFrame_SetMaterial` is the ref's own
|
||
body, but `GetQuestBackgroundMaterial()` is not a surface this engine has, so
|
||
`QuestFrame_GetMaterial` can only answer the ref's own nil-fallback "Parchment" — whose
|
||
arm hides all four. Same window as before; the four regions exist because they are the
|
||
ref's, and four corpus lookups address them by name.
|
||
- Reward-spell rows out of scope (`GetRewardSpell()` returns `nil`, decision 0088).
|
||
- Greeting active/available split is quest-log membership derived (`ui_quest.rs`'s
|
||
`is_active_quest`), not the wire icon — resolved already, unaffected by this pass.
|
||
-->
|
||
<Script><![CDATA[
|
||
-- The ref's OWN caps and the ref's OWN names (QuestFrame.lua l.2-3). This used to be a
|
||
-- private `BENILLA_QUEST_MAX_ITEMS = 6`, halving both — which also forced the detail and
|
||
-- reward panels to keep TWO pools of 6 (Choice*/Reward*) where the ref packs choices,
|
||
-- the spell row and fixed rewards into ONE 10-deep pool. The pools are merged below.
|
||
MAX_NUM_ITEMS = 10 -- detail/reward rows per panel (ref QuestFrame.lua:2)
|
||
MAX_REQUIRED_ITEMS = 6 -- progress-panel rows (ref QuestFrame.lua:3)
|
||
BENILLA_QUEST_MAX_TITLES = 10 -- greeting title buttons (active + available combined; ref
|
||
-- MAX_NUM_QUESTS=32, halved-and-then-some, an existing v1 cap)
|
||
BENILLA_QUEST_SCROLLCHILD_H = 700 -- the generous scroll-child budget, see header comment
|
||
|
||
-- The detail write-on (ref QuestFrame.lua:4-6): the reveal edge moves at CPS characters
|
||
-- per second, fading over LENGTH characters; the objectives/rewards block fades in over
|
||
-- QUESTINFO_FADE_IN seconds once the text has fully written.
|
||
QUEST_DESCRIPTION_GRADIENT_LENGTH = 30
|
||
QUEST_DESCRIPTION_GRADIENT_CPS = 40
|
||
QUESTINFO_FADE_IN = 1
|
||
|
||
-- "Instant Quest Text" (ref UIOptionsFrame.lua l.20/110 — uvar QUEST_FADING_DISABLE,
|
||
-- both the checkbox table's `default` and `UIOptionsFrame_Init`'s assignment are "0").
|
||
-- "0" is what we ship too, since 1804: the fade-in and the write-on are the reference's
|
||
-- out-of-box quest text, and this was pinned "1" by direction on 2026-07-17 — a taste
|
||
-- call made while the window was being built, never re-weighed as a *default*.
|
||
--
|
||
-- Flipped ON ("1"), text lands whole and the greeting/progress/reward fade-ins skip — and
|
||
-- the quill still scratches ONCE, because that is what the ref's instant mode actually
|
||
-- does (see the OnShow arm below): it jams the reveal edge past the text rather than
|
||
-- skipping the write-on, so the first OnUpdate tick plays one WriteQuest before the
|
||
-- gradient runs off. Instant is one scribble, not silence.
|
||
--
|
||
-- The ref home for this uvar is the options window, and that is where the row lives: the
|
||
-- Interface page's "Instant Quest Text" row drives it (decision 1136), and this assignment
|
||
-- is the only place the default is written down — the row CAPTURES it here rather than
|
||
-- restating one, so the Defaults button now walks the page back to the reference's value
|
||
-- because this line IS the reference's value. Registered for save on the line below
|
||
-- (1128's load order: this assignment, then the saved chunk, then consumers).
|
||
QUEST_FADING_DISABLE = "0"
|
||
RegisterForSave("QUEST_FADING_DISABLE")
|
||
|
||
-- One quest-item row (kind = "choice"/"reward"/"required", 1-based `index`) — unchanged from
|
||
-- before this pass; every panel's rows share it via `GetQuestItemInfo`.
|
||
function BenillaQuestItem_Set(button, kind, index)
|
||
local name, texture, count, quality, usable, itemId = GetQuestItemInfo(kind, index)
|
||
button.kind = kind
|
||
button.index = index
|
||
button:SetID(index) -- ref l.383/487 `questItem:SetID(i)` — the row's 1-based index
|
||
-- within its KIND, which is what GetID() answers on a real client.
|
||
button.itemId = itemId
|
||
-- ref l.388/490 ("-- For the tooltip"): every laid-out reward/choice row is stamped
|
||
-- rewardType = "item"; the ONE row that ever reads "spell" is the reward-spell row
|
||
-- (l.445), which v1 doesn't build (GetRewardSpell() is nil, decision 0088). The click
|
||
-- arms below guard on it exactly as the ref does, so the guard is live the day that
|
||
-- row lands. (Deviation, harmless: the ref leaves required rows' rewardType unset —
|
||
-- l.197-200 stamps only `.type` — which reads the same `~= "spell"` either way.)
|
||
button.rewardType = "item"
|
||
button.quality = quality
|
||
button.icon:SetTexture(texture or BENILLA_FALLBACK_ICON)
|
||
button.name:SetText(name or "...")
|
||
if (count or 1) > 1 then button.count:SetText(count) else button.count:SetText("") end
|
||
local r, g, b = 1, 1, 1
|
||
if quality and BenillaTooltip_QualityColor then r, g, b = BenillaTooltip_QualityColor(quality) end
|
||
button.name:SetTextColor(r, g, b)
|
||
button:Show()
|
||
end
|
||
|
||
-- ── The giver MATERIAL (ref QuestFrame.lua l.580-604), verbatim ─────────────────────────
|
||
-- Every quest panel is drawn on a material: Parchment (the bare corner art) or one of
|
||
-- Bronze/Marble/Silver/Stone, whose four quadrants overlay it. `SetMaterial` is the ref's
|
||
-- own body, byte-for-byte in shape; `GetMaterial` is the ref's with its one engine call
|
||
-- NAMED rather than faked.
|
||
--
|
||
-- **`GetQuestBackgroundMaterial()` IS NOT BOUND** — this engine has no such surface, so
|
||
-- `QuestFrame_GetMaterial` can only answer the ref's own fallback, "Parchment". That is
|
||
-- also the ref's answer whenever the getter returns nil, so the code path below is real and
|
||
-- reached, not a stub: the Parchment arm hides all four quadrants, which is the window we
|
||
-- ship. Written as a named absence (1134 §4) instead of a nil-returning fake binding —
|
||
-- a getter that always says nil would read like a working feature on a giver that has one.
|
||
function QuestFrame_GetMaterial()
|
||
return "Parchment"
|
||
end
|
||
|
||
function QuestFrame_SetMaterial(frame, material)
|
||
local n = frame:GetName()
|
||
local corners = { "MaterialTopLeft", "MaterialTopRight", "MaterialBotLeft", "MaterialBotRight" }
|
||
if material == "Parchment" then
|
||
for i = 1, 4 do getglobal(n .. corners[i]):Hide() end
|
||
else
|
||
for i = 1, 4 do
|
||
local t = getglobal(n .. corners[i])
|
||
t:SetTexture("Interface\\ItemTextFrame\\ItemText-" .. material .. "-" .. string.sub(corners[i], 9))
|
||
t:Show()
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ── The panel scroll kit ─────────────────────────────────────────────────────────────
|
||
-- There isn't one any more: the four panels wear the ref's OWN
|
||
-- `UIPanelScrollFrameTemplate` (ref l.107/326/508/754), so the wheel, the arrows, the
|
||
-- draggable Slider thumb and the range/arrow bookkeeping all come from the template's own
|
||
-- scripts. What stood here was a hand-rolled no-drag bar plus `BenillaQuestScroll_Step`/
|
||
-- `_OnMouseWheel`/`_SyncBar`, derived by name off "<scroll>Bar" — a private-name kit that
|
||
-- published four `Quest<panel>ScrollBar*` families the reference does not have, and that
|
||
-- pfUI's `skins/blizzard/gossipquest.lua` l.100 fell through: it skins
|
||
-- `_G[scroll:GetName().."ScrollBar"]`, which only exists on a real template instance.
|
||
--
|
||
-- TWO BEHAVIOUR CHANGES, both toward the reference: the thumb DRAGS now, and the bar STAYS
|
||
-- (greyed) on a panel with nothing to scroll instead of vanishing — the ref's quest panels
|
||
-- set no `scrollBarHideable`, so `ScrollFrame_OnScrollRangeChanged` takes its
|
||
-- disable-and-show arm.
|
||
|
||
-- Size the ACTIVE panel's scroll child to its measured content — the shared real-scroll
|
||
-- kit's `BenillaScroll_ResizeChild` (ScrollTemplates.xml), which owns the widget-bottom sum,
|
||
-- the change-guard, and the UpdateScrollChildRect. The bar needs no nudge from here: the
|
||
-- resize's own `UpdateScrollChildRect` fires OnScrollRangeChanged, and the template's
|
||
-- handler seats the arrows and the thumb.
|
||
function BenillaQuestPanel_Resize(scrollName, widgets)
|
||
BenillaScroll_ResizeChild(scrollName, widgets)
|
||
end
|
||
|
||
-- Per-panel resize candidates: every element that can be the LOWEST visible thing.
|
||
BENILLA_QUEST_PANEL_WIDGETS = {
|
||
["QuestGreetingScrollFrame"] = (function()
|
||
local t = { "GreetingText", "CurrentQuestsText", "AvailableQuestsText" }
|
||
for i = 1, BENILLA_QUEST_MAX_TITLES do table.insert(t, "QuestTitleButton" .. i) end
|
||
return t
|
||
end)(),
|
||
["QuestDetailScrollFrame"] = (function()
|
||
local t = { "QuestDescription", "QuestObjectiveText", "QuestDetailRewardTitleText",
|
||
"QuestDetailItemChooseText", "QuestDetailItemReceiveText" }
|
||
for i = 1, MAX_NUM_ITEMS do table.insert(t, "QuestDetailItem" .. i) end
|
||
table.insert(t, "QuestDetailMoneyFrame")
|
||
return t
|
||
end)(),
|
||
["QuestProgressScrollFrame"] = (function()
|
||
local t = { "QuestProgressText", "QuestProgressRequiredItemsText",
|
||
"QuestProgressRequiredMoneyText", "QuestProgressMoneyCoin1",
|
||
"QuestProgressMoneyCoin2", "QuestProgressMoneyCoin3" }
|
||
for i = 1, MAX_REQUIRED_ITEMS do table.insert(t, "QuestProgressItem" .. i) end
|
||
return t
|
||
end)(),
|
||
["QuestRewardScrollFrame"] = (function()
|
||
local t = { "QuestRewardText", "QuestRewardRewardTitleText",
|
||
"QuestRewardItemChooseText", "QuestRewardItemReceiveText" }
|
||
for i = 1, MAX_NUM_ITEMS do table.insert(t, "QuestRewardItem" .. i) end
|
||
table.insert(t, "QuestRewardMoneyFrame")
|
||
return t
|
||
end)(),
|
||
}
|
||
|
||
BENILLA_QUEST_PANEL_SCROLLS = {
|
||
greeting = "QuestGreetingScrollFrame", detail = "QuestDetailScrollFrame",
|
||
progress = "QuestProgressScrollFrame", reward = "QuestRewardScrollFrame",
|
||
}
|
||
|
||
-- The convergence driver: while the window shows, keep re-measuring the ACTIVE panel
|
||
-- (cheap — the resize itself no-ops once the sum stabilizes; the log's own OnUpdate idiom).
|
||
-- The greeting panel's title rows fit FIRST, so the panel sum below already sees their
|
||
-- final bottoms in this same pass.
|
||
function BenillaQuestFrame_OnUpdate()
|
||
local frame = getglobal("QuestFrame")
|
||
if not frame:IsVisible() or not frame.panel then return end
|
||
if frame.panel == "greeting" then
|
||
for i = 1, BENILLA_QUEST_MAX_TITLES do
|
||
local button = getglobal("QuestTitleButton" .. i)
|
||
if button:IsShown() then
|
||
BenillaQuestTitleButton_Resize(button)
|
||
end
|
||
end
|
||
end
|
||
local scroll = BENILLA_QUEST_PANEL_SCROLLS[frame.panel]
|
||
if scroll then
|
||
BenillaQuestPanel_Resize(scroll, BENILLA_QUEST_PANEL_WIDGETS[scroll])
|
||
end
|
||
end
|
||
|
||
-- ── Greeting panel (ref QuestFrameGreetingPanel_OnShow, QuestFrame.lua:219-282) ──────────────
|
||
function QuestTitleButton_OnClick()
|
||
local button = this
|
||
if button.isActive then SelectActiveQuest(button.titleIndex) else SelectAvailableQuest(button.titleIndex) end
|
||
PlaySound("igQuestListSelect") -- ref QuestTitleButton_OnClick, QuestFrame.lua:303
|
||
end
|
||
|
||
-- A title row is as tall as its own wrapped title, +2 (ref QuestFrameGreetingPanel_OnShow's
|
||
-- `SetHeight(GetTextHeight() + 2)`, QuestFrame.lua:243/272 — the same law GossipFrame.xml's
|
||
-- `BenillaGossipRow_Resize` runs on the gossip rows). Titles wrap at the ButtonText's 275 px,
|
||
-- and the rows hang off each other, so a row left at the template's 16px while its title
|
||
-- draws two lines prints the next title through it. Our GetStringHeight lands a frame after
|
||
-- the SetText (the measure round-trip), hence the guard + the OnUpdate settle above.
|
||
function BenillaQuestTitleButton_Resize(button)
|
||
local text = button:GetFontString()
|
||
local h = text and text:GetHeight() or 0
|
||
if h <= 0 or button.benillaFitHeight == h then return end
|
||
button.benillaFitHeight = h
|
||
button:SetHeight(h + 2)
|
||
end
|
||
|
||
function BenillaQuestGreetingPanel_OnShow()
|
||
getglobal("QuestFrameDetailPanel"):Hide()
|
||
getglobal("QuestFrameProgressPanel"):Hide()
|
||
getglobal("QuestFrameRewardPanel"):Hide()
|
||
|
||
local greetingText = getglobal("GreetingText")
|
||
greetingText:SetText(GetGreetingText() or "")
|
||
local activeHeader = getglobal("CurrentQuestsText")
|
||
local availableHeader = getglobal("AvailableQuestsText")
|
||
local hbreak = getglobal("QuestGreetingFrameHorizontalBreak")
|
||
local numActive = math.min(GetNumActiveQuests(), BENILLA_QUEST_MAX_TITLES)
|
||
local numAvailable = math.min(GetNumAvailableQuests(), BENILLA_QUEST_MAX_TITLES - numActive)
|
||
|
||
-- Current Quests + its title-button run (l.235-253).
|
||
if numActive == 0 then
|
||
activeHeader:SetText("")
|
||
else
|
||
activeHeader:SetText("Current Quests")
|
||
activeHeader:SetPoint("TOPLEFT", greetingText, "BOTTOMLEFT", 0, -10)
|
||
for i = 1, numActive do
|
||
local button = getglobal("QuestTitleButton" .. i)
|
||
button.isActive = true
|
||
button.titleIndex = i
|
||
button:SetText(GetActiveTitle(i))
|
||
BenillaQuestTitleButton_Resize(button)
|
||
button:Show()
|
||
if i == 1 then
|
||
button:SetPoint("TOPLEFT", activeHeader, "BOTTOMLEFT", -10, -5)
|
||
else
|
||
button:SetPoint("TOPLEFT", getglobal("QuestTitleButton" .. (i - 1)), "BOTTOMLEFT", 0, 0)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- The horizontal break + Available Quests + ITS title-button run (l.254-278) — the break
|
||
-- shows only when BOTH lists are non-empty (l.256-260).
|
||
if numActive > 0 and numAvailable > 0 then
|
||
hbreak:SetTexture("Interface\\QuestFrame\\UI-HorizontalBreak")
|
||
hbreak:SetPoint("TOPLEFT", getglobal("QuestTitleButton" .. numActive), "BOTTOMLEFT", 22, -10)
|
||
else
|
||
hbreak:SetTexture(nil)
|
||
end
|
||
if numAvailable == 0 then
|
||
availableHeader:SetText("")
|
||
else
|
||
availableHeader:SetText("Available Quests")
|
||
if numActive > 0 then
|
||
availableHeader:SetPoint("TOPLEFT", hbreak, "BOTTOMLEFT", -12, -10)
|
||
else
|
||
availableHeader:SetPoint("TOPLEFT", greetingText, "BOTTOMLEFT", 0, -10)
|
||
end
|
||
for i = numActive + 1, numActive + numAvailable do
|
||
local button = getglobal("QuestTitleButton" .. i)
|
||
button.isActive = false
|
||
button.titleIndex = i - numActive
|
||
button:SetText(GetAvailableTitle(i - numActive))
|
||
BenillaQuestTitleButton_Resize(button)
|
||
button:Show()
|
||
if i == numActive + 1 then
|
||
button:SetPoint("TOPLEFT", availableHeader, "BOTTOMLEFT", -10, -5)
|
||
else
|
||
button:SetPoint("TOPLEFT", getglobal("QuestTitleButton" .. (i - 1)), "BOTTOMLEFT", 0, 0)
|
||
end
|
||
end
|
||
end
|
||
for i = numActive + numAvailable + 1, BENILLA_QUEST_MAX_TITLES do
|
||
getglobal("QuestTitleButton" .. i):Hide()
|
||
end
|
||
|
||
getglobal("QuestGreetingScrollFrame"):SetVerticalScroll(0)
|
||
-- The action button inherits `hidden="true"` from `BenillaQuestPanelButtonTemplate`
|
||
-- (a virtual template — never itself drawn — declared hidden so a bare `inherits=` alone
|
||
-- doesn't imply "visible"); every panel must :Show() its own buttons explicitly, the same
|
||
-- way BenillaQuestItem_Set already does for item/title rows.
|
||
getglobal("QuestFrameGreetingGoodbyeButton"):Show()
|
||
if QUEST_FADING_DISABLE == "0" then -- ref l.223-226: instant text skips the fade-in
|
||
UIFrameFadeIn(getglobal("QuestGreetingScrollChildFrame"), QUESTINFO_FADE_IN)
|
||
end
|
||
end
|
||
|
||
function BenillaQuestFrameGreetingGoodbyeButton_OnClick()
|
||
-- ref l.749-752: no DeclineQuest() call here — the greeting has no in-progress panel to
|
||
-- decline yet. The window's own OnHide (CloseQuest()) still ends the giver session.
|
||
HideUIPanel(getglobal("QuestFrame"))
|
||
end
|
||
|
||
-- The reference's own `QuestMoneyFrame_OnLoad` (QuestFrame.lua:306-309), which lives in
|
||
-- THIS file in the reference too — so it is home, not a squatter. Its whole body is these
|
||
-- two calls. Needed because 1928 put the two reward panels on `MoneyFrameTemplate`, whose
|
||
-- instances call it from their OnLoad exactly as the reference's do. Both callees are our
|
||
-- `MoneyFrame.xml`'s, which the manifest loads at entry 141 — far above this file.
|
||
function QuestMoneyFrame_OnLoad()
|
||
MoneyFrame_OnLoad()
|
||
MoneyFrame_SetType("STATIC")
|
||
end
|
||
|
||
-- ── The shared reward grid — `QuestFrameItems_Update(questState)`, the REFERENCE'S OWN
|
||
-- NAME and the reference's own algorithm (QuestFrame.lua:311-522), ported line-for-line.
|
||
--
|
||
-- `questState` is "QuestDetail" or "QuestReward"; both panels read the SAME giver getters
|
||
-- (`GetNumQuestChoices`/`GetQuestItemInfo`/`GetRewardMoney` are giver-global, not
|
||
-- panel-specific — `benilla-ui`'s `quest.rs`), exactly as the ref's own one function feeds
|
||
-- its own two panels.
|
||
--
|
||
-- ONE POOL. This used to be `BenillaQuestItems_Update` over two static 6-deep pools
|
||
-- (`<panel>Choice1..6` and `<panel>Reward1..6`). The ref packs choices, then the
|
||
-- reward-spell row, then fixed rewards into a SINGLE `<panel>Item1..10` run with a running
|
||
-- `rewardsCount`, positioning each at runtime — which is why the ref's rows carry a bare
|
||
-- TOPLEFT anchor and why the split could not reproduce the function. pfUI is the report
|
||
-- (`skins/blizzard/gossipquest.lua` l.38-42 walks `QuestProgressItem`/`QuestDetailItem`/
|
||
-- `QuestRewardItem` 1..6 and indexes `:GetWidth()` unguarded), and it `hooksecurefunc`es
|
||
-- this function and `QuestFrameProgressItems_Update` by name.
|
||
--
|
||
-- The SPELL-REWARD arm is transcribed as the ref writes it and is dead on a 1.12 server:
|
||
-- `GetRewardSpell()` answers nil (decision 0088). Kept rather than dropped because it is
|
||
-- the arm that advances `rewardsCount` between the choices and the fixed rewards — deleting
|
||
-- it would silently change every index below it the day the row lands.
|
||
function QuestFrameItems_Update(questState)
|
||
local numChoices = GetNumQuestChoices()
|
||
local numRewards = GetNumQuestRewards()
|
||
local numSpellRewards = GetRewardSpell() and 1 or 0
|
||
local money = GetRewardMoney()
|
||
local itemName = questState .. "Item"
|
||
local totalRewards = numChoices + numRewards + numSpellRewards
|
||
|
||
-- ref l.341-349: the "Rewards" header shows iff there is anything at all to show.
|
||
local header = getglobal(questState .. "RewardTitleText")
|
||
header:SetText((totalRewards > 0 or (money and money > 0)) and "Rewards" or "")
|
||
|
||
-- ref l.358-361: hide the tail of the pool BEFORE laying any of it out.
|
||
for i = totalRewards + 1, MAX_NUM_ITEMS do
|
||
getglobal(itemName .. i):Hide()
|
||
end
|
||
|
||
local rewardsCount = 0
|
||
|
||
-- ref l.366-411: choosable rewards, 2-per-row — odd index starts a new row under the
|
||
-- row two back, even index sits beside the previous.
|
||
local chooseText = getglobal(questState .. "ItemChooseText")
|
||
chooseText:SetText(numChoices > 0 and "You may choose one of these rewards:" or "")
|
||
local lastChoice = math.min(numChoices, MAX_NUM_ITEMS)
|
||
for i = 1, lastChoice do
|
||
local index = i + rewardsCount
|
||
local item = getglobal(itemName .. index)
|
||
BenillaQuestItem_Set(item, "choice", i)
|
||
if i == 1 then
|
||
item:SetPoint("TOPLEFT", chooseText, "BOTTOMLEFT", -3, -5)
|
||
elseif i % 2 == 1 then
|
||
item:SetPoint("TOPLEFT", getglobal(itemName .. (index - 2)), "BOTTOMLEFT", 0, -2)
|
||
else
|
||
item:SetPoint("TOPLEFT", getglobal(itemName .. (index - 1)), "TOPRIGHT", 1, 0)
|
||
end
|
||
end
|
||
rewardsCount = rewardsCount + lastChoice
|
||
|
||
-- ref l.414-451: the reward-spell row. Dead here (GetRewardSpell() is nil), and the
|
||
-- `else` arm is the one that runs — it blanks the label exactly as the ref hides it.
|
||
local learnSpellText = getglobal(questState .. "SpellLearnText")
|
||
if learnSpellText then learnSpellText:SetText("") end
|
||
|
||
-- ref l.454-471: "You will receive:" / "You will also receive:" — shown for a fixed
|
||
-- reward OR money, even with zero fixed-reward rows (a money-only quest).
|
||
local receiveText = getglobal(questState .. "ItemReceiveText")
|
||
if numRewards > 0 or (money and money > 0) then
|
||
if numChoices > 0 then
|
||
receiveText:SetText("You will also receive:")
|
||
local index = lastChoice
|
||
if index % 2 == 0 then index = index - 1 end
|
||
receiveText:SetPoint("TOPLEFT", getglobal(itemName .. index), "BOTTOMLEFT", 3, -5)
|
||
else
|
||
receiveText:SetText("You will receive:")
|
||
receiveText:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 3, -5)
|
||
end
|
||
else
|
||
receiveText:SetText("")
|
||
end
|
||
|
||
-- ref l.474-513: fixed rewards, the SAME 2-per-row walk, continuing the pool.
|
||
local lastReward = math.min(numRewards, MAX_NUM_ITEMS - rewardsCount)
|
||
for i = 1, lastReward do
|
||
local index = i + rewardsCount
|
||
local item = getglobal(itemName .. index)
|
||
BenillaQuestItem_Set(item, "reward", i)
|
||
if i == 1 then
|
||
item:SetPoint("TOPLEFT", receiveText, "BOTTOMLEFT", -3, -5)
|
||
elseif i % 2 == 1 then
|
||
item:SetPoint("TOPLEFT", getglobal(itemName .. (index - 2)), "BOTTOMLEFT", 0, -2)
|
||
else
|
||
item:SetPoint("TOPLEFT", getglobal(itemName .. (index - 1)), "TOPRIGHT", 1, 0)
|
||
end
|
||
end
|
||
|
||
-- The reference's own tail (QuestFrame.lua:350-356), on the reference's own widget.
|
||
-- `QuestFrame_SetAsLastShown` is deliberately NOT called: it anchors a SPACER FRAME
|
||
-- that this client does not have — our panels size their scroll child from
|
||
-- `BENILLA_QUEST_PANEL_WIDGETS` instead (see 1928). The money half converges here; the
|
||
-- sizing model stays ours until this window migrates.
|
||
local moneyFrame = getglobal(questState .. "MoneyFrame")
|
||
if money and money > 0 then
|
||
moneyFrame:Show()
|
||
MoneyFrame_Update(questState .. "MoneyFrame", money)
|
||
else
|
||
moneyFrame:Hide()
|
||
end
|
||
end
|
||
|
||
-- ── Detail panel (ref QuestFrameDetailPanel_OnShow, QuestFrame.lua:524-552) ──────────────────
|
||
function BenillaQuestDetailPanel_OnShow()
|
||
getglobal("QuestFrameGreetingPanel"):Hide()
|
||
getglobal("QuestFrameProgressPanel"):Hide()
|
||
getglobal("QuestFrameRewardPanel"):Hide()
|
||
|
||
getglobal("QuestTitleText"):SetText(GetTitleText() or "")
|
||
getglobal("QuestDescription"):SetText(GetQuestText() or "")
|
||
getglobal("QuestDetailObjectiveTitleText"):SetText("Quest Objectives")
|
||
getglobal("QuestObjectiveText"):SetText(GetObjectiveText() or "")
|
||
QuestFrameItems_Update("QuestDetail")
|
||
getglobal("QuestDetailScrollFrame"):SetVerticalScroll(0)
|
||
getglobal("QuestFrameAcceptButton"):Show()
|
||
getglobal("QuestFrameDeclineButton"):Show()
|
||
|
||
-- Arm the write-on (ref l.538-551): objectives/rewards invisible and Accept dead
|
||
-- until the description has finished writing itself onto the parchment.
|
||
getglobal("TextAlphaDependentFrame"):SetAlpha(0)
|
||
getglobal("QuestFrameAcceptButton"):Disable()
|
||
local panel = getglobal("QuestFrameDetailPanel")
|
||
panel.fading = 1
|
||
panel.fadingProgress = 0
|
||
getglobal("QuestDescription"):SetAlphaGradient(0, QUEST_DESCRIPTION_GRADIENT_LENGTH)
|
||
-- Instant text (ref l.549-551): the write-on still arms, but the reveal edge starts
|
||
-- past any quest text's end — the first OnUpdate tick scratches the quill once, runs
|
||
-- the gradient off, and wakes everything on the spot.
|
||
if QUEST_FADING_DISABLE == "1" then
|
||
panel.fadingProgress = 1024
|
||
end
|
||
end
|
||
|
||
-- ref QuestFrameDetailPanel_OnUpdate (QuestFrame.lua:555-570): advance the reveal edge,
|
||
-- scratching the WriteQuest quill each tick — the kit's no-duplicates flag (0x20) keeps
|
||
-- the per-frame PlaySound from stacking (a new scribble only starts when the previous
|
||
-- wav ends, which IS the continuous writing sound). When the gradient runs off the end
|
||
-- of the text, fade the objectives/rewards block in (or snap it on, instant mode) and
|
||
-- wake the Accept button. With instant text the arm above started the edge at 1024, so
|
||
-- all of this happens on the first tick: one scratch, then the wake.
|
||
function BenillaQuestDetailPanel_OnUpdate(panel, elapsed)
|
||
if panel.fading then
|
||
panel.fadingProgress = panel.fadingProgress + (elapsed * QUEST_DESCRIPTION_GRADIENT_CPS)
|
||
PlaySound("WriteQuest")
|
||
if not getglobal("QuestDescription"):SetAlphaGradient(panel.fadingProgress, QUEST_DESCRIPTION_GRADIENT_LENGTH) then
|
||
panel.fading = nil
|
||
if QUEST_FADING_DISABLE == "0" then
|
||
UIFrameFadeIn(getglobal("TextAlphaDependentFrame"), QUESTINFO_FADE_IN)
|
||
else
|
||
-- instant: the block snaps on, no fade (ref l.561-564)
|
||
getglobal("TextAlphaDependentFrame"):SetAlpha(1)
|
||
end
|
||
getglobal("QuestFrameAcceptButton"):Enable()
|
||
end
|
||
end
|
||
end
|
||
|
||
function QuestFrameAcceptButton_OnClick()
|
||
AcceptQuest()
|
||
end
|
||
|
||
function QuestFrameDeclineButton_OnClick()
|
||
-- DeclineQuest() DOES send (decision 1738, byte-verified — this comment used to claim
|
||
-- the opposite for years): the app's session-end routine re-opens the giver's list
|
||
-- (CMSG_QUESTGIVER_HELLO / CMSG_GOSSIP_HELLO), which is what puts you back in an NPC's
|
||
-- menu after a decline, or answers a party member's share. Either way the panel is
|
||
-- hidden here immediately rather than waiting on a packet — the same convention every
|
||
-- NPC window's close button already uses (e.g. BenillaMerchantCloseButton_OnClick).
|
||
DeclineQuest()
|
||
PlaySound("igQuestCancel") -- ref QuestFrameDeclineButton_OnClick, QuestFrame.lua:577
|
||
HideUIPanel(getglobal("QuestFrame"))
|
||
end
|
||
|
||
-- ── Progress panel (ref QuestFrameProgressPanel_OnShow/Items_Update, QuestFrame.lua:143-217)
|
||
-- ITS OWN grid — NOT the choose/reward one above: item1 is the only Lua-repositioned row (below
|
||
-- the required-money line when money is required, else below the header directly, l.186-192);
|
||
-- items 2-6 are a STATIC XML 2-column×3-row chain off item1/item3/item5 (ref l.416-460) that
|
||
-- the resolver's fixpoint keeps correctly re-propagated as item1 moves — no Lua needed for
|
||
-- them at all. ─────────────────────────────────────────────────────────────────────────────
|
||
-- The progress panel's own grid, under the REFERENCE'S OWN NAME (ref
|
||
-- `QuestFrameProgressItems_Update`, QuestFrame.lua:165-217) — pfUI `hooksecurefunc`es it by
|
||
-- that name (`skins/blizzard/gossipquest.lua` l.131), which is why it is a function rather
|
||
-- than a block inside the OnShow it used to live in.
|
||
--
|
||
-- NOT the choose/reward walk above: `QuestProgressItem1` is the only Lua-repositioned row
|
||
-- (below the required-money line when money is required, else below the header directly,
|
||
-- ref l.186-192); items 2-6 are a STATIC XML 2-column x 3-row chain off items 1/3/5 (ref
|
||
-- l.416-460) that the resolver's fixpoint keeps re-propagated as item1 moves.
|
||
function QuestFrameProgressItems_Update()
|
||
local numItems = math.min(GetNumQuestItems(), MAX_REQUIRED_ITEMS)
|
||
local money = GetQuestMoneyToGet()
|
||
local reqText = getglobal("QuestProgressRequiredItemsText")
|
||
local moneyText = getglobal("QuestProgressRequiredMoneyText")
|
||
local item1 = getglobal("QuestProgressItem1")
|
||
if numItems > 0 or (money and money > 0) then
|
||
reqText:SetText("Items Needed:")
|
||
if money and money > 0 then
|
||
moneyText:SetText("Required Money:")
|
||
BenillaMoney_Set("QuestProgressMoney", money, true)
|
||
item1:SetPoint("TOPLEFT", moneyText, "BOTTOMLEFT", 0, -10)
|
||
else
|
||
moneyText:SetText("")
|
||
BenillaMoney_Clear("QuestProgressMoney")
|
||
item1:SetPoint("TOPLEFT", reqText, "BOTTOMLEFT", -3, -5)
|
||
end
|
||
else
|
||
reqText:SetText("")
|
||
moneyText:SetText("")
|
||
BenillaMoney_Clear("QuestProgressMoney")
|
||
end
|
||
for i = 1, MAX_REQUIRED_ITEMS do
|
||
if i <= numItems then
|
||
BenillaQuestItem_Set(getglobal("QuestProgressItem" .. i), "required", i)
|
||
else
|
||
getglobal("QuestProgressItem" .. i):Hide()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BenillaQuestProgressPanel_OnShow()
|
||
getglobal("QuestFrameGreetingPanel"):Hide()
|
||
getglobal("QuestFrameDetailPanel"):Hide()
|
||
getglobal("QuestFrameRewardPanel"):Hide()
|
||
|
||
getglobal("QuestProgressTitleText"):SetText(GetTitleText() or "")
|
||
getglobal("QuestProgressText"):SetText(GetProgressText() or "")
|
||
|
||
QuestFrameProgressItems_Update()
|
||
|
||
local continueButton = getglobal("QuestFrameCompleteButton")
|
||
if IsQuestCompletable() then continueButton:Enable() else continueButton:Disable() end
|
||
continueButton:Show()
|
||
getglobal("QuestFrameGoodbyeButton"):Show()
|
||
getglobal("QuestProgressScrollFrame"):SetVerticalScroll(0)
|
||
if QUEST_FADING_DISABLE == "0" then -- ref l.159-162: instant text skips the fade-in
|
||
UIFrameFadeIn(getglobal("QuestProgressScrollChildFrame"), QUESTINFO_FADE_IN)
|
||
end
|
||
end
|
||
|
||
function BenillaQuestFrameCompleteButton_OnClick()
|
||
CompleteQuest() -- the progress panel's "Continue" — requests the reward offer
|
||
end
|
||
|
||
function BenillaQuestFrameGoodbyeButton_OnClick()
|
||
DeclineQuest()
|
||
PlaySound("igQuestCancel") -- ref QuestGoodbyeButton_OnClick, QuestFrame.lua:112
|
||
HideUIPanel(getglobal("QuestFrame"))
|
||
end
|
||
|
||
-- ── Reward panel (ref QuestFrameRewardPanel_OnShow + reward-item clicks, QuestFrame.lua:72-141)
|
||
function BenillaQuestRewardPanel_OnShow()
|
||
getglobal("QuestFrameGreetingPanel"):Hide()
|
||
getglobal("QuestFrameDetailPanel"):Hide()
|
||
getglobal("QuestFrameProgressPanel"):Hide()
|
||
|
||
getglobal("QuestRewardTitleText"):SetText(GetTitleText() or "")
|
||
getglobal("QuestRewardText"):SetText(GetRewardText() or "")
|
||
getglobal("QuestFrame").itemChoice = 0
|
||
getglobal("QuestRewardItemHighlight"):Hide()
|
||
QuestFrameItems_Update("QuestReward")
|
||
getglobal("QuestRewardScrollFrame"):SetVerticalScroll(0)
|
||
getglobal("QuestFrameCompleteQuestButton"):Show()
|
||
getglobal("QuestFrameCancelButton"):Show()
|
||
-- ref l.85-88: the whole parchment content fades in — unless the text is instant.
|
||
if QUEST_FADING_DISABLE == "0" then
|
||
getglobal("QuestRewardScrollChildFrame"):SetAlpha(0)
|
||
UIFrameFadeIn(getglobal("QuestRewardScrollChildFrame"), QUESTINFO_FADE_IN)
|
||
end
|
||
end
|
||
|
||
-- ── The item-row modifier fork, shared by every quest-item row in this window ─────────────
|
||
-- ref QuestItem_OnClick (QuestFrame.lua:115-125), the OnClick QuestItemTemplate itself
|
||
-- carries (QuestFrameTemplates.xml:162-164) — so it covers the DETAIL panel's choice/reward
|
||
-- rows, the PROGRESS panel's required rows, and the reward panel's FIXED reward rows.
|
||
-- CTRL previews the item in the dressing room (decision 1060), SHIFT posts its link into an
|
||
-- open chat edit box (decision 1059); a plain click does nothing here, which is why these
|
||
-- rows carried no OnClick before this arc.
|
||
--
|
||
-- Two guards the ref's own code has, transcribed: the ctrl arm is gated on
|
||
-- `this.rewardType ~= "spell"` (l.117 — a spell reward has no item to wear), and the shift
|
||
-- arm additionally requires the edit box to be VISIBLE (l.121; the `and rewardType ~=
|
||
-- "spell"` rides the same line there). Ours adds `ChatFrameEditBox and` — ChatFrame.xml is
|
||
-- a separate file a window test need not load, exactly as BenillaPaperDollSlot_OnClick does.
|
||
--
|
||
-- One benilla-only guard: `link` is nil until the ask-once item template lands (a state the
|
||
-- reference's synchronous item cache never has), and EditBox:Insert takes a string. The ref
|
||
-- already carries the twin of this guard inside DressUpItemLink (ref DressUpFrame.lua:11-13).
|
||
function QuestItem_OnClick()
|
||
local button = this
|
||
if IsControlKeyDown() then
|
||
if button.rewardType ~= "spell" then
|
||
DressUpItemLink(GetQuestItemLink(button.kind, button.index))
|
||
end
|
||
elseif IsShiftKeyDown() then
|
||
-- The ref's spell guard rides this arm (l.121); the "edit box up" and "link not
|
||
-- nil" pair is the shared helper's (UIParent.xml — one law, one place).
|
||
if button.rewardType ~= "spell" then
|
||
BenillaChatEdit_InsertLink(GetQuestItemLink(button.kind, button.index))
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ref QuestRewardItem_OnClick (l.127-141), the OnClick the REWARD panel's choice rows carry
|
||
-- through QuestRewardItemTemplate (QuestFrameTemplates.xml:169-171). The first two arms are
|
||
-- QuestItem_OnClick's verbatim (only the shift arm's spell guard differs — the ref drops it
|
||
-- here, l.133); the choice SELECT is the THIRD arm, so a ctrl- or shift-click must NOT also
|
||
-- pick the reward. That ordering is the whole point of the fork.
|
||
function QuestRewardItem_OnClick()
|
||
local button = this
|
||
if IsControlKeyDown() then
|
||
if button.rewardType ~= "spell" then
|
||
DressUpItemLink(GetQuestItemLink(button.kind, button.index))
|
||
end
|
||
elseif IsShiftKeyDown() then
|
||
-- No spell guard on this arm — the ref drops it here (l.133). The visible/non-nil
|
||
-- pair is the shared helper's (UIParent.xml).
|
||
BenillaChatEdit_InsertLink(GetQuestItemLink(button.kind, button.index))
|
||
elseif button.kind == "choice" then
|
||
-- ref l.136's own `this.type == "choice"` test. The ref needs it because its reward
|
||
-- panel packs choices AND fixed rewards into ONE QuestRewardItem1..10 pool; ours
|
||
-- keeps two pools and hangs this template only on QuestRewardChoice*, so the
|
||
-- test is belt-and-braces — kept because it is the ref's, and because it is what
|
||
-- makes the template safe to reuse if the pools are ever merged.
|
||
BenillaQuestRewardItem_Select(button)
|
||
end
|
||
end
|
||
|
||
-- The third arm alone (ref l.136-139): only a REWARD-panel choice row is selectable — the
|
||
-- detail panel's rows and both panels' FIXED reward rows ride the plain
|
||
-- `QuestItemTemplate`, whose OnClick has no select arm at all, matching the ref's
|
||
-- separate QuestRewardItemTemplate vs QuestItemTemplate.
|
||
function BenillaQuestRewardItem_Select(button)
|
||
getglobal("QuestFrame").itemChoice = button.index
|
||
-- Ref QuestRewardItem_OnClick l.137-138 verbatim: the glow frame seats at (-8,7) on
|
||
-- the clicked row's TOPLEFT.
|
||
local hl = getglobal("QuestRewardItemHighlight")
|
||
hl:SetPoint("TOPLEFT", button, "TOPLEFT", -8, 7)
|
||
hl:Show()
|
||
end
|
||
|
||
function QuestFrameCompleteQuestButton_OnClick()
|
||
local choice = getglobal("QuestFrame").itemChoice or 0
|
||
if GetNumQuestChoices() > 0 and choice == 0 then return end -- must pick a choice first
|
||
GetQuestReward(math.max(choice - 1, 0)) -- 1-based row -> 0-based wire index
|
||
PlaySound("igQuestListComplete") -- ref QuestFrameCompleteQuestButton_OnClick, QuestFrame.lua:101
|
||
end
|
||
|
||
function QuestFrameCancelButton_OnClick()
|
||
DeclineQuest()
|
||
PlaySound("igQuestCancel") -- ref QuestFrameCancelButton_OnClick, QuestFrame.lua:93
|
||
HideUIPanel(getglobal("QuestFrame"))
|
||
end
|
||
|
||
-- ── Window lifecycle (ref QuestFrame_OnLoad/OnEvent, QuestFrame.lua:8-70) ────────────────────
|
||
function QuestFrame_OnLoad()
|
||
local frame = this
|
||
-- The NPC portrait: the "npc" unit token → the questgiver's live model bake
|
||
-- (crates/benilla/src/portrait, InteractNpc) — the same binding MerchantFrame/GossipFrame use.
|
||
SetPortraitTexture(getglobal(frame:GetName() .. "Portrait"), "npc")
|
||
frame:RegisterEvent("QUEST_GREETING")
|
||
frame:RegisterEvent("QUEST_DETAIL")
|
||
frame:RegisterEvent("QUEST_PROGRESS")
|
||
frame:RegisterEvent("QUEST_COMPLETE")
|
||
frame:RegisterEvent("QUEST_ITEM_UPDATE")
|
||
frame:RegisterEvent("QUEST_FINISHED")
|
||
frame.itemChoice = 0
|
||
frame.panel = nil
|
||
end
|
||
|
||
-- Re-run whichever panel is currently live (QUEST_ITEM_UPDATE — an in-place row refresh, e.g.
|
||
-- an item name landing async; ref l.45-58 calls the item-grid function directly rather than
|
||
-- re-showing the panel — re-running the panel's own OnShow here is equivalent AND simpler: it
|
||
-- reads the same live QuestState, so title/body come out unchanged and only the rows actually
|
||
-- differ).
|
||
function BenillaQuestFrame_Repaint(panel)
|
||
if panel == "greeting" then BenillaQuestGreetingPanel_OnShow()
|
||
elseif panel == "detail" then BenillaQuestDetailPanel_OnShow()
|
||
elseif panel == "progress" then BenillaQuestProgressPanel_OnShow()
|
||
elseif panel == "reward" then BenillaQuestRewardPanel_OnShow() end
|
||
end
|
||
|
||
function QuestFrame_OnEvent(event)
|
||
local frame = this
|
||
if event == "QUEST_FINISHED" then
|
||
HideUIPanel(frame)
|
||
frame.panel = nil
|
||
return
|
||
end
|
||
if event == "QUEST_ITEM_UPDATE" then
|
||
-- The in-place refresh also carries the NPC name (arg1) — in live play the ask-once
|
||
-- name often lands one frame AFTER the panel opened, arriving exactly here; dropping
|
||
-- it left the title bar blank (caught reviewing the ui-quest capture).
|
||
if arg1 and arg1 ~= "" then getglobal("QuestFrameNpcNameText"):SetText(arg1) end
|
||
if frame:IsVisible() and frame.panel then BenillaQuestFrame_Repaint(frame.panel) end
|
||
return
|
||
end
|
||
|
||
getglobal("QuestFrameNpcNameText"):SetText(arg1 or "")
|
||
if event == "QUEST_GREETING" then frame.panel = "greeting"
|
||
elseif event == "QUEST_DETAIL" then frame.panel = "detail"
|
||
elseif event == "QUEST_PROGRESS" then frame.panel = "progress"
|
||
elseif event == "QUEST_COMPLETE" then frame.panel = "reward" end
|
||
|
||
ShowUIPanel(frame)
|
||
-- ref l.33-44: Hide() then Show() the target CHILD panel — forces its own OnShow to run
|
||
-- (which hides the other three siblings + repaints itself), even on a same-panel refresh
|
||
-- (e.g. re-QUERY_QUEST on the same NPC while Detail is already open).
|
||
local names = {
|
||
greeting = "QuestFrameGreetingPanel", detail = "QuestFrameDetailPanel",
|
||
progress = "QuestFrameProgressPanel", reward = "QuestFrameRewardPanel",
|
||
}
|
||
local target = getglobal(names[frame.panel])
|
||
target:Hide()
|
||
target:Show()
|
||
end
|
||
|
||
function BenillaQuestFrameCloseButton_OnClick()
|
||
CloseQuest()
|
||
HideUIPanel(getglobal("QuestFrame"))
|
||
end
|
||
]]></Script>
|
||
|
||
<!--
|
||
One quest-item row, ref-verbatim (QuestItemTemplate, QuestFrameTemplates.xml:85-138): a bare
|
||
39×39 icon at TOPLEFT (the ref draws NO slot-well behind it — the earlier `UI-EmptySlot` here
|
||
was our own addition and read as a heavy black box on the parchment), the name plate
|
||
overlapping the icon's right edge by 10, the name in GameFontHighlight (12px, not Small),
|
||
and the count riding the icon's BOTTOMRIGHT. Kept in sync by hand with the quest log's
|
||
`QuestLogRewardItemTemplate` (per-window test-isolation duplication, that template's own
|
||
comment).
|
||
-->
|
||
<Button name="QuestItemTemplate" virtual="true" hidden="true">
|
||
<Size><AbsDimension x="147" y="41"/></Size>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentIconTexture">
|
||
<Size><AbsDimension x="39" y="39"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="$parentNameFrame" file="Interface\QuestFrame\UI-QuestItemNameFrame">
|
||
<Size><AbsDimension x="128" y="64"/></Size>
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentIconTexture" relativePoint="RIGHT"><Offset><AbsDimension x="-10" y="0"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<FontString name="$parentName" inherits="GameFontHighlight" justifyH="LEFT">
|
||
<Size><AbsDimension x="90" y="36"/></Size>
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentNameFrame"><Offset><AbsDimension x="15" y="0"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="$parentCount" inherits="NumberFontNormal" justifyH="RIGHT">
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativeTo="$parentIconTexture"><Offset><AbsDimension x="-4" y="1"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<!-- NO hover art: the ref QuestItemTemplate carries no HighlightTexture — reward rows
|
||
don't glow on hover; only the reward panel's CHOICE click seats the selection glow
|
||
(QuestRewardItemHighlight). The old ButtonHilight-Square here was our own
|
||
addition (the director's img-18). -->
|
||
<Scripts>
|
||
<OnLoad>
|
||
local n = self:GetName()
|
||
self.icon = getglobal(n .. "IconTexture")
|
||
self.name = getglobal(n .. "Name")
|
||
self.count = getglobal(n .. "Count")
|
||
</OnLoad>
|
||
<!-- The shared id-keyed item tooltip (ref QuestItemTemplate OnEnter →
|
||
GameTooltip:SetQuestItem — the same C++ renderer every item hover uses). -->
|
||
<OnEnter>
|
||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||
GameTooltip:SetItemById(self.itemId, self.name:GetText(), self.quality)
|
||
GameTooltip:Show()
|
||
</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
<!-- ref QuestItemTemplate's own OnClick (QuestFrameTemplates.xml:162-164): the CTRL
|
||
dressing-room preview + the SHIFT chat-link post, and nothing else — a plain click
|
||
on one of these rows is inert (decisions 1059/1060). -->
|
||
<OnClick>QuestItem_OnClick()</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
|
||
<!-- A REWARD-panel choice row: the same visual, plus the ref's `QuestRewardItemTemplate` click
|
||
(QuestFrameTemplates.xml:167-173) — the ctrl/shift arms shared with the base template, then
|
||
the choose highlight as the THIRD arm. The detail panel's rows and both panels' FIXED reward
|
||
rows stay on plain `QuestItemTemplate`, whose OnClick has no select arm (ref: only
|
||
reward-panel CHOICE rows select). -->
|
||
<Button name="QuestRewardItemTemplate" inherits="QuestItemTemplate" virtual="true" hidden="true">
|
||
<Scripts><OnClick>QuestRewardItem_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
|
||
<!-- **The reference's own name**, since 1751's thirteenth window. It was
|
||
`BenillaQuestTitleButtonTemplate` while both this file and its only consumers were ours;
|
||
the sourced `Interface\FrameXML\GuildRegistrarFrame.xml` inherits the reference's name
|
||
for its two service rows, and an unknown template is a loader WARNING — the frame builds
|
||
and silently has no art — so the rename is what keeps that window skinned.
|
||
A greeting quest-title button (ref QuestTitleButtonTemplate, QuestFrameTemplates.xml l.174-213):
|
||
a bullet + the quest title. -->
|
||
<Button name="QuestTitleButtonTemplate" virtual="true">
|
||
<Size><AbsDimension x="300" y="16"/></Size>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture file="Interface\QuestFrame\UI-Quest-BulletPoint">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<HighlightTexture file="Interface\QuestFrame\UI-QuestTitleHighlight" alphaMode="ADD"/>
|
||
<Scripts><OnClick>QuestTitleButton_OnClick()</OnClick></Scripts>
|
||
<!-- QuestFont (13px BLACK on parchment), LEFT, x+20 beside the bullet. We anchor LEFT (the
|
||
row's vertical centre), NOT the reference's TOPLEFT: the round UI-Quest-BulletPoint is
|
||
cell-centred, so a top-anchored title hangs its centreline ABOVE the bullet and reads
|
||
"too high" (director's falsifier). LEFT-anchoring drops the title onto the row centre
|
||
where the bullet sits — a deliberate deviation (the reference top-anchors both and lives
|
||
with the low bullet). -->
|
||
<ButtonText>
|
||
<Size><AbsDimension x="275" y="0"/></Size>
|
||
<Anchors><Anchor point="LEFT" relativePoint="LEFT"><Offset><AbsDimension x="20" y="0"/></Offset></Anchor></Anchors>
|
||
</ButtonText>
|
||
<NormalFont inherits="QuestFont" justifyH="LEFT"/>
|
||
</Button>
|
||
|
||
<!-- A panel action button (Accept/Decline/…): the UIPanelButtonTemplate face, label via text=. -->
|
||
<Button name="BenillaQuestPanelButtonTemplate" virtual="true" hidden="true">
|
||
<Size><AbsDimension x="80" y="22"/></Size>
|
||
<NormalFont inherits="GameFontNormal"/>
|
||
<HighlightFont inherits="GameFontHighlight"/>
|
||
<DisabledFont inherits="GameFontDisable"/>
|
||
<NormalTexture file="Interface\Buttons\UI-Panel-Button-Up"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></NormalTexture>
|
||
<PushedTexture file="Interface\Buttons\UI-Panel-Button-Down"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></PushedTexture>
|
||
<DisabledTexture file="Interface\Buttons\UI-Panel-Button-Disabled"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></DisabledTexture>
|
||
<HighlightTexture file="Interface\Buttons\UI-Panel-Button-Highlight" alphaMode="ADD"><TexCoords left="0" right="0.625" top="0" bottom="0.6875"/></HighlightTexture>
|
||
</Button>
|
||
|
||
<!-- One money coin slot (shared money display; BenillaMoney_Set fills three, high-denom first,
|
||
shrinking each to its number + 13px coin — the XML width is just the pre-fill state). -->
|
||
<Frame name="BenillaQuestMoneyCoinTemplate" virtual="true">
|
||
<Size><AbsDimension x="13" y="13"/></Size>
|
||
<Layers><Layer level="OVERLAY">
|
||
<Texture name="$parentIcon" file="Interface\MoneyFrame\UI-MoneyIcons"><Size><AbsDimension x="13" y="13"/></Size><Anchors><Anchor point="RIGHT" relativePoint="RIGHT"/></Anchors></Texture>
|
||
<FontString name="$parentNum" inherits="NumberFontNormal" justifyH="RIGHT"><Size><AbsDimension x="20" y="13"/></Size><Anchors><Anchor point="RIGHT" relativePoint="RIGHT"><Offset><AbsDimension x="-13" y="0"/></Offset></Anchor></Anchors></FontString>
|
||
</Layer></Layers>
|
||
</Frame>
|
||
|
||
<!-- The shared sub-panel chrome (ref `QuestFramePanelTemplate`, QuestFrameTemplates.xml l.3-84):
|
||
the four corner parchment quadrants every one of the four panels draws independently (the
|
||
ref's own choice — each real sub-panel repeats this art rather than the window compositing it
|
||
once). The ref's material BORDER textures (the Parchment/Book skin swap,
|
||
`QuestFrame_SetMaterial`) are omitted — no such Lua surface exists in this engine (this
|
||
window's header comment). Fills the whole window (384×512, TOPLEFT the parent panel's own
|
||
TOPLEFT — each concrete panel below inherits this and is itself anchored to fill
|
||
`QuestFrame`). -->
|
||
<!-- ref QuestFrameTemplates.xml l.20-84. Was `QuestFramePanelTemplate`, a name the reference
|
||
does not have. -->
|
||
<Frame name="QuestFramePanelTemplate" virtual="true" hidden="true">
|
||
<Size><AbsDimension x="384" y="512"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture file="Interface\QuestFrame\UI-QuestGreeting-TopLeft"><Size><AbsDimension x="256" y="256"/></Size><Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors></Texture>
|
||
<Texture file="Interface\QuestFrame\UI-QuestGreeting-TopRight"><Size><AbsDimension x="128" y="256"/></Size><Anchors><Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"/></Anchors></Texture>
|
||
<Texture file="Interface\QuestFrame\UI-QuestGreeting-BotLeft"><Size><AbsDimension x="256" y="256"/></Size><Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"/></Anchors></Texture>
|
||
<Texture file="Interface\QuestFrame\UI-QuestGreeting-BotRight"><Size><AbsDimension x="128" y="256"/></Size><Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"/></Anchors></Texture>
|
||
</Layer>
|
||
<!-- The MATERIAL quadrants (ref l.45-82), fileless and unshown: `QuestFrame_SetMaterial`
|
||
paints and shows them for a Bronze/Marble/Silver/Stone giver and HIDES all four for
|
||
a Parchment one. Parchment is the branch this client always takes
|
||
(`QuestFrame_GetMaterial` below), so they draw nothing today and the window looks
|
||
exactly as it did — they are here because they are four real regions of the ref's
|
||
template that four corpus lookups address by name, not to make a picture. -->
|
||
<Layer level="BORDER">
|
||
<Texture name="$parentMaterialTopLeft" hidden="true">
|
||
<Size><AbsDimension x="239" y="241"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="21" y="-75"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture name="$parentMaterialTopRight" hidden="true">
|
||
<Size><AbsDimension x="64" y="241"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentMaterialTopLeft" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="$parentMaterialBotLeft" hidden="true">
|
||
<Size><AbsDimension x="239" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentMaterialTopLeft" relativePoint="BOTTOMLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="$parentMaterialBotRight" hidden="true">
|
||
<Size><AbsDimension x="64" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentMaterialTopLeft" relativePoint="BOTTOMRIGHT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
|
||
<Frame name="QuestFrame" enableMouse="true" toplevel="true" parent="UIParent" hidden="true">
|
||
<Size><AbsDimension x="384" y="512"/></Size>
|
||
<Layers>
|
||
<!-- NPC portrait 60×60 TOPLEFT (7,-6) (ref QuestFramePortrait l.20-33). Drawn on the OUTER
|
||
frame, which is created/inserted BEFORE its child panels — the panel-level chrome
|
||
above therefore paints AFTER (and so visually "above") this portrait in the same
|
||
stratum (`order.rs`'s frame-level → insertion-order tie-break), letting the corner
|
||
art's baked-in circular cutout frame the portrait exactly like the flat layout did. -->
|
||
<Layer level="ARTWORK">
|
||
<Texture name="$parentPortrait">
|
||
<Size><AbsDimension x="60" y="60"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="7" y="-6"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- NPC name — the ref's OWN stacking solution transcribed (ref l.36-61): a dedicated
|
||
QuestNpcNameFrame child raised +2 frame levels in its OnLoad, so the name draws
|
||
ABOVE the four sub-panels' book art (a bare FontString on the outer frame sits at
|
||
level 0 and the level-1 panels paint over it — the blank-title-bar bug the
|
||
ui-quest capture caught; the engine z-order honors frame level exactly like the
|
||
client's). frameLevel="3" is the static equivalent of the ref's GetFrameLevel()+2
|
||
(outer 0, panels 1). -->
|
||
<Frame name="QuestNpcNameFrame" frameLevel="3">
|
||
<Size><AbsDimension x="300" y="14"/></Size>
|
||
<Anchors><Anchor point="TOP" relativePoint="TOP"><Offset><AbsDimension x="0" y="-23"/></Offset></Anchor></Anchors>
|
||
<Layers><Layer level="BACKGROUND">
|
||
<FontString name="QuestFrameNpcNameText" inherits="GameFontHighlight" justifyH="CENTER">
|
||
<Size><AbsDimension x="235" y="20"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="CENTER"/></Anchors>
|
||
</FontString>
|
||
</Layer></Layers>
|
||
</Frame>
|
||
<!-- Close (ref l.62-70: CENTER on the window's TOPRIGHT, -42,-31 — the SAME position
|
||
GossipFrame.xml's own close button uses, since quest and gossip are the same "list"
|
||
window family in the real client) on the minimize-button art this engine's windows all
|
||
substitute for the real UIPanelCloseButton (that art rides the tooltip/dialog arc). -->
|
||
<Button name="QuestFrameCloseButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-42" y="-31"/></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>BenillaQuestFrameCloseButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
|
||
<!-- ══════════════════════════ Greeting panel (ref l.719-1002) ══════════════════════════ -->
|
||
<Frame name="QuestFrameGreetingPanel" inherits="QuestFramePanelTemplate" hidden="true">
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<!-- Ref QuestFrame.xml:722-733: the greeting layout has no bottom-LEFT
|
||
button, but the shared UI-QuestGreeting-BotLeft art has the button
|
||
recess BAKED IN — the ref covers it with this patch (the director's
|
||
"bottom left hole"). -->
|
||
<Texture file="Interface\QuestFrame\UI-Quest-BotLeftPatch">
|
||
<Size><AbsDimension x="128" y="64"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="22" y="68"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<Button name="QuestFrameGreetingGoodbyeButton" inherits="BenillaQuestPanelButtonTemplate" text="Goodbye">
|
||
<Size><AbsDimension x="78" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-39" y="73"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>BenillaQuestFrameGreetingGoodbyeButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<ScrollFrame name="QuestGreetingScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||
<Size><AbsDimension x="300" y="334"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="23" y="-81"/></Offset></Anchor></Anchors>
|
||
<ScrollChild>
|
||
<Frame name="QuestGreetingScrollChildFrame">
|
||
<Size><AbsDimension x="300" y="700"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="GreetingText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="270" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="10" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="CurrentQuestsText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="300" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="GreetingText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<Texture name="QuestGreetingFrameHorizontalBreak" file="Interface\QuestFrame\UI-HorizontalBreak">
|
||
<Size><AbsDimension x="256" y="32"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="GreetingText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="12" y="-10"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<FontString name="AvailableQuestsText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="300" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="GreetingText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<Button name="QuestTitleButton1" inherits="QuestTitleButtonTemplate">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="CurrentQuestsText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-10" y="-5"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="QuestTitleButton2" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton1" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton3" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton2" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton4" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton3" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton5" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton4" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton6" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton5" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton7" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton6" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton8" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton7" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton9" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton8" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
<Button name="QuestTitleButton10" inherits="QuestTitleButtonTemplate"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleButton9" relativePoint="BOTTOMLEFT"/></Anchors></Button>
|
||
</Frames>
|
||
</Frame>
|
||
</ScrollChild>
|
||
</ScrollFrame>
|
||
</Frames>
|
||
<Scripts><OnShow>BenillaQuestGreetingPanel_OnShow()</OnShow></Scripts>
|
||
</Frame>
|
||
|
||
<!-- ══════════════════════════ Detail panel (ref l.472-718) ═════════════════════════════ -->
|
||
<Frame name="QuestFrameDetailPanel" inherits="QuestFramePanelTemplate" hidden="true">
|
||
<Frames>
|
||
<Button name="QuestFrameAcceptButton" inherits="BenillaQuestPanelButtonTemplate" text="Accept">
|
||
<Size><AbsDimension x="77" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="23" y="72"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>QuestFrameAcceptButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<Button name="QuestFrameDeclineButton" inherits="BenillaQuestPanelButtonTemplate" text="Decline">
|
||
<Size><AbsDimension x="78" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-39" y="72"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>QuestFrameDeclineButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<ScrollFrame name="QuestDetailScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||
<Size><AbsDimension x="300" y="334"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="23" y="-81"/></Offset></Anchor></Anchors>
|
||
<ScrollChild>
|
||
<Frame name="QuestDetailScrollChildFrame">
|
||
<Size><AbsDimension x="300" y="700"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="QuestTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="5" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestDescription" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="270" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- Everything below the description rides ONE frame whose alpha
|
||
the write-on machinery drives (ref TextAlphaDependentFrame,
|
||
QuestFrame.xml l.553): 1.12 SetAlpha overwrite-cascades into
|
||
the child item buttons/coins (wow-re propagation.md,
|
||
CORRECTED), so the whole block hides while the text writes
|
||
and fades in as one.
|
||
|
||
**The reference's own bare name.** This was spelled
|
||
`QuestDetailTextAlphaFrame` until decision 1757, with the
|
||
citation above already naming what it should have been —
|
||
the slip 1189 describes and `BlackoutWorld` paid for: a
|
||
published global spelled to our taste is a global the
|
||
reference has and we do not, and the reference's own
|
||
QuestFrame.lua indexes this one by hand (l.543/562/564). -->
|
||
<Frame name="TextAlphaDependentFrame">
|
||
<Size><AbsDimension x="1" y="1"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestDescription" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="QuestDetailObjectiveTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="18"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestDescription" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-15"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestObjectiveText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="270" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestDetailObjectiveTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestDetailRewardTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="18"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestObjectiveText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-15"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestDetailItemChooseText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="295" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestDetailRewardTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestDetailItemReceiveText" inherits="QuestFont" justifyH="LEFT">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestDetailRewardTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="3" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- ONE pool of 10, the ref's own shape (ref l.190-239 / l.627-676): the panel packs
|
||
CHOICES, then the reward-spell row, then FIXED rewards into a single numbered
|
||
run, and positions every one of them at runtime — so each carries the ref's own
|
||
bare TOPLEFT anchor and nothing else. This replaced two static 6-deep pools
|
||
(QuestDetailChoice*/QuestDetailReward*), whose names the reference does not have and
|
||
whose split QuestFrameItems_Update could not reproduce. -->
|
||
<Button name="QuestDetailItem1" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem2" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem3" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem4" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem5" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem6" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem7" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem8" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem9" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestDetailItem10" inherits="QuestItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
|
||
<Frame name="QuestDetailMoneyFrame" inherits="MoneyFrameTemplate"><Anchors><Anchor point="LEFT" relativeTo="QuestDetailItemReceiveText" relativePoint="RIGHT"><Offset><AbsDimension x="15" y="0"/></Offset></Anchor></Anchors><Scripts><OnLoad>QuestMoneyFrame_OnLoad()</OnLoad></Scripts></Frame>
|
||
</Frames>
|
||
</Frame>
|
||
</Frames>
|
||
</Frame>
|
||
</ScrollChild>
|
||
</ScrollFrame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnShow>BenillaQuestDetailPanel_OnShow()</OnShow>
|
||
<OnUpdate>BenillaQuestDetailPanel_OnUpdate(this, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- ══════════════════════════ Progress panel (ref l.290-471) ═══════════════════════════ -->
|
||
<Frame name="QuestFrameProgressPanel" inherits="QuestFramePanelTemplate" hidden="true">
|
||
<Frames>
|
||
<Button name="QuestFrameCompleteButton" inherits="BenillaQuestPanelButtonTemplate" text="Continue">
|
||
<Size><AbsDimension x="120" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="22" y="72"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>BenillaQuestFrameCompleteButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<Button name="QuestFrameGoodbyeButton" inherits="BenillaQuestPanelButtonTemplate" text="Goodbye">
|
||
<Size><AbsDimension x="78" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-39" y="73"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>BenillaQuestFrameGoodbyeButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<ScrollFrame name="QuestProgressScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||
<Size><AbsDimension x="300" y="334"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="23" y="-81"/></Offset></Anchor></Anchors>
|
||
<ScrollChild>
|
||
<Frame name="QuestProgressScrollChildFrame">
|
||
<Size><AbsDimension x="300" y="700"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="QuestProgressTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="5" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestProgressText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="270" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestProgressTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestProgressRequiredItemsText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="295" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestProgressText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestProgressRequiredMoneyText" inherits="QuestFontNormalSmall" justifyH="LEFT">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestProgressRequiredItemsText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<Frame name="QuestProgressMoneyCoin1" inherits="BenillaQuestMoneyCoinTemplate"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressRequiredMoneyText" relativePoint="RIGHT"><Offset><AbsDimension x="10" y="0"/></Offset></Anchor></Anchors></Frame>
|
||
<Frame name="QuestProgressMoneyCoin2" inherits="BenillaQuestMoneyCoinTemplate"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressMoneyCoin1" relativePoint="RIGHT"><Offset><AbsDimension x="4" y="0"/></Offset></Anchor></Anchors></Frame>
|
||
<Frame name="QuestProgressMoneyCoin3" inherits="BenillaQuestMoneyCoinTemplate"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressMoneyCoin2" relativePoint="RIGHT"><Offset><AbsDimension x="4" y="0"/></Offset></Anchor></Anchors></Frame>
|
||
|
||
<!-- The 2-col×3-row grid (ref l.407-460): item1 is Lua-repositioned
|
||
(money-line vs header-line); items 2-6 are a STATIC chain off
|
||
1/3/5 the resolver's fixpoint re-propagates automatically. -->
|
||
<Button name="QuestProgressItem1" inherits="QuestItemTemplate" id="1"><Anchors><Anchor point="TOPLEFT" relativeTo="QuestProgressRequiredItemsText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="-3" y="-5"/></Offset></Anchor></Anchors></Button>
|
||
<Button name="QuestProgressItem2" inherits="QuestItemTemplate" id="2"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressItem1" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor></Anchors></Button>
|
||
<Button name="QuestProgressItem3" inherits="QuestItemTemplate" id="3"><Anchors><Anchor point="TOP" relativeTo="QuestProgressItem1" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor></Anchors></Button>
|
||
<Button name="QuestProgressItem4" inherits="QuestItemTemplate" id="4"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressItem3" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor></Anchors></Button>
|
||
<Button name="QuestProgressItem5" inherits="QuestItemTemplate" id="5"><Anchors><Anchor point="TOP" relativeTo="QuestProgressItem3" relativePoint="BOTTOM"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor></Anchors></Button>
|
||
<Button name="QuestProgressItem6" inherits="QuestItemTemplate" id="6"><Anchors><Anchor point="LEFT" relativeTo="QuestProgressItem5" relativePoint="RIGHT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor></Anchors></Button>
|
||
</Frames>
|
||
</Frame>
|
||
</ScrollChild>
|
||
</ScrollFrame>
|
||
</Frames>
|
||
<Scripts><OnShow>BenillaQuestProgressPanel_OnShow()</OnShow></Scripts>
|
||
</Frame>
|
||
|
||
<!-- ══════════════════════════ Reward panel (ref l.71-289) ══════════════════════════════ -->
|
||
<Frame name="QuestFrameRewardPanel" inherits="QuestFramePanelTemplate" hidden="true">
|
||
<Frames>
|
||
<Button name="QuestFrameCompleteQuestButton" inherits="BenillaQuestPanelButtonTemplate" text="Complete Quest">
|
||
<Size><AbsDimension x="120" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="22" y="72"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>QuestFrameCompleteQuestButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<Button name="QuestFrameCancelButton" inherits="BenillaQuestPanelButtonTemplate" text="Cancel">
|
||
<Size><AbsDimension x="78" y="22"/></Size>
|
||
<Anchors><Anchor point="BOTTOMRIGHT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="-39" y="73"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnClick>QuestFrameCancelButton_OnClick()</OnClick></Scripts>
|
||
</Button>
|
||
<ScrollFrame name="QuestRewardScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||
<Size><AbsDimension x="300" y="334"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="23" y="-81"/></Offset></Anchor></Anchors>
|
||
<ScrollChild>
|
||
<Frame name="QuestRewardScrollChildFrame">
|
||
<Size><AbsDimension x="300" y="700"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString name="QuestRewardTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="5" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestRewardText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="275" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestRewardTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestRewardRewardTitleText" inherits="QuestTitleFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="285" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestRewardText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestRewardItemChooseText" inherits="QuestFont" justifyH="LEFT">
|
||
<Size><AbsDimension x="295" y="0"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestRewardRewardTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="QuestRewardItemReceiveText" inherits="QuestFont" justifyH="LEFT">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestRewardRewardTitleText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-5"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- ONE pool of 10, the ref's own shape (ref l.190-239 / l.627-676): the panel packs
|
||
CHOICES, then the reward-spell row, then FIXED rewards into a single numbered
|
||
run, and positions every one of them at runtime — so each carries the ref's own
|
||
bare TOPLEFT anchor and nothing else. This replaced two static 6-deep pools
|
||
(QuestRewardChoice*/QuestRewardReward*), whose names the reference does not have and
|
||
whose split QuestFrameItems_Update could not reproduce. -->
|
||
<Button name="QuestRewardItem1" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem2" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem3" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem4" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem5" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem6" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem7" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem8" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem9" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
<Button name="QuestRewardItem10" inherits="QuestRewardItemTemplate"><Anchors><Anchor point="TOPLEFT"/></Anchors></Button>
|
||
|
||
<Frame name="QuestRewardMoneyFrame" inherits="MoneyFrameTemplate"><Anchors><Anchor point="LEFT" relativeTo="QuestRewardItemReceiveText" relativePoint="RIGHT"><Offset><AbsDimension x="15" y="0"/></Offset></Anchor></Anchors><Scripts><OnLoad>QuestMoneyFrame_OnLoad()</OnLoad></Scripts></Frame>
|
||
|
||
<!-- The choice-selection glow (moved onto the clicked choice
|
||
row; ref QuestRewardItemHighlight, QuestFrame.xml:254-278
|
||
VERBATIM: the 256x64 UI-QuestItemHighlight ADD card, one
|
||
frame level above the rows). -->
|
||
<Frame name="QuestRewardItemHighlight" hidden="true" frameLevel="3">
|
||
<Size><AbsDimension x="256" y="64"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
<Layers><Layer level="BACKGROUND">
|
||
<Texture file="Interface\QuestFrame\UI-QuestItemHighlight" alphaMode="ADD">
|
||
<Size><AbsDimension x="256" y="64"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
</Layer></Layers>
|
||
</Frame>
|
||
</Frames>
|
||
</Frame>
|
||
</ScrollChild>
|
||
</ScrollFrame>
|
||
</Frames>
|
||
<Scripts><OnShow>BenillaQuestRewardPanel_OnShow()</OnShow></Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>QuestFrame_OnLoad()</OnLoad>
|
||
<OnEvent>QuestFrame_OnEvent(event)</OnEvent>
|
||
<OnUpdate>BenillaQuestFrame_OnUpdate()</OnUpdate>
|
||
<!-- OnShow/OnHide, quoted from the real QuestFrame.lua QuestFrame_OnShow/OnHide (kits
|
||
igQuestListOpen l.285 / igQuestListClose l.294, wired via QuestFrame.xml l.1012/1015).
|
||
Same pair as gossip — the questgiver and gossip panels are the same "list" surface.
|
||
Load-bearing: CloseQuest() on hide (the real QuestFrame_OnHide) ends the giver session
|
||
whenever the frame hides, INCLUDING when another NPC window displaces it at the UIPanel
|
||
slot (SetLeftFrame → oldFrame:Hide() → OnHide); without it the QuestGiver resource
|
||
stayed set after a vendor/gossip window replaced the panel (decision 0095). No-packet
|
||
client-side clear; idempotent with the close/decline buttons, which also call it.
|
||
Never fires at load (hidden="true"). Also hides all four child panels (ref l.289-292)
|
||
so a re-open always starts from a clean panel state. -->
|
||
<OnShow>PlaySound("igQuestListOpen")</OnShow>
|
||
<OnHide>
|
||
getglobal("QuestFrameGreetingPanel"):Hide()
|
||
getglobal("QuestFrameDetailPanel"):Hide()
|
||
getglobal("QuestFrameProgressPanel"):Hide()
|
||
getglobal("QuestFrameRewardPanel"):Hide()
|
||
CloseQuest()
|
||
PlaySound("igQuestListClose")
|
||
</OnHide>
|
||
</Scripts>
|
||
</Frame>
|
||
</Ui>
|