- /target and /assist find units by name like the original, and /follow walks you behind your target - right click opens clams and lockboxes, and the tooltip promises it - the freeze thaws clean, poses release instead of sticking, and you drop to neutral standing before it grips - unit frame art layers over the bars like the original Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1156 lines
70 KiB
XML
1156 lines
70 KiB
XML
<Ui>
|
||
<!--
|
||
benilla's player + target unit frames (decision 0068 slice-1 game shell), RE-SKINNED to the
|
||
real 1.12 UI-TargetingFrame art + geometry (dressing arc, decision 0084). The geometry below
|
||
is QUOTED from the real FrameXML (scratchpad ref-PlayerFrame.xml, ref-TargetFrame.xml; line
|
||
citations inline), turned onto our own snapshot → Unit* → event data flow. The player and
|
||
target are horizontal MIRRORS of one shared art (Interface\TargetingFrame\UI-TargetingFrame):
|
||
the player samples it flipped (portrait window on the LEFT), the target un-flipped (window on
|
||
the RIGHT). The mirror is a `<TexCoords left> right`; it reaches the vertex buffer un-normalized
|
||
via the engine's UvRect (see crates/benilla/src/ui_pass.rs).
|
||
|
||
LAYERING (matches the ref's structure). The draw order must be trough < bars < ring art < text:
|
||
the frame's metal well-edges overlap the bar edges so the bars read RECESSED, not pasted on top.
|
||
The ref gets this with a child `TargetFrameTextureFrame` (ring art) and `SetFrameLevel(bar,
|
||
textureFrame-1)` to push the bars beneath it, and we do the same, in BenillaUnitFrame_OnLoad:
|
||
the parent holds trough + portrait (+ target's name plate) in BACKGROUND; the
|
||
`$parentHealthBar`/`$parentPowerBar` StatusBars sit at the PARENT's frame level; and
|
||
`$parentTextureFrame` (232×100, filling the parent) holds the ring art (BACKGROUND) + name/level/dead text
|
||
(OVERLAY) one level ABOVE them, so it draws over the bar edges and the portrait.
|
||
|
||
That SetFrameLevel is load-bearing, and this file used to do without it. Until decision 0884
|
||
the bars were held under the ring art by DECLARING `$parentTextureFrame` after them, leaning on
|
||
the old draw key's insertion-order tie-break between siblings at one `(strata, level)`. 0884
|
||
pinned the real law at the binary: the draw LAYER is bucket-wide and outranks the frame, so
|
||
siblings interleave by layer and the bars' ARTWORK fills painted straight over the TextureFrame's
|
||
BACKGROUND ring art (the frames read as pasted-on slabs — director report, 2026-08-02). Frame
|
||
level is the one term above the layer, which is exactly why the reference spends a level here.
|
||
Do not "simplify" this back into declaration order. The ring's art is a THIN
|
||
band with transparent corners (not an opaque surround), so the square is hidden by the portrait
|
||
itself — set via SetPortraitToTexture, masked to its inscribed circle (the client's portraits are
|
||
always round: a model render or a circular-cropped icon), so no corner reaches the ring's gap. The
|
||
text lives under the TextureFrame, so its globals carry the `…TextureFrame…` name prefix (OnLoad).
|
||
The shared black `…Background` trough sits behind the unfilled bar portion.
|
||
|
||
DATA FLOW UNCHANGED (pin: re-anchor + re-skin, don't rewrite the eventing): BenillaUnitFrame_*
|
||
handlers, the power-color table, hide-on-nonexistent-unit. Names resolve asynchronously through
|
||
the name-query cache (UNIT_NAME_UPDATE repaints). A powerless unit (maxPower 0) hides its power
|
||
bar, as the real frames do. The target frame's "DEAD" text shows when the target's health hits
|
||
zero (ref TargetFrame_CheckDead, ref-TargetFrame.lua l.220-228).
|
||
|
||
DEVIATIONS (noted, not bugs):
|
||
- Portrait: the live model bake (SetPortraitTexture(region, unit) → crates/benilla/src/portrait.rs),
|
||
the modern high-res 2D take on the ref's low-res model snapshot (director's call; wow-re
|
||
portrait RE §5-verified). Circle-cut at draw (ui_quad.wgsl, the ref's stencil shape); the
|
||
TemporaryPortrait stand-in shows while a model streams in; the bake poses a fresh
|
||
instance at Stand through the model's authored portrait camera, helms/shoulders/held
|
||
items riding their bones (portrait/).
|
||
- Bar value FontStrings (ref-PlayerFrame.xml l.79-96) are omitted — the real client hides them
|
||
unless the statusText CVar is set; we match the default look.
|
||
- TargetFrameNameBackground (the level plate) is faction-tinted (TargetFrame_CheckFaction,
|
||
ref-TargetFrame.lua l.144-191). A PLAYER-controlled target takes the player branch (red when
|
||
mutually hostile, yellow attackable-not-hostile, green when we can assist them but they are
|
||
PvP-flagged, else blue — a player never reads the *reaction* green); an NPC
|
||
takes the reaction swatch, resolved from the same faction-template / reputation decode the
|
||
selection ring uses (ui_unit.rs → UnitState.reaction → UnitReaction). The player branch's
|
||
two middle legs — yellow "attackable but not hostile" (l.158) and green "assist +
|
||
PvP-flagged" (l.163) — landed with the PvP wire (decision 0646); only the tapped-by-other
|
||
grey (l.176) is still deferred, on the tap wire. The ref gates the player
|
||
branch on UnitPlayerControlled (which also covers pets); we resolve its player half via
|
||
UnitIsPlayer, so a player-controlled PET takes the NPC reaction branch until that flag lands.
|
||
- The classification border swap (elite/rare art, ref-TargetFrame.lua l.205-218) LANDED with
|
||
decision 0782 — UnitClassification is bound and BenillaTargetFrame_CheckClassification
|
||
below runs the ref's branch table. Two things worth knowing at this altitude. The rank
|
||
`UnitClassification` reads is the client's GATED rank (`0x605620`): a pet or charmed unit
|
||
reports rank 0, so an enslaved elite wears the plain border, and because the tooltip's
|
||
ELITE/BOSS word and UnitLevel's world-boss skull read the same getter, the gate lives at
|
||
the app's single write (ui_unit.rs enrich_unit), not per reader. And UNIT_CLASSIFICATION_
|
||
CHANGED is the repaint wire, edge-fired on that rank — without it the border would only be
|
||
right on re-target, since Update is otherwise the sole caller.
|
||
- The level slot runs the full CheckLevel law (ref-TargetFrame.lua l.119-142, transcribed in
|
||
Update below): corpse or "can't tell" (UnitLevel ≤ 0) → the HighLevelTexture skull;
|
||
otherwise the number, GetDifficultyColor-tinted when attackable, gold when not.
|
||
- The PVP icon landed with decision 0646 (the three-branch law in BenillaUnitFrame_UpdatePvP).
|
||
Its `PlayerPVPIconHitArea` did NOT, deliberately: the ref's hit area draws nothing at the
|
||
default settings — GameTooltip_AddNewbieTip with SHOW_NEWBIE_TIPS off and noNormalText=1
|
||
(which is exactly how it is called) shows no tooltip at all — while an enableMouse frame
|
||
over the portrait would eat the player frame's own hover and right-click. Zero pixels for a
|
||
real regression is not a trade; it comes back with the newbie-tip cvar if that ever ships.
|
||
RE-VERIFIED in 0652, both legs: ref-GameTooltip.lua l.107-123 takes the `not noNormalText`
|
||
branch when tips are off (so `noNormalText=1` → nothing), and "newbie" does not appear
|
||
anywhere in WoW.exe's strings, so SHOW_NEWBIE_TIPS has no cvar producer to be on.
|
||
- OUT (no wire / future arcs): leader/master/rest/attack icons, group indicator,
|
||
hit indicators, raid target icon, playtime, target-of-target.
|
||
|
||
TARGET AURA ROWS (0255's deferred slice): 5 buffs / 16 debuffs under the frame, geometry +
|
||
law QUOTED from ref-TargetFrame.xml (button templates l.26-87, instances l.293-481) and
|
||
TargetDebuffButton_Update (ref-TargetFrame.lua l.263-387): friend ⇒ buff row first, else
|
||
debuffs first and buffs below row 2; icons 21px shrinking to 17 when the debuff count
|
||
reaches the wrap; dispel-tinted UI-Debuff-Overlays border; stack count above 1; NO timers
|
||
(the 1.12 wire carries no duration for another unit — byte-verified, decision 0257 B6). The
|
||
list UnitBuff/UnitDebuff enumerate for the target is the app's straight descriptor read,
|
||
ascending raw slot within the half — the verified other-unit law (0257) — so icons sit in
|
||
server slot order, not insertion order, exactly like the reference. The target-of-target
|
||
branches take the not-shown leg (wrap 6, buffs under Debuff7) until a ToT frame exists.
|
||
-->
|
||
<Script><![CDATA[
|
||
-- The right-click-menu explanations the detailed-tooltip fork shows in place of the unit
|
||
-- lines (BenillaUnitFrame_OnEnter below) — ref GlobalStrings.lua l.2993/3081/2754/2755
|
||
-- (enUS), fallback form: the real localized GlobalStrings.lua runs before this file at
|
||
-- runtime (ui_script/mod.rs), so these only fill in for the tests. CombatText.xml's shape.
|
||
PARTY_OPTIONS_LABEL = PARTY_OPTIONS_LABEL or "Party Options"
|
||
PLAYER_OPTIONS_LABEL = PLAYER_OPTIONS_LABEL or "Player Options"
|
||
NEWBIE_TOOLTIP_PARTYOPTIONS = NEWBIE_TOOLTIP_PARTYOPTIONS or "If you belong to a party, you can right-click your portrait to bring up the Party Options menu. This menu will allow you to quit the party or see what looting rules the party is using. A party leader can add or remove party members, as well as change the party's looting rules."
|
||
NEWBIE_TOOLTIP_PLAYEROPTIONS = NEWBIE_TOOLTIP_PLAYEROPTIONS or "Right-click to bring up special commands for interacting with another player. You can inspect their equipment, issue a party invite, initiate a trade, or challenge a player to a duel. A group leader can promote or remove that player from the group."
|
||
|
||
-- The client's PowerBarColor values, keyed by the UnitPowerType token.
|
||
BENILLA_POWER_COLORS = {
|
||
MANA = { r = 0.0, g = 0.0, b = 1.0 },
|
||
RAGE = { r = 1.0, g = 0.0, b = 0.0 },
|
||
FOCUS = { r = 1.0, g = 0.5, b = 0.25 },
|
||
ENERGY = { r = 1.0, g = 1.0, b = 0.0 },
|
||
HAPPINESS = { r = 0.0, g = 1.0, b = 1.0 },
|
||
}
|
||
|
||
-- The client's UnitReactionColor table (ref-TargetFrame.lua l.6-14), indexed by
|
||
-- UnitReaction 1..8 (hated..exalted): 1-2 red, 3 orange, 4 neutral yellow, 5-7 green. The
|
||
-- name-plate reaction tint (TargetFrame_CheckFaction) reads it — this is what makes a neutral
|
||
-- beast's plate yellow, a hostile's red, a friendly's green.
|
||
BENILLA_REACTION_COLORS = {
|
||
{ r = 1.0, g = 0.0, b = 0.0 },
|
||
{ r = 1.0, g = 0.0, b = 0.0 },
|
||
{ r = 1.0, g = 0.5, b = 0.0 },
|
||
{ r = 1.0, g = 1.0, b = 0.0 },
|
||
{ r = 0.0, g = 1.0, b = 0.0 },
|
||
{ r = 0.0, g = 1.0, b = 0.0 },
|
||
{ r = 0.0, g = 1.0, b = 0.0 },
|
||
}
|
||
|
||
-- Wire an instance to its unit token (called from each frame's OnLoad), cache its child
|
||
-- widgets, register the event set, and do the first paint. deadText is target-only
|
||
-- (getglobal returns nil for the player, which has no DEAD region) — guarded at use.
|
||
function BenillaUnitFrame_OnLoad(frame, unit)
|
||
frame.unit = unit
|
||
local name = frame:GetName()
|
||
frame.healthBar = getglobal(name .. "HealthBar")
|
||
frame.powerBar = getglobal(name .. "PowerBar")
|
||
-- The name/level/dead text live inside $parentTextureFrame (so they draw over the ring art
|
||
-- that draws over the bars), so their global names carry the TextureFrame prefix.
|
||
local tf = name .. "TextureFrame"
|
||
-- The recessed-bar look, the reference's own mechanism (ref-TargetFrame.lua l.32-34):
|
||
-- push the bars one frame level BELOW the ring art's TextureFrame. Frame level is the
|
||
-- only key term above the draw layer (decision 0884), so this is the only thing that can
|
||
-- hold a BACKGROUND ring texture over an ARTWORK bar fill. See the LAYERING note up top.
|
||
local textureFrameLevel = getglobal(tf):GetFrameLevel()
|
||
frame.healthBar:SetFrameLevel(textureFrameLevel - 1)
|
||
frame.powerBar:SetFrameLevel(textureFrameLevel - 1)
|
||
frame.nameText = getglobal(tf .. "NameText")
|
||
frame.levelText = getglobal(tf .. "LevelText")
|
||
frame.deadText = getglobal(tf .. "DeadText")
|
||
-- Target-only (the "??" skull on the level slot); getglobal returns nil for the
|
||
-- player, guarded at use.
|
||
frame.highLevel = getglobal(tf .. "HighLevelTexture")
|
||
-- Target-only (the level/name plate); getglobal returns nil for the player, guarded at use.
|
||
frame.nameBackground = getglobal(name .. "NameBackground")
|
||
-- The live model portrait (the real API's global, ref-UnitFrame.lua): bind the portrait
|
||
-- region to this frame's unit token; the app renders that unit's model off-screen and feeds
|
||
-- the bake back into the region (crates/benilla/src/portrait.rs). The binding is a token, so
|
||
-- one call suffices — the app keeps the image current per token (it re-bakes on target /
|
||
-- model change), which is why the ref's UNIT_PORTRAIT_UPDATE re-call isn't needed here (the
|
||
-- event joins the surface when addon parity wants it). Until a bake lands (no unit / model
|
||
-- still loading) the circle is simply empty.
|
||
frame.portrait = getglobal(name .. "Portrait")
|
||
SetPortraitTexture(frame.portrait, unit)
|
||
-- The PvP flag icon (decision 0646), under the TextureFrame like the ring art it
|
||
-- draws over — see BenillaUnitFrame_UpdatePvP.
|
||
frame.pvpIcon = getglobal(tf .. "PVPIcon")
|
||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||
frame:RegisterEvent("UNIT_HEALTH")
|
||
frame:RegisterEvent("UNIT_MAXHEALTH")
|
||
frame:RegisterEvent("UNIT_LEVEL")
|
||
frame:RegisterEvent("UNIT_POWER_UPDATE")
|
||
frame:RegisterEvent("UNIT_MAXPOWER")
|
||
frame:RegisterEvent("UNIT_DISPLAYPOWER")
|
||
frame:RegisterEvent("UNIT_NAME_UPDATE")
|
||
-- The PvP icon's repaint wire (decision 0646 §2) — in the reference exactly the three
|
||
-- frames that draw the icon register it (PlayerFrame, TargetFrame, PartyMemberFrame)
|
||
-- and nothing else does.
|
||
frame:RegisterEvent("UNIT_FACTION")
|
||
frame:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||
-- The aura rows and the classification border are target-only (ref TargetFrame_OnLoad
|
||
-- registers UNIT_AURA and UNIT_CLASSIFICATION_CHANGED; PlayerFrame registers neither,
|
||
-- and there is no CheckClassification for the player — your own frame never wears a
|
||
-- dragon). The ring-art region is the one the border swap re-textures, so only the
|
||
-- target caches the handle: its presence is what gates the swap in Update, the same
|
||
-- nil-handle idiom highLevel/nameBackground use above.
|
||
if unit == "target" then
|
||
frame:RegisterEvent("UNIT_AURA")
|
||
frame:RegisterEvent("UNIT_CLASSIFICATION_CHANGED")
|
||
frame.frameTexture = getglobal(tf .. "Texture")
|
||
end
|
||
-- The portrait hit indicator (decision 0576): only the player frame registers
|
||
-- UNIT_COMBAT in 1.12 (ref PlayerFrame_OnLoad — the target frame has no feedback
|
||
-- text). Ref: CombatFeedback_Initialize(PlayerHitIndicator, 30).
|
||
if unit == "player" then
|
||
frame.feedbackText = getglobal(tf .. "HitIndicator")
|
||
frame.feedbackFontHeight = 30
|
||
frame:RegisterEvent("UNIT_COMBAT")
|
||
end
|
||
-- A plain Frame isn't mouse-enabled by construction (only Button/EditBox are); enable it so
|
||
-- the hover tooltip fires (the real client's unit frames take the mouse to target/tooltip).
|
||
frame:EnableMouse(true)
|
||
BenillaUnitFrame_Update(frame)
|
||
end
|
||
|
||
-- Hover: the engine's SetUnit — the byte-verified unit line law (decision 0276: name/
|
||
-- subtitle/level composition/PvP/Skinnable + the health bar), then the ref's reaction
|
||
-- recolor of line 1 (ref UnitFrame_OnEnter l.68-76: the FrameXML half of the split).
|
||
-- The plate goes to the DEFAULT corner, not beside the frame — ref UnitFrame_OnEnter
|
||
-- l.56 is GameTooltip_SetDefaultAnchor(GameTooltip, this): unit-frame tooltips live at
|
||
-- the screen's bottom-right like world hovers. (The TOOLTIP_UPDATE_TIME re-poll is not
|
||
-- ours: the engine's health watcher is the live half of it, and name/level don't drift
|
||
-- mid-hover yet.)
|
||
--
|
||
-- The DETAILED-TOOLTIP FORK (ref UnitFrame_OnEnter l.58-67, director-approved 0663) is the
|
||
-- surprising half: with tips on — 1.12's default, decision 0661 — the frame explains its
|
||
-- RIGHT-CLICK MENU instead of the unit, and returns BEFORE SetUnit, so the health/level
|
||
-- lines never render at all. Your own portrait always takes it; another player's takes it
|
||
-- whenever they're your target. The ref excepts PartyMemberFrame1-4 by name; ours are a
|
||
-- separate file with their own OnEnter (PartyFrame.xml), so there is nothing to except here.
|
||
--
|
||
-- One divergence, named: the ref gates the second branch on UnitPlayerControlled("target"),
|
||
-- which is true for a player OR a player's pet/charm. This engine has no such binding and no
|
||
-- flag to build one from — UnitIsPlayer is the nearest honest read, so a charmed mob or
|
||
-- another player's pet falls through to the unit tooltip where the reference would explain
|
||
-- the menu. The player case, which is the one anybody hovers, is exact.
|
||
function BenillaUnitFrame_OnEnter(frame)
|
||
local unit = frame.unit
|
||
if not UnitExists(unit) then return end
|
||
GameTooltip_SetDefaultAnchor(GameTooltip, frame)
|
||
if SHOW_NEWBIE_TIPS == "1" then
|
||
if frame:GetName() == "BenillaPlayerFrame" then
|
||
GameTooltip_AddNewbieTip(frame, PARTY_OPTIONS_LABEL, 1.0, 1.0, 1.0,
|
||
NEWBIE_TOOLTIP_PARTYOPTIONS)
|
||
return
|
||
elseif UnitIsPlayer("target") and not UnitIsUnit("target", "player")
|
||
and not UnitIsUnit("target", "pet") then
|
||
GameTooltip_AddNewbieTip(frame, PLAYER_OPTIONS_LABEL, 1.0, 1.0, 1.0,
|
||
NEWBIE_TOOLTIP_PLAYEROPTIONS)
|
||
return
|
||
end
|
||
end
|
||
if GameTooltip:SetUnit(unit) then
|
||
getglobal("GameTooltipTextLeft1"):SetTextColor(GameTooltip_UnitColor(unit))
|
||
end
|
||
end
|
||
|
||
-- ref UnitFrame_OnLeave l.84-88: the fade is the tips-OFF branch. With detailed tips on the
|
||
-- plate HIDES outright — the ref's own pairing, and the right one: an explanation that
|
||
-- lingers on a ramp reads as a stuck tooltip, where a unit readout fading is the client's
|
||
-- signature. (Items Hide, units fade — that split still holds for the world mouseover.)
|
||
function BenillaUnitFrame_OnLeave(frame)
|
||
if SHOW_NEWBIE_TIPS == "1" then
|
||
GameTooltip:Hide()
|
||
else
|
||
GameTooltip:FadeOut()
|
||
end
|
||
end
|
||
|
||
function BenillaUnitFrame_OnEvent(frame)
|
||
-- UNIT_* events name their unit in arg1; ignore other units' updates.
|
||
if string.sub(event, 1, 5) == "UNIT_" and arg1 ~= frame.unit then
|
||
return
|
||
end
|
||
-- The hit-indicator feed (ref PlayerFrame_OnEvent's UNIT_COMBAT arm): no repaint —
|
||
-- the event carries feedback, not state.
|
||
if event == "UNIT_COMBAT" then
|
||
CombatFeedback_OnCombatEvent(frame, arg2, arg3, arg4, arg5)
|
||
return
|
||
end
|
||
BenillaUnitFrame_Update(frame)
|
||
-- The player's flag-change sound (decision 0646 §2/§4). The reference plays
|
||
-- igPVPUpdate inside PlayerFrame_UpdatePvPStatus's two show branches, which it only
|
||
-- ever reaches from UNIT_FACTION; our repaint runs from the shared Update on every
|
||
-- event, so the sound rides the (edge-fired) event instead of the repaint — one
|
||
-- sound per real flag change, which is what the reference audibly does.
|
||
if event == "UNIT_FACTION" and frame.unit == "player" and frame.pvpShown then
|
||
PlaySound("igPVPUpdate")
|
||
end
|
||
end
|
||
|
||
-- The PvP flag icon (decision 0646 §4). The reference writes this law twice with
|
||
-- identical branches — PlayerFrame_UpdatePvPStatus (ref-PlayerFrame.lua l.55-79) and the
|
||
-- tail of TargetFrame_CheckFaction (ref-TargetFrame.lua l.193-202) — so it lives once
|
||
-- here. Branch ORDER is the reference's and it is load-bearing: free-for-all wins
|
||
-- outright (an FFA-flagged player shows the FFA skull even while ordinarily flagged), and
|
||
-- the faction leg needs BOTH a resolvable side and the flag. `frame.pvpShown` is what the
|
||
-- caller sounds off.
|
||
function BenillaUnitFrame_UpdatePvP(frame)
|
||
local icon = frame.pvpIcon
|
||
if not icon then return end
|
||
local unit = frame.unit
|
||
local texture
|
||
if UnitIsPVPFreeForAll(unit) then
|
||
texture = "Interface\\TargetingFrame\\UI-PVP-FFA"
|
||
else
|
||
local factionGroup = UnitFactionGroup(unit)
|
||
if factionGroup and UnitIsPVP(unit) then
|
||
texture = "Interface\\TargetingFrame\\UI-PVP-" .. factionGroup
|
||
end
|
||
end
|
||
frame.pvpShown = texture ~= nil
|
||
if texture then
|
||
icon:SetTexture(texture)
|
||
icon:Show()
|
||
else
|
||
icon:Hide()
|
||
end
|
||
end
|
||
|
||
-- ── Combat feedback: the portrait hit indicator (decision 0576) ──────────────────────
|
||
-- Ref CombatFeedback.lua, transcribed onto frame-param style (the ref reads `this`).
|
||
-- Timings/colors/size factors verbatim. The words come from the GLOBALS, exactly as the ref
|
||
-- builds this table (CombatFeedback.lua l.6-17: CombatFeedbackText["MISS"] = TEXT(MISS)),
|
||
-- so a localized install shows its own — the app runs the real GlobalStrings.lua off the
|
||
-- patch chain before this file (ui_script/mod.rs). The enUS literals are the fallback for
|
||
-- the test harnesses, which load no patch chain.
|
||
COMBATFEEDBACK_FADEINTIME = 0.2
|
||
COMBATFEEDBACK_HOLDTIME = 0.7
|
||
COMBATFEEDBACK_FADEOUTTIME = 0.3
|
||
|
||
CombatFeedbackText = {
|
||
INTERRUPT = INTERRUPT or "Interrupt",
|
||
MISS = MISS or "Miss",
|
||
RESIST = RESIST or "Resist",
|
||
DODGE = DODGE or "Dodge",
|
||
PARRY = PARRY or "Parry",
|
||
BLOCK = BLOCK or "Block",
|
||
EVADE = EVADE or "Evade",
|
||
IMMUNE = IMMUNE or "Immune",
|
||
DEFLECT = DEFLECT or "Deflect",
|
||
ABSORB = ABSORB or "Absorb",
|
||
REFLECT = REFLECT or "Reflect",
|
||
}
|
||
|
||
function CombatFeedback_OnCombatEvent(frame, event, flags, amount, type)
|
||
local feedbackText = frame.feedbackText
|
||
if not feedbackText then return end
|
||
local fontHeight = frame.feedbackFontHeight
|
||
local text = ""
|
||
local r, g, b = 1.0, 1.0, 1.0
|
||
|
||
if event == "IMMUNE" then
|
||
fontHeight = fontHeight * 0.5
|
||
text = CombatFeedbackText[event]
|
||
elseif event == "WOUND" then
|
||
if amount ~= 0 then
|
||
if flags == "CRITICAL" or flags == "CRUSHING" then
|
||
fontHeight = fontHeight * 1.5
|
||
elseif flags == "GLANCING" then
|
||
fontHeight = fontHeight * 0.75
|
||
end
|
||
-- type > 0 = a spell school: the number reads yellow, physical white.
|
||
if type > 0 then
|
||
r, g, b = 1.0, 1.0, 0.0
|
||
end
|
||
text = amount
|
||
elseif flags == "ABSORB" then
|
||
fontHeight = fontHeight * 0.75
|
||
text = CombatFeedbackText["ABSORB"]
|
||
elseif flags == "BLOCK" then
|
||
fontHeight = fontHeight * 0.75
|
||
text = CombatFeedbackText["BLOCK"]
|
||
elseif flags == "RESIST" then
|
||
fontHeight = fontHeight * 0.75
|
||
text = CombatFeedbackText["RESIST"]
|
||
else
|
||
text = CombatFeedbackText["MISS"]
|
||
end
|
||
elseif event == "BLOCK" then
|
||
fontHeight = fontHeight * 0.75
|
||
text = CombatFeedbackText[event]
|
||
elseif event == "HEAL" then
|
||
text = amount
|
||
r, g, b = 0.0, 1.0, 0.0
|
||
if flags == "CRITICAL" then
|
||
fontHeight = fontHeight * 1.5
|
||
end
|
||
elseif event == "ENERGIZE" then
|
||
text = amount
|
||
r, g, b = 0.41, 0.8, 0.94
|
||
if flags == "CRITICAL" then
|
||
fontHeight = fontHeight * 1.5
|
||
end
|
||
else
|
||
text = CombatFeedbackText[event]
|
||
end
|
||
|
||
frame.feedbackStartTime = GetTime()
|
||
|
||
feedbackText:SetTextHeight(fontHeight)
|
||
feedbackText:SetText(text)
|
||
feedbackText:SetTextColor(r, g, b)
|
||
feedbackText:SetAlpha(0.0)
|
||
feedbackText:Show()
|
||
end
|
||
|
||
-- The fade envelope (ref CombatFeedback_OnUpdate): 0.2 s ramp in, 0.7 s hold, 0.3 s
|
||
-- ramp out, then Hide. GetTime-based like the ref — no per-tick accumulation.
|
||
function CombatFeedback_OnUpdate(frame)
|
||
local feedbackText = frame.feedbackText
|
||
if not (feedbackText and feedbackText:IsVisible()) then return end
|
||
local elapsedTime = GetTime() - frame.feedbackStartTime
|
||
local fadeInTime = COMBATFEEDBACK_FADEINTIME
|
||
if elapsedTime < fadeInTime then
|
||
feedbackText:SetAlpha(elapsedTime / fadeInTime)
|
||
return
|
||
end
|
||
local holdTime = COMBATFEEDBACK_HOLDTIME
|
||
if elapsedTime < fadeInTime + holdTime then
|
||
feedbackText:SetAlpha(1.0)
|
||
return
|
||
end
|
||
local fadeOutTime = COMBATFEEDBACK_FADEOUTTIME
|
||
if elapsedTime < fadeInTime + holdTime + fadeOutTime then
|
||
feedbackText:SetAlpha(1.0 - (elapsedTime - holdTime - fadeInTime) / fadeOutTime)
|
||
return
|
||
end
|
||
feedbackText:Hide()
|
||
end
|
||
|
||
-- Pull the unit's current state and repaint. A non-existent unit hides the whole frame.
|
||
-- The classification border art (TargetFrame_CheckClassification, ref-TargetFrame.lua
|
||
-- l.205-218) — transcribed branch for branch, and the shape is the surprise: 1.12 has FIVE
|
||
-- classifications but only THREE border textures, because elite, rareelite and worldboss all
|
||
-- take the same Elite art. There is no rare-elite border in this build and no rare-elite
|
||
-- tooltip word either (the level line's rank table is {"", ELITE, ELITE, BOSS, ""}), so
|
||
-- "rareelite" is a distinction the API makes and the pixels never do. Verified rather than
|
||
-- assumed, because later expansions DO ship UI-TargetingFrame-Rare-Elite and it would be the
|
||
-- natural thing to write: that path is absent from 1.12's patch chain entirely, and the ref
|
||
-- Lua sends rareelite to the Elite art.
|
||
--
|
||
-- SetTexture is the whole operation — no TexCoords, size or anchor changes. That is only
|
||
-- sound because all three BLPs are 256x128 (checked, not assumed), so the region's
|
||
-- XML-declared TexCoords (0.09375..1.0 x 0..0.78125 = the 232x100 crop) frame all three
|
||
-- identically, and our SetTexture touches only the path (it leaves tex_coords alone).
|
||
function BenillaTargetFrame_CheckClassification(frame)
|
||
local classification = UnitClassification(frame.unit)
|
||
if classification == "worldboss" or classification == "rareelite" or classification == "elite" then
|
||
frame.frameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite")
|
||
elseif classification == "rare" then
|
||
frame.frameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Rare")
|
||
else
|
||
frame.frameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame")
|
||
end
|
||
end
|
||
|
||
function BenillaUnitFrame_Update(frame)
|
||
local unit = frame.unit
|
||
if not UnitExists(unit) then
|
||
frame:Hide()
|
||
return
|
||
end
|
||
frame:Show()
|
||
|
||
frame.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
|
||
frame.healthBar:SetValue(UnitHealth(unit))
|
||
|
||
local maxPower = UnitPowerMax(unit)
|
||
if maxPower > 0 then
|
||
frame.powerBar:Show()
|
||
local _, token = UnitPowerType(unit)
|
||
local c = BENILLA_POWER_COLORS[token] or BENILLA_POWER_COLORS.MANA
|
||
frame.powerBar:SetStatusBarColor(c.r, c.g, c.b)
|
||
frame.powerBar:SetMinMaxValues(0, maxPower)
|
||
frame.powerBar:SetValue(UnitPower(unit))
|
||
else
|
||
frame.powerBar:Hide()
|
||
end
|
||
|
||
frame.nameText:SetText(UnitName(unit) or "Unknown")
|
||
|
||
-- The level slot (TargetFrame_CheckLevel, ref-TargetFrame.lua l.119-142): a corpse
|
||
-- target or one whose level "can't be told" (UnitLevel ≤ 0 — the −1 return for a
|
||
-- world boss / a hostile 10+ levels up) shows the skull instead of the number; a
|
||
-- told level is difficulty-colored when the target is attackable (GetDifficultyColor,
|
||
-- the same con law the V-plate paints its level with) and plain gold when not.
|
||
-- The player frame has no skull region and shows its own level, always gold.
|
||
local level = UnitLevel(unit)
|
||
if frame.highLevel then
|
||
if UnitIsCorpse(unit) or level <= 0 then
|
||
frame.levelText:Hide()
|
||
frame.highLevel:Show()
|
||
else
|
||
frame.levelText:SetText(level)
|
||
if UnitCanAttack("player", unit) then
|
||
local color = GetDifficultyColor(level)
|
||
frame.levelText:SetVertexColor(color.r, color.g, color.b)
|
||
else
|
||
frame.levelText:SetVertexColor(1.0, 0.82, 0.0)
|
||
end
|
||
frame.levelText:Show()
|
||
frame.highLevel:Hide()
|
||
end
|
||
else
|
||
frame.levelText:SetText(level)
|
||
end
|
||
|
||
-- Tint the name/level plate (target only; TargetFrame_CheckFaction, ref-TargetFrame.lua
|
||
-- l.144-191). A PLAYER-CONTROLLED target takes the player branch (l.145-174); only an NPC
|
||
-- takes the reaction swatch (l.179-190): the resolved UnitReactionColor (neutral →
|
||
-- yellow), or blue when the reaction can't be told (nil) — a player never reads the
|
||
-- reaction green, which is why the two paths differ at all.
|
||
-- The player branch runs the ref's full ladder now that the
|
||
-- PvP wire carries it (decision 0646 §4): hostile red, else attackable-but-not-hostile
|
||
-- yellow (l.158), else "we can assist them but they're PvP-flagged" green (l.163), else
|
||
-- blue. Only the tapped-by-other grey (l.176) is still deferred — it needs the tap wire.
|
||
-- The ref's first leg tests mutual attackability (UnitCanAttack both ways); our
|
||
-- UnitCanAttack carries only the player→unit direction, so UnitIsEnemy (reaction ≤ 2)
|
||
-- stands in for it — the same substitution this branch has always made. (The ref gates on
|
||
-- UnitPlayerControlled, which also covers pets; UnitIsPlayer is the player half we can
|
||
-- resolve — see the header deviation.)
|
||
if frame.nameBackground then
|
||
if UnitIsPlayer(unit) then
|
||
local c
|
||
if UnitIsEnemy(unit, "player") then
|
||
c = BENILLA_REACTION_COLORS[2]
|
||
elseif UnitCanAttack("player", unit) then
|
||
c = BENILLA_REACTION_COLORS[4]
|
||
elseif UnitIsPVP(unit) then
|
||
c = BENILLA_REACTION_COLORS[6]
|
||
end
|
||
if c then
|
||
frame.nameBackground:SetVertexColor(c.r, c.g, c.b)
|
||
else
|
||
frame.nameBackground:SetVertexColor(0.0, 0.0, 1.0)
|
||
end
|
||
else
|
||
local reaction = UnitReaction(unit, "player")
|
||
local c = reaction and BENILLA_REACTION_COLORS[reaction]
|
||
if c then
|
||
frame.nameBackground:SetVertexColor(c.r, c.g, c.b)
|
||
else
|
||
frame.nameBackground:SetVertexColor(0.0, 0.0, 1.0)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- The classification border (target only) — the ref's TargetFrame_Update calls
|
||
-- CheckClassification right here, between CheckFaction and CheckDead.
|
||
if frame.frameTexture then
|
||
BenillaTargetFrame_CheckClassification(frame)
|
||
end
|
||
|
||
-- DEAD text (target only): shown at zero health (ref TargetFrame_CheckDead). Blanked
|
||
-- via SetText when alive — a site that predates region Show/Hide (region.rs has the
|
||
-- real pair now, the level slot above uses it); equivalent either way.
|
||
if frame.deadText then
|
||
if UnitHealth(unit) <= 0 then
|
||
frame.deadText:SetText("DEAD")
|
||
else
|
||
frame.deadText:SetText("")
|
||
end
|
||
end
|
||
|
||
-- The PvP flag icon, on both frames (decision 0646 §4).
|
||
BenillaUnitFrame_UpdatePvP(frame)
|
||
|
||
-- The aura rows (target only) — the ref's TargetFrame_Update →
|
||
-- TargetDebuffButton_Update: repainted on PLAYER_TARGET_CHANGED and UNIT_AURA alike.
|
||
if unit == "target" then
|
||
BenillaTargetAuras_Update()
|
||
end
|
||
end
|
||
|
||
-- ref TargetFrame.lua l.2-3.
|
||
MAX_TARGET_DEBUFFS = 16
|
||
MAX_TARGET_BUFFS = 5
|
||
|
||
-- TargetDebuffButton_Update (ref-TargetFrame.lua l.263-387), transcribed onto the Era API
|
||
-- (decision 0255: UnitBuff returns name,icon,count,debuffType,… — the 1.12 original returned
|
||
-- the texture first). Only called with a live target (BenillaUnitFrame_Update guards).
|
||
-- DebuffTypeColor is defined by BuffFrame.xml, which loads AFTER this file — safe, because
|
||
-- this function only runs on events, never at load (no target exists at load).
|
||
function BenillaTargetAuras_Update()
|
||
local button
|
||
local numBuffs = 0
|
||
for i = 1, MAX_TARGET_BUFFS do
|
||
local name, icon = UnitBuff("target", i)
|
||
button = getglobal("BenillaTargetFrameBuff" .. i)
|
||
if name then
|
||
getglobal(button:GetName() .. "Icon"):SetTexture(icon or BENILLA_FALLBACK_ICON)
|
||
button:Show()
|
||
numBuffs = numBuffs + 1
|
||
else
|
||
button:Hide()
|
||
end
|
||
end
|
||
|
||
local numDebuffs = 0
|
||
for i = 1, MAX_TARGET_DEBUFFS do
|
||
local name, icon, count, debuffType = UnitDebuff("target", i)
|
||
button = getglobal("BenillaTargetFrameDebuff" .. i)
|
||
if name then
|
||
getglobal(button:GetName() .. "Icon"):SetTexture(icon or BENILLA_FALLBACK_ICON)
|
||
local color = DebuffTypeColor[debuffType] or DebuffTypeColor["none"]
|
||
local countText = getglobal(button:GetName() .. "Count")
|
||
if count and count > 1 then
|
||
countText:SetText(count)
|
||
else
|
||
countText:SetText("")
|
||
end
|
||
getglobal(button:GetName() .. "Border"):SetVertexColor(color.r, color.g, color.b)
|
||
button:Show()
|
||
numDebuffs = numDebuffs + 1
|
||
else
|
||
button:Hide()
|
||
end
|
||
end
|
||
|
||
-- The dynamic anchors (ref l.312-331). No target-of-target frame exists yet, so its
|
||
-- branches take the not-shown leg: wrap 6, buffs open under Debuff7.
|
||
local targetofTarget = false
|
||
local debuffWrap = 6
|
||
|
||
if UnitIsFriend("player", "target") then
|
||
BenillaTargetFrameBuff1:SetPoint("TOPLEFT", "BenillaTargetFrame", "BOTTOMLEFT", 5, 32)
|
||
BenillaTargetFrameDebuff1:SetPoint("TOPLEFT", "BenillaTargetFrameBuff1", "BOTTOMLEFT", 0, -2)
|
||
else
|
||
BenillaTargetFrameDebuff1:SetPoint("TOPLEFT", "BenillaTargetFrame", "BOTTOMLEFT", 5, 32)
|
||
BenillaTargetFrameBuff1:SetPoint("TOPLEFT", "BenillaTargetFrameDebuff7", "BOTTOMLEFT", 0, -2)
|
||
end
|
||
|
||
-- Shrink when the debuffs would overlap the frame (ref l.340-347): 21→17 icons,
|
||
-- 23→19 borders.
|
||
local debuffSize, debuffFrameSize
|
||
if (targetofTarget and numBuffs == 5) or numDebuffs >= debuffWrap then
|
||
debuffSize = 17
|
||
debuffFrameSize = 19
|
||
else
|
||
debuffSize = 21
|
||
debuffFrameSize = 23
|
||
end
|
||
|
||
for i = 1, 5 do
|
||
button = getglobal("BenillaTargetFrameBuff" .. i)
|
||
button:SetWidth(debuffSize)
|
||
button:SetHeight(debuffSize)
|
||
end
|
||
-- The ref resizes only the FIRST ROW's debuffs (l.358-368) — rows 2+ stay 17px always.
|
||
for i = 1, 6 do
|
||
button = getglobal("BenillaTargetFrameDebuff" .. i)
|
||
local border = getglobal(button:GetName() .. "Border")
|
||
border:SetWidth(debuffFrameSize)
|
||
border:SetHeight(debuffFrameSize)
|
||
button:SetWidth(debuffSize)
|
||
button:SetHeight(debuffSize)
|
||
end
|
||
|
||
-- Re-seat the wrap points (ref l.370-385) — constant with wrap pinned at 6, kept
|
||
-- verbatim so the ToT wrap-5 leg drops in unchanged.
|
||
getglobal("BenillaTargetFrameDebuff" .. debuffWrap):ClearAllPoints()
|
||
getglobal("BenillaTargetFrameDebuff" .. debuffWrap):SetPoint("LEFT", getglobal("BenillaTargetFrameDebuff" .. (debuffWrap - 1)), "RIGHT", 3, 0)
|
||
getglobal("BenillaTargetFrameDebuff" .. (debuffWrap + 1)):ClearAllPoints()
|
||
getglobal("BenillaTargetFrameDebuff" .. (debuffWrap + 1)):SetPoint("TOPLEFT", "BenillaTargetFrameDebuff1", "BOTTOMLEFT", 0, -2)
|
||
getglobal("BenillaTargetFrameDebuff" .. (debuffWrap + 2)):ClearAllPoints()
|
||
getglobal("BenillaTargetFrameDebuff" .. (debuffWrap + 2)):SetPoint("LEFT", getglobal("BenillaTargetFrameDebuff" .. (debuffWrap + 1)), "RIGHT", 3, 0)
|
||
if debuffWrap == 5 then
|
||
BenillaTargetFrameDebuff11:ClearAllPoints()
|
||
BenillaTargetFrameDebuff11:SetPoint("TOPLEFT", "BenillaTargetFrameDebuff6", "BOTTOMLEFT", 0, -2)
|
||
else
|
||
BenillaTargetFrameDebuff11:ClearAllPoints()
|
||
BenillaTargetFrameDebuff11:SetPoint("LEFT", "BenillaTargetFrameDebuff10", "RIGHT", 3, 0)
|
||
end
|
||
end
|
||
|
||
-- The aura hover (ref TargetDebuffButtonTemplate/TargetBuffButtonTemplate OnEnter,
|
||
-- l.60-62/l.79-81): the aura tooltip, seated BOTTOMRIGHT of the button.
|
||
function BenillaTargetAuraButton_OnEnter(button, harmful)
|
||
if not GameTooltip then return end -- engine tests load file subsets
|
||
GameTooltip:SetOwner(button, "ANCHOR_BOTTOMRIGHT", 15, -25)
|
||
if harmful then
|
||
GameTooltip:SetUnitDebuff("target", button:GetID())
|
||
else
|
||
GameTooltip:SetUnitBuff("target", button:GetID())
|
||
end
|
||
end
|
||
|
||
-- Left-click the player frame to target yourself (ref PlayerFrame_OnClick, the LeftButton
|
||
-- branch: an item on the cursor auto-equips, otherwise TargetUnit("player")); right-click
|
||
-- opens the SELF menu (ref's ToggleDropDownMenu at (106, 27), decision 0434 phase 5). The
|
||
-- ref's frame is a Button; ours is a mouse-enabled Frame, which fires OnClick on release
|
||
-- with arg1 = the button. The self-target itself is the byte-verified way the client
|
||
-- selects its own unit; the world-model click is a separate path, deliberately left out
|
||
-- (director's call).
|
||
function BenillaPlayerFrame_OnClick(button)
|
||
if button == "RightButton" then
|
||
ToggleDropDownMenu(1, nil, PlayerFrameDropDown, "BenillaPlayerFrame", 106, 27)
|
||
return
|
||
end
|
||
if button ~= "LeftButton" then return end
|
||
if CursorHasItem() then
|
||
AutoEquipCursorItem()
|
||
else
|
||
TargetUnit("player")
|
||
end
|
||
end
|
||
|
||
-- The right-click dropdowns (decision 0434 phase 5; ref TargetFrame.lua l.431-455,
|
||
-- PlayerFrame.lua l.235-241): MENU displayMode over the shared kit (UIDropDownMenu.xml),
|
||
-- the menus themselves from UnitPopup.xml. The menu pick is the ref's law: self → SELF,
|
||
-- party member → PARTY, other player → PLAYER, NPC → the bare raid-target icon list.
|
||
function TargetFrameDropDown_OnLoad()
|
||
UIDropDownMenu_Initialize(this, TargetFrameDropDown_Initialize, "MENU")
|
||
end
|
||
|
||
function TargetFrameDropDown_Initialize()
|
||
local menu
|
||
local name
|
||
if UnitIsUnit("target", "player") then
|
||
menu = "SELF"
|
||
elseif UnitIsPlayer("target") then
|
||
if UnitInParty("target") then
|
||
menu = "PARTY"
|
||
else
|
||
menu = "PLAYER"
|
||
end
|
||
else
|
||
-- The ref checks UnitIsUnit("target", "pet") → PET before this branch; no "pet"
|
||
-- token exists until the pet slice (phase 4).
|
||
menu = "RAID_TARGET_ICON"
|
||
name = RAID_TARGET_ICON
|
||
end
|
||
if menu then
|
||
UnitPopup_ShowMenu(TargetFrameDropDown, menu, "target", name)
|
||
end
|
||
end
|
||
|
||
function PlayerFrameDropDown_OnLoad()
|
||
UIDropDownMenu_Initialize(this, PlayerFrameDropDown_Initialize, "MENU")
|
||
end
|
||
|
||
function PlayerFrameDropDown_Initialize()
|
||
UnitPopup_ShowMenu(PlayerFrameDropDown, "SELF", "player")
|
||
end
|
||
|
||
-- ref TargetFrame_OnClick: right-click opens the unit menu at (120, 10). The ref's
|
||
-- LeftButton branch (SpellTargetUnit / DropItemOnUnit) rides the spell-cursor and
|
||
-- item-drop slices — a bare left-click is a no-op on the ref too.
|
||
function BenillaTargetFrame_OnClick(button)
|
||
if button == "RightButton" then
|
||
ToggleDropDownMenu(1, nil, TargetFrameDropDown, "BenillaTargetFrame", 120, 10)
|
||
end
|
||
end
|
||
]]></Script>
|
||
|
||
<!--
|
||
PLAYER FRAME (ref-PlayerFrame.xml). Button 232×100 at UIParent TOPLEFT (-19,-4) (l.4-13); the
|
||
negative x trims the art's transparent left padding, seating the visible frame flush at the
|
||
screen's top-left, exactly as the real client does (our UIParent is the screen).
|
||
-->
|
||
<!-- frameStrata BACKGROUND is the ref's own (`PlayerFrame.xml` l.4) — the unit frames live
|
||
BELOW the MEDIUM panel windows on purpose, and the player frame shares the top-left corner
|
||
with the left-slot panel. See the note on PartyFrame.xml's template (decision 0597) for why
|
||
the default MEDIUM makes a unit frame's bar children draw through a window's background. -->
|
||
<Frame name="BenillaPlayerFrame" frameStrata="BACKGROUND">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="-19" y="-4"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<!-- The bar trough: 119×41 black a=0.5 behind both bars (ref l.20-32). -->
|
||
<Texture name="$parentBackground">
|
||
<Size><AbsDimension x="119" y="41"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="106" y="-22"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Color r="0" g="0" b="0" a="0.5"/>
|
||
</Texture>
|
||
<!-- Portrait 64×64 TOPLEFT (42,-12) (ref l.35-46, which puts it in ARTWORK; ours sits
|
||
in BACKGROUND, a leftover of the pre-0884 layering. The ring art now clears it by
|
||
frame LEVEL, and nothing else in this layer overlaps the portrait's square, so the
|
||
two are indistinguishable here — left alone rather than churned inside a bug fix).
|
||
Texture set in OnLoad via SetPortraitToTexture (circle-masked). -->
|
||
<Texture name="$parentPortrait">
|
||
<Size><AbsDimension x="64" y="64"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="42" y="-12"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<!-- The ring art + name/level text live in $parentTextureFrame below, one frame level
|
||
ABOVE the bars, so they draw OVER the bar edges — the recessed-bar look. OnLoad puts
|
||
them there (SetFrameLevel); see the LAYERING note at the top of this file. -->
|
||
</Layers>
|
||
<Frames>
|
||
<!-- Health bar 119×12 TOPLEFT (106,-41), UI-StatusBar, green (ref l.288-315). -->
|
||
<StatusBar name="$parentHealthBar">
|
||
<Size><AbsDimension x="119" y="12"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="106" y="-41"/></Offset></Anchor>
|
||
</Anchors>
|
||
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
||
<BarColor r="0.0" g="1.0" b="0.0"/>
|
||
</StatusBar>
|
||
<!-- Power bar 119×12 TOPLEFT (106,-52), UI-StatusBar; color set at runtime (ref l.316-341). -->
|
||
<StatusBar name="$parentPowerBar">
|
||
<Size><AbsDimension x="119" y="12"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="106" y="-52"/></Offset></Anchor>
|
||
</Anchors>
|
||
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
||
<BarColor r="0.0" g="0.0" b="1.0"/>
|
||
</StatusBar>
|
||
<!-- The ring art + text, over the bars (ref TargetFrameTextureFrame). 232×100 fills the
|
||
parent; it draws over the bar edges because OnLoad pushes the bars one frame level
|
||
BELOW it (the ref's SetFrameLevel(bar, textureFrame-1)) — NOT because of where it
|
||
is declared. See the LAYERING note at the top of this file. -->
|
||
<Frame name="$parentTextureFrame">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<!-- Ring art, MIRRORED: TexCoords left=1.0 right=0.09375 top=0 bottom=0.78125 (ref l.55-57). -->
|
||
<Texture name="$parentTexture" file="Interface\TargetingFrame\UI-TargetingFrame">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<TexCoords left="1.0" right="0.09375" top="0" bottom="0.78125"/>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<!-- The PvP flag icon, 64×64 TOPLEFT (18,-20) (ref PlayerPVPIcon,
|
||
ref-PlayerFrame.xml l.124-135) — ARTWORK over the BACKGROUND ring art,
|
||
like the ref's. Texture chosen at runtime (decision 0646 §4); the ref's
|
||
PlayerPVPIconHitArea is deliberately OUT (see the header). -->
|
||
<Texture name="$parentPVPIcon" hidden="true">
|
||
<Size><AbsDimension x="64" y="64"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="18" y="-20"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="OVERLAY">
|
||
<!-- Name 100×10 CENTER (50,19) (ref l.58-69). -->
|
||
<FontString name="$parentNameText" inherits="GameFontNormalSmall" text="Unknown">
|
||
<Size><AbsDimension x="100" y="10"/></Size>
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="50" y="19"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
<!-- Level number CENTER (-63,-16) (ref l.70-78). -->
|
||
<FontString name="$parentLevelText" inherits="GameFontNormalSmall">
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="-63" y="-16"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
<!-- The portrait hit indicator (ref PlayerHitIndicator, decision 0576):
|
||
CENTER at (73,-42) from the frame's TOPLEFT — the portrait circle's
|
||
center. Hidden until a UNIT_COMBAT event lands; CombatFeedback drives
|
||
text/size/color and the fade. -->
|
||
<FontString name="$parentHitIndicator" hidden="true" inherits="NumberFontNormalHuge">
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="TOPLEFT"><Offset><AbsDimension x="73" y="-42"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad><![CDATA[BenillaUnitFrame_OnLoad(this, "player")]]></OnLoad>
|
||
<OnEvent><![CDATA[BenillaUnitFrame_OnEvent(this)]]></OnEvent>
|
||
<OnUpdate><![CDATA[CombatFeedback_OnUpdate(this)]]></OnUpdate>
|
||
<OnEnter><![CDATA[BenillaUnitFrame_OnEnter(this)]]></OnEnter>
|
||
<OnLeave><![CDATA[BenillaUnitFrame_OnLeave(this)]]></OnLeave>
|
||
<OnClick><![CDATA[BenillaPlayerFrame_OnClick(arg1)]]></OnClick>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- The SELF-menu dropdown host (ref $parentDropDown, PlayerFrame.xml): hidden state-holder
|
||
only — the list anchors to the player frame by name, never to this. -->
|
||
<Frame name="PlayerFrameDropDown" parent="BenillaPlayerFrame" inherits="UIDropDownMenuTemplate" hidden="true">
|
||
<Size><AbsDimension x="10" y="10"/></Size>
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="-20" y="-10"/></Offset></Anchor></Anchors>
|
||
<Scripts>
|
||
<OnLoad>PlayerFrameDropDown_OnLoad()</OnLoad>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- ref TargetDebuffButtonTemplate (l.26-68): 17×17 icon, 19×19 UI-Debuff-Overlays border
|
||
(dispel-tinted at update), bottom-right stack count. Sizes are re-set every update by the
|
||
shrink law (first row only, verbatim ref quirk). -->
|
||
<Button name="BenillaTargetDebuffTemplate" virtual="true">
|
||
<Size><AbsDimension x="17" y="17"/></Size>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
<Layer level="OVERLAY">
|
||
<Texture name="$parentBorder" file="Interface\Buttons\UI-Debuff-Overlays">
|
||
<Size><AbsDimension x="19" y="19"/></Size>
|
||
<Anchors><Anchor point="CENTER"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0.296875" right="0.5703125" top="0" bottom="0.515625"/>
|
||
</Texture>
|
||
<FontString name="$parentCount" inherits="NumberFontNormalSmall">
|
||
<Anchors><Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-1" y="0"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>BenillaTargetAuraButton_OnEnter(this, true)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Button>
|
||
|
||
<!-- ref TargetBuffButtonTemplate (l.69-87): 21×21 icon, no border, no count. -->
|
||
<Button name="BenillaTargetBuffTemplate" virtual="true">
|
||
<Size><AbsDimension x="21" y="21"/></Size>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<Texture name="$parentIcon" setAllPoints="true"/>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnEnter>BenillaTargetAuraButton_OnEnter(this, false)</OnEnter>
|
||
<OnLeave>GameTooltip:Hide()</OnLeave>
|
||
</Scripts>
|
||
</Button>
|
||
|
||
<!--
|
||
TARGET FRAME (ref-TargetFrame.xml). Button 232×100 at UIParent TOPLEFT (250,-4) (l.88-98). The
|
||
un-mirrored twin of the player frame: portrait window on the RIGHT, bars anchored TOPRIGHT.
|
||
-->
|
||
<!-- hidden="true" is a deliberate deviation from the ref (whose TargetFrame starts shown and
|
||
gets its no-target Hide behind the loading screen, before audio is live): our OnLoad
|
||
Update runs with audio up, so starting shown would fire OnHide's lost-target sound at
|
||
every login. Steady-state behavior is identical — Update Shows/Hides on target changes. -->
|
||
<!-- frameStrata LOW is the ref's own (`TargetFrame.xml` l.88) — one above the player frame's
|
||
BACKGROUND, still below the MEDIUM panels. Same reasoning as PlayerFrame above. -->
|
||
<Frame name="BenillaTargetFrame" hidden="true" frameStrata="LOW">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="250" y="-4"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<!-- Bar trough 119×41 black a=0.5 TOPRIGHT (-106,-22) (ref l.104-116). -->
|
||
<Texture name="$parentBackground">
|
||
<Size><AbsDimension x="119" y="41"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-106" y="-22"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Color r="0" g="0" b="0" a="0.5"/>
|
||
</Texture>
|
||
<!-- The level/name plate 119×19 TOPRIGHT (-106,-22) (ref l.117-128) — target only,
|
||
untinted (see the header deviation on faction tinting). -->
|
||
<Texture name="$parentNameBackground" file="Interface\TargetingFrame\UI-TargetingFrame-LevelBackground">
|
||
<Size><AbsDimension x="119" y="19"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-106" y="-22"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
<!-- Portrait 64×64 TOPRIGHT (-42,-12) (ref l.131-142, BORDER→BACKGROUND for the same
|
||
ring-over-portrait layering as the player). -->
|
||
<Texture name="$parentPortrait">
|
||
<Size><AbsDimension x="64" y="64"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-42" y="-12"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<!-- The ring art + name/level/dead text live in $parentTextureFrame below (declared AFTER
|
||
the bars) so they draw OVER the bar edges — the recessed-bar look. -->
|
||
</Layers>
|
||
<Frames>
|
||
<!-- Health bar 119×12 TOPRIGHT (-106,-41), UI-StatusBar, green (ref l.252-273). -->
|
||
<StatusBar name="$parentHealthBar">
|
||
<Size><AbsDimension x="119" y="12"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-106" y="-41"/></Offset></Anchor>
|
||
</Anchors>
|
||
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
||
<BarColor r="0.0" g="1.0" b="0.0"/>
|
||
</StatusBar>
|
||
<!-- Power bar 119×12 TOPRIGHT (-106,-52), UI-StatusBar; color set at runtime (ref l.274-292). -->
|
||
<StatusBar name="$parentPowerBar">
|
||
<Size><AbsDimension x="119" y="12"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-106" y="-52"/></Offset></Anchor>
|
||
</Anchors>
|
||
<BarTexture file="Interface\TargetingFrame\UI-StatusBar"/>
|
||
<BarColor r="0.0" g="0.0" b="1.0"/>
|
||
</StatusBar>
|
||
<!-- The ring art + text, over the bars (ref TargetFrameTextureFrame); it draws over the
|
||
bar edges because OnLoad pushes the bars one frame level BELOW it (the ref's
|
||
SetFrameLevel(bar, textureFrame-1)) — NOT because of where it is declared. See the
|
||
LAYERING note at the top of this file. -->
|
||
<Frame name="$parentTextureFrame">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<!-- Ring art, UN-mirrored: TexCoords left=0.09375 right=1.0 (ref l.146-151). -->
|
||
<Texture name="$parentTexture" file="Interface\TargetingFrame\UI-TargetingFrame">
|
||
<Size><AbsDimension x="232" y="100"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPLEFT" relativePoint="TOPLEFT"><Offset><AbsDimension x="0" y="0"/></Offset></Anchor>
|
||
</Anchors>
|
||
<TexCoords left="0.09375" right="1.0" top="0" bottom="0.78125"/>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<!-- The PvP flag icon, 64×64 TOPRIGHT (3,-20) (ref TargetPVPIcon,
|
||
ref-TargetFrame.xml l.208-219) — the player's icon mirrored to the
|
||
frame's other edge, same law (decision 0646 §4). -->
|
||
<Texture name="$parentPVPIcon" hidden="true">
|
||
<Size><AbsDimension x="64" y="64"/></Size>
|
||
<Anchors>
|
||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="3" y="-20"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="OVERLAY">
|
||
<!-- Name 100×10 CENTER (-50,19) (ref l.152-163). -->
|
||
<FontString name="$parentNameText" inherits="GameFontNormalSmall" text="Unknown">
|
||
<Size><AbsDimension x="100" y="10"/></Size>
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="-50" y="19"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
<!-- Level number CENTER (63,-16) (ref l.164-172). -->
|
||
<FontString name="$parentLevelText" inherits="GameFontNormalSmall">
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="63" y="-16"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
<!-- The "too high to tell" skull, 16×16 on the level slot (ref
|
||
TargetHighLevelTexture, l.184-195): shown for a corpse target or
|
||
UnitLevel ≤ 0, replacing the number (TargetFrame_CheckLevel). -->
|
||
<Texture name="$parentHighLevelTexture" file="Interface\TargetingFrame\UI-TargetingFrame-Skull">
|
||
<Size><AbsDimension x="16" y="16"/></Size>
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="63" y="-16"/></Offset></Anchor>
|
||
</Anchors>
|
||
</Texture>
|
||
<!-- DEAD, CENTER (-50,3), shown at zero health (ref l.173-181). Blank while alive. -->
|
||
<FontString name="$parentDeadText" inherits="GameFontNormalSmall">
|
||
<Anchors>
|
||
<Anchor point="CENTER" relativePoint="CENTER"><Offset><AbsDimension x="-50" y="3"/></Offset></Anchor>
|
||
</Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
<!-- The aura rows (ref l.293-481, names re-based on $parent). Static anchors are the
|
||
ref's; the update re-seats Debuff1/6/7/8/11 and Buff1 every pass (the friend swap +
|
||
the wrap law). Row 1 debuffs 1-6 (+3 gaps), row 2 debuffs 7-16, buffs below. -->
|
||
<Button name="$parentDebuff1" inherits="BenillaTargetDebuffTemplate" id="1">
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="5" y="32"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff2" inherits="BenillaTargetDebuffTemplate" id="2">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff1" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff3" inherits="BenillaTargetDebuffTemplate" id="3">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff2" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff4" inherits="BenillaTargetDebuffTemplate" id="4">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff3" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff5" inherits="BenillaTargetDebuffTemplate" id="5">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff4" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff6" inherits="BenillaTargetDebuffTemplate" id="6">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff5" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff7" inherits="BenillaTargetDebuffTemplate" id="7">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentDebuff1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff8" inherits="BenillaTargetDebuffTemplate" id="8">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff7" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff9" inherits="BenillaTargetDebuffTemplate" id="9">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff8" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff10" inherits="BenillaTargetDebuffTemplate" id="10">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff9" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff11" inherits="BenillaTargetDebuffTemplate" id="11">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff10" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff12" inherits="BenillaTargetDebuffTemplate" id="12">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff11" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff13" inherits="BenillaTargetDebuffTemplate" id="13">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff12" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff14" inherits="BenillaTargetDebuffTemplate" id="14">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff13" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff15" inherits="BenillaTargetDebuffTemplate" id="15">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff14" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentDebuff16" inherits="BenillaTargetDebuffTemplate" id="16">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentDebuff15" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentBuff1" inherits="BenillaTargetBuffTemplate" id="1">
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="$parentDebuff1" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-2"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentBuff2" inherits="BenillaTargetBuffTemplate" id="2">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentBuff1" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentBuff3" inherits="BenillaTargetBuffTemplate" id="3">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentBuff2" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentBuff4" inherits="BenillaTargetBuffTemplate" id="4">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentBuff3" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
<Button name="$parentBuff5" inherits="BenillaTargetBuffTemplate" id="5">
|
||
<Anchors><Anchor point="LEFT" relativeTo="$parentBuff4" relativePoint="RIGHT"><Offset><AbsDimension x="3" y="0"/></Offset></Anchor></Anchors>
|
||
</Button>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad><![CDATA[BenillaUnitFrame_OnLoad(this, "target")]]></OnLoad>
|
||
<OnEvent><![CDATA[BenillaUnitFrame_OnEvent(this)]]></OnEvent>
|
||
<OnEnter><![CDATA[BenillaUnitFrame_OnEnter(this)]]></OnEnter>
|
||
<OnLeave><![CDATA[BenillaUnitFrame_OnLeave(this)]]></OnLeave>
|
||
<!-- The select/deselect pair rides the frame's visibility, exactly the ref
|
||
(TargetFrame_OnShow/OnHide, TargetFrame.lua l.104-117). In 5875 data all three
|
||
select kits resolve to the same iSelectTarget.wav — the reaction branch is
|
||
data-plumbing fidelity, not an audible difference. -->
|
||
<OnShow><![CDATA[
|
||
if UnitIsEnemy("target", "player") then
|
||
PlaySound("igCreatureAggroSelect")
|
||
elseif UnitIsFriend("player", "target") then
|
||
PlaySound("igCharacterNPCSelect")
|
||
else
|
||
PlaySound("igCreatureNeutralSelect")
|
||
end
|
||
]]></OnShow>
|
||
<!-- ref TargetFrame_OnHide: the lost-target sound + close any open unit menu (a
|
||
cleared target must not leave its menu acting on a stale unit). -->
|
||
<OnHide><![CDATA[
|
||
PlaySound("INTERFACESOUND_LOSTTARGETUNIT")
|
||
CloseDropDownMenus()
|
||
]]></OnHide>
|
||
<OnClick><![CDATA[BenillaTargetFrame_OnClick(arg1)]]></OnClick>
|
||
</Scripts>
|
||
</Frame>
|
||
|
||
<!-- The target-menu dropdown host (ref $parentDropDown, TargetFrame.xml): hidden
|
||
state-holder only, like the player's above. -->
|
||
<Frame name="TargetFrameDropDown" parent="BenillaTargetFrame" inherits="UIDropDownMenuTemplate" hidden="true">
|
||
<Size><AbsDimension x="10" y="10"/></Size>
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="-20" y="-10"/></Offset></Anchor></Anchors>
|
||
<Scripts>
|
||
<OnLoad>TargetFrameDropDown_OnLoad()</OnLoad>
|
||
</Scripts>
|
||
</Frame>
|
||
</Ui>
|