WoWInterface SVN oUF_Pazrael

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 58 to Rev 57
    Reverse comparison

Rev 58 → Rev 57

oUF_Pazrael/libs/LibMobHealth-4.0/LibMobHealth-4.0.toc New file
0,0 → 1,14
## Interface: 20400
## LoadOnDemand: 1
## Title: Lib: MobHealth-4.0
## Notes: Estimates a mob's health
## Author: ckknight
## X-Credits: neronix
## X-eMail: ckknight@gmail.com
## Version: 1.0
## X-Category: Library
## SavedVariables: LibMobHealth40DB, LibMobHealth40Opt
## X-License: LGPL v2.1
 
LibStub\LibStub.lua
lib.xml
oUF_Pazrael/libs/LibMobHealth-4.0/LibStub/LibStub.lua New file
0,0 → 1,30
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
 
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
oUF_Pazrael/libs/LibMobHealth-4.0/lib.xml New file
0,0 → 1,4
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibMobHealth-4.0.lua" />
</Ui>
\ No newline at end of file
oUF_Pazrael/libs/LibMobHealth-4.0/LibMobHealth-4.0.lua New file
0,0 → 1,714
--[[
Name: LibMobHealth-4.0
Revision: $Rev: 68090 $
Author: Cameron Kenneth Knight (ckknight@gmail.com)
Inspired By: MobHealth3 by Neronix
Website: http://www.wowace.com/
Description: Estimate a mob's health
License: LGPL v2.1
]]
 
local MAJOR_VERSION = "LibMobHealth-4.0"
local MINOR_VERSION = tonumber(("$Revision: 68090 $"):match("%d+")) or 0
 
-- #AUTODOC_NAMESPACE lib
 
local lib, oldMinor = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
if not lib then
return
end
local oldLib
if oldMinor then
oldLib = {}
for k,v in pairs(lib) do
oldLib[k] = v
lib[k] = nil
end
end
 
local _G = _G
local UnitLevel = _G.UnitLevel
local UnitIsPlayer = _G.UnitIsPlayer
local UnitPlayerControlled = _G.UnitPlayerControlled
local UnitName = _G.UnitName
local UnitHealth = _G.UnitHealth
local UnitHealthMax = _G.UnitHealthMax
local UnitIsFriend = _G.UnitIsFriend
local UnitIsDead = _G.UnitIsDead
local UnitCanAttack = _G.UnitCanAttack
local math_floor = _G.math.floor
local setmetatable = _G.setmetatable
local type = _G.type
local pairs = _G.pairs
local next = _G.next
 
local frame
if oldLib then
frame = oldLib.frame
frame:UnregisterAllEvents()
frame:SetScript("OnEvent", nil)
frame:SetScript("OnUpdate", nil)
_G.LibMobHealth40DB = nil
else
frame = _G.CreateFrame("Frame", MAJOR_VERSION .. "_Frame")
end
 
frame:RegisterEvent("UNIT_COMBAT")
frame:RegisterEvent("PLAYER_TARGET_CHANGED")
frame:RegisterEvent("PLAYER_FOCUS_CHANGED")
frame:RegisterEvent("UNIT_HEALTH")
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")
 
frame:SetScript("OnEvent", function(this, event, ...)
this[event](lib, ...)
end)
 
local mt = {__index = function(self, key)
if key == nil then
return nil
end
local t = {}
self[key] = t
return t
end}
 
local data = oldLib and oldLib.data
if data then
setmetatable(data, nil)
if not data.pc then
local npc, pc, pet, legacy = { {}, {}, {} }, {}, {}, {}
for k, v in pairs(data) do
legacy[k] = v
data[k] = nil
end
data.npc = npc
setmetatable(npc[1], mt)
setmetatable(npc[2], mt)
setmetatable(npc[3], mt)
data.pc = setmetatable(pc, mt)
data.pet = setmetatable(pet, mt)
data.legacy = setmetatable(legacy, mt)
elseif not rawget(data.npc, 1) or not rawget(data.npc, 2) or not rawget(data.npc, 3) then
data.npc = { setmetatable({}), setmetatable({}), setmetatable({}) }
end
else
data = {
npc = { setmetatable({}, mt), setmetatable({}, mt), setmetatable({}, mt), },
pc = setmetatable({}, mt),
pet = setmetatable({}, mt),
legacy = setmetatable({}, mt)
}
end
lib.data = data -- stores the maximum health of mobs that will actually be shown to the user
data.revision = MINOR_VERSION
 
local accumulatedHP = {setmetatable({}, mt), setmetatable({}, mt), setmetatable({}, mt)} -- Keeps Damage-taken data for mobs that we've actually poked during this session
local accumulatedPercent = {setmetatable({}, mt), setmetatable({}, mt), setmetatable({}, mt)} -- Keeps Percentage-taken data for mobs that we've actually poked during this session
local calculationUnneeded = {setmetatable({}, mt), setmetatable({}, mt), setmetatable({}, mt)} -- Keeps a list of things that don't need calculation (e.g. Beast Lore'd mobs)
 
local currentAccumulatedHP = { target = nil, focus = nil }
local currentAccumulatedPercent = { target = nil, focus = nil }
local currentName = { target = nil, focus = nil }
local currentLevel = { target = nil, focus = nil }
local recentDamage = { target = nil, focus = nil }
local lastPercent = { target = nil, focus = nil }
 
 
_G.hash_SlashCmdList["LIBMOBHEALTHFOUR"] = nil
_G.SlashCmdList["LIBMOBHEALTHFOUR"] = nil
 
function frame:ADDON_LOADED(name)
if name == MAJOR_VERSION then
-- if we're not an embedded library, then use a saved variable
frame:RegisterEvent("PLAYER_LOGOUT")
if type(_G.LibMobHealth40DB) == "table" then
data = _G.LibMobHealth40DB
if not data.pc then
local npc, pc, pet, legacy = { {}, {}, {} }, {}, {}, {}
for k, v in pairs(data) do
legacy[k] = v
data[k] = nil
end
data.npc = npc
data.pc = pc
data.pet = pet
data.legacy = legacy
elseif not rawget(data.npc, 1) or not rawget(data.npc, 2) or not rawget(data.npc, 3) then
if not data.legacy then
data.legacy = {}
end
for k, v in pairs(data.npc) do
data.legacy[k] = v
data.npc[k] = nil
end
data.npc = { {}, {}, {} }
end
setmetatable(data.npc[1], mt)
setmetatable(data.npc[2], mt)
setmetatable(data.npc[3], mt)
setmetatable(data.pc, mt)
setmetatable(data.pet, mt)
if not data.legacy then
data.legacy = {}
end
setmetatable(data.legacy, mt)
lib.data = data
else
_G.LibMobHealth40DB = data
end
 
local options = _G.LibMobHealth40Opt
if type(options) ~= "table" then
options = {
save = true,
prune = 1000,
}
_G.LibMobHealth40Opt = options
end
if type(options.save) ~= "boolean" then
options.save = true
end
if type(options.prune) ~= "number" then
options.prune = 1000
end
 
_G.hash_SlashCmdList["LIBMOBHEALTHFOUR"] = nil
_G.SlashCmdList["LIBMOBHEALTHFOUR"] = function(text)
text = text:lower():trim()
local alpha, bravo = text:match("^([^%s]+)%s+(.*)$")
if not alpha then
alpha = text
end
if alpha == "" or alpha == "help" then
DEFAULT_CHAT_FRAME:AddMessage(("|cffffff7f%s|r"):format(MAJOR_VERSION))
DEFAULT_CHAT_FRAME:AddMessage((" - |cffffff7f%s|r [%s] - %s"):format("save", options.save and "|cff00ff00On|r" or "|cffff0000Off|r", "whether to save mob health data"))
DEFAULT_CHAT_FRAME:AddMessage((" - |cffffff7f%s|r [%s] - %s"):format("prune", options.prune == 0 and "|cffff0000Off|r" or "|cff00ff00" .. options.prune .. "|r", "how many data points until data is pruned, 0 means no pruning"))
elseif alpha == "save" then
options.save = not options.save
DEFAULT_CHAT_FRAME:AddMessage(("|cffffff7f%s|r"):format(MAJOR_VERSION))
DEFAULT_CHAT_FRAME:AddMessage((" - |cffffff7f%s|r [%s]"):format("save", options.save and "|cff00ff00On|r" or "|cffff0000Off|r"))
elseif alpha == "prune" then
local bravo_num = tonumber(bravo)
if bravo_num then
options.prune = math.floor(bravo_num+0.5)
DEFAULT_CHAT_FRAME:AddMessage(("|cffffff7f%s|r"):format(MAJOR_VERSION))
DEFAULT_CHAT_FRAME:AddMessage((" - |cffffff7f%s|r [%s]"):format("prune", options.prune == 0 and "|cffff0000Off|r" or "|cff00ff00" .. options.prune .. "|r"))
else
DEFAULT_CHAT_FRAME:AddMessage(("|cffffff7f%s|r - prune must take a number, %q is not a number"):format(MAJOR_VERSION, bravo or ""))
end
else
DEFAULT_CHAT_FRAME:AddMessage(("|cffffff7f%s|r - unknown command %q"):format(MAJOR_VERSION, alpha))
end
end
 
_G.SLASH_LIBMOBHEALTHFOUR1 = "/lmh4"
_G.SLASH_LIBMOBHEALTHFOUR2 = "/lmh"
_G.SLASH_LIBMOBHEALTHFOUR3 = "/libmobhealth4"
_G.SLASH_LIBMOBHEALTHFOUR4 = "/libmobhealth"
 
function frame:PLAYER_LOGOUT()
if not options.save then
_G.LibMobHealth40DB = nil
return
end
local count = 0
setmetatable(data.npc, nil)
setmetatable(data.npc[1], nil)
setmetatable(data.npc[2], nil)
setmetatable(data.npc[3], nil)
setmetatable(data.pc, nil)
setmetatable(data.pet, nil)
setmetatable(data.legacy, nil)
for difficulty = 1, 3 do
for k, v in pairs(data.npc[difficulty]) do
if not next(v) then
data.npc[difficulty][k] = nil
else
for _ in pairs(v) do
count = count + 1
end
end
end
end
for _, kind in ipairs({ 'pc', 'pet', 'legacy' }) do
for k,v in pairs(data[kind]) do
if not next(v) then
data[kind][k] = nil
else
for _ in pairs(v) do
count = count + 1
end
end
end
end
if not next(data.legacy) then
data.legacy = nil
end
local prune = options.prune
if not prune or prune <= 0 then
return
end
if count <= prune then
return
end
 
if data.legacy then
-- prune all legacy data
for level, d in pairs(data.legacy) do
for mob in pairs(d) do
d[mob] = nil
count = count - 1
end
data.legacy[level] = nil
end
if count <= prune then
return
end
end
 
-- let's try to only have one mob-level, don't have duplicates for each level, since they can be estimated, and for players/pets, this will get rid of old data
for difficulty = 1, 3 do
local mobs = {}
for level, d in pairs(data.npc[difficulty]) do
for mob, health in pairs(d) do
if mobs[mob] then
d[mob] = nil
count = count - 1
end
mobs[mob] = level
end
if next(d) == nil then
data.npc[difficulty][level] = nil
end
end
end
for _, kind in ipairs({ 'pc', 'pet' }) do
local mobs = {}
for level, d in pairs(data[kind]) do
for mob, health in pairs(d) do
if mobs[mob] then
d[mob] = nil
count = count - 1
end
mobs[mob] = level
end
if next(d) == nil then
data[kind][level] = nil
end
end
end
if count <= prune then
return
end
-- still too much data, let's get rid of low-level non-bosses until we're at `prune`
local playerLevel = UnitLevel("player")
local maxLevel = playerLevel*3/4
if maxLevel > playerLevel - 5 then
maxLevel = playerLevel - 5
end
for level = 1, maxLevel do
for difficulty = 1, 3 do
local d = data.npc[difficulty][level]
if d then
for mob, health in pairs(d) do
d[mob] = nil
count = count - 1
end
data.npc[difficulty][level] = nil
if count <= prune then
return
end
end
end
for _, kind in ipairs({ 'pet', 'pc' }) do
local d = data[kind][level]
if d then
for mob, health in pairs(d) do
d[mob] = nil
count = count - 1
end
data[kind][level] = nil
if count <= prune then
return
end
end
end
end
end
end
frame:UnregisterEvent("ADDON_LOADED")
frame.ADDON_LOADED = nil
if IsLoggedIn() then
frame.PLAYER_LOGIN(self)
end
end
 
function frame:PLAYER_LOGIN()
if type(_G.MobHealth3DB) == "table" then
for index, value in pairs(_G.MobHealth3DB) do
if type(index) == "string" and type(value) == "number" then
local name, level = index:match("^(.+):(%-?%d+)$")
if name then
level = level+0
if not data.legacy[level][name] then
data.legacy[level][name] = value
end
end
end
end
end
frame:UnregisterEvent("PLAYER_LOGIN")
frame.PLAYER_LOGIN = nil
end
 
function frame:UNIT_COMBAT(unit, _, _, damage)
if (unit ~= "target" and unit ~= "focus") or not currentAccumulatedHP[unit] then
return
end
recentDamage[unit] = recentDamage[unit] + damage
end
 
local function PLAYER_unit_CHANGED(unit)
if not UnitCanAttack("player", unit) or UnitIsDead(unit) or UnitIsFriend("player", unit) then
-- don't store data on friends and dead men tell no tales
currentAccumulatedHP[unit] = nil
currentAccumulatedPercent[unit] = nil
return
end
 
local name, server = UnitName(unit)
if server and server ~= "" then
name = name .. "-" .. server
end
local isPlayer = UnitIsPlayer(unit)
local isPet = UnitPlayerControlled(unit) and not isPlayer -- some owners name their pets the same name as other people, because they're think they're funny. They're not.
currentName[unit] = name
local level = UnitLevel(unit)
currentLevel[unit] = level
 
recentDamage[unit] = 0
lastPercent[unit] = UnitHealth(unit)
 
local difficulty = 1
if not isPlayer and not isPet then
difficulty = GetInstanceDifficulty()
end
 
currentAccumulatedHP[unit] = accumulatedHP[difficulty][level][name]
currentAccumulatedPercent[unit] = accumulatedPercent[difficulty][level][name]
 
if not isPlayer and not isPet then
-- Mob
if not currentAccumulatedHP[unit] then
local saved = data.npc[difficulty][level][name]
if saved then
-- We claim that the saved value is worth 100%
accumulatedHP[difficulty][level][name] = saved
accumulatedPercent[difficulty][level][name] = 100
else
-- Nothing previously known. Start fresh.
accumulatedHP[difficulty][level][name] = 0
accumulatedPercent[difficulty][level][name] = 0
end
currentAccumulatedHP[unit] = accumulatedHP[difficulty][level][name]
currentAccumulatedPercent[unit] = accumulatedPercent[difficulty][level][name]
end
 
if currentAccumulatedPercent[unit] > 200 then
-- keep accumulated percentage below 200% in case we hit mobs with different hp
currentAccumulatedHP[unit] = currentAccumulatedHP[unit] / currentAccumulatedPercent[unit] * 100
currentAccumulatedPercent[unit] = 100
end
else
-- Player health can change a lot. Different gear, buffs, etc.. we only assume that we've seen 10% knocked off players previously
if not currentAccumulatedHP[unit] then
local saved = data[isPet and 'pet' or 'pc'][level][name]
if saved then
-- We claim that the saved value is worth 10%
accumulatedHP[difficulty][level][name] = saved/10
accumulatedPercent[difficulty][level][name] = 10
else
accumulatedHP[difficulty][level][name] = 0
accumulatedPercent[difficulty][level][name] = 0
end
currentAccumulatedHP[unit] = accumulatedHP[difficulty][level][name]
currentAccumulatedPercent[unit] = accumulatedPercent[difficulty][level][name]
end
 
if currentAccumulatedPercent[unit] > 10 then
currentAccumulatedHP[unit] = currentAccumulatedHP[unit] / currentAccumulatedPercent[unit] * 10
currentAccumulatedPercent[unit] = 10
end
end
end
 
function frame:PLAYER_TARGET_CHANGED()
PLAYER_unit_CHANGED("target")
end
 
function frame:PLAYER_FOCUS_CHANGED()
PLAYER_unit_CHANGED("focus")
end
 
function frame:UNIT_HEALTH(unit)
if (unit ~= "target" and unit ~= "focus") or not currentAccumulatedHP[unit] then
return
end
 
local current = UnitHealth(unit)
 
if unit == "focus" and UnitIsUnit("target", "focus") then
-- don't want to double-accumulate
recentDamage[unit] = 0
lastPercent[unit] = current
return
end
 
local max = UnitHealthMax(unit)
local name = currentName[unit]
local level = currentLevel[unit]
local difficulty = 1
local kind
if UnitIsPlayer(unit) then
kind = 'pc'
elseif UnitPlayerControlled(unit) then
kind = 'pet'
else
kind = 'npc'
difficulty = GetInstanceDifficulty()
end
 
if calculationUnneeded[difficulty][level][name] then
return
elseif current == 0 then
-- possibly targetting/focusing a dead person
elseif max ~= 100 then
-- beast lore, don't need to calculate.
if kind == 'npc' then
data.npc[difficulty][level][name] = max
else
data[kind][level][name] = max
end
calculationUnneeded[difficulty][level][name] = true
elseif current > lastPercent[unit] or lastPercent[unit] > 100 then
-- it healed, so let's reset our ephemeral calculations
lastPercent[unit] = current
recentDamage[unit] = 0
elseif recentDamage[unit] > 0 then
if current ~= lastPercent[unit] then
currentAccumulatedHP[unit] = currentAccumulatedHP[unit] + recentDamage[unit]
currentAccumulatedPercent[unit] = currentAccumulatedPercent[unit] + (lastPercent[unit] - current)
recentDamage[unit] = 0
lastPercent[unit] = current
 
if currentAccumulatedPercent[unit] >= 10 then
local num = currentAccumulatedHP[unit] / currentAccumulatedPercent[unit] * 100
if kind == 'npc' then
data.npc[difficulty][level][name] = num
else
data[kind][level][name] = num
end
end
end
end
end
 
local function guessAtMaxHealth(name, level, kind, difficulty, known)
-- if we have data on a mob of the same name but a different level, check within two levels and guess from there.
if not kind then
return guessAtMaxHealth(name, level, 'npc', GetInstanceDifficulty()) or guessAtMaxHealth(name, level, 'pc') or guessAtMaxHealth(name, level, 'pet') or guessAtMaxHealth(name, level, 'legacy')
elseif not difficulty then
difficulty = 1
end
 
if kind == 'npc' then
local value = data.npc[difficulty][level][name]
if value or level <= 0 or known then
return value
end
if level > 1 then
value = data.npc[difficulty][level - 1][name]
if value then
return value * level/(level - 1)
end
end
value = data.npc[difficulty][level + 1][name]
if value then
return value * level/(level + 1)
end
if level > 2 then
value = data.npc[difficulty][level - 2][name]
if value then
return value * level/(level - 2)
end
end
value = data.npc[difficulty][level + 2][name]
if value then
return value * level/(level + 2)
end
else
local value = data[kind][level][name]
if value or level <= 0 or known then
return value
end
if level > 1 then
value = data[kind][level - 1][name]
if value then
return value * level/(level - 1)
end
end
value = data[kind][level + 1][name]
if value then
return value * level/(level + 1)
end
if level > 2 then
value = data[kind][level - 2][name]
if value then
return value * level/(level - 2)
end
end
value = data[kind][level + 2][name]
if value then
return value * level/(level + 2)
end
end
return nil
end
 
--[[
Arguments:
string - name of the unit in question in the form of "Someguy", "Someguy-Some Realm"
number - level of the unit in question
string - kind of unit, can be "npc", "pc", "pet"
[optional] number - difficulty of the unit, only applies to "npc". see http://wowwiki.com/API_GetInstanceDifficulty for details. Can be 1, 2, or 3. 1 by default.
[optional] boolean - whether not to guess at the mob's health based on other levels of said mob.
Returns:
number or nil - the maximum health of the unit or nil if unknown
Example:
local hp = LibStub("LibMobHealth-4.0"):GetMaxHP("Young Wolf", 2)
]]
function lib:GetMaxHP(name, level, kind, difficulty, known)
local value = guessAtMaxHealth(name, level, kind, difficulty, known)
if value then
return math_floor(value + 0.5)
else
return nil
end
end
 
--[[
Arguments:
string - a unit ID
Returns:
number, boolean - the maximum health of the unit, whether the health is known or not
Example:
local maxhp, found = LibStub("LibMobHealth-4.0"):GetUnitMaxHP("target")
]]
function lib:GetUnitMaxHP(unit)
local max = UnitHealthMax(unit)
if max ~= 100 then
return max, true
end
local name, server = UnitName(unit)
if server and server ~= "" then
name = name .. "-" .. server
end
local level = UnitLevel(unit)
 
local kind
local difficulty = 1
if UnitIsPlayer(unit) then
kind = 'pc'
elseif UnitPlayerControlled(unit) then
kind = 'pet'
else
kind = 'npc'
difficulty = GetInstanceDifficulty()
end
 
local value = guessAtMaxHealth(name, level, kind, difficulty)
if value then
return math_floor(value + 0.5), true
else
return max, false
end
end
 
--[[
Arguments:
string - a unit ID
Returns:
number, boolean - the current health of the unit, whether the health is known or not
Example:
local curhp, found = LibStub("LibMobHealth-4.0"):GetUnitCurrentHP("target")
]]
function lib:GetUnitCurrentHP(unit)
local current, max = UnitHealth(unit), UnitHealthMax(unit)
if max ~= 100 then
return current, true
end
 
local name, server = UnitName(unit)
if server and server ~= "" then
name = name .. "-" .. server
end
local level = UnitLevel(unit)
 
local kind
local difficulty = 1
if UnitIsPlayer(unit) then
kind = 'pc'
elseif UnitPlayerControlled(unit) then
kind = 'pet'
else
kind = 'npc'
difficulty = GetInstanceDifficulty()
end
 
local value = guessAtMaxHealth(name, level, kind, difficulty)
if value then
return math_floor(current/max * value + 0.5), true
else
return current, false
end
end
 
--[[
Arguments:
string - a unit ID
Returns:
number, number, boolean - the current health of the unit, the maximum health of the unit, whether the health is known or not
Example:
local curhp, maxhp, found = LibStub("LibMobHealth-4.0"):GetUnitHealth("target")
]]
function lib:GetUnitHealth(unit)
local current, max = UnitHealth(unit), UnitHealthMax(unit)
if max ~= 100 then
return current, max, true
end
 
local name, server = UnitName(unit)
if server and server ~= "" then
name = name .. "-" .. server
end
local level = UnitLevel(unit)
 
local kind
local difficulty = 1
if UnitIsPlayer(unit) then
kind = 'pc'
elseif UnitPlayerControlled(unit) then
kind = 'pet'
else
kind = 'npc'
difficulty = GetInstanceDifficulty()
end
 
local value = guessAtMaxHealth(name, level, kind, difficulty)
if value then
return math_floor(current/max * value + 0.5), math_floor(value + 0.5), true
else
return current, max, false
end
end