- 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>
319 lines
20 KiB
XML
319 lines
20 KiB
XML
<Ui>
|
||
<!--
|
||
The dressing room (decision 1060) — ref `DressUpFrame.xml` / `DressUpFrame.lua`, quoted.
|
||
CTRL-left-click an item anywhere (bags, the paper doll, a chat link, the bank) and it lands
|
||
on your own character here, over the gear you are actually wearing. The window's own
|
||
instruction line says exactly that, in Blizzard's words:
|
||
`DRESSUP_FRAME_INSTRUCTIONS` = "CTRL-Left Click additional items to display them on your
|
||
character" (ref-GlobalStrings.lua:944) — which is also where the modifier is settled: CTRL
|
||
previews, SHIFT posts the link to chat (`ContainerFrame.lua:565-571`).
|
||
|
||
THE MODEL PANE is a booth-texture stand-in, not the ref's live `<DressUpModel>` widget —
|
||
the settled doctrine (0105/0118) and exactly what the character window's own pane does
|
||
(`CharacterFrame.xml`'s header). So the ref's three model METHODS have no widget to live on
|
||
and become the engine globals `BenillaDressUpModel_Dress/TryOn/Close/SetFacing`
|
||
(`benilla-ui/src/script/dressup.rs` has the why); `DressUpItem`/`DressUpItemLink` keep their
|
||
real global names, because every ctrl-click site in the UI calls those.
|
||
|
||
Departures, each named:
|
||
- No drag (the ref is `movable` with StartMoving/StopMovingOrSizing): benilla has no
|
||
user-moved-frame affordance yet — the window sits in the left UIPanel slot, which the ref
|
||
registers it into too (`UIParent.lua:41`, transcribed in UiPanels.xml).
|
||
- `DressUpModel:SetUnit("player")` and `:Dress()` are ONE verb here
|
||
(`BenillaDressUpModel_Dress`): our model is always the player's, so "point it at the
|
||
player" and "put the player's own gear back on it" are the same effect.
|
||
- The ref's `scale="2.0"` on the model widget is a 3D-widget zoom with no meaning for a
|
||
baked pane — the booth frames the body from its own bounds (`framing::body_frame`), the
|
||
same law the paper doll is framed by. The bake is framed at THIS pane's 316×351 aspect,
|
||
not square, or the UI's stretch would leave every character 11% too tall (decision 1069).
|
||
- The pane ANIMATES, as the ref's live widget does — Stand looping (decision 1069; the look
|
||
call 0822 §5 left open, made by the director). Its booth is TRANSPARENT for the same
|
||
reason a widget is: the dark room behind the character is the `DressUpBackground-<Race>`
|
||
art below, and Reset/Close sit on that art *inside* this pane's rect (both anchor sets
|
||
transcribed byte-identically from the ref, which is why the overlap is the ref's too).
|
||
-->
|
||
<Script><![CDATA[
|
||
-- GlobalStrings this window uses (ref-GlobalStrings.lua, cited per line; the
|
||
-- `X = X or "..."` idiom is this codebase's convention — CharacterFrame.xml/InspectFrame.xml).
|
||
DRESSUP_FRAME = DRESSUP_FRAME or "Dressing Room" -- :943
|
||
DRESSUP_FRAME_INSTRUCTIONS = DRESSUP_FRAME_INSTRUCTIONS
|
||
or "CTRL-Left Click additional items to display them on your character" -- :944
|
||
RESET = RESET or "Reset" -- :3340
|
||
CLOSE = CLOSE or "Close" -- :760
|
||
|
||
-- ref DressUpFrame.lua:2-8. The `not IsVisible()` gate is the reference's own state reset:
|
||
-- opening the room fresh re-dresses the model in the player's real gear, and only then
|
||
-- tries the clicked item on. Both halves ride ONE ordered intent queue app-side, so the
|
||
-- reset can never overtake the try-on (dressup.rs's module doc).
|
||
function DressUpItem(item)
|
||
if not DressUpFrame:IsVisible() then
|
||
ShowUIPanel(DressUpFrame)
|
||
BenillaDressUpModel_Dress() -- ref: DressUpModel:SetUnit("player")
|
||
end
|
||
BenillaDressUpModel_TryOn(item) -- ref: DressUpModel:TryOn(item)
|
||
end
|
||
|
||
-- ref DressUpFrame.lua:10-16, verbatim: pull the bare item id out of the `|Hitem:<id>:…`
|
||
-- payload and hand THAT to TryOn. Every ctrl-click site in the UI calls this one function,
|
||
-- which is why it keeps the reference's global name.
|
||
function DressUpItemLink(link)
|
||
if not link then
|
||
return
|
||
end
|
||
local item = gsub(link, ".*item:(%d+).*", "%1", 1)
|
||
DressUpItem(tonumber(item))
|
||
end
|
||
|
||
-- ref DressUpFrame.lua:18-32 including its own "-- HACK!!!" comment: gnomes borrow the
|
||
-- dwarf backdrop and trolls the orc one (there is no Gnome/Troll art), and an unknown race
|
||
-- falls back to Orc. Quoted, not corrected.
|
||
function DressUpTexturePath()
|
||
local race, fileName = UnitRace("player")
|
||
if fileName == "Gnome" or fileName == "GNOME" then
|
||
fileName = "Dwarf"
|
||
elseif fileName == "Troll" or fileName == "TROLL" then
|
||
fileName = "Orc"
|
||
end
|
||
if not fileName then
|
||
fileName = "Orc"
|
||
end
|
||
return "Interface\\DressUpFrame\\DressUpBackground-" .. fileName
|
||
end
|
||
|
||
-- ref DressUpFrame.lua:34-40. Called on OnShow as well as OnLoad: at load time the app has
|
||
-- usually not pushed the player's unit snapshot yet, so `UnitRace` answers nil and the ref's
|
||
-- own fallback would freeze an Orc backdrop onto every character (the same one-tick nil the
|
||
-- character window's level line documents).
|
||
function SetDressUpBackground()
|
||
local texture = DressUpTexturePath()
|
||
DressUpBackgroundTopLeft:SetTexture(texture .. 1)
|
||
DressUpBackgroundTopRight:SetTexture(texture .. 2)
|
||
DressUpBackgroundBotLeft:SetTexture(texture .. 3)
|
||
DressUpBackgroundBotRight:SetTexture(texture .. 4)
|
||
end
|
||
|
||
-- The pane's facing — the paper doll's pair of handlers, over this room's own booth yaw
|
||
-- (ref Model_OnLoad/Model_RotateLeft/Model_RotateRight/Model_OnUpdate, UIParent.lua:1421-1462;
|
||
-- CharacterFrame.xml carries the full note on the ref's sign quirk, quoted here too).
|
||
function BenillaDressUpModel_OnLoad(frame)
|
||
frame.facing = 0.61 -- ref UIParent.lua:1422, the literal default facing
|
||
BenillaDressUpModel_SetFacing(frame.facing)
|
||
end
|
||
|
||
function BenillaDressUpModel_RotateLeft(frame)
|
||
frame.facing = frame.facing - 0.03
|
||
BenillaDressUpModel_SetFacing(frame.facing)
|
||
PlaySound("igInventoryRotateCharacter")
|
||
end
|
||
|
||
function BenillaDressUpModel_RotateRight(frame)
|
||
frame.facing = frame.facing + 0.03
|
||
BenillaDressUpModel_SetFacing(frame.facing)
|
||
PlaySound("igInventoryRotateCharacter")
|
||
end
|
||
|
||
-- The held-button spin (ref Model_OnUpdate) — half a turn per second while a rotate button
|
||
-- reads PUSHED, the ref's own opposite-sign held branches included.
|
||
function BenillaDressUpModel_OnUpdate(frame, elapsed)
|
||
local step = elapsed * 2 * PI * ROTATIONS_PER_SECOND
|
||
if getglobal(frame:GetName() .. "RotateLeftButton"):GetButtonState() == "PUSHED" then
|
||
frame.facing = frame.facing + step
|
||
if frame.facing < 0 then
|
||
frame.facing = frame.facing + (2 * PI)
|
||
end
|
||
BenillaDressUpModel_SetFacing(frame.facing)
|
||
end
|
||
if getglobal(frame:GetName() .. "RotateRightButton"):GetButtonState() == "PUSHED" then
|
||
frame.facing = frame.facing - step
|
||
if frame.facing > (2 * PI) then
|
||
frame.facing = frame.facing - (2 * PI)
|
||
end
|
||
BenillaDressUpModel_SetFacing(frame.facing)
|
||
end
|
||
end
|
||
]]></Script>
|
||
|
||
<!-- A panel action button (Reset/Close): the ref's UIPanelButtonTemplate face, locally
|
||
reconstructed — this house dialect ships no such template, and each window keeps its own
|
||
copy (CraftFrame.xml's identical note). -->
|
||
<Button name="BenillaDressUpPanelButtonTemplate" virtual="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>
|
||
|
||
<Frame name="DressUpFrame" enableMouse="true" parent="UIParent" toplevel="true" hidden="true">
|
||
<!-- The ref's 384×512 window. No <Anchors>: ShowUIPanel seats it in the left slot, this
|
||
house's convention for every panel window (MerchantFrame.xml/CraftFrame.xml). -->
|
||
<Size><AbsDimension x="384" y="512"/></Size>
|
||
<HitRectInsets><AbsInset left="0" right="30" top="0" bottom="45"/></HitRectInsets>
|
||
<Layers>
|
||
<!-- The "player" portrait, 60×60 at TOPLEFT (7,-6) (ref l.20-33) — BACKGROUND so the
|
||
window art's ring frames it; bound in OnShow, like every other portrait here. -->
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="DressUpFramePortrait">
|
||
<Size><AbsDimension x="60" y="60"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="7" y="-6"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<!-- The window art: the general-panel top pair + the skill-frame bottom pair, the ref's
|
||
own four slabs (l.34-72). -->
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\PaperDollInfoFrame\UI-Character-General-TopLeft">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\PaperDollInfoFrame\UI-Character-General-TopRight">
|
||
<Size><AbsDimension x="128" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="256" y="0"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\PaperDollInfoFrame\SkillFrame-BotLeft">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-256"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\PaperDollInfoFrame\SkillFrame-BotRight">
|
||
<Size><AbsDimension x="128" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="256" y="-256"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<FontString name="DressUpFrameTitleText" inherits="GameFontHighlight" text="DRESSUP_FRAME">
|
||
<Size><AbsDimension x="300" y="14"/></Size>
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-17"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="DressUpFrameDescriptionText" inherits="GameFontNormalSmall" text="DRESSUP_FRAME_INSTRUCTIONS">
|
||
<Size><AbsDimension x="260" y="36"/></Size>
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativeTo="DressUpFrameTitleText" relativePoint="BOTTOM"><Offset><AbsDimension x="10" y="-22"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
<!-- The race backdrop behind the model, four quadrants (ref l.73-118); the files are
|
||
chosen per race by SetDressUpBackground above. -->
|
||
<Layer level="OVERLAY">
|
||
<Texture name="DressUpBackgroundTopLeft">
|
||
<Size><AbsDimension x="256" y="255"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="22" y="-76"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture name="DressUpBackgroundTopRight">
|
||
<Size><AbsDimension x="62" y="255"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="DressUpBackgroundTopLeft" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="DressUpBackgroundBotLeft">
|
||
<Size><AbsDimension x="256" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="DressUpBackgroundTopLeft" relativePoint="BOTTOMLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="DressUpBackgroundBotRight">
|
||
<Size><AbsDimension x="62" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="DressUpBackgroundTopLeft" relativePoint="BOTTOMRIGHT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- The corner close X: the ref's UIPanelCloseButton seat (CENTER of TOPRIGHT, -46,-25 —
|
||
ref l.120-127) on the minimize-button art every close button in this house uses. -->
|
||
<Button name="DressUpFrameCloseButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-46" y="-25"/></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>HideUIPanel(DressUpFrame)</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
<!-- Close (ref l.128-146) and Reset (l.147-165, chained off Close's LEFT). Reset is the
|
||
ref's `DressUpModel:Dress()` + its gsTitleOptionOK click. -->
|
||
<Button name="DressUpFrameCancelButton" inherits="BenillaDressUpPanelButtonTemplate" text="CLOSE">
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPLEFT"><Offset><AbsDimension x="305" y="-422"/></Offset></Anchor></Anchors>
|
||
<Scripts>
|
||
<OnClick>HideUIPanel(DressUpFrame)</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
<Button name="DressUpFrameResetButton" inherits="BenillaDressUpPanelButtonTemplate" text="RESET">
|
||
<Anchors><Anchor point="RIGHT" relativeTo="DressUpFrameCancelButton" relativePoint="LEFT"/></Anchors>
|
||
<Scripts>
|
||
<OnClick>
|
||
BenillaDressUpModel_Dress()
|
||
PlaySound("gsTitleOptionOK")
|
||
</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
|
||
<!-- The model pane (ref the <DressUpModel> widget, l.166-207): 316×351 anchored BOTTOM
|
||
(-11,+85). A plain Frame sampling the "dressup" booth bake (header). -->
|
||
<Frame name="DressUpModelFrame">
|
||
<Size><AbsDimension x="316" y="351"/></Size>
|
||
<Anchors><Anchor point="BOTTOM"><Offset><AbsDimension x="-11" y="85"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<!-- BACKGROUND, not ARTWORK — the booth quad is an OPAQUE stand-in for a widget
|
||
the reference renders outside the layer batches, so it must sit as low as a
|
||
region goes or it swallows same-level siblings (decision 1070; the pet
|
||
page's diet icon is where that bit). This window is the one where the
|
||
change is visible: the CLOSE/RESET buttons are declared BEFORE the pane and
|
||
overlap its lower edge, so at ARTWORK the pane was painting over them. -->
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="$parentTexture">
|
||
<Size><AbsDimension x="316" y="351"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- Rotate buttons (ref l.183-206): 35×35 at the WINDOW's TOPLEFT (21,-75), left
|
||
then right chained off its TOPRIGHT. Both edges registered, so one tap fires
|
||
OnClick twice and holding hands the spin to the pane's OnUpdate — the ref's
|
||
own tap-and-hold (decision 0638 §3). -->
|
||
<Button name="DressUpModelFrameRotateLeftButton">
|
||
<Size><AbsDimension x="35" y="35"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="DressUpFrame" relativePoint="TOPLEFT"><Offset><AbsDimension x="21" y="-75"/></Offset></Anchor></Anchors>
|
||
<NormalTexture file="Interface\Buttons\UI-RotationLeft-Button-Up"/>
|
||
<PushedTexture file="Interface\Buttons\UI-RotationLeft-Button-Down"/>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Round" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>self:RegisterForClicks("LeftButtonDown", "LeftButtonUp")</OnLoad>
|
||
<OnClick>BenillaDressUpModel_RotateLeft(getglobal("DressUpModelFrame"))</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
<Button name="DressUpModelFrameRotateRightButton">
|
||
<Size><AbsDimension x="35" y="35"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="DressUpModelFrameRotateLeftButton" relativePoint="TOPRIGHT"/></Anchors>
|
||
<NormalTexture file="Interface\Buttons\UI-RotationRight-Button-Up"/>
|
||
<PushedTexture file="Interface\Buttons\UI-RotationRight-Button-Down"/>
|
||
<HighlightTexture file="Interface\Buttons\ButtonHilight-Round" alphaMode="ADD"/>
|
||
<Scripts>
|
||
<OnLoad>self:RegisterForClicks("LeftButtonDown", "LeftButtonUp")</OnLoad>
|
||
<OnClick>BenillaDressUpModel_RotateRight(getglobal("DressUpModelFrame"))</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>
|
||
BenillaDressUpModel_OnLoad(self)
|
||
BenillaSetBoothTexture(getglobal(self:GetName() .. "Texture"), "dressup")
|
||
</OnLoad>
|
||
<OnUpdate>BenillaDressUpModel_OnUpdate(self, arg1)</OnUpdate>
|
||
</Scripts>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>SetDressUpBackground()</OnLoad>
|
||
<OnShow>
|
||
SetDressUpBackground()
|
||
SetPortraitTexture(DressUpFramePortrait, "player")
|
||
PlaySound("igCharacterInfoOpen")
|
||
</OnShow>
|
||
<!-- Closing empties the booth (dressup.rs's `Close` intent): the ref's widget keeps its
|
||
state while hidden, but its next DressUpItem re-issues SetUnit("player") *because*
|
||
the frame wasn't visible, so that state is never observable. -->
|
||
<OnHide>
|
||
BenillaDressUpModel_Close()
|
||
PlaySound("igCharacterInfoClose")
|
||
</OnHide>
|
||
</Scripts>
|
||
</Frame>
|
||
</Ui>
|