Name | Type | is_array | initial_value |
-- in 1.31 and upto 1.32.9 PTR (when I wrote this). Frames are not correctly saved and loaded, breaking the game.
-- This runs all functions added to it with a 0s delay after the game was loaded.
FrameLoader = {
OnLoadTimer = function ()
for _,v in ipairs(FrameLoader) do v() end
end
,OnLoadAction = function()
TimerStart(FrameLoader.Timer, 0, false, FrameLoader.OnLoadTimer)
end
}
function FrameLoaderAdd(func)
if not FrameLoader.Timer then
FrameLoader.Trigger = CreateTrigger()
FrameLoader.Timer = CreateTimer()
TriggerRegisterGameEvent(FrameLoader.Trigger, EVENT_GAME_LOADED)
TriggerAddAction(FrameLoader.Trigger, FrameLoader.OnLoadAction)
end
table.insert(FrameLoader, func)
end
--[[ UnitInfoPanels V4f by Tasyen
AddUnitInfoPanel(frame, update[, condition])
frame is the containerPanel, update a function(unit) that runs every updateTick, condition is a function(unit) that returns true or false it is used to prevent rotating to this panel.
AddUnitInfoPanelEx(update, condition)
wrapper for AddUnitInfoPanel, it creates and returns a new frame
SetUnitInfoPanelFrame(frame)
makes a non SimpleFrame share visibility with the last Added InfoPanel, supports only one Frame per InfoPanel
SetUnitInfoPanelFrameEx()
wrapper SetUnitInfoPanelFrame creates and returns a new empty Frame
UnitInfoPanelAddTooltipListener(frame, code)
detects if this frame is visible if it is call the given function which should return a text which is the now wanted tooltipText.
UnitInfoCreateCustomInfo(parent, label, texture, tooltipCode)
return createContext, infoFrame, iconFrame, labelFrame, textFrame
UnitInfoGetUnit([player])
returns & recacls the current selected Unit
without a player it will use the local player.
function UnitInfoPanelSetPage(newPage, updateWanted)
ignores conditions, newPage can be "+" or "-" or a frame
--]]
do
local AutoRun = true -- (false) call InitUnitInfoPanels()
local wantedIndex = 1
local panels, panelsCondition, panelFrame, updates
local tooltipListener, tooltipBox, tooltipText
local isReforged = (BlzFrameGetChild ~= nil)
local UnitInfoPanelUnit = nil
local group, timer, trigger
local unitInfo, parent, pageUp, pageDown, pageUpBig, pageSwaps, createContext, activeIndex
local HAVE_BIG_PAGE_BUTTON = false --places a big unseeable Button over the UnitInfo, this button lies below all content of the Panels. But it breaks interactive non-SimpleFrames.
function UnitInfoGetUnit(player)
if not player then player = GetLocalPlayer() end
GroupEnumUnitsSelected(group, player, nil)
UnitInfoPanelUnit = FirstOfGroup(group)
GroupClear(group)
return UnitInfoPanelUnit
end
-- frame is the containerPanel, update a function(unit) that runs every updateTick, condition is a function that returns true or false it is used to prevent showing this panel currently.
function AddUnitInfoPanel(frame, update, condition)
BlzFrameSetParent(frame, BlzGetFrameByName("SimpleInfoPanelUnitDetail", 0))
table.insert(panels, frame)
panelsCondition[#panels] = condition
updates[#panels] = update
BlzFrameSetVisible(frame, false)
end
function AddUnitInfoPanelEx(update, condition)
local frame = BlzCreateFrameByType("SIMPLEFRAME", "", BlzGetFrameByName("SimpleInfoPanelUnitDetail", 0), "", 0)
AddUnitInfoPanel(frame, update, condition)
return frame
end
function SetUnitInfoPanelFrame(frame)
panelFrame[#panels] = frame
BlzFrameSetVisible(frame, false)
end
function SetUnitInfoPanelFrameEx()
local frame = BlzCreateFrameByType("FRAME", "", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
SetUnitInfoPanelFrame(frame)
return frame
end
-- detects if this frame is visible if it is call the given function which should return a text which is the now wanted tooltipText.
function UnitInfoPanelAddTooltipListener(frame, code)
if not tooltipListener[frame] then
table.insert(tooltipListener, frame)
tooltipListener[frame] = code
end
end
if not isReforged then
function UnitInfoAddTooltip(parent, frame)
-- pre reforged one can not use the auto generated mouse listener, hence create an empty button
local button = BlzCreateSimpleFrame("EmptySimpleButton", parent, 0)
local toolTip = BlzCreateFrameByType("SIMPLEFRAME", "", button, "", 0)
BlzFrameSetAllPoints(button, frame)
BlzFrameSetTooltip(button, toolTip)
BlzFrameSetLevel(button, 9)
BlzFrameSetVisible(toolTip, false)
return toolTip
end
else
function UnitInfoAddTooltip(parent, frame)
-- the used simpleFrame autogenerates a mouselistener, lets use it
local button = BlzFrameGetChild(parent, 0)
local toolTip = BlzCreateFrameByType("SIMPLEFRAME", "", parent, "", 0)
BlzFrameSetTooltip(button, toolTip)
BlzFrameSetVisible(toolTip, false)
return toolTip
end
end
function UnitInfoAddTooltipEx(parent, frame, code)
UnitInfoPanelAddTooltipListener(UnitInfoAddTooltip(parent, frame), code)
end
function UnitInfoCreateCustomInfo(parent, label, texture, tooltipCode)
createContext = createContext + 1
local infoFrame = BlzCreateSimpleFrame("SimpleInfoPanelIconRank", parent, createContext)
local iconFrame = BlzGetFrameByName("InfoPanelIconBackdrop", createContext)
local labelFrame = BlzGetFrameByName("InfoPanelIconLabel", createContext)
local textFrame = BlzGetFrameByName("InfoPanelIconValue", createContext)
BlzFrameSetText(labelFrame, label)
BlzFrameSetText(textFrame, "xxx")
BlzFrameSetTexture(iconFrame, texture, 0, false)
BlzFrameClearAllPoints(iconFrame)
BlzFrameSetSize(iconFrame, 0.028, 0.028)
if tooltipCode then
UnitInfoAddTooltipEx(infoFrame, iconFrame, tooltipCode)
end
return createContext, infoFrame, iconFrame, labelFrame, textFrame
end
local function PageSwapCheck()
pageSwaps = pageSwaps - 1
if pageSwaps < 0 then
print("Unit Info Panel - NO VALID PANEL", GetUnitName(UnitInfoPanelUnit))
return false
end
return true
end
local function nextPanel()
activeIndex = activeIndex + 1
if activeIndex > #panels then
activeIndex = 1
end
if PageSwapCheck() and not panelsCondition[activeIndex](UnitInfoPanelUnit) then
nextPanel()
end
end
local function prevPanel()
activeIndex = activeIndex - 1
if activeIndex < 1 then
activeIndex = #panels
end
if PageSwapCheck() and not panelsCondition[activeIndex](UnitInfoPanelUnit) then
prevPanel()
end
end
local function makeSub(frame)
BlzFrameSetParent(frame, parent)
end
function UnitInfoPanelSetPage(newPage, updateWanted)
if string.sub(tostring(newPage), 1, 12 ) == "framehandle:" then
local found = false
for i, v in ipairs(panels) do
if v == newPage or panelFrame[i] == newPage then
newPage = i
found = true
break
end
end
if not found then return end
end
BlzFrameSetVisible(panels[activeIndex], false)
BlzFrameSetVisible(panelFrame[activeIndex], false)
if newPage == "+" then
pageSwaps = #panels
nextPanel()
elseif newPage == "-" then
pageSwaps = #panels
prevPanel()
else
activeIndex = math.min(#panels, math.max(1, newPage))
end
if updateWanted then wantedIndex = activeIndex end
BlzFrameSetVisible(panels[activeIndex], true)
BlzFrameSetVisible(panelFrame[activeIndex], true)
end
local function defaultCondition() return true end
local function Init()
BlzLoadTOCFile("war3mapImported\\UnitInfoPanels.toc")
tooltipListener = {}
panelsCondition = __jarray(defaultCondition)
panels = {}
panelFrame = {}
updates = {}
activeIndex = 1
createContext = 1000
unitInfo = BlzGetFrameByName("SimpleInfoPanelUnitDetail", 0)
parent = BlzCreateFrameByType("SIMPLEFRAME", "", unitInfo, "", 0)
pageUp = BlzCreateSimpleFrame("UnitInfoSimpleIconButtonUp", unitInfo, 0)
pageDown = BlzCreateSimpleFrame("UnitInfoSimpleIconButtonDown", unitInfo, 0)
BlzFrameSetPoint(pageUp, FRAMEPOINT_TOPLEFT, unitInfo, FRAMEPOINT_TOPRIGHT, 0, 0)
if HAVE_BIG_PAGE_BUTTON then
pageUpBig = BlzCreateSimpleFrame("EmptySimpleButton", unitInfo, 0)
BlzFrameSetAllPoints(pageUpBig, unitInfo)
BlzFrameSetLevel(pageUpBig, 0)
BlzTriggerRegisterFrameEvent(trigger, pageUpBig, FRAMEEVENT_CONTROL_CLICK)
end
BlzTriggerRegisterFrameEvent(trigger, pageUp, FRAMEEVENT_CONTROL_CLICK)
BlzTriggerRegisterFrameEvent(trigger, pageDown, FRAMEEVENT_CONTROL_CLICK)
panels[1] = parent
makeSub(BlzGetFrameByName("SimpleInfoPanelIconDamage", 0))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconDamage", 1))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconArmor", 2))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconRank", 3))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconFood", 4))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconGold", 5))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconHero", 6))
makeSub(BlzGetFrameByName("SimpleInfoPanelIconAlly", 7))
-- tooltip handling
if isReforged then parent = BlzGetFrameByName("ConsoleUIBackdrop", 0) else parent = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0) end
tooltipBox = BlzCreateFrame("CustomUnitInfoTextBox", parent, 0, 0)
tooltipText = BlzCreateFrame("CustomUnitInfoText", tooltipBox, 0, 0)
BlzFrameSetAbsPoint(tooltipText, FRAMEPOINT_BOTTOMRIGHT, 0.79, 0.18)
BlzFrameSetSize(tooltipText, 0.275, 0)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_TOPLEFT, tooltipText, FRAMEPOINT_TOPLEFT, -0.01, 0.01)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_BOTTOMRIGHT, tooltipText, FRAMEPOINT_BOTTOMRIGHT, 0.005, -0.01)
BlzFrameSetVisible(tooltipBox, false)
TimerStart(timer, 0.05, true, function()
xpcall(function()
local found = false
if BlzFrameIsVisible(unitInfo) then
UnitInfoGetUnit(GetLocalPlayer())
for int = 1, #tooltipListener, 1 do
if BlzFrameIsVisible(tooltipListener[int]) then
BlzFrameSetText(tooltipText, tooltipListener[tooltipListener[int]](UnitInfoPanelUnit))
found = true
break
end
end
local useAblePages = 0
for i, v in ipairs(panels) do
if not panels[v] or panels[v](UnitInfoPanelUnit) then
useAblePages = useAblePages + 1
end
end
BlzFrameSetVisible(pageUp, useAblePages > 1)
BlzFrameSetVisible(pageDown, useAblePages > 1)
if wantedIndex ~= activeIndex and panelsCondition[wantedIndex](UnitInfoPanelUnit) then
UnitInfoPanelSetPage(wantedIndex)
end
if not panelsCondition[activeIndex](UnitInfoPanelUnit) then
UnitInfoPanelSetPage("+")
end
--for i, v in ipairs(updates) do v(UnitInfoPanelUnit) end
if updates[activeIndex] then updates[activeIndex](UnitInfoPanelUnit) end
BlzFrameSetVisible(panelFrame[activeIndex], true)
else
BlzFrameSetVisible(panelFrame[activeIndex], false)
end
BlzFrameSetVisible(tooltipBox, found)
end, print)
end)
end
function InitUnitInfoPanels()
group = CreateGroup()
timer = CreateTimer()
trigger = CreateTrigger()
TriggerAddAction(trigger, function()
if GetTriggerPlayer() == GetLocalPlayer() then
if BlzGetTriggerFrame() == pageDown then UnitInfoPanelSetPage("-", true) else UnitInfoPanelSetPage("+", true) end
end
end)
Init()
if FrameLoaderAdd then FrameLoaderAdd(Init) end
end
if AutoRun then
if OnInit then -- Total Initialization v5.2.0.1 by Bribe
OnInit.trig(InitUnitInfoPanels)
else
local real = MarkGameStarted
function MarkGameStarted()
real()
InitUnitInfoPanels()
end
end
end
end
-- Shows how much gold and Lumber bounty one gets when slaying an unit
do
local realFunction = InitUnitInfoPanels
local lumberText, goldText, parent
local createContext, infoFrame, iconFrame, labelFrame, textFrame
local function Init()
-- create a new Unit Info Panel, this panel can only be shown when the current selected unit's owner gives bounty
parent = AddUnitInfoPanelEx(function(unit)
local min, max
min = BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_NUMBER_OF_DICE) + BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE)
max = BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_NUMBER_OF_DICE) *BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_SIDES_PER_DIE) + BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE)
BlzFrameSetText(goldText, min.." - "..max)
min = BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_NUMBER_OF_DICE) + BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_BASE)
max = BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_NUMBER_OF_DICE) *BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_SIDES_PER_DIE) + BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_BASE)
BlzFrameSetText(lumberText, min.." - "..max)
end,
function(unit) return IsPlayerFlagSetBJ(PLAYER_STATE_GIVES_BOUNTY, GetOwningPlayer(unit)) end)
-- define locals
-- create a new custom Info and load all created frames into the locals
createContext, infoFrame, iconFrame, labelFrame, textFrame = UnitInfoCreateCustomInfo(parent, " Gold:", "UI\\Widgets\\ToolTips\\Human\\ToolTipGoldIcon", function(unit)
-- this function returns the text shown inside the tooltip when this UnitInfo is mouse hovered.
local min, max
min = BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_NUMBER_OF_DICE) + BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE)
max = BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_NUMBER_OF_DICE) *BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_SIDES_PER_DIE) + BlzGetUnitIntegerField(unit, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE)
return "Bounty Gold: "..min.." - "..max
.."\nWhen an unit owned by you kills this unit, you gain this amount of Gold.\nOnly unallied unit give bounty."
end)
local prevIcon = iconFrame
goldText = textFrame
BlzFrameSetPoint(iconFrame, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("SimpleHeroLevelBar", 0), FRAMEPOINT_BOTTOMLEFT, 0, -0.001)
-- 2. Custom Info
createContext, infoFrame, iconFrame, labelFrame, textFrame = UnitInfoCreateCustomInfo(parent, " Lumber:", "UI\\Widgets\\ToolTips\\Human\\ToolTipLumberIcon", function(unit)
local min, max
min = BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_NUMBER_OF_DICE) + BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_BASE)
max = BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_NUMBER_OF_DICE) *BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_SIDES_PER_DIE) + BlzGetUnitIntegerField(unit, UNIT_IF_LUMBER_BOUNTY_AWARDED_BASE)
return "Bounty Lumber: "..min.." - "..max
.."\nWhen an unit owned by you kills this unit, you gain this amount of Lumber.\nOnly unallied unit give bounty."
end)
lumberText = textFrame
BlzFrameSetPoint(iconFrame, FRAMEPOINT_TOPLEFT, prevIcon, FRAMEPOINT_TOPLEFT, 0.095, 0)
prevIcon = nil
end
function InitUnitInfoPanels()
realFunction()
Init()
if FrameLoaderAdd then FrameLoaderAdd(Init) end
end
end
-- Creates an UnitInfopanel showing the last 8 abilities the unit got, ignoring abilities having no tooltip.
-- Ignores abilities without a Tooltip: When BlzGetAbilityStringLevelField returns "Tool tip missing!" or "" or " "
do
local realFunction = InitUnitInfoPanels
local index, frame, tooltip, trigger, iconFrame, textFrame
local buttonCount, frameObject, parent
local function abiFilter(abi, text)
if BlzGetAbilityBooleanField(abi, ABILITY_BF_ITEM_ABILITY) then
return false
end
if text == "Tool tip missing!" or text == "" and text == " " then
return false
end
return true
end
local function Init()
buttonCount = 8 --has to fit the created frame
frameObject = {}
parent = BlzCreateSimpleFrame("CustomUnitInfoPanel2x4", BlzGetFrameByName("SimpleInfoPanelUnitDetail", 0), 0)
AddUnitInfoPanel(parent, function(unit)
local abi
local buttonIndex = 1
local abiIndex = 0
local text
while(buttonIndex <= buttonCount) do
abi = BlzGetUnitAbilityByIndex(unit, abiIndex)
if abi then
text = BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL, 0)
if abiFilter(abi, text) then
frameObject[buttonIndex].Skill = abiIndex
BlzFrameSetVisible(frameObject[buttonIndex].Button, true)
BlzFrameSetTexture(frameObject[buttonIndex].Icon, BlzGetAbilityStringLevelField(abi, ABILITY_SLF_ICON_NORMAL, 0), 0, false)
BlzFrameSetText(frameObject[buttonIndex].Text, text)
buttonIndex = buttonIndex + 1
end
abiIndex = abiIndex + 1
else
BlzFrameSetVisible(frameObject[buttonIndex].Button, false)
buttonIndex = buttonIndex + 1
end
end
end,
function(unit) return IsUnitOwnedByPlayer(unit, Player(PLAYER_NEUTRAL_AGGRESSIVE)) end
)
for int = 1, buttonCount do
frame = BlzGetFrameByName("CustomUnitInfoButton"..int, 0)
tooltip = BlzCreateFrameByType("SIMPLEFRAME", "", frame, "", 0)
iconFrame = BlzGetFrameByName("CustomUnitInfoButtonIcon"..int, 0)
textFrame = BlzGetFrameByName("CustomUnitInfoButtonText"..int, 0)
BlzTriggerRegisterFrameEvent(trigger, frame, FRAMEEVENT_CONTROL_CLICK)
BlzFrameSetTooltip(frame, tooltip)
BlzFrameSetVisible(tooltip, false)
UnitInfoPanelAddTooltipListener(tooltip, function(unit)
-- the tooltip function is async do not create or destroy here
local abi = BlzGetUnitAbilityByIndex(unit, frameObject[int].Skill)
if BlzGetAbilityBooleanField(abi, ABILITY_BF_HERO_ABILITY) then
return BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_LEARN, 0) .."\n"..BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_LEARN_EXTENDED, 0)
else
return BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL, 0) .."\n"..BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED, 0)
end
end)
frameObject[int] = {Index = int, Icon = iconFrame, Text = textFrame, Button = frame, ToolTip = tooltip}
frameObject[frame] = frameObject[int]
end
end
function InitUnitInfoPanels()
realFunction()
trigger = CreateTrigger()
TriggerAddAction(trigger, function()
-- request currently used unit of the clicking player
local unit = UnitInfoGetUnit(GetTriggerPlayer())
-- get the clicked buttonIndex
local buttonIndex = frameObject[BlzGetTriggerFrame()].Index
-- do something base on the unit and buttonIndex
print("Skill Panel")
print(GetPlayerName(GetTriggerPlayer()),"Clicked:", frameObject[BlzGetTriggerFrame()].Index, GetUnitName(unit))
end)
Init()
if FrameLoaderAdd then FrameLoaderAdd(Init) end
end
end
-- CustomStat3x4
do
local realFunction = InitUnitInfoPanels
local parent, frameObject, buttonCount, Data, unit
local index, frame, tooltip, trigger, iconFrame, textFrame
local ArmorRatio = 0.06
local TooltipNumberColor = "|cffffcc00"
-- How strong are Hero Attributes (for Tooltip)
local HeroAgiArmor = nil -- autocalced when nil
local HeroAgiArmorBoni = -2
local HeroAgiATKSpeed = 0.02
local HeroAgiMoveSpeed = nil -- autocalced when nil
local HeroStrLife = nil -- autocalced when nil
local HeroStrLifeReg = 0.05
local HeroIntMana = nil -- autocalced when nil
local HeroIntManaReg = 0.05
local HeroDamageBonus = nil -- autocalced when nil (upto 0.00x precision)
Data = {
{"COLON_DAMAGE", "ReplaceableTextures\\CommandButtons\\BTNSteelMelee", "Damage done by each Basic Attack"},
{"Armor: ", "ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpOne", "Reduces Taken non magical damage", "COLON_DAMAGE_REDUCTION"},
{"Ress: ", "ReplaceableTextures\\CommandButtons\\BTNThickFur", "Reduces Taken magical damage"},
{"Crit: ", "ReplaceableTextures\\CommandButtons\\BTNCriticalStrike",""},
{"COLON_MOVE_SPEED", "ReplaceableTextures\\CommandButtons\\BTNBootsOfSpeed", "TURN-RATE"},
{"COLON_STRENGTH", "ReplaceableTextures\\CommandButtons\\BTNGauntletsOfOgrePower", "Increases Life and Liferegeneration"},
{"COLON_AGILITY", "ReplaceableTextures\\CommandButtons\\BTNSlippersOfAgility", "Improves Armor and Attackspeed"},
{"COLON_INTELLECT", "ReplaceableTextures\\CommandButtons\\BTNMantleOfIntelligence", "Improves Mana and Manaregeneration"},
{"Zaubermacht: ", "ReplaceableTextures\\CommandButtons\\BTNControlMagic", "Makes most abilities better"},
{"Hp/s: ", "ReplaceableTextures\\CommandButtons\\BTNRegenerate",""},
{"Mp/s: ", "ReplaceableTextures\\CommandButtons\\BTNMagicalSentry",""},
{"Ausweichen: ", "ReplaceableTextures\\CommandButtons\\BTNEvasion",""}
}
local percentChar = "\x25"
-- HERO_ATTRIBUTE_STR = 0 offset HERO_ATTRIBUTE_INT = 2 HERO_ATTRIBUTE_AGI = 1
local HeroAttributeOffset = {0,2,1}
local DefTypeKey = {
"ARMORTIP_SMALL",
"ARMORTIP_MEDIUM",
"ARMORTIP_LARGE",
"ARMORTIP_FORT",
"ARMORTIP_NORMAL",
"ARMORTIP_HERO",
"ARMORTIP_DIVINE",
"ARMORTIP_NONE",
"ARMORTIP_UNKNOWN"
}
--[[
DEFENSE_TYPE_LIGHT = ConvertDefenseType(0)
DEFENSE_TYPE_MEDIUM = ConvertDefenseType(1)
DEFENSE_TYPE_LARGE = ConvertDefenseType(2)
DEFENSE_TYPE_FORT = ConvertDefenseType(3)
DEFENSE_TYPE_NORMAL = ConvertDefenseType(4)
DEFENSE_TYPE_HERO = ConvertDefenseType(5)
DEFENSE_TYPE_DIVINE = ConvertDefenseType(6)
DEFENSE_TYPE_NONE = ConvertDefenseType(7)
-]]
local AtkTypeKey = {
"DAMAGETIP_NORMAL",
"DAMAGETIP_MELEE",
"DAMAGETIP_PIERCE",
"DAMAGETIP_SIEGE",
"DAMAGETIP_MAGIC",
"DAMAGETIP_CHAOS",
"DAMAGETIP_HERO"
}
--[[
ATTACK_TYPE_NORMAL = ConvertAttackType(0)
ATTACK_TYPE_MELEE = ConvertAttackType(1)
ATTACK_TYPE_PIERCE = ConvertAttackType(2)
ATTACK_TYPE_SIEGE = ConvertAttackType(3)
ATTACK_TYPE_MAGIC = ConvertAttackType(4)
ATTACK_TYPE_CHAOS = ConvertAttackType(5)
ATTACK_TYPE_HERO = ConvertAttackType(6)
-]]
local function NoDigits(text)
return string.format( percentChar..".0f", text)
end
-- this index requires a custom Tooltip function
local function NonSimpleRising(amount, ratio)
if amount >= 0 then
amount = (amount * ratio) / (amount * ratio + 1 )
return 1 - 1 * amount
else
amount = - amount
return 1 + 1 * amount * ratio -- negative power is linear
end
end
-- have a customized Tooltip function?
local TooltipFunctions = {
-- this functions are called async (don't create objects, also clear all handle-references started in this functions)
[1] = function(unit)
local text = GetLocalizedString(Data[1][1])
.. " ".. BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0))
.."\n"..GetLocalizedString(Data[1][3])
-- + 1 because the Types and DefTypeKey indexes are shifted by 1
-- does not work in Warcraft 3 V1.31
if GetLocalizedString("REFORGED") ~= "REFORGED" then
text = text .. "\n\n".. GetLocalizedString(AtkTypeKey[BlzGetUnitWeaponIntegerField(unit, UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE, 0) + 1])
end
return text
end
,[2] = function(unit)
return GetLocalizedString(Data[2][1])
.." ".. BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 2))
.."\n" .. GetLocalizedString(Data[2][4]).. " ".. NoDigits((1 -NonSimpleRising(BlzGetUnitArmor(unit), ArmorRatio))*100) ..percentChar
.."\n"..GetLocalizedString(Data[2][3])
-- + 1 because the Types and DefTypeKey indexes are shifted by 1
.. "\n\n".. GetLocalizedString(DefTypeKey[BlzGetUnitIntegerField(unit, UNIT_IF_DEFENSE_TYPE) + 1])
end
,[5] = function(unit)
local text = GetLocalizedString(Data[5][1])
if GetUnitMoveSpeed(unit) > GetUnitDefaultMoveSpeed(unit) then
text = text .." |cff01ff01".. NoDigits(GetUnitMoveSpeed(unit)) .. "|r"
elseif GetUnitMoveSpeed(unit) < GetUnitDefaultMoveSpeed(unit) then
text = text .." |cffff0101".. NoDigits(GetUnitMoveSpeed(unit)) .. "|r"
else
text = text .." " .. TooltipNumberColor .. GetUnitMoveSpeed(unit) .. "|r"
end
return text
end
,[6] = function(unit)
local text = GetLocalizedString(Data[6][1])
.." ".. BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroStrengthValue", 6))
.."\n".. "PerLevel: " .. TooltipNumberColor .. BlzGetUnitRealField(unit, UNIT_RF_STRENGTH_PER_LEVEL) .. "|r"
.."\n".. string.gsub(GetLocalizedString("BONUS_HITPOINTS"), percentChar..percentChar.."d", TooltipNumberColor..NoDigits(HeroStrLife) .. "|r (".. TooltipNumberColor .. NoDigits(HeroStrLife*GetHeroStr(unit, true)) .. "|r)" )
.."\n"..GetLocalizedString("BONUS_HPREGEN") .. " "..TooltipNumberColor.. HeroStrLifeReg .. "|r ("..TooltipNumberColor.. HeroStrLifeReg*GetHeroStr(unit, true) .. "|r)"
return text
end
,[7] = function(unit)
return GetLocalizedString(Data[7][1])
.." ".. BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroAgilityValue", 6))
.."\n".. "PerLevel: " .. TooltipNumberColor .. BlzGetUnitRealField(unit, UNIT_RF_AGILITY_PER_LEVEL) .. "|r"
.."\n"..GetLocalizedString("BONUS_ATTACK_SPEED").. " " .. TooltipNumberColor.. HeroAgiATKSpeed .. "|r (".. TooltipNumberColor.. NoDigits(HeroAgiATKSpeed*GetHeroAgi(unit, true)*100) .. percentChar .. "|r)"
.."\n"..string.gsub(GetLocalizedString("BONUS_DEFENSE_FIXED"), percentChar..percentChar.."d", TooltipNumberColor .. NoDigits(1/HeroAgiArmor) .. "|r") .. " (" .. TooltipNumberColor .. NoDigits(HeroAgiArmor * GetHeroAgi(unit, true) + HeroAgiArmorBoni) .."|r)"
end
,[8] = function(unit)
return GetLocalizedString(Data[8][1])
.." ".. BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroIntellectValue", 6))
.."\n".. "PerLevel: " .. TooltipNumberColor .. BlzGetUnitRealField(unit, UNIT_RF_INTELLIGENCE_PER_LEVEL) .. "|r"
.."\n".. string.gsub(GetLocalizedString("BONUS_MANA"), percentChar..percentChar.."d", TooltipNumberColor.. NoDigits(HeroIntMana) .. "|r (".. TooltipNumberColor.. NoDigits(HeroIntMana*GetHeroInt(unit, true)) .. "|r)" )
.."\n"..GetLocalizedString("BONUS_MANAREGEN") .. " " .. TooltipNumberColor.. HeroIntManaReg .. "|r (".. TooltipNumberColor.. HeroIntManaReg*GetHeroInt(unit, true) .. "|r)"
end
}
local function Init()
buttonCount = 12
frameObject = {}
-- preload this frames, they are later used in a async context, make sure they have a handleId for all players before using them in a local async context
-- otherwise you get a desync
BlzGetFrameByName("InfoPanelIconValue", 0)
BlzGetFrameByName("InfoPanelIconValue", 2)
BlzGetFrameByName("InfoPanelIconHeroStrengthValue", 6)
BlzGetFrameByName("InfoPanelIconHeroAgilityValue", 6)
BlzGetFrameByName("InfoPanelIconHeroIntellectValue", 6)
parent = BlzCreateSimpleFrame("CustomUnitInfoPanel3x4", BlzGetFrameByName("SimpleInfoPanelUnitDetail", 0), 0)
AddUnitInfoPanel(parent, function(unit)
--string.sub( BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)), string.find(text, " - ") + 3)
local text = string.sub( BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)), string.find(BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)), " - ") + 3)
if string.find(text, "+") then
local a, b = string.find(text, "+")
-- xxx |Cffffcc00+xx|r
-- combine both
local numberA = string.sub( text, 1, a - 12 )
local numberB = string.sub( text, b, string.len( text ) - 2)
text = tostring(tonumber(numberA) + tonumber(numberB))
elseif string.find(text, "-") then
local a, b = string.find(text, "-")
local numberA = string.sub( text, 1, a - 12 )
local numberB = string.sub( text, b, string.len( text ) - 2)
text = tostring(tonumber(numberA) + tonumber(numberB))
end
--BlzFrameSetText(frameObject[1].Text, string.sub( BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)), string.find(BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 0)), " - ") + 3))
BlzFrameSetText(frameObject[1].Text, text)
--BlzFrameSetText(frameObject[2].Text, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconValue", 2)))
BlzFrameSetText(frameObject[2].Text, NoDigits(BlzGetUnitArmor(unit)))
BlzFrameSetText(frameObject[3].Text, "0")
BlzFrameSetText(frameObject[4].Text, "0")
BlzFrameSetText(frameObject[5].Text, NoDigits(GetUnitMoveSpeed(unit)))
--BlzFrameSetText(frameObject[6].Text, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroStrengthValue", 6)))
--BlzFrameSetText(frameObject[7].Text, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroAgilityValue", 6)))
--BlzFrameSetText(frameObject[8].Text, BlzFrameGetText(BlzGetFrameByName("InfoPanelIconHeroIntellectValue", 6)))
BlzFrameSetText(frameObject[6].Text, GetHeroStr(unit, true))
BlzFrameSetText(frameObject[7].Text, GetHeroAgi(unit, true))
BlzFrameSetText(frameObject[8].Text, GetHeroInt(unit, true))
if IsUnitType(unit, UNIT_TYPE_HERO) then
local heroFrameOffset = HeroAttributeOffset[BlzGetUnitIntegerField(unit, UNIT_IF_PRIMARY_ATTRIBUTE)]
BlzFrameSetText(frameObject[6 + heroFrameOffset].Text, "*"..BlzFrameGetText(frameObject[6 + heroFrameOffset].Text))
end
BlzFrameSetText(frameObject[10].Text, string.format( percentChar..".1f", BlzGetUnitRealField(unit, UNIT_RF_HIT_POINTS_REGENERATION_RATE)))
BlzFrameSetText(frameObject[11].Text, string.format( percentChar..".1f", BlzGetUnitRealField(unit, UNIT_RF_MANA_REGENERATION)))
end,
function(unit) return IsUnitType(unit, UNIT_TYPE_HERO) end
)
for int = 1, buttonCount do
frame = BlzGetFrameByName("CustomUnitInfoButton"..int, 0)
tooltip = BlzCreateFrameByType("SIMPLEFRAME", "", frame, "", 0)
iconFrame = BlzGetFrameByName("CustomUnitInfoButtonIcon"..int, 0)
textFrame = BlzGetFrameByName("CustomUnitInfoButtonText"..int, 0)
BlzFrameSetTexture(iconFrame, Data[int][2], 0, false)
BlzTriggerRegisterFrameEvent(trigger, frame, FRAMEEVENT_CONTROL_CLICK)
BlzFrameSetTooltip(frame, tooltip)
BlzFrameSetVisible(tooltip, false)
if TooltipFunctions[int] then
UnitInfoPanelAddTooltipListener(tooltip, TooltipFunctions[int])
else
UnitInfoPanelAddTooltipListener(tooltip, function(unit) return GetLocalizedString(Data[int][1]) .. " ".. BlzFrameGetText(frameObject[int].Text).."\n"..GetLocalizedString(Data[int][3]) end)
end
frameObject[int] = {Index = int, Icon = iconFrame, Text = textFrame, Button = frame, ToolTip = tooltip}
frameObject[frame] = frameObject[int]
end
end
function InitUnitInfoPanels()
realFunction()
-- Detect HeroAttribute Power
if not HeroIntMana or not HeroStrLife or not HeroAgiArmor or not HeroAgiMoveSpeed or not HeroDamageBonus then
local hero = CreateUnit(Player(GetPlayerNeutralPassive()), FourCC('Hpal'), 0, 0, 0)
local oldValue
if not HeroStrLife then
oldValue = GetUnitState(hero, UNIT_STATE_MAX_LIFE)
SetHeroStr(hero, GetHeroStr(hero, false) + 1, true)
HeroStrLife = GetUnitState(hero, UNIT_STATE_MAX_LIFE) - oldValue
end
if not HeroDamageBonus then
-- find right attribute getter/setter in case Paladin is not a str hero anymore.
local get , set
if BlzGetUnitIntegerField(hero, UNIT_IF_PRIMARY_ATTRIBUTE) == GetHandleId(HERO_ATTRIBUTE_STR) then
get = GetHeroStr
set = SetHeroStr
elseif BlzGetUnitIntegerField(hero, UNIT_IF_PRIMARY_ATTRIBUTE) == GetHandleId(HERO_ATTRIBUTE_AGI) then
get = GetHeroAgi
set = SetHeroAgi
elseif BlzGetUnitIntegerField(hero, UNIT_IF_PRIMARY_ATTRIBUTE) == GetHandleId(HERO_ATTRIBUTE_INT) then
get = GetHeroInt
set = SetHeroInt
end
oldValue = BlzGetUnitBaseDamage(hero, 0)
set(hero, get(hero, false) + 1000, true)
HeroDamageBonus = (BlzGetUnitBaseDamage(hero, 0) - oldValue)/1000
end
if not HeroAgiArmor then
oldValue = BlzGetUnitArmor(hero)
SetHeroAgi(hero, GetHeroAgi(hero, false) + 1, true)
HeroAgiArmor = BlzGetUnitArmor(hero) - oldValue
end
if not HeroAgiMoveSpeed then
oldValue = GetUnitMoveSpeed(hero)
SetHeroAgi(hero, GetHeroAgi(hero, false) + 1, true)
HeroAgiMoveSpeed = GetUnitMoveSpeed(hero) - oldValue
end
if not HeroIntMana then
oldValue = GetUnitState(hero, UNIT_STATE_MAX_MANA)
SetHeroInt(hero, GetHeroInt(hero, false) + 1, true)
HeroIntMana = GetUnitState(hero, UNIT_STATE_MAX_MANA) - oldValue
end
RemoveUnit(hero)
hero = nil
end
trigger = CreateTrigger()
TriggerAddAction(trigger, function()
-- request currently used unit of the clicking player
local unit = UnitInfoGetUnit(GetTriggerPlayer())
-- get the clicked buttonIndex
local buttonIndex = frameObject[BlzGetTriggerFrame()].Index
-- do something base on the unit and buttonIndex
print("Custom Stat Panel")
print(GetPlayerName(GetTriggerPlayer()),"Clicked:", frameObject[BlzGetTriggerFrame()].Index, GetUnitName(unit))
end)
Init()
if FrameLoaderAdd then FrameLoaderAdd(Init) end
end
end
-- Examle for a non SimpleFrame Button
do
local realFunction = InitUnitInfoPanels
local parent, frameParent, textArea
local function Init()
BlzLoadTOCFile("war3mapImported\\Templates.toc")
parent = AddUnitInfoPanelEx(function(unit)
BlzFrameSetText(textArea, BlzGetAbilityExtendedTooltip(GetUnitTypeId(unit), 0))
end)
frameParent = SetUnitInfoPanelFrameEx()
textArea = BlzCreateFrameByType("TEXTAREA", "", frameParent, "EscMenuTextAreaTemplate", 0)
BlzFrameSetPoint(textArea, FRAMEPOINT_TOP, BlzGetFrameByName("SimpleHeroLevelBar", 0), FRAMEPOINT_BOTTOM, 0, -0.001)
BlzFrameSetSize(textArea, 0.18, 0.08)
end
function InitUnitInfoPanels()
realFunction()
Init()
if FrameLoaderAdd then FrameLoaderAdd(Init) end
end
end