Files
benilla-octo/crates/benilla-app/assets/ui/ZoneText.xml
T
SamandClaude Fable 5 44ff435304 the addon arc: the AddOns folder opens
- benilla loads real 1.12 addons from Interface/AddOns — TOC, XML and Lua through one loader, with per-addon saved variables, Bindings.xml and the lifecycle events addons expect
- both AddOns screens are in: the character-select list with per-addon enable state, and the ESC menu's in-game list
- the API surface is measured, not guessed — a corpus harness runs hundreds of real 1.12 addons and ranks exactly which globals, templates and verbs they demand
- the Lua dialect is the client's own, read off the binary — 5.0 semantics with the 1.12 additions, and UI source files are bytes, not UTF-8

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 18:18:31 +07:00

341 lines
16 KiB
XML

<!--
ZoneText.xml — the zone-entry splash (decision 0287): ZoneTextFrame (the THICK-outline zone
name — nominal FontHeight 102, DRAWN at the 32px one-to-one raster cap like the real client
(wow-re fontstring-overflow.md), which is why it fits its 512-wide box on one line — + the PvP
territory line) and SubZoneTextFrame (the 26px subzone line + the FFA "PvP Area" line), faded
by the FadingFrame kit when the app fires the ZONE_CHANGED family off the player's area
(`area.rs`).
Quoted from ref-ZoneText.xml as the live 5875 patch chain ships it (patch.MPQ overrides the
interface.MPQ copy — decision 0246) — now all THREE of its frames, the third being
AutoFollowStatus (the /follow status text, and the only thing ref-ZoneText.lua actually
contains), which waited here until follow support existed and no longer does. The FadingFrame
kit (ref-FadingFrame.lua, its own TOC line right before ZoneText.xml) is inlined verbatim below
too: ZoneTextFrame/SubZoneTextFrame are its only consumers in the whole 1.12 FrameXML
(grep-verified over the extraction), so it rides with them. AutoFollowStatus is NOT one of
them — it rolls its own fade, which is why the kit stays a two-frame affair.
The subtle law worth naming (it looks like a bug and is not): SubZoneTextString — a child of
SubZoneTextFrame — anchors to regions of the *other* frame (ZoneTextString / PVPInfoTextString),
which is usually hidden when only the subzone changes. The resolver computes hidden frames'
rects all the same, so a subzone-only splash seats where it would sit *under the invisible zone
name* — the authentic lower position. ZoneTextFrame's OnEvent caches GetZoneText() silently on
plain ZONE_CHANGED and splashes only when an INDOORS/NEW_AREA event finds the zone text changed;
PvP info shows only on NEW_AREA (SetZoneText(1)).
-->
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script><![CDATA[
-- ref-GlobalStrings.lua values this file formats (the CastingBar.xml guarded idiom):
CONTESTED_TERRITORY = CONTESTED_TERRITORY or "Contested Territory";
FACTION_CONTROLLED_TERRITORY = FACTION_CONTROLLED_TERRITORY or "%s Territory"; -- Faction name
FREE_FOR_ALL_TERRITORY = FREE_FOR_ALL_TERRITORY or "PvP Area";
AUTOFOLLOWSTART = AUTOFOLLOWSTART or "Following %s.";
AUTOFOLLOWSTOP = AUTOFOLLOWSTOP or "You stop following %s.";
-- The ref's localization identity (UIParent.lua), so the AutoFollowStatus body below can
-- stay verbatim. Guarded like everything else here rather than leaning on UnitPopup.xml
-- happening to load first — a one-line helper is no place to acquire a load-order edge.
if ( not TEXT ) then
TEXT = function(s) return s end
end
-- ── ref-FadingFrame.lua, verbatim ──────────────────────────────────────────────────────
function FadingFrame_SetFadeInTime(this, time)
this.fadeInTime = time;
end
function FadingFrame_SetHoldTime(this, time)
this.holdTime = time;
end
function FadingFrame_SetFadeOutTime(this, time)
this.fadeOutTime = time;
end
function FadingFrame_OnLoad()
this.fadeInTime = 0;
this.holdTime = 0;
this.fadeOutTime = 0;
this:Hide();
end
function FadingFrame_Show()
this.startTime = GetTime();
this:Show();
end
function FadingFrame_OnUpdate()
local elapsed = GetTime() - this.startTime;
local fadeInTime = this.fadeInTime;
if ( elapsed < fadeInTime ) then
local alpha = (elapsed / fadeInTime);
this:SetAlpha(alpha);
return;
end
local holdTime = this.holdTime;
if ( elapsed < (fadeInTime + holdTime) ) then
this:SetAlpha(1.0);
return;
end
local fadeOutTime = this.fadeOutTime;
if ( elapsed < (fadeInTime + holdTime + fadeOutTime) ) then
local alpha = 1.0 - ((elapsed - holdTime - fadeInTime) / fadeOutTime);
this:SetAlpha(alpha);
return;
end
this:Hide();
end
-- ── ref-ZoneText.xml <Script>, verbatim ────────────────────────────────────────────────
ZoneFadeInDuration = 0.5;
ZoneHoldDuration = 1.0;
ZoneFadeOutDuration = 2.0;
function SetZoneText(showPVPInfo)
ZoneTextString:SetText(GetZoneText());
local pvpType, factionName, isArena = GetZonePVPInfo();
if ( pvpType == "friendly" ) then
PVPInfoTextString:SetText(format(FACTION_CONTROLLED_TERRITORY, factionName));
ZoneTextString:SetTextColor(0.1, 1.0, 0.1);
SubZoneTextString:SetTextColor(0.1, 1.0, 0.1);
PVPInfoTextString:SetTextColor(0.1, 1.0, 0.1);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
elseif ( pvpType == "hostile" ) then
PVPInfoTextString:SetText(format(FACTION_CONTROLLED_TERRITORY, factionName));
ZoneTextString:SetTextColor(1.0, 0.1, 0.1);
SubZoneTextString:SetTextColor(1.0, 0.1, 0.1);
PVPInfoTextString:SetTextColor(1.0, 0.1, 0.1);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
elseif ( pvpType == "contested" ) then
PVPInfoTextString:SetText(CONTESTED_TERRITORY);
ZoneTextString:SetTextColor(1.0, 0.7, 0);
SubZoneTextString:SetTextColor(1.0, 0.7, 0);
PVPInfoTextString:SetTextColor(1.0, 0.7, 0);
SubZoneTextString:SetPoint("TOP", "PVPInfoTextString", "BOTTOM", 0, 0);
else
PVPInfoTextString:SetText("");
ZoneTextString:SetTextColor(1.0, 0.9294, 0.7607);
SubZoneTextString:SetTextColor(1.0, 0.9294, 0.7607);
SubZoneTextString:SetPoint("TOP", "ZoneTextString", "BOTTOM", 0, 0);
end
if ( isArena ) then
PVPArenaTextString:SetText(FREE_FOR_ALL_TERRITORY);
SubZoneTextString:SetTextColor(1.0, 0.1, 0.1);
else
PVPArenaTextString:SetText("");
end
if ( not showPVPInfo ) then
PVPInfoTextString:SetText("");
SubZoneTextString:SetPoint("TOP", "ZoneTextString", "BOTTOM", 0, 0);
end
end
-- ── ref-ZoneText.lua, verbatim ─────────────────────────────────────────────────────────
-- The auto-follow status line. Note it does NOT use the FadingFrame kit above: its own
-- OnUpdate rolls a plain linear alpha fade with no fade-in and no hold, started only on
-- AUTOFOLLOW_END. BEGIN is a full reset (fadeTime cleared, alpha restored, shown), which
-- is why a follow that switches subject needs no END first.
AUTOFOLLOW_STATUS_FADETIME = 4.0;
function AutoFollowStatus_OnLoad()
this:RegisterEvent("AUTOFOLLOW_BEGIN");
this:RegisterEvent("AUTOFOLLOW_END");
this:RegisterEvent("PLAYER_ENTERING_WORLD");
end
function AutoFollowStatus_OnEvent(event)
if ( event == "AUTOFOLLOW_BEGIN" ) then
this.unit = arg1;
this.fadeTime = nil;
this:SetAlpha(1.0);
AutoFollowStatusText:SetText(format(TEXT(AUTOFOLLOWSTART),this.unit));
this:Show();
end
if ( event == "AUTOFOLLOW_END" ) then
this.fadeTime = AUTOFOLLOW_STATUS_FADETIME;
AutoFollowStatusText:SetText(format(TEXT(AUTOFOLLOWSTOP),this.unit));
this:Show();
end
if ( event == "PLAYER_ENTERING_WORLD" ) then
this:Hide();
end
end
function AutoFollowStatus_OnUpdate(elapsed)
if( this.fadeTime ) then
if( elapsed >= this.fadeTime ) then
this:Hide();
else
this.fadeTime = this.fadeTime - elapsed;
local alpha = this.fadeTime / AUTOFOLLOW_STATUS_FADETIME;
this:SetAlpha(alpha);
end
end
end
]]></Script>
<!-- These frames are shown when the current zone or subzone changes.
(ref carries toplevel="true" on both; still dropped here, but the reason has changed.
`SetToplevel` is no longer a gap — the raise law is built, `script::object::toplevel` —
and its real trigger is Show, not a click, so "click-raise is meaningless on mouse-less
splash text" was the wrong argument. What holds now: these are LOW-strata splash frames
that overlap nothing in LOW, so the occlusion gate declines. One word to re-add.) -->
<Frame name="ZoneTextFrame" parent="UIParent" frameStrata="LOW">
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="0" y="512"/>
</Offset>
</Anchor>
</Anchors>
<Size>
<AbsDimension x="128" y="128"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="ZoneTextString" inherits="ZoneTextFont">
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
</FontString>
<FontString name="PVPInfoTextString" inherits="SubZoneTextFont">
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="ZoneTextString" relativePoint="BOTTOM"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
FadingFrame_OnLoad();
FadingFrame_SetFadeInTime(this, ZoneFadeInDuration);
FadingFrame_SetHoldTime(this, ZoneHoldDuration);
FadingFrame_SetFadeOutTime(this, ZoneFadeOutDuration);
this:RegisterEvent("ZONE_CHANGED");
this:RegisterEvent("ZONE_CHANGED_INDOORS");
this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
</OnLoad>
<OnEvent>
local newText = GetZoneText();
if ( event == "ZONE_CHANGED" ) then
this.zoneText = newText;
return;
end
if ( newText ~= this.zoneText ) then
this.zoneText = newText;
if ( event == "ZONE_CHANGED_NEW_AREA" ) then
SetZoneText(1);
else
SetZoneText();
end
FadingFrame_Show();
end
</OnEvent>
<OnUpdate>
FadingFrame_OnUpdate();
</OnUpdate>
</Scripts>
</Frame>
<Frame name="SubZoneTextFrame" parent="UIParent" frameStrata="LOW">
<Anchors>
<Anchor point="BOTTOM">
<Offset>
<AbsDimension x="0" y="512"/>
</Offset>
</Anchor>
</Anchors>
<Size>
<AbsDimension x="128" y="128"/>
</Size>
<Layers>
<Layer level="ARTWORK">
<FontString name="SubZoneTextString" inherits="SubZoneTextFont">
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="ZoneTextString" relativePoint="BOTTOM"/>
</Anchors>
</FontString>
<FontString name="PVPArenaTextString" inherits="SubZoneTextFont">
<Size>
<AbsDimension x="512" y="0"/>
</Size>
<Anchors>
<Anchor point="TOP" relativeTo="SubZoneTextString" relativePoint="BOTTOM"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
FadingFrame_OnLoad();
FadingFrame_SetFadeInTime(this, ZoneFadeInDuration);
FadingFrame_SetHoldTime(this, ZoneHoldDuration);
FadingFrame_SetFadeOutTime(this, ZoneFadeOutDuration);
this:RegisterEvent("ZONE_CHANGED");
this:RegisterEvent("ZONE_CHANGED_INDOORS");
this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
PVPArenaTextString:SetTextColor(1.0, 0.1, 0.1);
SetZoneText(1);
SubZoneTextString:SetText(GetSubZoneText());
</OnLoad>
<OnEvent>
local text = SubZoneTextString:GetText();
local newText = GetSubZoneText();
if(text ~= newText) then
SubZoneTextString:SetText(newText);
SetZoneText(1);
FadingFrame_Show();
end
</OnEvent>
<OnUpdate>
FadingFrame_OnUpdate();
</OnUpdate>
</Scripts>
</Frame>
<!-- The auto-follow status line, quoted from ref-ZoneText.xml. The only thing ref-ZoneText.lua
actually contains, and the reason that .lua exists at all; it waited here until follow
support did (decisions 0890, 0893). `setAllPoints` over UIParent, so the line sits dead
centre of the screen. BACKGROUND strata: it is under everything, which is why a full-screen
panel hides it.
ONE DEVIATION, forced: the ref anchors the string CENTER to **WorldFrame**, and benilla has
no WorldFrame — it is the reference's 3D-scene layer frame, which our renderer does not
model as a frame at all. This is the ONLY `relativeTo="WorldFrame"` in the whole 1.12
FrameXML (grep-verified over the extraction), so it buys no convention; left verbatim it
merely logged an unresolved-anchor WARN every boot and fell back to the owner. UIParent is
the right substitute and not an approximation: both are full-screen in the reference, so
their CENTERs coincide, and AutoFollowStatus is setAllPoints over UIParent anyway. -->
<Frame name="AutoFollowStatus" parent="UIParent" setAllPoints="true" frameStrata="BACKGROUND" hidden="true">
<Layers>
<Layer level="ARTWORK">
<FontString name="AutoFollowStatusText" inherits="GameFontNormal">
<Anchors>
<Anchor point="CENTER" relativeTo="UIParent">
<Offset>
<AbsDimension x="0" y="0"/>
</Offset>
</Anchor>
</Anchors>
<FontHeight>
<AbsValue val="20"/>
</FontHeight>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
AutoFollowStatus_OnLoad();
</OnLoad>
<OnEvent>
AutoFollowStatus_OnEvent(event);
</OnEvent>
<OnUpdate>
AutoFollowStatus_OnUpdate(arg1);
</OnUpdate>
</Scripts>
</Frame>
</Ui>