Files
benilla-octo/crates/benilla/assets/ui/ZoneText.xml
T
SamandClaude Fable 5 2ad0043523 benilla: initial public release
A from-scratch World of Warcraft 1.12.1 client in Rust + Bevy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:27:01 +07:00

242 lines
11 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), reduced by ONE frame: AutoFollowStatus (the /follow status
text, the only thing ref-ZoneText.lua actually contains) stays behind until follow support
exists. The FadingFrame kit (ref-FadingFrame.lua, its own TOC line right before ZoneText.xml)
is inlined verbatim below instead: ZoneTextFrame/SubZoneTextFrame are its only consumers in the
whole 1.12 FrameXML (grep-verified over the extraction), so it rides with them.
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";
-- ── 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
]]></Script>
<!-- These frames are shown when the current zone or subzone changes.
(ref carries toplevel="true" on both; dropped here — SetToplevel is a v1 object-model
gap and click-raise is meaningless on mouse-less splash text.) -->
<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>
</Ui>