Files
ElvUIModernized/!Compatibility/api/wowAPI.lua
T

331 lines
10 KiB
Lua

--Cache global variables
local _G = _G
local assert = assert
local date = date
local pairs = pairs
local tonumber = tonumber
local type = type
local unpack = unpack
local format, gsub, lower, match, upper = string.format, string.gsub, string.lower, string.match, string.upper
local getn = table.getn
--WoW API
local GetQuestGreenRange = GetQuestGreenRange
local GetRealZoneText = GetRealZoneText
local IsInInstance = IsInInstance
local UnitBuff = UnitBuff
local UnitDebuff = UnitDebuff
local UnitLevel = UnitLevel
--WoW Variables
local DUNGEON_DIFFICULTY1 = DUNGEON_DIFFICULTY1
local TIMEMANAGER_AM = gsub(TIME_TWELVEHOURAM, "^.-(%w+)$", "%1")
local TIMEMANAGER_PM = gsub(TIME_TWELVEHOURPM, "^.-(%w+)$", "%1")
--Libs
local LBC = LibStub("LibBabble-Class-3.0"):GetLookupTable()
local LBZ = LibStub("LibBabble-Zone-3.0"):GetLookupTable()
CLASS_SORT_ORDER = {
"WARRIOR",
"PALADIN",
"PRIEST",
"SHAMAN",
"DRUID",
"ROGUE",
"MAGE",
"WARLOCK",
"HUNTER"
}
MAX_CLASSES = getn(CLASS_SORT_ORDER)
LOCALIZED_CLASS_NAMES_MALE = {}
LOCALIZED_CLASS_NAMES_FEMALE = {}
CLASS_ICON_TCOORDS = {
["WARRIOR"] = {0, 0.25, 0, 0.25},
["MAGE"] = {0.25, 0.49609375, 0, 0.25},
["ROGUE"] = {0.49609375, 0.7421875, 0, 0.25},
["DRUID"] = {0.7421875, 0.98828125, 0, 0.25},
["HUNTER"] = {0, 0.25, 0.25, 0.5},
["SHAMAN"] = {0.25, 0.49609375, 0.25, 0.5},
["PRIEST"] = {0.49609375, 0.7421875, 0.25, 0.5},
["WARLOCK"] = {0.7421875, 0.98828125, 0.25, 0.5},
["PALADIN"] = {0, 0.25, 0.5, 0.75}
}
QuestDifficultyColors = {
["impossible"] = {r = 1.00, g = 0.10, b = 0.10},
["verydifficult"] = {r = 1.00, g = 0.50, b = 0.25},
["difficult"] = {r = 1.00, g = 1.00, b = 0.00},
["standard"] = {r = 0.25, g = 0.75, b = 0.25},
["trivial"] = {r = 0.50, g = 0.50, b = 0.50},
["header"] = {r = 0.70, g = 0.70, b = 0.70}
}
function hooksecurefunc(arg1, arg2, arg3)
local isMethod = type(arg1) == "table" and type(arg2) == "string" and type(arg1[arg2]) == "function" and type(arg3) == "function"
assert(isMethod or (type(arg1) == "string" and type(_G[arg1]) == "function" and type(arg2) == "function"), "Usage: hooksecurefunc([table,] \"functionName\", hookfunc)")
if not isMethod then
arg1, arg2, arg3 = _G, arg1, arg2
end
local original_func = arg1[arg2]
arg1[arg2] = function(...)
local original_return = {original_func(unpack(arg))}
arg3(unpack(arg))
return unpack(original_return)
end
end
--[[ issecurevariable([table], variable)
Returns 1, nil for undefined variables. This is because an undefined variable is secure since you have not tainted it.
Returns 1, nil for all untainted variables (i.e. Blizzard variables).
Returns nil for any global variable that is hooked insecurely (tainted), even unprotected ones like UnitName().
Returns nil for all user defined global variables.
If a table is passed first, it checks table.variable (e.g. issecurevariable(PlayerFrame, "Show") checks PlayerFrame["Show"] or PlayerFrame.Show (they are the same thing)).
]]
function issecurevariable(t, var)
-- assert(type(t) == "table" and type(var) == "string", "Usage: issecurevariable([table,] \"variable\")")
return
end
function UnitAura(unit, i, filter)
assert((type(unit) == "string" or type(unit) == "number") and (type(i) == "string" or type(i) == "number"), "Usage: UnitAura(\"unit\", index [, filter])")
if not filter or match(filter, "(HELPFUL)") then
local name, rank, aura, count, duration, maxDuration = UnitBuff(unit, i, filter)
return name, rank, aura, count, nil, duration or 0, maxDuration or 0
else
local name, rank, aura, count, dType, duration, maxDuration = UnitDebuff(unit, i, filter)
return name, rank, aura, count, dType, duration or 0, maxDuration or 0
end
end
function BetterDate(formatString, timeVal)
local dateTable = date("*t", timeVal)
local amString = (dateTable.hour >= 12) and "PM" or "AM"
--First, we'll replace %p with the appropriate AM or PM.
formatString = gsub(formatString, "^%%p", amString) --Replaces %p at the beginning of the string with the am/pm token
formatString = gsub(formatString, "([^%%])%%p", "%1"..amString) -- Replaces %p anywhere else in the string, but doesn't replace %%p (since the first % escapes the second)
return date(formatString, timeVal)
end
function GetQuestDifficultyColor(level)
local levelDiff = level - UnitLevel("player")
if levelDiff >= 5 then
return QuestDifficultyColors["impossible"]
elseif levelDiff >= 3 then
return QuestDifficultyColors["verydifficult"]
elseif levelDiff >= -2 then
return QuestDifficultyColors["difficult"]
elseif -levelDiff <= GetQuestGreenRange() then
return QuestDifficultyColors["standard"]
else
return QuestDifficultyColors["trivial"]
end
end
function FillLocalizedClassList(tab, female)
assert(type(tab) == "table", "Usage: FillLocalizedClassList(classTable[, isFemale])")
for _, engClass in ipairs(CLASS_SORT_ORDER) do
if female then
tab[engClass] = LBC[engClass]
else
tab[engClass] = LBC[gsub(lower(engClass), "^%l", upper)]
end
end
return true
end
FillLocalizedClassList(LOCALIZED_CLASS_NAMES_MALE)
FillLocalizedClassList(LOCALIZED_CLASS_NAMES_FEMALE, true)
local zoneInfo = {
-- Battlegrounds
[LBZ["Warsong Gulch"]] = {mapID = 443, maxPlayers = 10},
[LBZ["Arathi Basin"]] = {mapID = 461, maxPlayers = 15},
[LBZ["Alterac Valley"]] = {mapID = 401, maxPlayers = 40},
-- Raids
[LBZ["Zul'Gurub"]] = {mapID = 309, maxPlayers = 20},
[LBZ["Onyxia's Lair"]] = {mapID = 249, maxPlayers = 40},
[LBZ["Molten Core"]] = {mapID = 409, maxPlayers = 40},
[LBZ["Ruins of Ahn'Qiraj"]] = {mapID = 509, maxPlayers = 20},
[LBZ["Temple of Ahn'Qiraj"]] = {mapID = 531, maxPlayers = 40},
[LBZ["Blackwing Lair"]] = {mapID = 469, maxPlayers = 40},
[LBZ["Naxxramas"]] = {mapID = 533, maxPlayers = 40},
}
local mapByID = {}
for mapName in pairs(zoneInfo) do
mapByID[zoneInfo[mapName].mapID] = mapName
end
local function GetMaxPlayersByType(instanceType, zoneName)
if instanceType == "none" then
return 40
elseif instanceType == "party" then
return 5
elseif instanceType == "arena" then
return 5
elseif zoneName ~= "" and zoneInfo[zoneName] then
if instanceType == "pvp" then
return zoneInfo[zoneName].maxPlayers
elseif instanceType == "raid" then
return zoneInfo[zoneName].maxPlayers
end
else
return 0
end
end
function GetInstanceInfo()
local inInstance, instanceType = IsInInstance()
if not inInstance then return end
local name = GetRealZoneText()
local difficulty = 1
local difficultyName = DUNGEON_DIFFICULTY1
local maxPlayers = GetMaxPlayersByType(instanceType, name)
difficultyName = format("%d %s", maxPlayers, difficultyName)
return name, instanceType, difficulty, difficultyName, maxPlayers
end
function GetCurrentMapAreaID()
if not IsInInstance() then return end
local zoneName = GetRealZoneText()
if zoneName ~= "" and zoneInfo[zoneName] then
return zoneInfo[zoneName].mapID
else
return 0
end
end
function GetMapNameByID(id)
assert(type(id) == "string" or type(id) == "number", format("Bad argument #1 to \"GetMapNameByID\" (number expected, got %s)", id and type(id) or "no value"))
return mapByID[tonumber(id)]
end
local arrow
function GetPlayerFacing()
if not arrow then
local obj = Minimap
for i = 1, obj:GetNumChildren() do
local child = select(i, obj:GetChildren())
if child and child.GetModel and child:GetModel() == "interface\\minimap\\minimaparrow.m2" then
arrow = child
break
end
end
end
return arrow and arrow:GetFacing()
end
function ToggleFrame(frame)
if frame:IsShown() then
HideUIPanel(frame)
else
ShowUIPanel(frame)
end
end
local function OnOrientationChanged(self, orientation)
self.texturePointer.verticalOrientation = orientation == "VERTICAL"
if self.texturePointer.verticalOrientation then
self.texturePointer:SetPoint("BOTTOMLEFT", self)
else
self.texturePointer:SetPoint("LEFT", self)
end
end
local function OnSizeChanged(self, width, height)
self.texturePointer.width = width
self.texturePointer.height = height
self.texturePointer:SetWidth(width)
self.texturePointer:SetHeight(height)
end
local function OnValueChanged(self, value)
local _, max = self:GetMinMaxValues()
if self.texturePointer.verticalOrientation then
self.texturePointer:SetHeight(self.texturePointer.height * (value / max))
else
self.texturePointer:SetWidth(self.texturePointer.width * (value / max))
end
end
function CreateStatusBarTexturePointer(statusbar)
assert(type(statusbar) == "table", format("Bad argument #1 to \"CreateStatusBarTexturePointer\" (table expected, got %s)", statusbar and type(statusbar) or "no value"))
assert(statusbar.GetObjectType and statusbar:GetObjectType() == "StatusBar", "Bad argument #1 to \"CreateStatusBarTexturePointer\" (statusbar object expected)")
local f = statusbar:CreateTexture()
f.width = statusbar:GetWidth()
f.height = statusbar:GetHeight()
f.vertical = statusbar:GetOrientation() == "VERTICAL"
f:SetWidth(f.width)
f:SetHeight(f.height)
if f.verticalOrientation then
f:SetPoint("BOTTOMLEFT", statusbar)
else
f:SetPoint("LEFT", statusbar)
end
statusbar.texturePointer = f
statusbar:SetScript("OnSizeChanged", OnSizeChanged)
statusbar:SetScript("OnValueChanged", OnValueChanged)
hooksecurefunc(statusbar, "SetOrientation", OnOrientationChanged)
return f
end
local threatColors = {
[0] = {0.69, 0.69, 0.69},
[1] = {1, 1, 0.47},
[2] = {1, 0.6, 0},
[3] = {1, 0, 0}
}
function GetThreatStatusColor(statusIndex)
if not (type(statusIndex) == "number" and statusIndex >= 0 and statusIndex < 4) then
statusIndex = 0
end
return threatColors[statusIndex][1], threatColors[statusIndex][2], threatColors[statusIndex][3]
end
function GetThreatStatus(currentThreat, maxThreat)
assert(type(currentThreat) == "number" and type(maxThreat) == "number", "Usage: GetThreatStatus(currentThreat, maxThreat)")
if not maxThreat or maxThreat == 0 then
maxThreat = 0
maxThreat = 1
end
local threatPercent = currentThreat / maxThreat * 100
if threatPercent >= 100 then
return 3, threatPercent
elseif threatPercent < 100 and threatPercent >= 80 then
return 2, threatPercent
elseif threatPercent < 80 and threatPercent >= 50 then
return 1, threatPercent
else
return 0, threatPercent
end
end