- the select screen's ghost is four mechanisms off one roster-row bit, and the rest of them land: the FFX pass swap — the reference builds TWO pass pairs, world and glue, and a ghost row installs the glue DEATH pass over the whole diorama while the character list and buttons composite clean above it; the ghost-gated sun — the scene's light gather is wiped and one hardcoded overhead directional injected, its colours turning out to be Light.dbc's death preset (diffuse (94,153,198), ambient (26,56,85)) rather than the live capture we had parked them as, with the sign settled at the bytes (an authored light already carries one negation, so reusing that convention lights the ghost from underneath); and three glow weights corrected — the glue screens pin 0.30 login / 0.40 living select / 0.15 ghost where we rendered a flat 0.5 everywhere, so login and create get slightly less glow too, a fidelity correction to a value we had never verified - a press brings its window to the front: the mouse-DOWN handler raises the capture-or-hover frame unguarded, the toplevel gate living inside the worker — which is what makes a click on a child raise the window that owns it — and the release never raises; behind it, a frame-by-frame diff against the reference put back what the transcription dropped: toplevel on 47 frames (without it every raise trigger was a silent no-op across the whole interface), the mouse on 16 window bodies (a click on the bank's or merchant's own background was turning the camera or dropping your target), and id= on 81 frames — the slot index a 1.12 addon reads, where GetID() answered 0; a new gate reads our flags off the LOADED engine against the reference's, both directions with a reason each, so the next drift can't hide behind renamed templates - the jump stops being frame-rate dependent: the fall step becomes the reference's closed form (the mean of the endpoint velocities is the exact displacement rate, and both our movers had the error in opposite directions), taking the apex from 1.668 yd at 144 fps and 1.844 at 20 to a flat 1.640 against the analytic 1.640 — a live run apexed at 1.6410; and the knockback's freeze is its PLANTED direction bit, not a velocity test — air control opens exactly while the direction nibble is clear, the launch plants forward whatever its speed, and the bit now rides the wire, which we had never sent at all - the walk-away leash belongs to the OBJECT: the reference's watchdog overwrites the opener's stored range on the player typemask bit alone with (10+4)², so a player-shared quest panel is leashed at 14 yards — not at the 5.56-yard NPC reach, and not never, as two earlier readings had it — while a census of all 14 arming sites confirms every other NPC window already closed at the right distance; the walk-away also sends strictly LESS than the button: an NPC panel closes silently while a share still owes its decline Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
104 lines
6.4 KiB
XML
104 lines
6.4 KiB
XML
<Ui>
|
||
<!--
|
||
The real client's UIErrorsFrame, now declared as what it actually IS: a
|
||
`<MessageFrame>` (ref UIErrorsFrame.xml:4 — 512×60 at TOP (0,-122), displayDuration="5",
|
||
insertMode="TOP", with `<FontString inherits="ErrorFont" justifyH="CENTER"/>` as its line
|
||
font). UI_INFO_MESSAGE shows YELLOW (1,1,0) — the quest objective-progress toasts land
|
||
here — and UI_ERROR_MESSAGE red (1,0.1,0.1), the ref handler verbatim (UIErrorsFrame.lua:8-16;
|
||
its SYSMSG arm is unwired, no engine producer yet).
|
||
|
||
It used to be a hand-rolled `<Frame>` painting three stacked FontStrings from Lua, because
|
||
this engine had no MessageFrame widget. It has one now (`script::messageframe::plain`,
|
||
`widget::MessageFrameState`), so the file that stood in for it is gone and the display —
|
||
insertMode, the vertical cap, the two-phase fade — is the widget's own, exactly as in the
|
||
reference. Two consequences worth naming:
|
||
|
||
* `UIErrorsFrame:AddMessage(text, r, g, b, a)` is REAL now, so FrameXML producers call it
|
||
the way the reference does (the old `BenillaErrorsFrame_AddMessage` seam is retired),
|
||
and so does an addon: `EasyCopy`, `QuestHistory` and `QuestItem` each died on that exact
|
||
line at load. A sixth argument (all three pass one, believing it is a hold time) is
|
||
silently IGNORED — the real binding reads five, and honouring it would be unfaithful.
|
||
* The post-hold fade is the class ctor's 3.0 s (msgframe-runtime.md, byte-verified), not
|
||
the 1.0 s this file used to carry as an explicitly INTERIM guess while that curve was
|
||
unpinned. The 5 s hold is unchanged.
|
||
|
||
frameStrata HIGH is the ref's own (`UIErrorsFrame.xml:4`) and decision 0597's: this frame
|
||
overlaps the right edge of every left-slot panel window (character, quest log, loot,
|
||
merchant, mail, trainer, taxi — all at TOPLEFT (0,-104)), so in the default MEDIUM its
|
||
toasts draw UNDER whichever panel is open, invisible in exactly the state you most want to
|
||
read them. The ref also carries toplevel="true"; that is deliberately not transcribed —
|
||
HIGH already wins the strata and 0597's fix is the one that was looked at.
|
||
-->
|
||
<Script><![CDATA[
|
||
function UIErrorsFrame_OnLoad()
|
||
this:RegisterEvent("UI_INFO_MESSAGE")
|
||
this:RegisterEvent("UI_ERROR_MESSAGE")
|
||
end
|
||
|
||
-- ref UIErrorsFrame_OnEvent(event, message) (UIErrorsFrame.lua:8-15) — the message is the
|
||
-- DECLARED second parameter, not the `arg1` global: the XML passes `arg1` into it exactly
|
||
-- as the reference's own does, and an addon calling the 1.12 arity is then read correctly.
|
||
function UIErrorsFrame_OnEvent(event, message)
|
||
if not message then return end
|
||
if event == "UI_INFO_MESSAGE" then
|
||
this:AddMessage(message, 1.0, 1.0, 0.0, 1.0) -- ref UIErrorsFrame.lua:12
|
||
elseif event == "UI_ERROR_MESSAGE" then
|
||
this:AddMessage(message, 1.0, 0.1, 0.1, 1.0) -- ref UIErrorsFrame.lua:14
|
||
end
|
||
end
|
||
]]></Script>
|
||
|
||
<MessageFrame name="UIErrorsFrame" toplevel="true" parent="UIParent" displayDuration="5" insertMode="TOP" frameStrata="HIGH">
|
||
<Size><AbsDimension x="512" y="60"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOP" relativePoint="TOP">
|
||
<Offset><AbsDimension x="0" y="-122"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<Scripts>
|
||
<OnLoad>UIErrorsFrame_OnLoad()</OnLoad>
|
||
<OnEvent>UIErrorsFrame_OnEvent(event, arg1)</OnEvent>
|
||
</Scripts>
|
||
<!-- The line font AND the centring, both: the class draws its messages through this
|
||
declared child, so `justifyH="CENTER"` is what keeps the toasts centred in the 512-wide
|
||
box (a chat frame's own child says LEFT). ErrorFont = GameFontNormalLarge (ref
|
||
Fonts.xml:258), which is the face the hand-rolled version used too. -->
|
||
<FontString inherits="ErrorFont" justifyH="CENTER"/>
|
||
</MessageFrame>
|
||
|
||
<!-- RaidWarningFrame (ref RaidWarning.xml:4-24), declared here beside the frame it anchors to.
|
||
|
||
Two corpus addons push into it directly — `Participant/RaidWarn.lua:133` and
|
||
`oRA2/RaidWarn.lua:133` are the same code in two distributions, plus their MainTank.lua's
|
||
"Tank %s has died!" — and both call
|
||
`RaidWarningFrame:AddMessage(text, r, g, b, 1.0, UIERRORS_HOLD_TIME)`. That is the plain
|
||
MessageFrame arity we already ship: the 6th argument is read and DROPPED, because the
|
||
reference's own `0x795590` reads five and stops (messageframe/plain.rs's first law).
|
||
Absent, that line is `attempt to index global` and takes the handler with it.
|
||
(`BigWigs` also names it — in a LOCALISATION STRING, "Suppressing RaidWarningFrame". Not a
|
||
use; 1207.)
|
||
|
||
Geometry quoted: 512x40, insertMode TOP, HIGH + toplevel, TOP anchored to UIErrorsFrame's
|
||
BOTTOM at (0,-10), and the direct-child FontString the class draws its lines through —
|
||
GameFontNormalHuge, CENTER, exactly as the sibling above takes ErrorFont.
|
||
|
||
**No <Scripts>, deliberately.** The reference's OnLoad/OnEvent call into RaidWarning.lua to
|
||
register CHAT_MSG_RAID_WARNING and route it here. We already deliver that chat type through
|
||
`ui_chat::feed`, so wiring a second consumer would print every raid warning TWICE; and
|
||
declaring handlers whose functions we do not ship would raise at load. The frame exists and
|
||
accepts messages, which is what the corpus asks of it — the automatic routing is the
|
||
ChatFrame_OnEvent architecture question, not this frame's.
|
||
|
||
RaidBossEmoteFrame, its sibling in the same file, is NOT declared: zero corpus addons name
|
||
it, and a shadowed name with no caller is building against a guess (1222's rejected clause). -->
|
||
<MessageFrame name="RaidWarningFrame" parent="UIParent" insertMode="TOP" frameStrata="HIGH" toplevel="true">
|
||
<Size><AbsDimension x="512" y="40"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOP" relativeTo="UIErrorsFrame" relativePoint="BOTTOM">
|
||
<Offset><AbsDimension x="0" y="-10"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<FontString inherits="GameFontNormalHuge" justifyH="CENTER"/>
|
||
</MessageFrame>
|
||
</Ui>
|