- a 40-man raid cost +5 to +8 ms of CPU per frame — a population, not a hot function — and three cuts landed where it was measured: the rig palette upload sends one `write_buffer` per run, bridging the gaps parked bodies leave between live rigs (calls 93 → 3); a built material becomes an asset when something visible binds it, not when a spawner builds it — 9.9k material assets were alive for 36 drawn batches, so a material is realized only once bound and visible, readers that clone before binding doing it themselves through one new function in the engine's wall (172 → 173): a 17× cut in live GPU objects; and a body's batches spawn as material groups — a geared body stood as 12–27 mesh parts, its skin composite drawn as five separate batches, and two visible batches now join when nothing downstream can tell them apart: parts per body 17 → 12, the Stormwind raid leg 17.0–21.0 → 15.65–15.82 `cpu_ms` (1929, 1940) - the instruments that priced it, all on the probe line: wgpu's own resource census, because a sampled profile put roughly half of the pass encoder in usage trackers sized to the device's live buffer and texture counts — a term that scales with residency, not with what is drawn, and nothing printed the number; the active camera count, since every view is its own pass set; the UI's live texture-identity runs, one 2D draw each, which is the number a UI change moves, not the quad count; and parts and materials per dressed body on the dress census, the ceiling on merging a body's batches read off a real body instead of guessed from a model's batch table (1940) - the coin kit retires: every remaining money display — quest progress, the mail purse and postage, the trade recipient, the tooltip, the quest log, the trainer's purse and cost — moves onto the reference's `MoneyFrameTemplate`, each seat already matching ours; the progress panel's required-money flow is ported in full — `QuestFrame.lua:168-190` colours the FRAME red/white AND the LABEL black/dark-grey when the quest costs more than you hold, where ours had neither colour; the mail postage takes the reference's name and label, trade and mail issue no explicit update because the frames repaint on their own events, and the trainer's cost label is shown or hidden with its `local COSTS_LABEL` shadow deleted; with the trainer converted the hand-built coin trios have no consumer, so their templates and the `BenillaMoney_*` helpers are deleted and `MoneyFrame.xml` is the only money kit (1937) - the crowd-control ladder's aura exemption exists, and it is a join between two `Spell.dbc` records — each arm asks whether the spell being cast is itself an immunity covering the aura that blocks it (Ice Block cast while stunned), the school arm shifting because `School` is an index and `EffectMiscValue` a mask; what the scan mostly decides is WHICH message a refusal carries — a blocking aura the cast does not counter renames the reason to "Can't do that while %s" (1941); bevy_audio leaves the build — its plugin had been disabled since 0530, but disabling a plugin does not remove a crate, and rodio, a second cpal and an Ogg/Vorbis decoder were still linked into a client that mixes through kira (1932); and cpal has four stream errors, not two — a routine ALSA underrun was treated as "the device is gone", tearing the stream down on every hiccup; now only a lost or invalidated device rebuilds (1939) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1367 lines
97 KiB
XML
1367 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", "QuestProgressRequiredMoneyFrame" }
|
||
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")
|
||
-- ref QuestFrame.lua:168-190, ported in full (1937): the money frame paints from
|
||
-- GetQuestMoneyToGet(); BOTH colours branch on whether the purse covers it — the frame
|
||
-- red/white and the LABEL black/dark-grey; the label and frame are Shown/Hidden rather
|
||
-- than blanked (the label's text is the XML's REQUIRED_MONEY); and the first required
|
||
-- item re-anchors to whichever text is showing.
|
||
local moneyFrame = getglobal("QuestProgressRequiredMoneyFrame")
|
||
if numItems > 0 or (money and money > 0) then
|
||
reqText:Show()
|
||
if money and money > 0 then
|
||
MoneyFrame_Update("QuestProgressRequiredMoneyFrame", money)
|
||
if money > GetMoney() then
|
||
moneyText:SetTextColor(0, 0, 0)
|
||
SetMoneyFrameColor("QuestProgressRequiredMoneyFrame", 1.0, 0.1, 0.1)
|
||
else
|
||
moneyText:SetTextColor(0.2, 0.2, 0.2)
|
||
SetMoneyFrameColor("QuestProgressRequiredMoneyFrame", 1.0, 1.0, 1.0)
|
||
end
|
||
moneyText:Show()
|
||
moneyFrame:Show()
|
||
item1:SetPoint("TOPLEFT", moneyText, "BOTTOMLEFT", 0, -10)
|
||
else
|
||
moneyText:Hide()
|
||
moneyFrame:Hide()
|
||
item1:SetPoint("TOPLEFT", reqText, "BOTTOMLEFT", -3, -5)
|
||
end
|
||
else
|
||
reqText:Hide()
|
||
moneyText:Hide()
|
||
moneyFrame:Hide()
|
||
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>
|
||
|
||
<!-- 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" text="REQUIRED_MONEY" justifyH="LEFT">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="QuestProgressRequiredItemsText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- ref QuestFrame.xml:392-406: the REQUIRED-money frame — money the player hands over, a
|
||
different flow from the two reward seats 1928 converted, with its own colour and anchor
|
||
rules in QuestFrameProgressItems_Update. Same LEFT->text RIGHT (10,0) seat (1937). -->
|
||
<Frame name="QuestProgressRequiredMoneyFrame" inherits="MoneyFrameTemplate">
|
||
<Anchors><Anchor point="LEFT" relativeTo="QuestProgressRequiredMoneyText" relativePoint="RIGHT"><Offset><AbsDimension x="10" y="0"/></Offset></Anchor></Anchors>
|
||
<Scripts><OnLoad>SmallMoneyFrame_OnLoad(); MoneyFrame_SetType("STATIC");</OnLoad></Scripts>
|
||
</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>
|