1
0
Bifurcation 0
Ce dépôt a été archivé le 2020-03-15. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
questhelperredux/QuestHelper/utility.lua
2011-12-31 23:51:43 +00:00

449 lignes
15 Kio
Lua

local GetTime = debugprofilestop
QuestHelper_File["utility.lua"] = "4.0.1.$svnversion$"
QuestHelper_Loadtime["utility.lua"] = GetTime()
QuestHelper = CreateFrame("Frame", "QuestHelper", nil)
--[[ static ]] ALLIANCE = 1
--[[ static ]] HORDE = 2
local default_colour_theme =
{message_prefix={0.4, 0.78, 1},
message={1, 0.6, 0.2},
tooltip={1, 0.8, 0.5},
message_highlight={0.73, 1, 0.84},
menu_text={1, 1, 1},
menu_text_highlight={0, 0, 0},
menu={0, 0, 0},
menu_highlight={0.3, 0.5, 0.7},
menu_title_text={1, 1, 1},
menu_title_text_highlight={1, 1, 1},
menu_title={0, 0.2, 0.6},
menu_title_highlight={0.1, 0.4, 0.8}}
local xmas_colour_theme =
{message_prefix={0.0, 0.7, 0.0},
message={0.2, 1, 0.2},
tooltip={0.4, 1, 0.4},
message_highlight={1, 0.3, 0.1},
menu_text={1, 1, 1},
menu_text_highlight={0, 0, 0},
menu={0.2, 0, 0},
menu_highlight={1, 0.3, 0.3},
menu_title_text={0.8, 1, 0.8},
menu_title_text_highlight={1, 1, 1},
menu_title={0.2, 0.6, 0.2},
menu_title_highlight={0.4, 0.7, 0.4}}
function QuestHelper:GetColourTheme()
if date("%b%d") == "Dec25" then
return xmas_colour_theme
end
return default_colour_theme
end
QuestHelper.nop = function () end -- Who wouldn't want a function that does nothing?
function QuestHelper:HashString(text)
-- Computes an Adler-32 checksum.
local a, b = 1, 0
for i=1,string.len(text) do
a = (a+string.byte(text,i))%65521
b = (b+a)%65521
end
return b*65536+a
end
function QuestHelper:CreateUID(length)
local result = ""
local characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for k = 1, (math.floor(time() % 1000) + 5) do math.random() end -- it's sort of like seeding. only worse.
local base = GetUnitName("player")..":"..GetRealmName()..":"..math.random(0, 2147483647)..":"..time()..":"..time()
for c = 1,(length or 32) do
local pos = 1+math.floor(self:HashString(result..base..math.random(0, 2147483647))%string.len(characters))
result = result .. string.sub(characters, pos, pos)
end
return result
end
function QuestHelper:ZoneSanity()
local sane = true
for c in pairs(self.Astrolabe:GetMapVirtualContinents()) do
local pz = self.Astrolabe:GetMapVirtualZones(c)
pz[0] = true
for z in pairs(pz) do
local name
if z == 0 then
name = self.Astrolabe:GetMapVirtualContinents()[c]
else
name = self.Astrolabe:GetMapVirtualZones(c)[z]
end
--[[ assert(name) ]]
-- c,z should be equal to name, unless c = 5 and z = 0, in which case it should be equal to name .. " Continent"
if QuestHelper_Zones[c][z] ~= name then
sane = false
QuestHelper_ErrorCatcher_ExplicitError(false, string.format("'%s' has the wrong ID (should be %d,%d).", name, c, z))
--QuestHelper:TextOut(string.format("'%s' has the wrong ID (should be %d,%d).", name, c, z))
end
local pair = QuestHelper_ZoneLookup[name]
if not pair then
sane = false
QuestHelper_ErrorCatcher_ExplicitError(false, string.format("ZoneLookup['%s'] is missing data. PANIC!", name))
elseif c ~= pair[1] or z ~= pair[2] then
sane = false
QuestHelper_ErrorCatcher_ExplicitError(false, string.format("ZoneLookup['%s'] maps to wrong pair. It should be (%d, %d) but is (%d, %d)", name, c, z, pair[1], pair[2]))
--QuestHelper:TextOut("ZoneLookup['"..name.."'] maps to wrong pair.")
end
local index = QuestHelper_IndexLookup[name]
if QuestHelper_ZoneLookup[index] ~= pair then
sane = false
QuestHelper_ErrorCatcher_ExplicitError(false, "ZoneLookup['"..name.."'] isn't equal to ZoneLookup["..index.."] they are "..tostring(QuestHelper_ZoneLookup[name]).." and "..tostring(QuestHelper_ZoneLookup[index])..", respectively.")
--QuestHelper:TextOut("ZoneLookup['"..name.."'] isn't equal to ZoneLookup["..index.."] they are "..tostring(QuestHelper_ZoneLookup[name]).." and "..tostring(QuestHelper_ZoneLookup[index])..", respectively.")
end
if not index or QuestHelper_NameLookup[index] ~= name then
sane = false
QuestHelper_ErrorCatcher_ExplicitError(false, "NameLookup["..(index or "???").."] doesn't equal '"..name.."', it is "..tostring(QuestHelper_NameLookup[index]))
--QuestHelper:TextOut("NameLookup["..(index or "???").."] doesn't equal '"..name.."', it is "..tostring(QuestHelper_NameLookup[index]))
end
end
end
return sane
end
function QuestHelper:TextOut(text)
local theme = self:GetColourTheme()
DEFAULT_CHAT_FRAME:AddMessage(string.format("|cff%2x%2x%2xQuestHelper: |r%s", theme.message_prefix[1]*255,
theme.message_prefix[2]*255,
theme.message_prefix[3]*255, text),
theme.message[1],
theme.message[2],
theme.message[3])
end
function QuestHelper:Error(what)
--DEFAULT_CHAT_FRAME:AddMessage("QuestHelper Error: "..(what or "Unknown").."\n"..debugstack(2), 1,.5,0)
QuestHelper_ErrorCatcher_ExplicitError(true, what or "Unknown", nil, nil)
error((what or "") .. " Abort!")
end
function QuestHelper:HighlightText(text)
local theme = self:GetColourTheme()
return string.format("|cff%2x%2x%2x%s|r", theme.message_highlight[1]*255,
theme.message_highlight[2]*255,
theme.message_highlight[3]*255, text)
end
function QuestHelper:GetUnitID(unit)
local id = UnitGUID(unit)
if id then
return (string.sub(id, 5, 5) == "3") and tonumber(string.sub(id, 6, 12), 16) or nil
end
return nil
end
function QuestHelper:GetQuestID(index)
return tonumber(select(3, string.find(GetQuestLink(index), "|Hquest:(%d+):")))
end
-- For future reference:
-- Hearthstone = 6948
-- Rune of Teleportation = 17031
-- Rune of Portals = 17032
function QuestHelper:CountItem(item_id)
local count = 0
for bag = 0,NUM_BAG_SLOTS do
for slot = 1,GetContainerNumSlots(bag) do
local link = GetContainerItemLink(bag, slot)
if link and string.find(link, string.format("|Hitem:%d:", item_id)) then
count = count + (select(2, GetContainerItemInfo(bag, slot)) or 0)
end
end
end
return count
end
function QuestHelper:ItemCooldown(item_id)
local now = time()
local cooldown = nil
for bag = 0,NUM_BAG_SLOTS do
for slot = 1,GetContainerNumSlots(bag) do
local link = GetContainerItemLink(bag, slot)
if link and string.find(link, string.format("|Hitem:%d:", item_id)) then
local s, d, e = GetContainerItemCooldown(bag, slot)
if e then
if cooldown then
cooldown = math.min(cooldown, math.max(0, d-now+s))
else
cooldown = math.max(0, d-now+s)
end
else
return 0
end
end
end
end
return cooldown
end
function QuestHelper:TimeString(seconds)
if not seconds then
--self:AppendNotificationError("2008-10-8 nil-timestring") -- we're just going to do away with this entirely, the fact is that a lot of this is going to be ripped to shreds soon anyway
return "(unknown)"
end
local seconds = math.ceil(seconds)
local h, m, s = math.floor(seconds/(60*60)), math.floor(seconds/60)%60, seconds%60
if h > 0 then
return string.format("|cffffffff%d|r:|cffffffff%02d|r:|cffffffff%02d|r", h, m, s)
else
return string.format("|cffffffff%d|r:|cffffffff%02d|r", m, s)
end
end
function QuestHelper:ProgressString(str, pct)
if pct > 1 then
return string.format("|cff00ff00%s|r", str)
elseif pct < 0 then
return string.format("|cffff0000%s|r", str)
elseif pct > 0.5 then
return string.format("|cff%2xff00%s|r", 510-pct*510, str)
else
return string.format("|cffff%2x00%s|r", pct*510, str)
end
end
function QuestHelper:PercentString(pct)
if pct > 1 then
return string.format("|cff00ff00%.1f%%|r", pct*100)
elseif pct < 0 then
return string.format("|cffff0000%.1f%%|r", pct*100)
elseif pct > 0.5 then
return string.format("|cff%2xff00%.1f%%|r", 510-pct*510, pct*100)
else
return string.format("|cffff%2x00%.1f%%|r", pct*510, pct*100)
end
end
function QuestHelper:PlayerPosition()
return self.i, self.x, self.y
end
function QuestHelper:UnitPosition(unit)
local c, z, x, y = self.Astrolabe:GetUnitPosition(unit,true)
if c then
if z == 0 then
SetMapToCurrentZone()
z = GetCurrentMapZone()
if z ~= 0 then
x, y = self.Astrolabe:TranslateWorldMapPosition(c, 0, x, y, c, z)
end
end
return QuestHelper_IndexLookup[c][z], x, y
else
return self:PlayerPosition()
end
end
function QuestHelper:PlayerFaction()
return UnitFactionGroup("player") == "Alliance" and ALLIANCE or HORDE
end
function QuestHelper:LocationString(i, x, y)
return ("[|cffffffff%s|r:|cffffffff%d,%.3f,%.3f|r]"):format(QuestHelper_NameLookup[i] or "nil", i or -7777, x or -7777, y or -7777)
end
function QuestHelper:Location_RawString(delayed, c, z, x, y)
return ("[|cffffffff%s/%s,%s,%s,%s|r]"):format(delayed and "D" or "c", c and string.format("%d", c) or tostring(c), z and string.format("%d", z) or tostring(z), x and string.format("%.3f", x) or tostring(x), y and string.format("%.3f", y) or tostring(y))
end
function QuestHelper:Location_AbsoluteString(delayed, c, x, y)
return ("[|cffffffff%s/%s,%s,%s|r]"):format(delayed and "D" or "c", c and string.format("%d", c) or tostring(c), x and string.format("%.3f", x) or tostring(x), y and string.format("%.3f", y) or tostring(y))
end
function QuestHelper:Distance(i1, x1, y1, i2, x2, y2)
local p1, p2 = QuestHelper_ZoneLookup[i1], QuestHelper_ZoneLookup[i2]
return self.Astrolabe:ComputeDistance(p1[1], p1[2], x1, y1, p2[1], p2[2], x2, y2) or 10000
end
function QuestHelper:AppendPosition(list, index, x, y, w, min_dist)
if not x or not y or (x == 0 and y == 0) or x <= -0.1 or y <= -0.1 or x >= 1.1 or y >= 1.1 then
local nc, nz, nx, ny = self.Astrolabe:GetCurrentPlayerPosition()
--self:AppendNotificationError("2008-10-6 nil-position", string.format("nilposition, %s %s %s %s vs %s %s", tostring(nc), tostring(nz), tostring(nx), tostring(ny), tostring(x), tostring(y))) -- We're just not worrying about this too much anymore. Slash and burn.
return list -- This isn't a real position.
end
local closest, distance = nil, 0
w = w or 1
min_dist = min_dist or 200
for i, p in ipairs(list) do
if index == p[1] then
local d = self:Distance(index, x, y, p[1], p[2], p[3])
if not closest or d < distance then
closest, distance = i, d
end
end
end
if closest and distance < min_dist then
local p = list[closest]
p[2] = (p[2]*p[4]+x*w)/(p[4]+w)
p[3] = (p[3]*p[4]+y*w)/(p[4]+w)
p[4] = p[4]+w
else
table.insert(list, {index, x, y, w})
end
return list
end
function QuestHelper:PositionListDistance(list, index, x, y)
local closest, distance = nil, 0
for i, p in ipairs(list) do
local d = self:Distance(index, x, y, p[1], p[2], p[3])
if not closest or d < distance then
closest, distance = p, d
end
end
if closest then
return distance, closest[1], closest[2], closest[3]
end
end
function QuestHelper:PositionListDistance2(list, i1, x1, y1, i2, x2, y2)
local closest, bd1, bd2, bdt = nil, 0, 0, 0
for i, p in ipairs(list) do
local d1 = self:Distance(i1, x1, y1, p[1], p[2], p[3])
local d2 = self:Distance(i2, x2, y2, p[1], p[2], p[3])
local t = d1+d2
if not closest or t < bdt then
closest, bd1, bd2, bdt = p, d1, d2, t
end
end
if closest then
return d1, d2, closest[1], closest[2], closest[3]
end
end
function QuestHelper:MergePositions(list1, list2)
for i, p in ipairs(list2) do
self:AppendPosition(list1, unpack(p))
end
end
function QuestHelper:MergeDrops(list1, list2)
for element, count in pairs(list2) do
list1[element] = (list1[element] or 0) + count
end
end
function QuestHelper: Assert(a, b) -- the space exists so the anti-assert script doesn't find it :D
if not a then
QuestHelper:Error(b or "Assertion Failed")
end
end
function QuestHelper:StringizeTable(a)
if not a then return "nil" end
acu = tostring(self.recycle_tabletyping[a])..": "
for i,v in pairs(a) do acu = acu.."["..tostring(i)..","..tostring(v).."] " end
return acu
end
function QuestHelper:StringizeTableDouble(a)
if not a then return "nil" end
acu = tostring(self.recycle_tabletyping[a])..": "
for i,v in pairs(a) do acu = acu.."["..self:StringizeTable(i)..","..self:StringizeTable(v).."] " end
return acu
end
function QuestHelper:StringizeRecursive(a, d)
if not a then return "nil" end
if d <= 0 or type(a) ~= "table" then return tostring(a) end
acu = tostring(self.recycle_tabletyping[a])..": "
for i,v in pairs(a) do acu = acu.."["..self:StringizeRecursive(i, d - 1)..","..self:StringizeRecursive(v, d - 1).."] " end
return acu
end
function QuestHelper:TableSize(tbl)
local count = 0
for k, v in pairs(tbl) do
count = count + 1
end
return count
end
function QuestHelper:IsWrath()
--return GetBuildInfo():sub(1,1) == '3' or GetBuildInfo() == "0.0.2" -- come on
return true -- this had better be true :D
end
function QuestHelper:IsWrath32()
return tonumber(GetBuildInfo():sub(3,3)) >= 2
end
function QuestHelper:AppendNotificationError(type, data)
local terror = QuestHelper_ErrorPackage(2)
terror.data = data
QuestHelper_ErrorCatcher_RegisterError(type, terror)
end
function QuestHelper.CreateLoadingCounter()
return {
MakeSubcategory = function(self, weight)
QuestHelper: Assert(not self.percentage)
if not self.weighting then self.weighting = {} end
local subcat = QuestHelper:CreateLoadingCounter()
table.insert(self.weighting, {weight = weight, item = subcat})
return subcat
end,
SetPercentage = function(self, percent)
QuestHelper: Assert(not self.weighting)
self.percentage = percent
end,
GetPercentage = function(self)
if self.percentage then return self.percentage end
if not self.weighting then return 0 end
local total_weight = 0
local total_value = 0
for _, v in ipairs(self.weighting) do
total_weight = total_weight + v.weight
total_value = total_value + v.weight * v.item:GetPercentage()
end
return total_value / total_weight
end
}
end
local msgid = 0
function QH_fixedmessage(text)
local msgtext = "QH_MSG_" .. msgid
StaticPopupDialogs[msgtext] = {
text = text,
button1 = OKAY,
OnAccept = function(self)
end,
timeout = 0,
whileDead = 1,
hideOnEscape = 1
}
StaticPopup_Show(msgtext)
end