- follow a player and the screen names who you're following, the right-click menu grows its Follow row, and your own movement is what cancels it — creatures are refused like the real client - a locked lockbox click asks the server instead of refusing silently, a quest-starter chest offers its quest before opening, and an item on cooldown hides its green "open" line - a parried swing plays its clang like the real client keys it - the README's What works / Not built yet caught up on a week of shipping Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
338 lines
16 KiB
XML
338 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; 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>
|
|
<!-- 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>
|