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
Nathanial.C.Jones 87617c4eed QH Now queries the WoW client for quests, though it doesn't seem to update correctly when a quest is accepted (and though untested, probably doesn't update locations when the WoW poi changes).
Added LibMapData and began transitioning map data needs to use LibMapData.

Began changing the data collection, yet again. Once this goes beta, the new collection system will be in place... My hope is to allow QH to "learn" as you play, eliminating any need for data compilation, though I will still make attempts to compile said data into a full on db.

Added some code that will eventually be usable to get data from LightHeaded. This is not yet implemented in full, but will be the preferred method of QH doesn't know about a quest. Order of preference will eventually be: 1) Learned data, 2) Internal DB, 3) LightHeaded, 4) WoW client.

NOTE: THIS COMMIT IS ON THE WOW-DB-GET BRANCH. An alpha release will be up on the downloads page by 6:30 US EST on February 29, 2012 (tomorrow).

I THINK I have covered all the changes in this, but I have done so much since my last commit, I cannot be sure.
2012-02-29 03:27:41 +00:00

464 lignes
15 Kio
Lua

function QuestHelper_GetTime()
if inWorld then return theTime end
if IsMacClient() then return debugprofilestop()
else return debugprofilestop() / 1000
end
end
local GetTime = QuestHelper_GetTime
QuestHelper_File["utility.lua"] = "4.0.1.$svnversion$"
QuestHelper_Loadtime["utility.lua"] = GetTime()
local theTime = GetTime()
local inWorld = false
QuestHelper = CreateFrame("Frame", "QuestHelper", nil)
local TimeUpdater = CreateFrame("Frame", "TimeUpdater", nil)
TimeUpdater:SetScript("OnUpdate", function () theTime = GetTime() end)
TimeUpdater:RegisterEvent("PLAYER_ENTERING_WORLD")
TimeUpdater:SetScript("OnEvent", function () inWorld = true end)
--[[ 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(GetTime() % 1000) + 5) do math.random() end -- it's sort of like seeding. only worse.
local base = GetUnitName("player")..":"..GetRealmName()..":"..math.random(0, 2147483647)..":"..GetTime()..":"..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, tostring(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 = GetTime()
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