- the world map's landmarks: city icons and the Eastern Plaguelands towers, from AreaPOI.dbc through the reference's own three gates (level flags, exploration, world state) — the tower rows are one per (tower, owner, state), so the server flipping a world state swaps which icon exists; and the always-up PvP readout ("Towers Controlled: n") over a new WorldStateUI.dbc loader, the init clearing the table on a zone change as the client does
- the character-select scene holds its authored 4:3 view box: the diagonal-FOV relation was fed the display's aspect, so every extra pixel of width came out of height (1.55× zoom at 21:9, head and feet gone) — now width grows and height never shrinks; the reference does the same and is wrong on the same panel
- a trail particle is stored in world space and drawn raw: Sprint's trail was welded to the chest bone (turn and it swings, run and it wobbles) because the trail was faked by subtracting translation inside a bone-local store; the correction machinery deleted itself, gravity is plain world down, and the emitters' live attach frame is retired
- the spellbook can shrink: `SMSG_REMOVED_SPELL` had no handler, so a talent wipe took the points back and left every rank drawn; and the chat dock's hover driver rides a frame the dock cannot hide, so selecting the Combat Log no longer freezes the tab alphas
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
816 lines
45 KiB
XML
816 lines
45 KiB
XML
<!--
|
||
The fullscreen world map — our implementation of the behaviour the 1.12 FrameXML
|
||
WorldMapFrame.xml/.lua specifies (decision 0203 phase 2; decision 0221 settled the layout on
|
||
the fullscreen sheet — the windowed / 1.14-header direction of 0214/0217/0219 is parked, and
|
||
this faithful fullscreen sheet is the baseline we return to). The reference is the SPEC, not
|
||
the source of this text: the names are its contract (globals addons call, frame and template
|
||
names, art paths, every constant and texcoord) and the code that uses them is ours. The map
|
||
is pure FrameXML over the worldmap host API (benilla-ui script/worldmap.rs): detail tiles are
|
||
plain textures whose art the Lua swaps per selection (GetMapInfo →
|
||
Interface\WorldMap\<name>\<name>1..12), the player blip is positioned from
|
||
GetPlayerMapPosition in the same 0..1 map space the reference uses, navigation is
|
||
SetMapZoom/-ToCurrentZone/ProcessMapClick.
|
||
|
||
IN (this file): the FULLSCREEN frame + blackout, the 12-piece parchment chrome, the title,
|
||
the 1002×668 detail frame with its 12 tiles + ADD highlight, the discovery-overlay pool
|
||
(0222 — the explored sub-areas paint their detail over the base parchment), the click/hover
|
||
button layer, the continent/zone dropdowns (over UIDropDownMenu.xml's kit), the zoom-out
|
||
button (panel-button shape — our engine ships no UIPanelButtonTemplate), the close X (the
|
||
QuestLog/BagFrame hand-drawn shape), the area label pair, and the player arrow (MinimapArrow
|
||
art spun by SetRotation(GetPlayerFacing()) — the reference renders an engine arrow model;
|
||
0203 flags the stand-in).
|
||
|
||
OUT (later slices, per 0203): the raid/battlefield/ping children (the PARTY blips landed with
|
||
report B320 — the raid pool waits on `GetPlayerMapPosition` answering a `raid` token); the
|
||
magnifying-glass zoom-out shortcut (redundant with the button); SetupFullscreenScale (the map renders at its native
|
||
1024×768 centered; a scale pass is a taste knob); WorldMapTooltip (only unit blips used it).
|
||
|
||
Deviations from the reference, deliberate: BlackoutWorld fills via anchors instead of the
|
||
GetScreenWidth resize dance (same pixels); OnShow calls WorldMapFrame_Update() directly after
|
||
SetMapToCurrentZone (the reference repaints off the synchronous WORLD_MAP_UPDATE; ours fires
|
||
next tick — the direct call keeps the open paint flicker-free); ESC/M close via the app key
|
||
arm, not OnKeyDown+RunBinding (no binding system).
|
||
-->
|
||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||
<Script><![CDATA[
|
||
NUM_WORLDMAP_DETAIL_TILES = 12;
|
||
NUM_WORLDMAP_OVERLAYS = 0;
|
||
NUM_WORLDMAP_POIS = 0;
|
||
|
||
-- ref WorldMapFrame.lua l.509-515 is the spec. Through the PANEL MANAGER, not a bare
|
||
-- Show/Hide: the map is registered `area = "full"` (UiPanels.xml), which is what makes it
|
||
-- take the screen from the other windows on the way in and — the reason this changed —
|
||
-- what stops it opening from behind the game menu, the one window that still could
|
||
-- (director-reported, decision 0674).
|
||
function ToggleWorldMap()
|
||
if ( WorldMapFrame:IsVisible() ) then
|
||
HideUIPanel(WorldMapFrame);
|
||
else
|
||
ShowUIPanel(WorldMapFrame);
|
||
end
|
||
end
|
||
|
||
-- Fill the screen: scale the native 1024×768 sheet up until it touches the constraining
|
||
-- screen edge — full height on any screen wider than 4:3 (the common case), full width on
|
||
-- a narrower one (ref SetupFullscreenScale, deferred at 0203, wired at 0224). The blackout
|
||
-- is a SEPARATE unscaled frame behind the sheet, so only the sheet grows.
|
||
function SetupFullscreenScale()
|
||
local xScale = GetScreenWidth() / 1024;
|
||
local yScale = GetScreenHeight() / 768;
|
||
local scale = xScale;
|
||
if ( yScale < xScale ) then
|
||
scale = yScale;
|
||
end
|
||
WorldMapFrame:SetScale(scale);
|
||
end
|
||
|
||
-- One overlay tile's extent along one axis: how many pixels of art it draws, and how wide
|
||
-- the FILE holding them is. Every tile is a full 256 except the last of a row or column,
|
||
-- which carries whatever remains of the overlay — and its file is padded up to the next
|
||
-- power of two (16 the smallest the art uses), so that tile shows only the leading
|
||
-- pixels/file fraction of it. Both axes want the same answer, so they ask the same way.
|
||
local function overlayTileExtent(index, count, span)
|
||
if ( index < count ) then
|
||
return 256, 256;
|
||
end
|
||
local pixels = mod(span, 256);
|
||
if ( pixels == 0 ) then
|
||
pixels = 256;
|
||
end
|
||
local file = 16;
|
||
while ( file < pixels ) do
|
||
file = file * 2;
|
||
end
|
||
return pixels, file;
|
||
end
|
||
|
||
-- The repaint (spec: ref WorldMapFrame.lua WorldMapFrame_Update): the tile swap, the
|
||
-- discovery-overlay pool, and the zoom-out arming (POI landmarks are still deferred). The
|
||
-- "World" fallback is the reference's own hack for the nil GetMapInfo at the world level,
|
||
-- kept because our host answers nil at that level for the same reason.
|
||
function WorldMapFrame_Update()
|
||
local mapFileName = GetMapInfo();
|
||
if ( not mapFileName ) then
|
||
mapFileName = "World";
|
||
end
|
||
for i=1, NUM_WORLDMAP_DETAIL_TILES, 1 do
|
||
getglobal("WorldMapDetailTile"..i):SetTexture("Interface\\WorldMap\\"..mapFileName.."\\"..mapFileName..i);
|
||
end
|
||
|
||
-- The discovery overlays (spec: ref WorldMapFrame.lua, "Setup the overlays"): the base
|
||
-- tiles are the unexplored parchment, and each REVEALED sub-area (GetNumMapOverlays /
|
||
-- GetMapOverlayInfo, filtered host-side by the explored bitset) paints its detailed
|
||
-- art over them. That art is cut into a grid of 256-px tiles, numbered 1..n across
|
||
-- then down, which we lay onto ARTWORK textures pooled on WorldMapDetailFrame — the
|
||
-- pool grows on demand, never shrinks, and the tail left over from a busier map is
|
||
-- parked hidden below. Offsets are native pixels: the map renders at its native
|
||
-- 1024×768 (no WORLDMAP_SX/SY scale, unlike the parked windowed layout), so the
|
||
-- overlays share the detail tiles' coordinate space untouched.
|
||
local used = 0;
|
||
for overlay = 1, GetNumMapOverlays() do
|
||
local art, artWidth, artHeight, originX, originY = GetMapOverlayInfo(overlay);
|
||
local columns = ceil(artWidth/256);
|
||
local rows = ceil(artHeight/256);
|
||
local wanted = used + (columns * rows);
|
||
if ( wanted > NUM_WORLDMAP_OVERLAYS ) then
|
||
for slot = NUM_WORLDMAP_OVERLAYS + 1, wanted do
|
||
WorldMapDetailFrame:CreateTexture("WorldMapOverlay"..slot, "ARTWORK");
|
||
end
|
||
NUM_WORLDMAP_OVERLAYS = wanted;
|
||
end
|
||
-- Tile n of the overlay is file <art>n, and its place in the grid follows from n.
|
||
for tile = 1, columns * rows do
|
||
local column = mod(tile - 1, columns) + 1;
|
||
local row = ceil(tile / columns);
|
||
local wide, fileWide = overlayTileExtent(column, columns, artWidth);
|
||
local tall, fileTall = overlayTileExtent(row, rows, artHeight);
|
||
used = used + 1;
|
||
local texture = getglobal("WorldMapOverlay"..used);
|
||
texture:SetWidth(wide);
|
||
texture:SetHeight(tall);
|
||
texture:SetTexCoord(0, wide/fileWide, 0, tall/fileTall);
|
||
texture:ClearAllPoints();
|
||
texture:SetPoint("TOPLEFT", originX + (256 * (column - 1)), -(originY + (256 * (row - 1))));
|
||
texture:SetTexture(art..tile);
|
||
texture:Show();
|
||
end
|
||
end
|
||
for slot = used + 1, NUM_WORLDMAP_OVERLAYS do
|
||
getglobal("WorldMapOverlay"..slot):Hide();
|
||
end
|
||
|
||
-- The POI icons (spec: ref WorldMapFrame.lua's landmark pass). One frame per landmark
|
||
-- the host reports for the displayed map, grown on demand from WorldMapPOITemplate and
|
||
-- never shrunk — the tail from a busier map is parked hidden, like the overlay pool
|
||
-- above. The host reports the AreaPOI.dbc rows the displayed level admits (town and
|
||
-- city icons, a capital's "Under Attack" marker, the Eastern Plaguelands towers),
|
||
-- then the guard-directions marker (SMSG_GOSSIP_POI) last.
|
||
local numPOIs = GetNumMapLandmarks();
|
||
if ( numPOIs > NUM_WORLDMAP_POIS ) then
|
||
for slot = NUM_WORLDMAP_POIS + 1, numPOIs do
|
||
CreateFrame("Button", "WorldMapFramePOI"..slot, WorldMapButton, "WorldMapPOITemplate");
|
||
end
|
||
NUM_WORLDMAP_POIS = numPOIs;
|
||
end
|
||
for slot = 1, NUM_WORLDMAP_POIS do
|
||
local poi = getglobal("WorldMapFramePOI"..slot);
|
||
if ( slot > numPOIs ) then
|
||
poi:Hide();
|
||
else
|
||
local name, description, textureIndex, x, y = GetMapLandmarkInfo(slot);
|
||
WorldMapPOI_SetTexture(poi, textureIndex);
|
||
poi.name = name;
|
||
poi.description = description;
|
||
poi:ClearAllPoints();
|
||
poi:SetPoint("CENTER", "WorldMapDetailFrame", "TOPLEFT",
|
||
x * WorldMapDetailFrame:GetWidth(), -y * WorldMapDetailFrame:GetHeight());
|
||
poi:Show();
|
||
end
|
||
end
|
||
|
||
if ( GetCurrentMapContinent() == 0 ) then
|
||
WorldMapZoomOutButton:Disable();
|
||
else
|
||
WorldMapZoomOutButton:Enable();
|
||
end
|
||
end
|
||
|
||
-- Point a POI frame's texture at its cell of Interface\Minimap\POIIcons — an 8x8 grid of
|
||
-- icons indexed across then down, the same atlas and the same indexing the minimap's
|
||
-- landmark blips use (the corpse marker below hardcodes its own cell of it).
|
||
function WorldMapPOI_SetTexture(poi, textureIndex)
|
||
local column = mod(textureIndex, 8);
|
||
local row = floor(textureIndex / 8);
|
||
getglobal(poi:GetName().."Texture"):SetTexCoord(
|
||
column * 0.125, (column + 1) * 0.125, row * 0.125, (row + 1) * 0.125);
|
||
end
|
||
|
||
-- Every marker on the sheet — the corpse, a POI — names itself in the shared GameTooltip,
|
||
-- and every one of them wants the plate opening AWAY from the edge it sits nearest, so the
|
||
-- side pick lives here once instead of in each OnEnter. `subtitle` is the second line the
|
||
-- landmarks that carry a live status use; the rest pass nothing.
|
||
-- The party blips (ref WorldMapFrame.lua:391-403's party arm, report B320): the same
|
||
-- (0,0)-means-hide law as the player and the corpse, one frame per slot.
|
||
--
|
||
-- It rides the per-frame pass beside those two rather than WorldMapFrame_Update, where the
|
||
-- reference keeps it: a member's position moves continuously and the map has no event that
|
||
-- fires when it does, so placing it on the repaint alone would freeze every blip between
|
||
-- roster changes. Its own function so the live pass and the tests enter it identically.
|
||
--
|
||
-- The reference's RAID arm is not taken — see the blip frames' note.
|
||
function WorldMapParty_Update()
|
||
for i = 1, 4 do
|
||
local blip = getglobal("WorldMapParty" .. i)
|
||
local px, py = GetPlayerMapPosition("party" .. i)
|
||
if ( px == 0 and py == 0 ) then
|
||
blip:Hide()
|
||
else
|
||
px = px * WorldMapDetailFrame:GetWidth()
|
||
py = -py * WorldMapDetailFrame:GetHeight()
|
||
blip:SetPoint("CENTER", "WorldMapDetailFrame", "TOPLEFT", px, py)
|
||
blip:Show()
|
||
end
|
||
end
|
||
end
|
||
|
||
-- A party blip's hover names the member (ref WorldMapUnit_OnEnter, which reads the
|
||
-- frame's own `unit`). The frame id IS the party slot, so the token needs no bookkeeping.
|
||
function WorldMapParty_OnEnter(blip)
|
||
local unit = "party" .. blip:GetID()
|
||
WorldMapMarker_ShowTooltip(blip, UnitName(unit) or UNKNOWN)
|
||
end
|
||
|
||
function WorldMapMarker_ShowTooltip(marker, title, subtitle)
|
||
local markerX = marker:GetCenter();
|
||
local sheetX = marker:GetParent():GetCenter();
|
||
if ( markerX > sheetX ) then
|
||
GameTooltip:SetOwner(marker, "ANCHOR_LEFT");
|
||
else
|
||
GameTooltip:SetOwner(marker, "ANCHOR_RIGHT");
|
||
end
|
||
GameTooltip:SetText(title);
|
||
if ( subtitle and subtitle ~= "" ) then
|
||
GameTooltip:AddLine(subtitle, 1, 1, 1);
|
||
end
|
||
GameTooltip:Show();
|
||
end
|
||
|
||
-- The reference's rule: zone view → its continent; continent view → the world.
|
||
function WorldMapZoomOutButton_OnClick()
|
||
if ( GetCurrentMapZone() ~= 0 ) then
|
||
SetMapZoom(GetCurrentMapContinent());
|
||
else
|
||
SetMapZoom(0);
|
||
end
|
||
end
|
||
|
||
-- ── The continent/zone dropdowns (the reference's wiring; its `arg.n` vararg walk is
|
||
-- written here as select("#", ...), the 5.1-native spelling and this tree's house style
|
||
-- for it). ────────────────────────────────────────────────────────────────────────────
|
||
function WorldMapContinentsDropDown_OnLoad()
|
||
UIDropDownMenu_Initialize(this, WorldMapContinentsDropDown_Initialize);
|
||
UIDropDownMenu_SetWidth(130);
|
||
end
|
||
|
||
function WorldMapContinentsDropDown_Initialize()
|
||
WorldMapFrame_LoadContinents(GetMapContinents());
|
||
end
|
||
|
||
function WorldMapFrame_LoadContinents(...)
|
||
local info;
|
||
for i=1, select("#", ...), 1 do
|
||
info = {};
|
||
info.text = select(i, ...);
|
||
info.func = WorldMapContinentButton_OnClick;
|
||
UIDropDownMenu_AddButton(info);
|
||
end
|
||
end
|
||
|
||
function WorldMapZoneDropDown_OnLoad()
|
||
UIDropDownMenu_Initialize(this, WorldMapZoneDropDown_Initialize);
|
||
UIDropDownMenu_SetWidth(130);
|
||
end
|
||
|
||
function WorldMapZoneDropDown_Initialize()
|
||
WorldMapFrame_LoadZones(GetMapZones(GetCurrentMapContinent()));
|
||
end
|
||
|
||
function WorldMapFrame_LoadZones(...)
|
||
local info;
|
||
for i=1, select("#", ...), 1 do
|
||
info = {};
|
||
info.text = select(i, ...);
|
||
info.func = WorldMapZoneButton_OnClick;
|
||
UIDropDownMenu_AddButton(info);
|
||
end
|
||
end
|
||
|
||
function WorldMapContinentButton_OnClick()
|
||
UIDropDownMenu_SetSelectedID(WorldMapContinentDropDown, this:GetID());
|
||
SetMapZoom(this:GetID());
|
||
end
|
||
|
||
function WorldMapZoneButton_OnClick()
|
||
UIDropDownMenu_SetSelectedID(WorldMapZoneDropDown, this:GetID());
|
||
SetMapZoom(GetCurrentMapContinent(), this:GetID());
|
||
end
|
||
|
||
function WorldMap_UpdateZoneDropDownText()
|
||
if ( GetCurrentMapZone() == 0 ) then
|
||
UIDropDownMenu_ClearAll(WorldMapZoneDropDown);
|
||
else
|
||
UIDropDownMenu_SetSelectedID(WorldMapZoneDropDown, GetCurrentMapZone());
|
||
end
|
||
end
|
||
|
||
function WorldMap_UpdateContinentDropDownText()
|
||
if ( GetCurrentMapContinent() == 0 ) then
|
||
UIDropDownMenu_ClearAll(WorldMapContinentDropDown);
|
||
else
|
||
UIDropDownMenu_SetSelectedID(WorldMapContinentDropDown, GetCurrentMapContinent());
|
||
end
|
||
end
|
||
|
||
-- Where the cursor sits inside a map-sized frame, as a fraction of it measured from the
|
||
-- TOPLEFT: (0,0) the top-left corner of the map art, (1,1) the bottom-right. Both sides of
|
||
-- the host's map API — the click (ProcessMapClick) and the hover (UpdateMapHighlight) —
|
||
-- take a position in exactly that space, and the cursor arrives in screen pixels with the
|
||
-- y axis pointing the other way, so this is the one conversion between them: undo the
|
||
-- frame's effective scale, then measure from its edges, which a frame gives up as its
|
||
-- center and its size (each edge being half the size away from the center).
|
||
local function cursorMapPosition(frame)
|
||
local cursorX, cursorY = GetCursorPosition();
|
||
local scale = frame:GetEffectiveScale();
|
||
local midX, midY = frame:GetCenter();
|
||
local frameWidth = frame:GetWidth();
|
||
local frameHeight = frame:GetHeight();
|
||
local fromLeft = (cursorX / scale) - (midX - (frameWidth/2));
|
||
local fromTop = (midY + (frameHeight/2)) - (cursorY / scale);
|
||
return fromLeft / frameWidth, fromTop / frameHeight;
|
||
end
|
||
|
||
-- Left click drills into whatever the host finds at that map position; every other button
|
||
-- is the zoom-out shortcut (ref WorldMapButton_OnClick — ours takes no button argument,
|
||
-- since nothing but the map button itself routes here).
|
||
function WorldMapButton_OnClick(mouseButton)
|
||
CloseDropDownMenus();
|
||
if ( mouseButton == "LeftButton" ) then
|
||
ProcessMapClick(cursorMapPosition(WorldMapButton));
|
||
else
|
||
WorldMapZoomOutButton_OnClick();
|
||
end
|
||
end
|
||
|
||
-- The per-frame hover pass (spec: ref WorldMapButton_OnUpdate), reduced to the area
|
||
-- highlight + the player blip (raid/flags/ping are still deferred; the party blips
|
||
-- landed with B320 and ride WorldMapFrame_Update, not this pass).
|
||
-- UpdateMapHighlight is a stub until the area-bitmap source lands (wow-re dispatch) — a
|
||
-- nil area/art takes the hide paths.
|
||
function WorldMapButton_OnUpdate(elapsed)
|
||
local width = this:GetWidth();
|
||
local height = this:GetHeight();
|
||
local area, art, cropX, cropY, sizeX, sizeY, atX, atY =
|
||
UpdateMapHighlight(cursorMapPosition(this));
|
||
WorldMapFrameAreaLabel:SetText(area or "");
|
||
if ( art ) then
|
||
-- The sub-area under the cursor lights up: <zone>Highlight holds one shape per
|
||
-- sub-area, of which crop names the fraction actually used (the file is padded to
|
||
-- a power of two), while size and at are the shape's extent and top-left corner as
|
||
-- fractions of the map — so both scale by the button's pixel size. Nothing to draw
|
||
-- for a degenerate shape, but the art is still swapped in for the next frame.
|
||
WorldMapHighlight:SetTexCoord(0, cropX, 0, cropY);
|
||
WorldMapHighlight:SetTexture("Interface\\WorldMap\\"..art.."\\"..art.."Highlight");
|
||
local drawWidth = sizeX * width;
|
||
local drawHeight = sizeY * height;
|
||
if ( drawWidth > 0 and drawHeight > 0 ) then
|
||
WorldMapHighlight:SetWidth(drawWidth);
|
||
WorldMapHighlight:SetHeight(drawHeight);
|
||
WorldMapHighlight:SetPoint("TOPLEFT", "WorldMapDetailFrame", "TOPLEFT", atX * width, -atY * height);
|
||
WorldMapHighlight:Show();
|
||
end
|
||
else
|
||
WorldMapHighlight:Hide();
|
||
end
|
||
-- The player blip: the reference's engine arrow, as our rotating texture stand-in.
|
||
WorldMapPlayerIcon:SetRotation(GetPlayerFacing());
|
||
local playerX, playerY = GetPlayerMapPosition("player");
|
||
if ( playerX == 0 and playerY == 0 ) then
|
||
WorldMapPlayer:Hide();
|
||
else
|
||
playerX = playerX * WorldMapDetailFrame:GetWidth();
|
||
playerY = -playerY * WorldMapDetailFrame:GetHeight();
|
||
WorldMapPlayer:SetPoint("CENTER", "WorldMapDetailFrame", "TOPLEFT", playerX, playerY);
|
||
WorldMapPlayer:Show();
|
||
end
|
||
WorldMapParty_Update()
|
||
-- Position corpse (ref WorldMapFrame.lua:443-452 — the law is that (0,0) means hide).
|
||
local corpseX, corpseY = GetCorpseMapPosition();
|
||
if ( corpseX == 0 and corpseY == 0 ) then
|
||
WorldMapCorpse:Hide();
|
||
else
|
||
corpseX = corpseX * WorldMapDetailFrame:GetWidth();
|
||
corpseY = -corpseY * WorldMapDetailFrame:GetHeight();
|
||
WorldMapCorpse:SetPoint("CENTER", "WorldMapDetailFrame", "TOPLEFT", corpseX, corpseY);
|
||
WorldMapCorpse:Show();
|
||
end
|
||
end
|
||
]]></Script>
|
||
<!-- The fullscreen blackout — a separate, UNSCALED frame behind the map sheet (0224). The map
|
||
itself (WorldMapFrame) is now the native 1024×768 sheet that SetupFullscreenScale grows to
|
||
fill the screen; the blackout stays screen-sized so the world never shows through the
|
||
margins, and eats clicks so nothing leaks to the world behind it. -->
|
||
<Frame name="WorldMapBlackout" frameStrata="FULLSCREEN" hidden="true" enableMouse="true" parent="UIParent">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT"/>
|
||
<Anchor point="BOTTOMRIGHT"/>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture setAllPoints="true"><Color r="0.0" g="0.0" b="0.0"/></Texture>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
<!-- One POI icon on the map (spec: ref WorldMapPOITemplate, WorldMapFrameTemplates.xml): a
|
||
16x16 cell of Interface\Minimap\POIIcons picked by the landmark's own textureIndex, with a
|
||
name/description tooltip. Grown on demand by WorldMapFrame_Update into WorldMapButton. -->
|
||
<Button name="WorldMapPOITemplate" virtual="true" enableMouse="true">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture name="$parentTexture" file="Interface\Minimap\POIIcons" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>
|
||
WorldMapMarker_ShowTooltip(this, this.name, this.description);
|
||
</OnEnter>
|
||
<OnLeave>
|
||
GameTooltip:Hide();
|
||
</OnLeave>
|
||
</Scripts>
|
||
</Button>
|
||
<Frame name="WorldMapFrame" frameStrata="FULLSCREEN_DIALOG" hidden="true" enableMouse="true" parent="UIParent">
|
||
<Size><AbsDimension x="1024" y="768"/></Size>
|
||
<Anchors>
|
||
<Anchor point="CENTER"/>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Top1">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-512" y="384"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Top2">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-256" y="384"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Top3">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="0" y="384"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Top4">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="256" y="384"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Middle1">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-512" y="128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Middle2">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-256" y="128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Middle3">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="0" y="128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Middle4">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="256" y="128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Bottom1">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-512" y="-128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Bottom2">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="-256" y="-128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Bottom3">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="0" y="-128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\WorldMap\UI-WorldMap-Bottom4">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="CENTER"><Offset><AbsDimension x="256" y="-128"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<FontString inherits="GameFontNormal" text="World Map">
|
||
<Anchors><Anchor point="CENTER"><Offset><AbsDimension x="0" y="372"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<Frame name="WorldMapPositioningGuide">
|
||
<Size><AbsDimension x="1024" y="768"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
</Frame>
|
||
<!-- ref: the continent picker (id 1) at the top row's left, the zone picker (id 2)
|
||
chained to its right, the zoom-out button closing the row. OnLoad instead of the
|
||
ref's OnShow (our engine fires OnShow only on the frame itself, not children of
|
||
a shown parent; OnLoad + the WORLD_MAP_UPDATE re-init below cover every open). -->
|
||
<Frame name="WorldMapContinentDropDown" inherits="UIDropDownMenuTemplate" id="1">
|
||
<Anchors>
|
||
<Anchor point="TOP" relativePoint="TOP" relativeTo="WorldMapPositioningGuide">
|
||
<Offset><AbsDimension x="-80" y="-35"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<FontString inherits="GameFontNormalSmall" text="Continent">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="10"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>
|
||
WorldMapContinentsDropDown_OnLoad();
|
||
</OnLoad>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="WorldMapZoneDropDown" inherits="UIDropDownMenuTemplate" id="2">
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="WorldMapContinentDropDown" relativePoint="RIGHT">
|
||
<Offset><AbsDimension x="-33" y="0"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<FontString inherits="GameFontNormalSmall" text="Zone">
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT"><Offset><AbsDimension x="20" y="10"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>
|
||
WorldMapZoneDropDown_OnLoad();
|
||
this:RegisterEvent("WORLD_MAP_UPDATE");
|
||
</OnLoad>
|
||
<OnEvent>
|
||
if ( this:IsVisible() ) then
|
||
WorldMapContinentsDropDown_OnLoad();
|
||
WorldMap_UpdateContinentDropDownText();
|
||
WorldMapZoneDropDown_OnLoad();
|
||
WorldMap_UpdateZoneDropDownText();
|
||
end
|
||
</OnEvent>
|
||
</Scripts>
|
||
</Frame>
|
||
<Button name="WorldMapZoomOutButton" text="Zoom Out">
|
||
<Size><AbsDimension x="110" y="22"/></Size>
|
||
<Anchors>
|
||
<Anchor point="LEFT" relativeTo="WorldMapZoneDropDown" relativePoint="RIGHT">
|
||
<Offset><AbsDimension x="-10" y="3"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<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>
|
||
<Scripts>
|
||
<OnClick>WorldMapZoomOutButton_OnClick();</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
<Button name="WorldMapFrameCloseButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOP" relativeTo="WorldMapPositioningGuide">
|
||
<Offset><AbsDimension x="516" y="4"/></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(WorldMapFrame);</OnClick>
|
||
</Scripts>
|
||
</Button>
|
||
<Frame name="WorldMapDetailFrame">
|
||
<Size><AbsDimension x="1002" y="668"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOP" relativeTo="WorldMapPositioningGuide">
|
||
<Offset><AbsDimension x="-502" y="-69"/></Offset>
|
||
</Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="WorldMapDetailTile1">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile2">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile1" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile3">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile2" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile4">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile3" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile5">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile1" relativePoint="BOTTOMLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile6">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile5" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile7">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile6" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile8">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile7" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile9">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile5" relativePoint="BOTTOMLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile10">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile9" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile11">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile10" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="WorldMapDetailTile12">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailTile11" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<Texture name="WorldMapHighlight" alphaMode="ADD" hidden="true">
|
||
<Size><AbsDimension x="128" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
<Button name="WorldMapButton" enableMouse="true">
|
||
<Size><AbsDimension x="1002" y="668"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="WorldMapDetailFrame"/></Anchors>
|
||
<Frames>
|
||
<Frame name="WorldMapPlayer">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="WorldMapPlayerIcon" file="Interface\Minimap\MinimapArrow" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
<!-- The corpse marker (decision 0308 §5) — ref WorldMapCorpseTemplate
|
||
(WorldMapFrameTemplates.xml l.55-88) inlined: 16x16, the POIIcons skull
|
||
cell (0.875-1.0 / 0-0.125), hover names it CORPSE_RED. The ref anchors its
|
||
tooltip to a WorldMapTooltip; ours rides the shared GameTooltip (this
|
||
map ships no separate tooltip — header note) through the side-pick every
|
||
marker on the sheet shares. -->
|
||
<Frame name="WorldMapCorpse" hidden="true" enableMouse="true">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\Minimap\POIIcons" setAllPoints="true">
|
||
<TexCoords left="0.875" right="1.0" top="0" bottom="0.125"/>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>
|
||
WorldMapMarker_ShowTooltip(this, "|cffff2020Corpse|r")
|
||
</OnEnter>
|
||
<OnLeave>
|
||
GameTooltip:Hide()
|
||
</OnLeave>
|
||
</Scripts>
|
||
</Frame>
|
||
<!-- The party blips (report B320) — ref WorldMapUnitTemplate
|
||
(WorldMapFrameTemplates.xml l.3-28) re-expressed: 16x16 centered,
|
||
WorldMapPartyIcon art, one frame per `party1..4` slot, placed by
|
||
GetPlayerMapPosition in the Update above. The reference hovers them into
|
||
its own WorldMapTooltip; this map ships none (header note), so they take
|
||
the shared GameTooltip through WorldMapMarker_ShowTooltip exactly as the
|
||
corpse marker beside them does.
|
||
|
||
The reference's RAID pool (25 more frames, its `GetNumRaidMembers() > 0`
|
||
arm) is NOT here: `GetPlayerMapPosition` answers no `raid` token yet, so
|
||
a raid would show these four filled from its own subgroup and nothing
|
||
else. That is the honest half-step, and it is named in the OUT list. -->
|
||
<Frame name="WorldMapParty1" hidden="true" enableMouse="true" id="1">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\WorldMap\WorldMapPartyIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>WorldMapParty_OnEnter(this)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="WorldMapParty2" hidden="true" enableMouse="true" id="2">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\WorldMap\WorldMapPartyIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>WorldMapParty_OnEnter(this)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="WorldMapParty3" hidden="true" enableMouse="true" id="3">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\WorldMap\WorldMapPartyIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>WorldMapParty_OnEnter(this)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="WorldMapParty4" hidden="true" enableMouse="true" id="4">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture file="Interface\WorldMap\WorldMapPartyIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>WorldMapParty_OnEnter(this)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Frame>
|
||
<Frame name="WorldMapFrameAreaFrame">
|
||
<Size><AbsDimension x="400" y="128"/></Size>
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="0" y="-10"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<FontString name="WorldMapFrameAreaLabel" inherits="WorldMapTextFont">
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="20" y="-20"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="WorldMapFrameAreaDescription" inherits="SubZoneTextFont">
|
||
<Anchors><Anchor point="TOP" relativeTo="WorldMapFrameAreaLabel" relativePoint="BOTTOM"/></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>
|
||
this:RegisterForClicks("LeftButtonUp", "RightButtonUp");
|
||
</OnLoad>
|
||
<OnClick>
|
||
WorldMapButton_OnClick(arg1);
|
||
</OnClick>
|
||
<OnUpdate>
|
||
WorldMapButton_OnUpdate(arg1);
|
||
</OnUpdate>
|
||
</Scripts>
|
||
</Button>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>
|
||
this:RegisterEvent("WORLD_MAP_UPDATE");
|
||
-- The hover area label inherits WorldMapTextFont (nominal 102). 33 was the
|
||
-- director's taste call (0235) — which the one-to-one raster cap (the fold-back
|
||
-- record; wow-re fontstring-overflow.md) now clamps to the byte law's 32, one
|
||
-- unit under that call and closer to it than the 36 the atlas snap used to
|
||
-- deliver. The real client draws this SetFont(33) at 32 too. Still a taste dial:
|
||
-- any value ≤ 32 is honored exactly.
|
||
WorldMapFrameAreaLabel:SetFont("Fonts\\FRIZQT__.TTF", 33);
|
||
WorldMapFrame_Update();
|
||
</OnLoad>
|
||
<!-- UpdateMicroButtons leads both, as in the ref (WorldMapFrame.xml l.599/606) — live
|
||
since the micro-menu slice (MicroMenu.xml). -->
|
||
<OnShow>
|
||
WorldMapBlackout:Show();
|
||
SetupFullscreenScale();
|
||
SetMapToCurrentZone();
|
||
WorldMapFrame_Update();
|
||
if UpdateMicroButtons then UpdateMicroButtons() end;
|
||
PlaySound("igQuestLogOpen");
|
||
CloseDropDownMenus();
|
||
</OnShow>
|
||
<OnHide>
|
||
WorldMapBlackout:Hide();
|
||
if UpdateMicroButtons then UpdateMicroButtons() end;
|
||
PlaySound("igQuestLogClose");
|
||
</OnHide>
|
||
<OnEvent>
|
||
if ( WorldMapFrame:IsVisible() ) then
|
||
WorldMapFrame_Update();
|
||
end
|
||
</OnEvent>
|
||
</Scripts>
|
||
</Frame>
|
||
</Ui>
|