Files
benilla-octo/crates/benilla-app/assets/ui/ComboFrame.xml
T
SamandClaude Fable 5 d1140829d7 the interface code is ours: the transcription debt is paid
- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that
- the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down
- a lost session ends at the login screen instead of silently re-authenticating and stealing the account back
- a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars

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

200 lines
9.9 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Ui>
<!--
The combo-point dots (decision 0869) — our implementation of the behaviour the reference's
`FrameXML/ComboFrame.xml` + `ComboFrame.lua` specify, on our frames and driven by our
`PLAYER_COMBO_POINTS` feed. The Lua below is our own; what IS quoted, deliberately, is the
published surface and the measurements: the global function and constant names addons call,
and every number — offsets, sizes, TexCoords and the five fade durations are the reference's
own, because they are facts about how the real interface looks and moves, not choices.
ONE `Interface\ComboFrame\ComboPoint` sheet holds all three layers, split by TexCoords: the
dim socket (0 .. 0.375), the lit highlight (0.375 .. 0.5625) and the additive shine
(0.5625 .. 1). A point that comes up fades its highlight in, and the highlight's completion
hands off to the shine's fade-in → fade-out — the reference's two-hop `finishedFunc` chain,
which our `UIFrameFade` (UiPanels.xml) implements in full.
NO CLASS TEST HERE, and none is missing: this file gates on `GetComboPoints() > 0` and
nothing else because the reference does, and `0x51a190` carries both real gates itself —
rogue-or-druid (`cmp al,4 / cmp al,0xb`), and the points must be banked on the CURRENT
target. So a *warrior* never lights a dot even though the server really does bank them a
point on a victim's dodge — that byte greys Overpower through the usable walk's leg 5 and
goes no further (§5 byte-read, decision 0875). Re-targeting empties these dots with the
count untouched, which is exactly why the reference registers PLAYER_TARGET_CHANGED.
The five dots march down-left, each anchored TOP-to-BOTTOM of the one before with a small
rightward drift — the reference's diagonal, hugging the target frame's ring.
-->
<Frame name="BenillaComboPointTemplate" virtual="true">
<Size><AbsDimension x="12" y="12"/></Size>
<Layers>
<!-- The empty socket (ref l.8-19). -->
<Layer level="BACKGROUND">
<Texture file="Interface\ComboFrame\ComboPoint">
<Size><AbsDimension x="12" y="16"/></Size>
<Anchors>
<Anchor point="TOPLEFT"/>
</Anchors>
<TexCoords left="0" right="0.375" top="0" bottom="1"/>
</Texture>
</Layer>
<!-- The lit point, faded in as the point is earned (ref l.20-34). -->
<Layer level="ARTWORK">
<Texture name="$parentHighlight" file="Interface\ComboFrame\ComboPoint">
<Size><AbsDimension x="8" y="16"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="2" y="0"/></Offset></Anchor>
</Anchors>
<TexCoords left="0.375" right="0.5625" top="0" bottom="1"/>
</Texture>
</Layer>
<!-- The additive flare, chained off the highlight's fade (ref l.35-48). -->
<Layer level="OVERLAY">
<Texture name="$parentShine" file="Interface\ComboFrame\ComboPoint" alphaMode="ADD">
<Size><AbsDimension x="14" y="16"/></Size>
<Anchors>
<Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="4"/></Offset></Anchor>
</Anchors>
<TexCoords left="0.5625" right="1" top="0" bottom="1"/>
</Texture>
</Layer>
</Layers>
</Frame>
<Frame name="ComboFrame" frameStrata="MEDIUM" toplevel="true" parent="UIParent" hidden="true" alpha="0">
<Size><AbsDimension x="256" y="32"/></Size>
<!-- ref l.56-62: TOPRIGHT of the target frame, (-44,-9). -->
<Anchors>
<Anchor point="TOPRIGHT" relativeTo="TargetFrame">
<Offset><AbsDimension x="-44" y="-9"/></Offset>
</Anchor>
</Anchors>
<Frames>
<Frame name="ComboPoint1" inherits="BenillaComboPointTemplate">
<Anchors>
<Anchor point="TOPRIGHT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
</Anchors>
</Frame>
<Frame name="ComboPoint2" inherits="BenillaComboPointTemplate">
<Anchors>
<Anchor point="TOP" relativeTo="ComboPoint1" relativePoint="BOTTOM">
<Offset><AbsDimension x="7" y="4"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="ComboPoint3" inherits="BenillaComboPointTemplate">
<Anchors>
<Anchor point="TOP" relativeTo="ComboPoint2" relativePoint="BOTTOM">
<Offset><AbsDimension x="5" y="2"/></Offset>
</Anchor>
</Anchors>
</Frame>
<Frame name="ComboPoint4" inherits="BenillaComboPointTemplate">
<Anchors>
<Anchor point="TOP" relativeTo="ComboPoint3" relativePoint="BOTTOM">
<Offset><AbsDimension x="2" y="1"/></Offset>
</Anchor>
</Anchors>
</Frame>
<!-- The fifth is the odd one out: the reference sizes it 15×18 (ref l.101-104). -->
<Frame name="ComboPoint5" inherits="BenillaComboPointTemplate">
<Size><AbsDimension x="15" y="18"/></Size>
<Anchors>
<Anchor point="TOP" relativeTo="ComboPoint4" relativePoint="BOTTOM">
<Offset><AbsDimension x="0" y="1"/></Offset>
</Anchor>
</Anchors>
</Frame>
</Frames>
<Scripts>
<OnLoad>
this:RegisterEvent("PLAYER_TARGET_CHANGED");
this:RegisterEvent("PLAYER_COMBO_POINTS");
ComboPoint1Highlight:SetAlpha(0);
ComboPoint1Shine:SetAlpha(0);
</OnLoad>
<OnEvent>
ComboPointsFrame_OnEvent();
</OnEvent>
</Scripts>
</Frame>
<Script>
<![CDATA[
-- The reference's global names, carrying the reference's measured timings: addons read
-- these by name, and the five durations are what the real interface's fades take, so both
-- halves are fixed. MAX_COMBO_POINTS lives in the ref's TargetFrame.lua; we have no such
-- file, and CombatText.xml's five-point flash reads it, so it is declared here.
MAX_COMBO_POINTS = 5;
COMBOFRAME_FADE_IN = 0.3;
COMBOFRAME_FADE_OUT = 0.5;
COMBOFRAME_HIGHLIGHT_FADE_IN = 0.4;
COMBOFRAME_SHINE_FADE_IN = 0.3;
COMBOFRAME_SHINE_FADE_OUT = 0.4;
COMBO_FRAME_LAST_NUM_POINTS = 0;
-- Dot `index`'s two animated layers: the lit point, and the additive flare over it. The
-- socket beneath them never moves, so nothing ever needs to reach for it.
local function comboPointLayers(index)
return getglobal("ComboPoint"..index.."Highlight"),
getglobal("ComboPoint"..index.."Shine");
end
-- Repaint the dots for the count `GetComboPoints` reports. Only points ABOVE the previous
-- count animate: a repaint at an unchanged count (PLAYER_TARGET_CHANGED fires one on every
-- re-select) must not re-flare dots that are already lit — which is why the count is
-- remembered across events instead of being read back off the dots.
function ComboPointsFrame_OnEvent()
local points = GetComboPoints();
if points > 0 then
if not ComboFrame:IsVisible() then
ComboFrame:Show();
UIFrameFadeIn(ComboFrame, COMBOFRAME_FADE_IN);
end
for i = 1, MAX_COMBO_POINTS do
local highlight, shine = comboPointLayers(i);
if i > points then
-- Past the count: dark at once, never animated back down.
highlight:SetAlpha(0);
shine:SetAlpha(0);
elseif i > COMBO_FRAME_LAST_NUM_POINTS then
-- Newly earned: light it, and hand the finished fade on to its flare.
UIFrameFade(highlight, {
mode = "IN",
timeToFade = COMBOFRAME_HIGHLIGHT_FADE_IN,
finishedFunc = ComboPointShineFadeIn,
finishedArg1 = shine,
});
end
end
else
-- Nothing banked. The frame goes away, so only the first dot is worth clearing:
-- the loop above blanks every dot past the count the next time one is earned.
local highlight, shine = comboPointLayers(1);
highlight:SetAlpha(0);
shine:SetAlpha(0);
ComboFrame:Hide();
end
COMBO_FRAME_LAST_NUM_POINTS = points;
end
-- Leg two of the chain, reached as the highlight finishes: flare the shine in, and book
-- leg three off ITS completion. The hand-off travels by NAME because a fade's finishedArg
-- rides on the frame's own fadeInfo, and the reference notes the same self-reference
-- problem where it does this.
function ComboPointShineFadeIn(shine)
UIFrameFade(shine, {
mode = "IN",
timeToFade = COMBOFRAME_SHINE_FADE_IN,
finishedFunc = ComboPointShineFadeOut,
finishedArg1 = shine:GetName(),
});
end
-- Leg three: the flare burns back out on its own.
function ComboPointShineFadeOut(shineName)
UIFrameFadeOut(getglobal(shineName), COMBOFRAME_SHINE_FADE_OUT);
end
]]>
</Script>
</Ui>