library ArmorTooltipUI initializer InitArmorTooltip
globals
private unit array at_LastSel
private framehandle at_TooltipBox = null
private framehandle at_TooltipText = null
private framehandle at_ArmorIcon = null
private framehandle at_OverlayBtn = null // intercepts mouse so default tooltip won't show
private trigger at_SelectTrg = null
private trigger at_HoverTrg = null
private string array at_TypeName
endglobals
// ---------- helpers ----------
private function RoundInt takes real r returns integer
if r >= 0.0 then
return R2I(r + 0.5)
endif
return R2I(r - 0.5)
endfunction
private function ArmorReductionPercent takes real armor returns real
local real a
local real p
set a = armor
if a >= 0.0 then
set p = (0.06 * a) / (1.0 + 0.06 * a)
else
set a = -a
set p = - (0.06 * a) / (1.0 + 0.06 * a)
endif
return p * 100.0
endfunction
private function ArmorTypeToName takes defensetype dt returns string
if dt == DEFENSE_TYPE_NONE then
return at_TypeName[0]
elseif dt == DEFENSE_TYPE_LIGHT then
return at_TypeName[1]
elseif dt == DEFENSE_TYPE_MEDIUM then
return at_TypeName[2]
elseif dt == DEFENSE_TYPE_LARGE then
return at_TypeName[3]
elseif dt == DEFENSE_TYPE_FORT then
return at_TypeName[4]
elseif dt == DEFENSE_TYPE_HERO then
return at_TypeName[5]
elseif dt == DEFENSE_TYPE_DIVINE then
return at_TypeName[6]
endif
return "Armor"
endfunction
private function BuildTooltipText takes unit u returns string
local real armor
local integer armorI
local integer defTypeI
local string typeName
local real red
local string s
set armor = BlzGetUnitArmor(u)
set armorI = RoundInt(armor)
set defTypeI = BlzGetUnitIntegerField(u, UNIT_IF_DEFENSE_TYPE)
set typeName = ArmorTypeToName(ConvertDefenseType(defTypeI))
set red = ArmorReductionPercent(armor)
set s = ""
set s = s + "|cffffcc00Armor:|r " + I2S(armorI) + " (" + R2S(armor) + ")\n"
set s = s + "|cffffcc00Type:|r " + typeName + "\n"
set s = s + "|cffffcc00Damage Reduction:|r " + I2S(RoundInt(red)) + "%"
return s
endfunction
// ---------- selection tracking ----------
private function OnSelected takes nothing returns nothing
local integer pid
local unit u
set pid = GetPlayerId(GetTriggerPlayer())
set u = GetTriggerUnit()
set at_LastSel[pid] = u
endfunction
// ---------- UI ----------
private function FindArmorIcon takes nothing returns framehandle
local framehandle f
// Try common names across patches/skins
set f = BlzGetFrameByName("SimpleInfoPanelIconArmorType", 0)
if f != null then
return f
endif
set f = BlzGetFrameByName("InfoPanelIconArmor", 0)
if f != null then
return f
endif
set f = BlzGetFrameByName("SimpleInfoPanelIconArmor", 0)
return f
endfunction
private function CreateTooltipFrames takes nothing returns nothing
local framehandle parent
set parent = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
// Use stock tooltip container so z-order & skin look correct
set at_TooltipBox = BlzCreateFrame("Tooltip", parent, 0, 0)
call BlzFrameSetSize(at_TooltipBox, 0.24, 0.12)
call BlzFrameSetVisible(at_TooltipBox, false)
set at_TooltipText = BlzCreateFrameByType("TEXT", "ArmorTipText", at_TooltipBox, "", 0)
call BlzFrameSetPoint(at_TooltipText, FRAMEPOINT_TOPLEFT, at_TooltipBox, FRAMEPOINT_TOPLEFT, 0.010, -0.010)
call BlzFrameSetPoint(at_TooltipText, FRAMEPOINT_BOTTOMRIGHT, at_TooltipBox, FRAMEPOINT_BOTTOMRIGHT, -0.010, 0.010)
call BlzFrameSetEnable(at_TooltipText, false)
call BlzFrameSetTextAlignment(at_TooltipText, TEXT_JUSTIFY_LEFT, TEXT_JUSTIFY_TOP)
call BlzFrameSetText(at_TooltipText, "Armor…")
endfunction
private function RefreshTooltipText takes nothing returns nothing
local player lp
local integer pid
local unit u
local string txt
set lp = GetLocalPlayer()
set pid = GetPlayerId(lp)
set u = at_LastSel[pid]
if u != null then
set txt = BuildTooltipText(u)
else
set txt = "|cffffcc00Armor666:|r —\n|cffffcc00Type:|r —\n|cffffcc00Damage Reduction:|r —"
endif
if GetLocalPlayer() == lp then
call BlzFrameSetText(at_TooltipText, txt)
endif
endfunction
private function MakeOverlay takes nothing returns nothing
local framehandle parent
local trigger enter
local trigger leave
if at_ArmorIcon == null then
return
endif
set parent = BlzFrameGetParent(at_ArmorIcon)
// Transparent button overlay on top of the armor icon
set at_OverlayBtn = BlzCreateFrameByType("BUTTON", "ArmorOverlay", parent, "", 0)
call BlzFrameSetLevel(at_OverlayBtn, 10) // above icon
call BlzFrameClearAllPoints(at_OverlayBtn)
// Anchor overlay exactly to the icon (two corners is enough)
call BlzFrameSetPoint(at_OverlayBtn, FRAMEPOINT_TOPLEFT, at_ArmorIcon, FRAMEPOINT_TOPLEFT, 0.0, 0.0)
call BlzFrameSetPoint(at_OverlayBtn, FRAMEPOINT_BOTTOMRIGHT, at_ArmorIcon, FRAMEPOINT_BOTTOMRIGHT, 0.0, 0.0)
call BlzFrameSetVisible(at_OverlayBtn, true)
// Position our tooltip relative to the overlay
call BlzFrameClearAllPoints(at_TooltipBox)
call BlzFrameSetPoint(at_TooltipBox, FRAMEPOINT_BOTTOMLEFT, at_OverlayBtn, FRAMEPOINT_TOPRIGHT, 0.006, 0.006)
call BlzFrameSetTooltip(at_OverlayBtn, at_TooltipBox)
// Refresh text when hovered
set enter = CreateTrigger()
call BlzTriggerRegisterFrameEvent(enter, at_OverlayBtn, FRAMEEVENT_MOUSE_ENTER)
call TriggerAddAction(enter, function RefreshTooltipText)
set leave = CreateTrigger()
call BlzTriggerRegisterFrameEvent(leave, at_OverlayBtn, FRAMEEVENT_MOUSE_LEAVE)
call TriggerAddAction(leave, function RefreshTooltipText) // optional
endfunction
// Retry until the info panel exists, then build overlay
private function TryInitUI takes nothing returns nothing
local timer t
if at_TooltipBox == null then
call CreateTooltipFrames()
endif
if at_ArmorIcon == null then
set at_ArmorIcon = FindArmorIcon()
endif
if at_ArmorIcon != null and at_OverlayBtn == null then
call MakeOverlay()
endif
if at_OverlayBtn == null then
set t = CreateTimer()
call TimerStart(t, 0.10, false, function TryInitUI)
endif
endfunction
// ---------- core init ----------
private function InitCore takes nothing returns nothing
local integer i
set i = 0
set at_TypeName[0] = "None"
set at_TypeName[1] = "Light"
set at_TypeName[2] = "Medium"
set at_TypeName[3] = "Large" // your build
set at_TypeName[4] = "Fortified"
set at_TypeName[5] = "Hero"
set at_TypeName[6] = "Divine"
set at_SelectTrg = CreateTrigger()
loop
exitwhen i >= bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent(at_SelectTrg, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
set i = i + 1
endloop
call TriggerAddAction(at_SelectTrg, function OnSelected)
endfunction
// ---------- self-init ----------
private function InitArmorTooltip takes nothing returns nothing
call InitCore()
// tiny delay so Simple Info Panel frames exist
call TimerStart(CreateTimer(), 0.03, false, function TryInitUI)
endfunction
endlibrary