From ec57f73384c4c4a738611bd8440c3d67462d053f Mon Sep 17 00:00:00 2001 From: "Nathanial.C.Jones" Date: Mon, 2 Jan 2012 01:34:49 +0000 Subject: [PATCH] Abandoning the idea of separating the collection system from the core for the moment. It is looking a bit harder than anticipated for the moment. I will revisit this later. --- QHCollector/QHCollector.toc | 36 -- QHCollector/collect.lua | 308 ------------- QHCollector/collect_achievement.lua | 75 ---- QHCollector/collect_bitstream.lua | 56 --- QHCollector/collect_equip.lua | 134 ------ QHCollector/collect_flight.lua | 114 ----- QHCollector/collect_hearth.lua | 54 --- QHCollector/collect_item.lua | 63 --- QHCollector/collect_location.lua | 49 --- QHCollector/collect_loot.lua | 649 ---------------------------- QHCollector/collect_lzw.lua | 338 --------------- QHCollector/collect_merchant.lua | 82 ---- QHCollector/collect_merger.lua | 27 -- QHCollector/collect_monster.lua | 138 ------ QHCollector/collect_notifier.lua | 29 -- QHCollector/collect_object.lua | 109 ----- QHCollector/collect_patterns.lua | 21 - QHCollector/collect_quest.lua | 439 ------------------- QHCollector/collect_spec.lua | 75 ---- QHCollector/collect_traveled.lua | 220 ---------- QHCollector/collect_upgrade.lua | 103 ----- QHCollector/collect_util.lua | 53 --- QHCollector/collect_warp.lua | 74 ---- QHCollector/collect_zone.lua | 65 --- QHCollector/utility.lua | 454 ------------------- QuestHelper/QuestHelper.toc | 50 +-- 26 files changed, 25 insertions(+), 3790 deletions(-) delete mode 100644 QHCollector/QHCollector.toc delete mode 100644 QHCollector/collect.lua delete mode 100644 QHCollector/collect_achievement.lua delete mode 100644 QHCollector/collect_bitstream.lua delete mode 100644 QHCollector/collect_equip.lua delete mode 100644 QHCollector/collect_flight.lua delete mode 100644 QHCollector/collect_hearth.lua delete mode 100644 QHCollector/collect_item.lua delete mode 100644 QHCollector/collect_location.lua delete mode 100644 QHCollector/collect_loot.lua delete mode 100644 QHCollector/collect_lzw.lua delete mode 100644 QHCollector/collect_merchant.lua delete mode 100644 QHCollector/collect_merger.lua delete mode 100644 QHCollector/collect_monster.lua delete mode 100644 QHCollector/collect_notifier.lua delete mode 100644 QHCollector/collect_object.lua delete mode 100644 QHCollector/collect_patterns.lua delete mode 100644 QHCollector/collect_quest.lua delete mode 100644 QHCollector/collect_spec.lua delete mode 100644 QHCollector/collect_traveled.lua delete mode 100644 QHCollector/collect_upgrade.lua delete mode 100644 QHCollector/collect_util.lua delete mode 100644 QHCollector/collect_warp.lua delete mode 100644 QHCollector/collect_zone.lua delete mode 100644 QHCollector/utility.lua diff --git a/QHCollector/QHCollector.toc b/QHCollector/QHCollector.toc deleted file mode 100644 index ff535d5..0000000 --- a/QHCollector/QHCollector.toc +++ /dev/null @@ -1,36 +0,0 @@ -## Interface: 40300 -## Title: QuestHelper Collector -## Author: zorbathut, smariot, vipersniper, nesher, nconantj -## Notes: Collects data for QuestHelper -## Version: 4.0.1.$svnversion$ -## SavedVariables: QuestHelper_Collector -## X-Website: http://www.quest-helper.com/ - -# Basic utilities used for miscellaneous things, also creates the QH frame -utility.lua - -# oh shut up -collect_notifier.lua - -collect_achievement.lua -collect_lzw.lua -collect_traveled.lua -collect_location.lua -collect_zone.lua -collect_hearth.lua -collect_merger.lua -collect_monster.lua -collect_item.lua -collect_object.lua -collect_loot.lua -collect_patterns.lua -collect_flight.lua -collect_util.lua -collect_quest.lua -collect_equip.lua -collect_spec.lua -collect_bitstream.lua -collect_upgrade.lua -collect_merchant.lua -collect_warp.lua -collect.lua diff --git a/QHCollector/collect.lua b/QHCollector/collect.lua deleted file mode 100644 index f9986be..0000000 --- a/QHCollector/collect.lua +++ /dev/null @@ -1,308 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect.lua"] = GetTime() - -local --[[ static ]] MINSVNVERSION = 185 -local --[[ static ]] PURGEDEV = false -local debug_output = false -if QuestHelper_File["collect.lua"] == "Development Version" then debug_output = true end - -local QuestHelper_Collector_Version_Current = 8 - -QuestHelper_Collector = {} -QuestHelper_Collector_Version = QuestHelper_Collector_Version_Current - -local OnUpdateRegistrar = {} -local TooltipRegistrar = {} - -local function OnUpdateHookRegistrar(func) - QuestHelper: Assert(func) - table.insert(OnUpdateRegistrar, func) -end - -local suppress = false - - -- real tooltips don't use this function -local SetTextScript = GameTooltip.SetText -GameTooltip.SetText = function (...) - suppress = true - SetTextScript(...) - suppress = false -end - -local function CollectTooltippery(self) - if not self then self = GameTooltip end - - for k, v in pairs(TooltipRegistrar) do - v(self) - end - - -- anything past here is not my fault -end - -local ottsu = GameTooltip:GetScript("OnTooltipSetUnit") -QH_Hook(GameTooltip, "OnTooltipSetUnit", function (self, ...) - CollectTooltippery(self) - if ottsu then return QH_Hook_NotMyFault(ottsu, self, ...) end -end, "collection OnTooltipSetUnit") - -local ottsi = GameTooltip:GetScript("OnTooltipSetItem") -QH_Hook(GameTooltip, "OnTooltipSetItem", function (self, ...) - CollectTooltippery(self) - if ottsi then return QH_Hook_NotMyFault(ottsi, self, ...) end -end, "collection OnTooltipSetItem") - -local ottsh = GameTooltip:GetScript("OnShow") -QH_Hook(GameTooltip, "OnShow", function (self, ...) - CollectTooltippery(self) - if ottsh then return QH_Hook_NotMyFault(ottsh, self, ...) end -end, "collection OnShow") - - -local function TooltipHookRegistrar(func) - QuestHelper: Assert(func) - table.insert(TooltipRegistrar, func) -end - -local API = { - Registrar_OnUpdateHook = OnUpdateHookRegistrar, - Registrar_TooltipHook = TooltipHookRegistrar, - Callback_Location_Raw = function () return QuestHelper:Location_RawRetrieve() end, - Callback_Location_Absolute = function () return QuestHelper:Location_AbsoluteRetrieve() end, -} - --- We do these early, because some things that aren't in collect may rely on these. Yes I realize that avoiding this was one of my main goals in the separate collect system, shut up go away I hate you (in all seriousness: crunch mode + lazy = some nasty bits.) --- TODO: Make a common collect/mainmodule system, then rely on that better. -QH_Collect_Util_Init(nil, API) -- Some may actually add their own functions to the API, and should go first. There's no real formalized order, I just know which depend on others, and it's heavily asserted so it will break if it goes in the wrong order. -QH_Collect_Merger_Init(nil, API) -QH_Collect_Bitstream_Init(nil, API) -QH_Collect_Location_Init(nil, API) -QH_Collect_Patterns_Init(nil, API) -QH_Collect_Notifier_Init(nil, API) -QH_Collect_Spec_Init(nil, API) -QH_Collect_LZW_Init(nil, API) - -local CompressCollection - -function QH_Collector_Init() - -- Dunno why, but these statements cause the 1% issue. - --[[ - QH_Collector_UpgradeAll(QuestHelper_Collector) - - for _, v in pairs(QuestHelper_Collector) do - if not v.modified then v.modified = time() - 7 * 24 * 60 * 60 end -- eugh. Yeah, we set it to be a week ago. It's pretty grim. - end - --]] - QuestHelper_Collector_Version = QuestHelper_Collector_Version_Current - - local svnversion = "$svnversion$" - local buildInfo, locale, faction = GetBuildInfo(), GetLocale(), QuestHelper:PlayerFaction() - local altfaction = "" - if faction == ALLIANCE then - altfaction = "Alliance" - else - altfaction = "Horde" - end - local realm = GetRealmName() - - local remove_sigs = {} - for k, v in pairs(QuestHelper_Collector) do - local sig = k:match("^(%d)a$") or k:match("^(%d)b$") or k:match("^(%d)r$") - if sig then - if tonumber(sig) < MINSVNVERSION then - table.insert(remove_sigs, sig) - end - elseif k ~= svnversion then - table.insert(remove_sigs, k) - elseif k == "$svnversion\$" and PURGEDEV then - table.insert(remove_sigs, k) - end - end - - for _, v in ipairs(remove_sigs) do - QuestHelper_Collector[v] = nil - end - - if not QuestHelper_Collector.created then - QuestHelper_Collector.created = time(); - end - - -- Swap buildInfo and svnversion once first alteration is complete. - -- Perhaps move locale out of the "signature" - if not QuestHelper_Collector[svnversion] then - QuestHelper_Collector[svnversion] = {} - end - - if not QuestHelper_Collector[svnversion][realm] then - QuestHelper_Collector[svnversion][realm] = {} - end - - if not QuestHelper_Collector[svnversion][realm][buildInfo] then - QuestHelper_Collector[svnversion][realm][buildInfo] = {} - end - - if not QuestHelper_Collector[svnversion][realm][buildInfo][locale] then - QuestHelper_Collector[svnversion][realm][buildInfo][locale] = {} - end - - if not QuestHelper_Collector[svnversion][realm][buildInfo][locale][altfaction] then - QuestHelper_Collector[svnversion][realm][buildInfo][locale][altfaction] = {} - end - - --if not QuestHelper_Collector[sig] or QuestHelper_Collector[sig].compressed then QuestHelper_Collector[sig] = {version = QuestHelper_Collector_Version} end -- fuckin' bullshit, man - local QHCData = QuestHelper_Collector[svnversion][realm][buildInfo][locale][altfaction] - QuestHelper: Assert(not QHCData.compressed) - QHCData.modified = time() - - QH_Collect_Achievement_Init(QHCData, API) - QH_Collect_Traveled_Init(QHCData, API) - QH_Collect_Zone_Init(QHCData, API) - QH_Collect_Hearth_Init(QHCData, API) - QH_Collect_Monster_Init(QHCData, API) - QH_Collect_Item_Init(QHCData, API) - QH_Collect_Object_Init(QHCData, API) - QH_Collect_Flight_Init(QHCData, API) - QH_Collect_Quest_Init(QHCData, API) - QH_Collect_Warp_Init(QHCData, API) - - QH_Collect_Loot_Init(QHCData, API) - QH_Collect_Equip_Init(QHCData, API) - QH_Collect_Merchant_Init(QHCData, API) - - if false then -- this will be disabled in most public releases, or set to a very rare probabalistic thing - if not QHCData.routing_dump then QHCData.routing_dump = {} end - local nt = {} - table.insert(QHCData.routing_dump, nt) - QH_Collect_Routing_Dump = nt - end ---[[ NOPE DO NOT DO THIS! IT'LL MESS UP THE NEW SYSTEM. - do -- Clean some stuff up! - local obliterate = {} - for k, v in pairs(QuestHelper_Collector) do - if not v.modified or v.modified + 30 * 24 * 60 * 60 < GetTime() then - table.insert(obliterate, k) - end - end - - for _, v in ipairs(obliterate) do - QuestHelper_Collector[v] = nil - end - end ---]] - - -- So, why do we delay it? - -- It's simple. People are gonna update to this version, and then they're going to look at the memory usage. Then they will panic because omg this version uses so much more memory, I bet that will somehow hurt my framerates in a way which is not adequately explained! - -- So instead, we just wait half an hour before compressing. Compression will still get done, and I won't have to deal with panicked comments about how bloated QH has gotten. - -- addendum: yeah naturally I'm getting all sorts of panicked comments about how bloated qh has gotten, sigh - --API.Utility_Notifier(GetTime() + (debug_output and 0 or (30 * 60)), function() CompressCollection(QHCData, QuestHelper_Collector[sig_altfaction], API.Utility_Merger, API.Utility_LZW.Compress) end) -end - -QH_OnUpdate(function () - local tstart = GetTime() - for _, v in pairs(OnUpdateRegistrar) do - v() - end - QH_Timeslice_Increment(GetTime() - tstart, "collect_update") -end) - - - ---- I've tossed the compression stuff down here just 'cause I don't feel like making an entire file for it (even though I probably should.) - -local noncompressible = { - modified = true, - version = true, -} - -local squarify - -local seritem - -local serializers = { - ["nil"] = function(item, add) - add("nil") - end, - ["number"] = function(item, add) - add(tostring(item)) - end, - ["string"] = function(item, add) - add(string.format("%q", item)) - end, - ["boolean"] = function(item, add) - add(item and "true" or "false") - end, - ["table"] = function(item, add) - add("{") - local first = true - for k, v in pairs(item) do - if not first then add(",") end - first = false - add("[") - seritem(k, add) - add("]=") - seritem(v, add) - end - add("}") - end, -} - -seritem = function(item, add) - QH_Timeslice_Yield() - serializers[type(item)](item, add) -end - -local function DoCompress(item, merger, comp) - if debug_output then QuestHelper: TextOut("Item condensing") end - local ts = GetTime() - - local target = {} - for k, v in pairs(item) do - if not noncompressible[k] then - target[k] = v - end - end - - local mg = {} - seritem(target, function(dat) merger.Add(mg, dat) end) - - local tg = merger.Finish(mg) - if debug_output then QuestHelper: TextOut(string.format("Item condensed to %d bytes, %f taken so far", #tg, GetTime() - ts)) end - mg = nil - - local cmp = {} - local cmptot = 0 - - local doublecheck = "" - for chunk = 1, #tg, 1048576 do - local fragment = tg:sub(chunk, chunk + 1048575) - doublecheck = doublecheck .. fragment - local ite = comp(fragment, 256, 8) - cmptot = cmptot + #ite - table.insert(cmp, ite) - end - QuestHelper: Assert(doublecheck == tg) - - if #cmp == 1 then cmp = cmp[1] end - - for k, v in pairs(target) do - if not noncompressible[k] then - item[k] = nil - end - end - item.compressed = cmp - - if debug_output then QuestHelper: TextOut(string.format("Item compressed to %d bytes in %d shards (previously %d), %f taken", cmptot, type(cmp) == "table" and #cmp or 1, #tg, GetTime() - ts)) end -end - -CompressCollection = function(active, active2, merger, comp) - for _, v in pairs(QuestHelper_Collector) do - if v ~= active and v ~= active2 and not v.compressed then - QH_Timeslice_Add(function () - DoCompress(v, merger, comp) - CompressCollection(active, active2, merger, comp) - end, "compress") - break - end - end -end diff --git a/QHCollector/collect_achievement.lua b/QHCollector/collect_achievement.lua deleted file mode 100644 index b38bf00..0000000 --- a/QHCollector/collect_achievement.lua +++ /dev/null @@ -1,75 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_achievement.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_achievement.lua"] = GetTime() - -local QHCA - -local GetLoc -local Merger - -local cloc - -local function ScanAchievements(oldADB, newADB) - --QuestHelper:TextOut("scanach") - local changes = 0 - for k, v in pairs(newADB.achievements) do - if v.complete ~= oldADB.achievements[k].complete then - changes = changes + 1 - end - end - for k, v in pairs(newADB.criteria) do - if v.complete and not oldADB.criteria[k].complete then - changes = changes + 1 - end - end - - if changes < 10 then -- if someone gets 10 criteria at once, well, I guess that's just what happens - for k, v in pairs(newADB.achievements) do - if v.complete ~= oldADB.achievements[k].complete then - QuestHelper: Assert(v.complete and not oldADB.achievements[k].complete) - if not QHCA[k] then QHCA[k] = {} end - if not QHCA[k].achieved then QHCA[k].achieved = {} end - table.insert(QHCA[k].achieved, cloc) - --QHCA[k].achieved = (QHCA[k].achieved or "") .. cloc - - --QuestHelper:TextOut(string.format("Achievement complete, %s", select(2, GetAchievementInfo(k)))) - end - end - - for k, v in pairs(newADB.criteria) do - if v.complete and not oldADB.criteria[k].complete then -- Note that it's possible for objectives to be "uncompleted" when it's things like "do a bunch of shit in one run of this battleground" (see: isle of conquest) - --QuestHelper:TextOut(string.format("Criteria complete, %d", k)) - --QuestHelper:TextOut(string.format("Criteria complete, %s", select(1, GetAchievementCriteriaInfo(k)))) - if not QHCA[k] then QHCA[k] = {} end - if not QHCA[k].parent then QHCA[k].parent = v.parent end - if not QHCA[k].achieved then QHCA[k].achieved = {} end - table.insert(QHCA[k].achieved, cloc) - --QHCA[v.parent][k] = (QHCA[v.parent][k] or "") .. cloc - elseif v.progress > oldADB.criteria[k].progress then - --QuestHelper:TextOut(string.format("Criteria progress, %d", k)) - --QuestHelper:TextOut(string.format("Criteria progress, %s", select(1, GetAchievementCriteriaInfo(k)))) - end - end - end -end - -function SetCloc() - cloc = GetLoc() -- yoink -end - -function QH_Collect_Achievement_Init(QHCData, API) - if not QHCData.achievement then QHCData.achievement = {} end - QHCA = QHCData.achievement - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) - - QH_AchievementManagerRegister(ScanAchievements) - QH_AchievementManagerRegister_Prescan(SetCloc) - - QH_AchievementManager_Init() -end diff --git a/QHCollector/collect_bitstream.lua b/QHCollector/collect_bitstream.lua deleted file mode 100644 index 7e8b9db..0000000 --- a/QHCollector/collect_bitstream.lua +++ /dev/null @@ -1,56 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_bitstream.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_bitstream.lua"] = GetTime() - -local Merger - -local function Output(outbits) - return { - r = {}, - cbits = 0, - cval = 0, - - append = function (self, value, bits) - self.cbits = self.cbits + bits - self.cval = bit.lshift(self.cval, bits) - self.cval = self.cval + value - while self.cbits >= outbits do - Merger.Add(self.r, strchar(bit.rshift(self.cval, self.cbits - outbits))) - self.cbits = self.cbits - outbits - self.cval = bit.band(self.cval, bit.lshift(1, self.cbits) - 1) - end - end, - finish = function (self) - if self.cbits > 0 then self:append(0, outbits - self.cbits) end - return Merger.Finish(self.r) - end, - } -end - -local function Input(indata, outbits) - return { - cbits = 0, - cval = 0, - coffset = 1, - - depend = function (self, bits) - while self.cbits < bits do - self.cbits = self.cbits + outbits - self.cval = bit.lshift(self.cval, outbits) + strbyte(indata, self.coffset) - self.coffset = self.coffset + 1 - end - local rv = bit.rshift(self.cval, self.cbits - bits) - self.cbits = self.cbits - bits; - self.cval = bit.band(self.cval, bit.lshift(1, self.cbits) - 1) - return rv - end, - } -end - -function QH_Collect_Bitstream_Init(_, API) - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) - - API.Utility_Bitstream = {Input = Input, Output = Output} -end diff --git a/QHCollector/collect_equip.lua b/QHCollector/collect_equip.lua deleted file mode 100644 index 91ff8cb..0000000 --- a/QHCollector/collect_equip.lua +++ /dev/null @@ -1,134 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_equip.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_equip.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_equip.lua"] == "Development Version" then debug_output = true end - -local GetItemType -local Notifier -local GetSpecBolus -local Patterns - -local QHCI - --- why does this need to exist -local invloc_lookup_proto = { - INVTYPE_HEAD = {"HeadSlot"}, - INVTYPE_NECK = {"NeckSlot"}, - INVTYPE_SHOULDER = {"ShoulderSlot"}, - INVTYPE_CHEST = {"ChestSlot"}, - INVTYPE_ROBE = {"ChestSlot"}, - INVTYPE_WAIST = {"WaistSlot"}, - INVTYPE_LEGS = {"LegsSlot"}, - INVTYPE_FEET = {"FeetSlot"}, - INVTYPE_WRIST = {"WristSlot"}, - INVTYPE_HAND = {"HandsSlot"}, - INVTYPE_FINGER = {"Finger0Slot", "Finger1Slot"}, - INVTYPE_TRINKET = {"Trinket0Slot", "Trinket1Slot"}, - INVTYPE_CLOAK = {"BackSlot"}, - INVTYPE_WEAPON = {"MainHandSlot", "SecondaryHandSlot"}, - INVTYPE_SHIELD = {"SecondaryHandSlot"}, - INVTYPE_2HWEAPON = {"MainHandSlot"}, - INVTYPE_WEAPONMAINHAND = {"MainHandSlot"}, - INVTYPE_WEAPONOFFHAND = {"SecondaryHandSlot"}, - INVTYPE_HOLDABLE = {"RangedSlot"}, - INVTYPE_RANGED = {"RangedSlot"}, - INVTYPE_THROWN = {"RangedSlot"}, - INVTYPE_RANGEDRIGHT = {"RangedSlot"}, - INVTYPE_RELIC = {"RangedSlot"}, -} - -local invloc_lookup = {} - -for k, v in pairs(invloc_lookup_proto) do - local temp = {} - for _, tv in pairs(v) do - table.insert(temp, (GetInventorySlotInfo(tv))) - end - invloc_lookup[k] = temp -end - -local function Recheck(item, location, competing) - local replaced_item = nil - local confused = false - - for i, v in pairs(invloc_lookup[location]) do - if competing[i] then - local ilink = GetInventoryItemLink("player", v) - if ilink then - local itype = GetItemType(ilink) - local eqtext = nil - if itype == item then - replaced_item = competing[i] - elseif itype == competing[i] then - else - confused = true - end - end - end - end - - if confused then - if debug_output then QuestHelper:TextOut(string.format("Confused about %s", GetItemInfo(item))) end - return - end - - if not QHCI[item] then QHCI[item] = {} end - if replaced_item then - if debug_output then QuestHelper:TextOut(string.format("Equipped %s over %s", GetItemInfo(item), GetItemInfo(replaced))) end - if not QHCI[item].equip_yes then QHCI[item].equip_yes = {} end - table.insert(QHCI[item].equip_yes, { replaced = replaced_item, spec = GetSpecBolus() }) - else - for _, v in pairs(competing) do - if debug_output then QuestHelper:TextOut(string.format("Did not equip %s over %s", GetItemInfo(item), GetItemInfo(v))) end - if not QHCI[item].equip_no then QHCI[item].equip_no = {} end - table.insert(QHCI[item].equip_no, { item = v, spec = GetSpecBolus() }) - end - end -end - -local function Looted(message) - item = string.match(message, Patterns.LOOT_ITEM_PUSHED_SELF) - if not item then item = string.match(message, Patterns.LOOT_ITEM_SELF) end - if not item then return end - - local item = GetItemType(message, true) - - local name, _, quality, ilvl, min, itype, isubtype, _, equiploc, _ = GetItemInfo(item) - - if name and IsEquippableItem(item) and min <= UnitLevel("player") and invloc_lookup[equiploc] then -- The level comparison may be redundant - local competing = {} - local nonempty = false - for i, v in pairs(invloc_lookup[equiploc]) do - local litem = GetInventoryItemLink("player", v) - if litem then litem = GetItemType(litem) end - if litem and litem ~= item then competing[i] = litem nonempty = true end - end - - if not nonempty then return end -- congratulations you are better than nothing, we do not care - - Notifier(GetTime() + 5 * 60, function () Recheck(item, equiploc, competing) end) - end -end - -function QH_Collect_Equip_Init(QHCData, API) - if not QHCData.item then QHCData.item = {} end - QHCI = QHCData.item - - Patterns = API.Patterns - QuestHelper: Assert(Patterns) - - API.Patterns_Register("LOOT_ITEM_PUSHED_SELF", "|c.*|r") - API.Patterns_Register("LOOT_ITEM_SELF", "|c.*|r") - - QH_Event("CHAT_MSG_LOOT", Looted) - - GetItemType = API.Utility_GetItemType - Notifier = API.Utility_Notifier - GetSpecBolus = API.Utility_GetSpecBolus - QuestHelper: Assert(GetItemType) - QuestHelper: Assert(Notifier) - QuestHelper: Assert(GetSpecBolus) -end diff --git a/QHCollector/collect_flight.lua b/QHCollector/collect_flight.lua deleted file mode 100644 index abf5819..0000000 --- a/QHCollector/collect_flight.lua +++ /dev/null @@ -1,114 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_flight.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_flight.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_flight.lua"] == "Development Version" then debug_output = true end - -local QHCFM -local QHCFT - -local IsMonsterGUID -local GetMonsterType - -local function GetRoute(currentname, endnode) - local path = currentname .. "@@" .. TaxiNodeName(endnode) - - local links = GetNumRoutes(endnode) - if links > 50 then -- links is apparently sometimes 999998. Why? I could not say. It is a mystery. Hopefully this will show up in the datafiles and I'll be able to debug it. - if (TaxiNodeGetType(endnode) == "NONE") then - return path, TaxiNodeName(endnode) .. " not currently in use." - else - return path, string.format("@@@ WACKYLAND %s %d @@@", TaxiNodeGetType(endnode), links) - end - end - - local route = "" - for j = 1, links - 1 do -- Why only the first n-1 links? Why not all? Research. - if #route > 0 then route = route .. "," end - route = route .. string.format("(%f,%f)", TaxiGetDestX(endnode, j), TaxiGetDestY(endnode, j)) - end - - return path, route -end - -local function GetCurrentname() - QuestHelper: Assert(NumTaxiNodes() < 150, tostring(NumTaxiNodes())) -- hmm what - for i = 1, NumTaxiNodes() do if TaxiNodeGetType(i) == "CURRENT" then return TaxiNodeName(i) end end -end - -local path, route -local start_time -local phase = "IDLE" - -local real_TakeTaxiNode = TakeTaxiNode -TakeTaxiNode = function(id) - path, route = GetRoute(GetCurrentname(), id) - - phase = "PENDING" - - start_time = GetTime() - - real_TakeTaxiNode(id) -end - -local function TaximapOpened() - -- Figure out who we have targeted and what our location name is - local currentname = GetCurrentname() - if not currentname then return end -- must not actually have opened the map - - QuestHelper: Assert(NumTaxiNodes() < 100) - for i = 1, NumTaxiNodes() do - local name, type = TaxiNodeName(i), TaxiNodeGetType(i) - if not QHCFM[name] then QHCFM[name] = {} end - QHCFM[name].x, QHCFM[name].y = TaxiNodePosition(i) - if type == "CURRENT" then - local guid = UnitGUID("target") - if guid and IsMonsterGUID(guid) then QHCFM[name].master = GetMonsterType(guid) end - end - - if type ~= "CURRENT" then - local path, route = GetRoute(currentname, i) - if not QHCFT[path] then QHCFT[path] = {} end - if not QHCFT[path][route] then QHCFT[path][route] = {} end - end - end -end - -local function OnUpdate() - if UnitOnTaxi("player") then - if phase == "PENDING" then - start_time = GetTime() - phase = "FLYING" - end - else - if phase == "PENDING" then - if GetTime() > start_time + 5 then -- something has gone wrong, abort - phase = "IDLE" - path, route, start_time = nil, nil, nil - end - elseif phase == "FLYING" then - -- yaay - QHCFT[path][route].time = (QHCFT[path][route].time or 0) + (GetTime() - start_time) - QHCFT[path][route].count = (QHCFT[path][route].count or 0) + 1 - phase = "IDLE" - path, route, start_time = nil, nil, nil - end - end -end - -function QH_Collect_Flight_Init(QHCData, API) - if not QHCData.flight_master then QHCData.flight_master = {} end - if not QHCData.flight_times then QHCData.flight_times = {} end - QHCFM, QHCFT = QHCData.flight_master, QHCData.flight_times - - IsMonsterGUID = API.Utility_IsMonsterGUID - GetMonsterType = API.Utility_GetMonsterType - QuestHelper: Assert(IsMonsterGUID) - QuestHelper: Assert(GetMonsterType) - - QH_Event("TAXIMAP_OPENED", TaximapOpened) - - API.Registrar_OnUpdateHook(OnUpdate) -end diff --git a/QHCollector/collect_hearth.lua b/QHCollector/collect_hearth.lua deleted file mode 100644 index 78b94ed..0000000 --- a/QHCollector/collect_hearth.lua +++ /dev/null @@ -1,54 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_hearth.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_hearth.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_hearth.lua"] == "Development Version" then debug_output = true end - -local QHCZ - -local GetLoc -local Merger - -local last_hearth = 0 - -local function OnZoneChanged() - local start, cd, _ = GetItemCooldown(6948) - if last_hearth + 1800 < GetTime() and cd == 1800 then - last_hearth = start - local home = GetBindLocation() - if not QHCZ[home] then QHCZ[home] = {} end - QHCZ[home].Landing = GetLoc() - end -end - -local GetMonsterType - -local function OnConfirmBinder(...) - local new_home = ... - if not QHCZ[new_home] then QHCZ[new_home] = {} end - if not QHCZ[new_home].Innkeeper then QHCZ[new_home].Innkeeper = {} end - QHCZ[new_home].Innkeeper.ID = GetMonsterType(UnitGUID("target")) -end - -function QH_Collect_Hearth_Init(QHCData, API) - if not QHCData.hearth then QHCData.hearth = {} end - QHCZ = QHCData.hearth - - QH_Event("ZONE_CHANGED", OnZoneChanged) - QH_Event("ZONE_CHANGED_INDOORS", OnZoneChanged) - QH_Event("ZONE_CHANGED_NEW_AREA", OnZoneChanged) - QH_Event("CONFIRM_BINDER", OnConfirmBinder) - - --API.Registrar_OnUpdateHook(OnUpdate) - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) - - GetMonsterType = API.Utility_GetMonsterType - QuestHelper: Assert(GetMonsterType) -end diff --git a/QHCollector/collect_item.lua b/QHCollector/collect_item.lua deleted file mode 100644 index 109fd00..0000000 --- a/QHCollector/collect_item.lua +++ /dev/null @@ -1,63 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_item.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_item.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_item.lua"] == "Development Version" then debug_output = true end - -local GetItemType - -local QHCI - --- We could probably snag data from other locations as well, but at the moment, we're not. -local function Tooltipy(self) - if not self.GetItem then return end -- ughhhh, inventoryonpar - - local _, ilink = self:GetItem() - if not ilink then return end - - local id = GetItemType(ilink) - - if not QHCI[id] then QHCI[id] = {} end - local item = QHCI[id] - - local name, _, quality, ilvl, min, itype, isubtype, _, equiploc, _ = GetItemInfo(id) - - if name then - item.name = name - item.quality = quality - item.ilevel = ilvl - item.minlevel = min - item.type = itype -- Was originally type/subtype, but we can do that during processing. Might want to eventually have it separated, so we separate here. - item.subtype = isubtype - - local loc = string.match(equiploc, "INVTYPE_(.*)") - if loc then - item.equiplocation = loc - else - item.equiplocation = nil - end - - local lines = GameTooltip:NumLines() - local openable = false - for i = 2, lines do - if _G["GameTooltipTextLeft" .. tostring(i)]:GetText() == ITEM_OPENABLE then - openable = true - end - end - - openable = "open_" .. (openable and "yes" or "no") - item[openable] = (item[openable] or 0) + 1 -- so we're going to add a lot to this if the user keeps whipping their mouse over it. I'll live. - end -end - -function QH_Collect_Item_Init(QHCData, API) - if not QHCData.item then QHCData.item = {} end - QHCI = QHCData.item - - API.Registrar_TooltipHook(Tooltipy) - - GetItemType = API.Utility_GetItemType - QuestHelper: Assert(GetItemType) -end diff --git a/QHCollector/collect_location.lua b/QHCollector/collect_location.lua deleted file mode 100644 index 7f9d1a8..0000000 --- a/QHCollector/collect_location.lua +++ /dev/null @@ -1,49 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_location.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_location.lua"] = GetTime() - --- little endian two's complement -local function signed(c) - QuestHelper: Assert(not c or c >= -127 and c < 127) - if not c then c = -128 end - if c < 0 then c = c + 256 end - return c - --return strchar(c) -end - -local function float(c) --- if not c then c = -128 end --- QuestHelper: Assert( c >= -128, string.format("c is too small. It is %s.", tostring(c))) --- QuestHelper: Assert( c < 128, string.format("c is too big. It is %s.", tostring(c))) - local ret = tostring(c):gsub(",",".") -- eliminate issues with locales that use a comma as the decimal separator. - return ret -end - -local function BolusizeLocation(delayed, c, z, x, y, dl, mid, mf, f) - -- c and z are *signed* integers that fit within an 8-bit int. - -- x and y are floating-point values, generally between 0 and 1. We'll dedicate 24 bits to the fractional part, largely because we can. - -- Overall we're using a weird 11 bytes on this. Meh. - -- Also, any nil values are being turned into MIN_WHATEVER. - local float_x = float(x) - local float_y = float(y) - local loc = {} - loc["delayed"] = (delayed and 1 or 0) - loc["c"] = c - loc["z"] = z - loc["x"] = float_x - loc["y"] = float_y - loc["dungeonLevel"] = dl - loc["mapid"] = mid - loc["mapfile"] = mf - loc["facing"] = f - return loc; - --return string.format("%s,%s,%s,%s,%s", signed(delayed and 1 or 0), signed(c), signed(z), float_x, float_y) - --return signed(delayed and 1 or 0) .. signed(c) .. signed(z) .. float_x .. float_y -end - --- This merely provides another API function -function QH_Collect_Location_Init(_, API) - API.Callback_LocationBolus = BolusizeLocation -- Yeah. *Bolusize*. You heard me. - API.Callback_LocationBolusCurrent = function () return BolusizeLocation(API.Callback_Location_Raw()) end -- This is just a convenience function, really -end diff --git a/QHCollector/collect_loot.lua b/QHCollector/collect_loot.lua deleted file mode 100644 index 910740a..0000000 --- a/QHCollector/collect_loot.lua +++ /dev/null @@ -1,649 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_loot.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_loot.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_loot.lua"] == "Development Version" then debug_output = true end - -local QHC - -local PseudoIDs = { - ["gold"] = -1, -} - -local GetMonsterUID -local GetMonsterType - -local GetItemType - -local GetLoc - -local Patterns - -local members = {} -local members_count = 0 -local members_refs = {} -- "raid6" and the like - -local function MembersUpdate() - -- We want to keep track of exactly who is in a group with this player, so we can watch for combat messages involving them, so we can see who's been tapped, so we can record the right deaths, so we can know who the player should be able to loot. - -- I hate my life. - -- >:( - - local alone = false - - --QuestHelper:TextOut("MU start") - members = {} -- we burn a table every time this updates, but whatever - members_count = 0 - if GetNumRaidMembers() > 0 then - -- we is in a raid - for i = 1, 40 do - local ite = string.format("raid%d", i) - local gud = UnitGUID(ite) - if gud then - members[gud] = true - table.insert(members_refs, ite) - --QuestHelper:TextOut(string.format("raid member %s added", UnitName(ite))) - end - end - elseif GetNumPartyMembers() > 0 then - -- we is in a party - for i = 1, 4 do - local ite = string.format("party%d", i) - local gud = UnitGUID(ite) - if gud then - members[gud] = true - table.insert(members_refs, ite) - --QuestHelper:TextOut(string.format("party member %s added", UnitName(ite))) - end - end - members[UnitGUID("player")] = true - table.insert(members_refs, "player") - --QuestHelper:TextOut(string.format("player %s added", UnitName("player"))) - else - -- we is alone ;.; - if UnitGUID("player") then members[UnitGUID("player")] = true end -- it's possible that we haven't logged in entirely yet - table.insert(members_refs, "player") - --QuestHelper:TextOut(string.format("player %s added as %s", UnitName("player"), tostring(UnitGUID("player")))) - alone = true - end - - if GetLootMethod() == "master" and not alone then members = {} members_refs = {} end -- We're not going to bother trying to deal with master loot right now - it's just too different and I just don't care enough. - - for _, _ in pairs(members) do members_count = members_count + 1 end -- lulz -end - -local MS_TAPPED_US = 1 -local MS_TAPPED_US_TRIVIAL = 2 -local MS_TAPPED_OTHER = 3 -local MS_TAPPED_LOOTABLE = 4 -local MS_TAPPED_LOOTABLE_TRIVIAL = 5 -local MS_TAPPED_LOOTED = 6 - -local last_cleanup = GetTime() - -local monsterstate = {} -local monsterrefresh = {} -local monstertimeout = {} - --- This all does something quite horrible. --- Some monsters don't become lootable when they're killed and didn't drop anything. We need to record this so we can get real numbers for them. --- Unfortunately, we can't just record when "something" is killed. We have to record when "our group" killed it, so we know that there *was* a chance of looting it. --- As such, we need to check for monster deaths that the player may never have actually targeted. It gets, to put it mildly, grim, and unfortunately we'll never be able to solve it entirely. --- Worse, we need to *not* record item drops for things that we never actually "saw" but that were lootable anyway, because if we do, we bias the results towards positive (i.e. if we AOE ten monsters down, and two of them drop, and we loot those, that's 2/2 if we record the drops, and 0/0 if we don't, while what we really want is 2/10. 0/0 is at least "not wrong".) --- On top of this, we want to avoid looting "discarded items", but unfortunately there's no real good way to determine this. Welp. -local last_scan = 0 --- Here's a little bottleneck - we're going to try to only do one scan per second. Fingers crossed. - -local function CombatLogEvent(_, event, sourceguid, _, _, destguid, _, _, _, spellname) - -- There's many things that are handled here. - -- First, if there's any damage messages coming either to or from a party member, we check to see if that monster is tapped by us. If it's tapped, we cache the value for 15 seconds, expiring entirely in 30. - -- Second, there's the Death message. If it's tapped by us, increases the kill count by 1/partymembers and changes its state to lootable. - if event ~= "UNIT_DIED" then - if last_scan > GetTime() then return end -- welp - - -- Something has been attacked by something, maybe. - if not string.find(event, "_DAMAGE$") then return end -- We only care about something punching something else. - - local target, source - if members[sourceguid] then - source = sourceguid - target = destguid - elseif members[destguid] then - source = targetguid - target = sourceguid - end -- If one of the items is in our party, the other is our target. - - if not target then return end -- If we don't have a target, then nobody is in our party, and we don't care. - - if monsterrefresh[target] and monsterrefresh[target] > GetTime() then return end -- we already have fresh data, so we're good - - -- Now comes the tricky part. We can't just look at the target because we're not allowed to target by GUID. So we iterate through all the party/raid members and hope *someone* has it targeted. Luckily, we can stop once we find someone who does. - local targ - for _, v in pairs(members_refs) do - targ = v .. "target" if UnitGUID(targ) == target then break end - targ = nil - end - last_scan = GetTime() + 1 - - if not targ then - --monsterrefresh[target] = GetTime() + 5 - --monstertimeout[target] = GetTime() + 5 - return - end -- Well, nobody seems to be targeting it. That's . . . odd, and annoying. We were thinking of tossing on a 5-second timeout. But we didn't, because we decided the global one-second lockout might help. So we'll do that for now. - - -- Okay. So we know who's targeting it. Now, let's see who has it tapped, if anyone. - if not UnitIsTapped(targ) then - -- Great. Nobody is. That is just *great*. Look how exuberant I feel at this moment. You know what? 5-second timeout. - monsterstate[target] = nil - monsterrefresh[target] = GetTime() + 5 - monstertimeout[target] = GetTime() + 5 - --if debug_output then QuestHelper:TextOut(string.format("Monster ignorified")) end - else - -- We know someone is, so we're going to set up our caching . . . - monsterrefresh[target] = GetTime() + 15 - monstertimeout[target] = GetTime() + 30 - monsterstate[target] = (UnitIsTappedByPlayer(targ)) and (not UnitIsTrivial(targ) and MS_TAPPED_US or MS_TAPPED_US_TRIVIAL) or MS_TAPPED_OTHER -- and figure out if it's us. Or if it's trivial. We somewhat-ignore it if it's trivial, since it's much less likely to be looted and that could throw off our numbers - --if debug_output then QuestHelper:TextOut(string.format("Monster %s set to %d, %s, %s", target, monsterstate[target], tostring(UnitIsTappedByPlayer(targ)), tostring(UnitIsTrivial(targ)))) end - end - - -- DONE - else - -- It's dead. Hooray! - - if monsterstate[destguid] and monstertimeout[destguid] > GetTime() and (monsterstate[destguid] == MS_TAPPED_US or monsterstate[destguid] == MS_TAPPED_US_TRIVIAL) and members_count > 0 then -- yaaay - local type = GetMonsterType(destguid) - if not QHC.monster[type] then QHC.monster[type] = {} end - if monsterstate[destguid] == MS_TAPPED_US then - QHC.monster[type].kills = (QHC.monster[type].kills or 0) + 1 / members_count -- Hopefully, most people loot their kills. Divide by members_count 'cause there's a 1/members chance that we get to loot. We'll flag the loot count some other way if it was a trivial monster. - end - - monsterstate[destguid] = (monsterstate[destguid] == MS_TAPPED_US and MS_TAPPED_LOOTABLE or MS_TAPPED_LOOTABLE_TRIVIAL) - monsterrefresh[destguid] = GetTime() + 600 - monstertimeout[destguid] = GetTime() + 600 - --QuestHelper:TextOut(string.format("Tapped monster %s slain, set to lootable", destguid)) - else - monsterstate[destguid] = nil - monsterrefresh[destguid] = nil - monstertimeout[destguid] = nil - --QuestHelper:TextOut(string.format("Untapped monster %s slain, cleared", destguid)) - end - end -end - -local skintypes = {} - -skintypes[UNIT_SKINNABLE_ROCK] = "mine" -skintypes[UNIT_SKINNABLE_HERB] = "herb" -skintypes[UNIT_SKINNABLE_BOLTS] = "eng" -skintypes[UNIT_SKINNABLE_LEATHER] = "skin" - -local function SkinnableflagsTooltipy(self, ...) - --QuestHelper:TextOut("tooltipy") - if UnitExists("mouseover") and UnitIsVisible("mouseover") and not UnitIsPlayer("mouseover") and not UnitPlayerControlled("mouseover") and UnitIsDead("mouseover") then - local guid = UnitGUID("mouseover") - --QuestHelper:TextOut("critar") - if not monsterstate[guid] or monsterstate[guid] ~= MS_TAPPED_LOOTED or monsterrefresh[guid] > GetTime() then return end - --QuestHelper:TextOut("runin") - - local cid = GetMonsterType(guid) - - local skintype = nil - - local lines = GameTooltip:NumLines() - for i = 3, lines do - --QuestHelper:TextOut(_G["GameTooltipTextLeft" .. tostring(i)]:GetText()) - local skeen = skintypes[_G["GameTooltipTextLeft" .. tostring(i)]:GetText()] - if skeen then QuestHelper: Assert(not skintype) skintype = skeen end - end - - if not QHC.monster[cid] then QHC.monster[cid] = {} end - local qhci = QHC.monster[cid] - - for _, v in pairs(skintypes) do - if v == skintype then - --QuestHelper:TextOut(v .. "_yes") - qhci[v .. "_yes"] = (qhci[v .. "_yes"] or 0) + 1 - else - --QuestHelper:TextOut(v .. "_no") - qhci[v .. "_no"] = (qhci[v .. "_no"] or 0) + 1 - end - end - end -end - --- Logic behind this module: --- Watch for the spell to be sent --- Watch for it to start --- Check out the combat log and see what GUID we get --- If the GUID is null, we're targeting an object, otherwise, we're targeting a critter --- Wait for spell to succeed --- If anything doesn't synch up, or the spell is interrupted, nil out all these items. --- We've got a little special case for pickpocketing, because people often use macros, so we detect that case specifically. - -local PP_PHASE_IDLE -local PP_PHASE_SENT -local PP_PHASE_COMPLETE - -local pickpocket_phase = PP_PHASE_IDLE -local pickpocket_target -local pickpocket_otarget_guid -local pickpocket_timestamp - -local pickpocket_name = GetSpellInfo(921) -- this is the pickpocket spell ID - -local function pp_reset() - pickpocket_target, pickpocket_otarget_guid, pickpocket_timestamp, pickpocket_phase = nil, nil, nil, PP_PHASE_IDLE -end -pp_reset() - -local function PPSent(player, spell, _, target) - if player ~= "player" then return end - if spell ~= pickpocket_name then return end - if UnitName("target") ~= target then return end -- DENY - - pickpocket_timestamp, pickpocket_target, pickpocket_otarget_guid, pickpocket_phase = GetTime(), target, UnitGUID("target"), PP_PHASE_SENT -end - -local function PPSucceed(player, spell, rank) - if player ~= "player" then return end - if spell ~= pickpocket_name then return end - - if pickpocket_phase ~= PP_PHASE_SENT and (not pickpocket_otarget_guid or last_timestamp + 1 < GetTime()) then - pp_reset() - return - end - - pickpocket_timestamp, pickpocket_phase = GetTime(), PP_PHASE_COMPLETE -end - - --- This segment deals with openable containers - -local touched_itemid -local touched_timestamp - -local function ItemLock(bag, slot) - if not bag or not slot then return end -- probably changing equipment - - local _, _, locked = GetContainerItemInfo(bag, slot) - --QuestHelper:TextOut(string.format("trying lock %s", tostring(locked))) - if locked then - touched_itemid = GetItemType(GetContainerItemLink(bag, slot)) - --[[QuestHelper:TextOut(string.format("trying lock %s", tostring(touched_itemid))) - QuestHelper:TextOut(string.format("trying lock %s", tostring(type(touched_itemid)))) - QuestHelper:TextOut(string.format("trying lock %s", tostring(QHC.item[touched_itemid].open_yes))) - QuestHelper:TextOut(string.format("trying lock %s", tostring(QHC.item[touched_itemid].open_no)))]] - touched_timestamp = GetTime() - if not QHC.item[touched_itemid] or (QHC.item[touched_itemid].open_yes or 0) <= (QHC.item[touched_itemid].open_no or 0) then - touched_itemid = nil - touched_timestamp = nil - end - else - touched_itemid = nil - touched_timestamp = nil - end -end - - --- Here's the segment for longer spells. There aren't any instant spells we currently care about, besides pickpocketing. This will probably change eventually (arrows in the DK starting zone?) - -local LAST_PHASE_IDLE = 0 -local LAST_PHASE_SENT = 1 -local LAST_PHASE_START = 2 -local LAST_PHASE_COMBATLOG = 3 -local LAST_PHASE_COMPLETE = 4 - -local last_phase = LAST_PHASE_IDLE -local last_spell -local last_rank -local last_target -local last_target_guid -local last_otarget -local last_otarget_guid -local last_timestamp -local last_succeed = false -local last_succeed_trade = GetTime() - -local gathereffects = {} - -gathereffects[GetSpellInfo(51306)] = {token = "eng", noclog = true} -gathereffects[GetSpellInfo(32606)] = {token = "mine"} -gathereffects[GetSpellInfo(2366)] = {token = "herb"} -gathereffects[GetSpellInfo(8613)] = {token = "skin"} -gathereffects[GetSpellInfo(21248)] = {token = "open", noclog = true} -gathereffects[GetSpellInfo(30427)] = {token = "extract", noclog = true} -- not a loot window, so it won't really work, but hey -gathereffects[GetSpellInfo(13262)] = {token = "de", noclog = true, ignore = true} -gathereffects[GetSpellInfo(31252)] = {token = "prospect", noclog = true, ignore = true} -gathereffects[GetSpellInfo(51005)] = {token = "mill", noclog = true, ignore = true} - - -local function normalize_spell(spell) - for k in pairs(gathereffects) do - if spell:find(k) then return k end - end - return spell -end - - -local function last_reset() - last_timestamp, last_spell, last_rank, last_target, last_target_guid, last_otarget, last_otarget_guid, last_succeed, last_phase = nil, nil, nil, nil, nil, nil, false, LAST_PHASE_IDLE -end -last_reset() - --- This all doesn't work with instant spells. Luckily, I don't care about instant spells (yet). -local function SpellSent(player, spell, rank, target) - if player ~= "player" then return end - spell = normalize_spell(spell) - - last_timestamp, last_spell, last_rank, last_target, last_target_guid, last_otarget, last_otarget_guid, last_succeed, last_phase = GetTime(), spell, rank, target, nil, UnitName("target"), UnitGUID("target"), false, LAST_PHASE_SENT - - if last_otarget and last_otarget ~= last_target then last_reset() return end - - --QuestHelper:TextOut(string.format("ss %s", spell)) -end - -local function SpellStart(player, spell, rank) - if player ~= "player" then return end - spell = normalize_spell(spell) - - if spell ~= last_spell or rank ~= last_rank or last_target_guid or last_phase ~= LAST_PHASE_SENT or last_timestamp + 1 < GetTime() then - last_reset() - else - --QuestHelper:TextOut(string.format("sst %s", spell)) - last_timestamp, last_phase = GetTime(), LAST_PHASE_START - end -end - -local function SpellCombatLog(_, event, sourceguid, _, _, destguid, _, _, _, spellname) - if event ~= "SPELL_CAST_START" then return end - - if sourceguid ~= UnitGUID("player") then return end - spellname = normalize_spell(spellname) - - --QuestHelper:TextOut(string.format("cle_ss enter %s %s %s %s", tostring(spellname ~= last_spell), tostring(not last_target), tostring(not not last_target_guid), tostring(last_timestamp + 1 < GetTime()))) - - if spellname ~= last_spell or not last_target or last_target_guid or last_timestamp + 1 < GetTime() then - last_reset() - return - end - - --QuestHelper:TextOut("cle_ss enter") - - if last_phase ~= LAST_PHASE_START then - last_reset() - return - end - - --QuestHelper:TextOut(string.format("cesst %s", spellname)) - last_timestamp, last_target_guid, last_phase = GetTime(), destguid, LAST_PHASE_COMBATLOG - - if last_target_guid == "0x0000000000000000" then last_target_guid = nil end - if last_target_guid and last_target_guid ~= last_otarget_guid then last_reset() return end -end - -local function SpellSucceed(player, spell, rank) - if player ~= "player" then return end - spell = normalize_spell(spell) - - if gathereffects[spell] then last_succeed_trade = GetTime() end - - --QuestHelper:TextOut(string.format("sscu enter %s %s %s %s %s", tostring(last_spell), tostring(last_target), tostring(last_rank), tostring(spell), tostring(rank))) - - if not last_spell or not last_target or last_spell ~= spell or last_rank ~= rank then - last_reset() - return - end - - --QuestHelper:TextOut("sscu enter") - - if gathereffects[spell] and gathereffects[spell].noclog then - if last_phase ~= LAST_PHASE_START or last_timestamp + 10 < GetTime() then - last_reset() - return - end - else - if last_phase ~= LAST_PHASE_COMBATLOG or last_timestamp + 10 < GetTime() then - last_reset() - return - end - end - - --QuestHelper:TextOut(string.format("sscu %s, %d, %s, %s", spell, last_phase, tostring(last_phase == LAST_PHASE_SENT), tostring((last_phase == LAST_PHASE_SENT) and LAST_PHASE_SHORT_SUCCEEDED))) - last_timestamp, last_succeed, last_phase = GetTime(), true, LAST_PHASE_COMPLETE - --QuestHelper:TextOut(string.format("last_phase %d", last_phase)) - - --[[if last_phase == LAST_PHASE_COMPLETE then - QuestHelper:TextOut(string.format("spell succeeded, casting %s %s on %s/%s", last_spell, last_rank, tostring(last_target), tostring(last_target_guid))) - end]] -end - -local function SpellInterrupt(player, spell, rank) - if player ~= "player" then return end - - -- I don't care what they were casting, they're certainly not doing it now - --QuestHelper:TextOut(string.format("si %s", spell)) - last_reset() -end - -local function LootOpened() - - local targetguid = UnitGUID("target") - - -- We're cleaning up the monster charts here, on the theory that if someone is looting, they're okay with a tiny lag spike. - if last_cleanup + 300 < GetTime() then - local cleanup = {} - for k, v in pairs(monstertimeout) do - if v < GetTime() then table.insert(cleanup, k) end - end - - for _, v in pairs(cleanup) do - monsterstate[v] = nil - monsterrefresh[v] = nil - monstertimeout[v] = nil - end - end - - -- First off, we try to figure out where the hell these items came from. - - local ltype = nil - local spot = nil - local prefix = nil - - if IsFishingLoot() then - -- yaaaaay - --if debug_output then QuestHelper:TextOut("Fishing loot") end - local loc = GetLoc() - if not QHC.fishing then QHC.fishing = {} end - ltype = QHC.fishing - spot = {} - spot.loc = loc - prefix = "fish" - - elseif pickpocket_phase == PP_PHASE_COMPLETE and pickpocket_timestamp and pickpocket_timestamp + 1 > GetTime() and targetguid == pickpocket_otarget_guid then - --if debug_output then QuestHelper:TextOut(string.format("Pickpocketing from %s/%s", pickpocket_target, UnitName("target"), targetguid)) end - local mid = GetMonsterType(targetguid) - if not QHC.monster[mid] then QHC.monster[mid] = {} end - spot = QHC.monster[mid] - prefix = "rob" - - elseif last_phase == LAST_PHASE_COMPLETE and gathereffects[last_spell] and last_timestamp + 1 > GetTime() then - local beef = string.format("%s/%s %s/%s", tostring(last_target), tostring(last_target_guid), tostring(last_otarget), tostring(last_otarget_guid)) - - if gathereffects[last_spell].ignore then return end - - prefix = gathereffects[last_spell].token - - -- this one is sort of grim actually - -- If we have an last_otarget_guid, it's the right one, and it's a monster - -- If we don't, use last_target, and it's an object - -- This is probably going to be buggy. Welp. - if last_otarget_guid then - if debug_output then QuestHelper:TextOut(string.format("%s from monster %s", gathereffects[last_spell].token, beef)) end - local mid = GetMonsterType(last_otarget_guid) - if not QHC.monster[mid] then QHC.monster[mid] = {} end - spot = QHC.monster[mid] - else - if debug_output then QuestHelper:TextOut(string.format("%s from object %s", gathereffects[last_spell].token, beef)) end - if not QHC.object[last_target] then QHC.object[last_target] = {} end - spot = QHC.object[last_target] - end - - elseif touched_timestamp and touched_timestamp + 1 > GetTime() then - -- Opening a container, possibly - --if debug_output then QuestHelper:TextOut(string.format("Opening container %d", touched_itemid)) end - if not QHC.item[touched_itemid] then QHC.item[touched_itemid] = {} end - spot = QHC.item[touched_itemid] - prefix = "open" - - elseif targetguid and (monsterstate[targetguid] == MS_TAPPED_LOOTABLE or monsterstate[targetguid] == MS_TAPPED_LOOTABLE_TRIVIAL) and monstertimeout[targetguid] > GetTime() and (not pickpocket_timestamp or pickpocket_timestamp + 5 < GetTime()) and (not last_timestamp or last_timestamp + 5 < GetTime()) and (last_succeed_trade + 5 < GetTime()) then -- haha holy shit - -- Monster is lootable, so we loot the monster. Should we check to see if it's dead first? Probably. - --if debug_output then QuestHelper:TextOut(string.format("%s from %s/%s", (monsterstate[targetguid] == MS_TAPPED_LOOTABLE and "Monsterloot" or "Trivial monsterloot"), UnitName("target"), targetguid)) end - - local mid = GetMonsterType(targetguid) - if not QHC.monster[mid] then QHC.monster[mid] = {} end - spot = QHC.monster[mid] - if monsterstate[targetguid] == MS_TAPPED_LOOTABLE then - prefix = "loot" - elseif monsterstate[targetguid] == MS_TAPPED_LOOTABLE_TRIVIAL then - prefix = "loot_trivial" -- might be a better way to do this, but we'll see - end - - monsterstate[targetguid] = MS_TAPPED_LOOTED - monstertimeout[targetguid] = GetTime() + 300 - monsterrefresh[targetguid] = GetTime() + 2 - else - --if debug_output then QuestHelper:TextOut("Who knows") end -- ugh - local loc = GetLoc() - if not QHC.worldloot then QHC.worldloot = {} end - ltype = QHC.worldloot - spot = {} - spot.loc = loc - prefix = "loot" - - end - - - - local items = {} - items[PseudoIDs["gold"]] = 0 - for i = 1, GetNumLootItems() do - tex, name, quant, qual, locked = GetLootSlotInfo(i) - link = GetLootSlotLink(i) - local curr = LootSlotIsCurrency(i) - local coin = LootSlotIsCoin(i) - local itm = LootSlotIsItem(i) - - if quant == 0 then - -- moneys - local tot = 0 - local _, _, gold = string.find(name, Patterns.GOLD_AMOUNT) - local _, _, silver = string.find(name, Patterns.SILVER_AMOUNT) - local _, _, copper = string.find(name, Patterns.COPPER_AMOUNT) - tot = (tonumber(gold) or 0) * 10000 + (tonumber(silver) or 0) * 100 + (tonumber(copper) or 0) * 1 - items[PseudoIDs["gold"]] = tot - else - if curr then - if not QHC.PseudoIDs[name] then - QHC.PseudoIDsMin = QHC.PseudoIDsMin - 1 - QHC.PseudoIDs[name] = QHC.PseudoIDsMin - end - items[QHC.PseudoIDs[name]] = (items[QHC.PseudoIDs[name]] or 0) + quant - else - if not link and not name then - local msg = "Texture is " .. tostring(tex) .. " with a quantity of " .. tostring(quant) .. ", a quality of " .. qual .. "." - if coin then - QuestHelper:Assert(false, "Loot slot " .. tostring(i) .. " is coin. " .. msg) - elseif itm then - QuestHelper:Assert(false, "Loot slot " .. tostring(i) .. " is item. " .. msg) - else - QuestHelper_ErrorCatcher_ExplicitError(false, "Loot slot " .. tostring(i) .. " is ???. " .. msg) - --QuestHelper:Assert(false, "Loot slot " .. tostring(i) .. " is ???. " .. msg) - end - elseif not link then - QuestHelper:Assert(link, "Need more info on '" .. name .. "'x" .. tostring(quant) .. ".") - elseif not name then - QuestHelper:Assert(name, "Need more info on '" .. link .. "'x" .. tostring(quant) .. ".") - end - local itype = GetItemType(link) - items[itype] = (items[itype] or 0) + quant - end - end - end - - if not spot[prefix] then spot[prefix] = {} end - spot[prefix]["count"] = (spot[prefix]["count"] or 0) + 1 - if not spot[prefix]["loot"] then spot[prefix]["loot"] = {} end - local pt = spot[prefix]["loot"] - for k, v in pairs(items) do - if v > 0 then pt[k] = (pt[k] or 0) + v end - end - - if ltype then table.insert(ltype, spot) end -end - -function QH_Collect_Loot_Init(QHCData, API) - QHC = QHCData - - if not QHC.monster then QHC.monster = {} end - if not QHC.worldloot then QHC.worldloot = {} end - if not QHC.fishing then QHC.fishing = {} end - if not QHC.item then QHC.item = {} end - if not QHC.PseudoIDs then - QHC.PseudoIDs = PseudoIDs - QHC.PseudoIDsMin = -1 - end - - QH_Event("PLAYER_ENTERING_WORLD", MembersUpdate) - QH_Event("RAID_ROSTER_UPDATE", MembersUpdate) - QH_Event("PARTY_MEMBERS_CHANGED", MembersUpdate) - QH_Event("COMBAT_LOG_EVENT_UNFILTERED", CombatLogEvent) - - QH_Event("UPDATE_MOUSEOVER_UNIT", SkinnableflagsTooltipy) - - QH_Event("UNIT_SPELLCAST_SENT", PPSent) - QH_Event("UNIT_SPELLCAST_SUCCEEDED", PPSucceed) - - QH_Event("ITEM_LOCK_CHANGED", ItemLock) - - QH_Event("UNIT_SPELLCAST_SENT", SpellSent) - QH_Event("UNIT_SPELLCAST_START", SpellStart) - QH_Event("COMBAT_LOG_EVENT_UNFILTERED", SpellCombatLog) - QH_Event("UNIT_SPELLCAST_SUCCEEDED", SpellSucceed) - QH_Event("UNIT_SPELLCAST_INTERRUPTED", SpellInterrupt) - - QH_Event("LOOT_OPENED", LootOpened) - - MembersUpdate() -- to get self, probably won't work but hey - - GetMonsterUID = API.Utility_GetMonsterUID - GetMonsterType = API.Utility_GetMonsterType - GetItemType = API.Utility_GetItemType - QuestHelper: Assert(GetMonsterUID) - QuestHelper: Assert(GetMonsterType) - QuestHelper: Assert(GetItemType) - - Patterns = API.Patterns - API.Patterns_RegisterNumber("GOLD_AMOUNT") - API.Patterns_RegisterNumber("SILVER_AMOUNT") - API.Patterns_RegisterNumber("COPPER_AMOUNT") - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - -- What I want to know is whether it was tagged by me or my group when dead - -- Check target-of-each-groupmember? Once we see him tapped once, and by us, it's probably sufficient. - -- Notes: - --[[ - - COMBAT_LOG_EVENT_UNFILTERED arg2 UNIT_DIED, PLAYER_TARGET_CHANGED, LOOT_OPENED, (LOOT_CLOSED, [LOOT_SLOT_CLEARED, ITEM_PUSH, CHAT_MSG_LOOT]), PLAYER_TARGET_CHANGED, SPELLCAST_SENT, SPELLCAST_START, SUCCEEDED/INTERRUPTED, STOP, LOOT_OPENED (etc) - - ITEM_PUSH can happen after LOOT_CLOSED, but it still happens. - Between LOOT_OPENED and LOOT_CLOSED, the lootable target is still targeted. Unsure what happens when looting items. LOOT_CLOSED triggers first if we target someone else. - ITEM_PUSH happens, then CHAT_MSG_LOOT. CHAT_MSG_LOOT includes quite a lot of potentially useful arguments. - PLAYER_TARGET_CHANGED before either looting or skinning. - SPELLCAST_SENT, SPELLCAST_START, SUCCEEDED/INTERRUPTED, STOP in that order. Arg4 on SENT seems to be the target's name. Arg4 on the others appears to be a unique identifier. - When started, we target the right thing. After that, we don't seem to. Check the combat log. - - ]] -end diff --git a/QHCollector/collect_lzw.lua b/QHCollector/collect_lzw.lua deleted file mode 100644 index 0a54408..0000000 --- a/QHCollector/collect_lzw.lua +++ /dev/null @@ -1,338 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_lzw.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_lzw.lua"] = GetTime() - -local Merger -local Bitstream - -local function cleanup(tab) - for _, v in pairs(tab) do - QuestHelper:ReleaseTable(v) - end - QuestHelper:ReleaseTable(tab) -end - -local function QH_LZW_Decompress(input, tokens, outbits, inputstatic) - local d = QuestHelper:CreateTable("lzw") - local i - for i = 0, tokens-1 do - d[i] = QuestHelper:CreateTable("lzw") - d[i][0] = string.char(i) - end - - local dsize = tokens + 1 -- we use the "tokens" value as an EOF marker - - if inputstatic then - local used = QuestHelper:CreateTable("lzw") - for _, v in ipairs(inputstatic) do - for i = #v, 2, -1 do - local subi = v:sub(1, i) - if not used[subi] then - used[subi] = true - - d[bit.mod(dsize, tokens)][math.floor(dsize / tokens)] = subi - dsize = dsize + 1 - else - break - end - end - end - QuestHelper:ReleaseTable(used) - end - - local bits = 1 - local nextbits = 2 - - while nextbits < dsize do bits = bits + 1; nextbits = nextbits * 2 end - - local i = Bitstream.Input(input, outbits) - local rv = {} - - local idlect = 0 - - local tok = i:depend(bits) - if tok == tokens then cleanup(d) return "" end -- Okay. There's nothing. We get it. - - Merger.Add(rv, d[bit.mod(tok, tokens)][math.floor(tok / tokens)]) - local w = d[bit.mod(tok, tokens)][math.floor(tok / tokens)] - while true do - if idlect == 25 then - QH_Timeslice_Yield() - idlect = 0 - else - idlect = idlect + 1 - end - - dsize = dsize + 1 -- We haven't actually added the next element yet. However, we could in theory include it in the stream, so we need to adjust the number of bits properly. - if dsize > nextbits then - bits = bits + 1 - nextbits = nextbits * 2 - end - - tok = i:depend(bits) - if tok == tokens then break end -- we're done! - - local entry - if d[bit.mod(tok, tokens)][math.floor(tok / tokens)] then - entry = d[bit.mod(tok, tokens)][math.floor(tok / tokens)] - elseif tok == dsize - 1 then - entry = w .. w:sub(1, 1) - else - QuestHelper: Assert(false, "faaaail") - end - Merger.Add(rv, entry) - - d[bit.mod(dsize - 1, tokens)][math.floor((dsize - 1) / tokens)] = w .. entry:sub(1, 1) -- Naturally, we're writing to one *less* than dsize, since we already incremented. - - w = entry - end - - cleanup(d) - - return Merger.Finish(rv) -end - -local function QH_LZW_Compress(input, tokens, outbits, inputstatic) - -- shared init code - local d = {} - local i - for i = 0, tokens-1 do - d[string.char(i)] = {[""] = i} - end - - local dsize = tokens + 1 -- we use the "tokens" value as an EOF marker - - if inputstatic then - for _, v in ipairs(inputstatic) do - local da = d[v:sub(1, 1)] - for i = #v, 2, -1 do - local b = v:sub(2, i) - if not da[b] then - da[b] = dsize - dsize = dsize + 1 - else - break - end - end - end - end - - local bits = 1 - local nextbits = 2 - - while nextbits < dsize do bits = bits + 1; nextbits = nextbits * 2 end - - local r = Bitstream.Output(outbits) - - local idlect = 0 - - local w = "" - for ci = 1, #input do - if idlect == 100 then - QH_Timeslice_Yield() - idlect = 0 - else - idlect = idlect + 1 - end - - local c = input:sub(ci, ci) - local wcp = w .. c - if d[wcp:sub(1, 1)][wcp:sub(2)] then - w = wcp - else - r:append(d[w:sub(1, 1)][w:sub(2)], bits) - d[wcp:sub(1, 1)][wcp:sub(2)] = dsize - dsize = dsize + 1 - if dsize > nextbits then - bits = bits + 1 - nextbits = nextbits * 2 - end - w = c - end - end - - if w ~= "" then - r:append(d[w:sub(1, 1)][w:sub(2)], bits) - - dsize = dsize + 1 -- Our decompressor doesn't realize we're ending here, so it will have added a table entry for that last token. Sigh. - if dsize > nextbits then - bits = bits + 1 - nextbits = nextbits * 2 - end - end - - r:append(tokens, bits) - - local rst = r:finish() - QuestHelper: Assert(QH_LZW_Decompress(rst, tokens, outbits, inputstatic) == input) -- yay - - return rst -end - -local function mdict(inputdict) - local idc = QuestHelper:CreateTable("lzw mdict") - for i = 1, #inputdict do if math.fmod(i, 100) == 0 then QH_Timeslice_Yield() end idc[inputdict:sub(i, i)] = strchar(i - 1) end - return idc -end - -local function dictize(idcl, stt) - local im = QuestHelper:CreateTable("lzw dictize") - for i = 1, #stt do - local subl = idcl[stt:sub(i, i)] - QuestHelper: Assert(subl) - Merger.Add(im, subl) - end - local result = Merger.Finish(im) - QuestHelper:ReleaseTable(im) - return result -end - -local function QH_LZW_Prepare(inputdict, inputstatic) - QuestHelper: Assert(inputdict and inputstatic) - - local idc = mdict(inputdict) - - local inpstat = {} - local ct = 0 - for _, v in ipairs(inputstatic) do - ct = ct + 1 - if ct == 10 then QH_Timeslice_Yield() ct = 0 end - table.insert(inpstat, dictize(idc, v)) - end - - return idc, #inputdict, inpstat -end - -local function QH_LZW_Compress_Dicts_Prepared(input, idprepped, idpreppedsize, outputdict, isprepped) - input = dictize(idprepped, input) - - local bits, dsize = 1, 2 - if not outputdict then bits = 8 else while dsize < #outputdict do bits = bits + 1 ; dsize = dsize * 2 end end - QuestHelper: Assert(not outputdict or #outputdict == dsize) - - local comp = QH_LZW_Compress(input, idpreppedsize, bits, isprepped) - - if outputdict then - local origcomp = comp - local im = {} - for i = 1, #origcomp do Merger.Add(im, outputdict:sub(strbyte(origcomp:sub(i, i)) + 1)) end - comp = Merger.Finish(im) - end - - return comp -end - -local function QH_LZW_Compress_Dicts(input, inputdict, outputdict, inputstatic) - local inproc = input - local inpstat = inputstatic - if inputdict then - local idc = mdict(inputdict) - - inproc = dictize(idc, input) - - if inputstatic then - inpstat = {} - for _, v in ipairs(inputstatic) do - table.insert(inpstat, dictize(idc, v)) - end - end - - QuestHelper:ReleaseTable(idc) - end - - local bits, dsize = 1, 2 - if not outputdict then bits = 8 else while dsize < #outputdict do bits = bits + 1 ; dsize = dsize * 2 end end - QuestHelper: Assert(not outputdict or #outputdict == dsize) - - local comp = QH_LZW_Compress(inproc, inputdict and #inputdict or 256, bits, inpstat) - - if outputdict then - local origcomp = comp - local im = {} - for i = 1, #origcomp do Merger.Add(im, outputdict:sub(strbyte(origcomp:sub(i, i)) + 1)) end - comp = Merger.Finish(im) - end - - return comp -end - -local function QH_LZW_Decompress_Dicts_Prepared(compressed, inputdict, outputdict, ispreppred) -- this is kind of backwards - we assume that "outputdict" is the dictionary that "compressed" is encoded in - QuestHelper: Assert(not outputdict) - QuestHelper: Assert(inputdict) - - local decomp = QH_LZW_Decompress(compressed, #inputdict, 8, ispreppred) - - local ov = {} - for i = 1, #decomp do - Merger.Add(ov, inputdict:sub(decomp:byte(i) + 1, decomp:byte(i) + 1)) - end - return Merger.Finish(ov) -end - -local function QH_LZW_Decompress_Dicts(compressed, inputdict, outputdict, inputstatic) -- this is kind of backwards - we assume that "outputdict" is the dictionary that "compressed" is encoded in - QuestHelper: Assert(not outputdict) - QuestHelper: Assert(inputdict) - - local inpstat = inputstatic - if inputdict and inputstatic then - local idc = mdict(inputdict) - - inpstat = {} - for _, v in ipairs(inputstatic) do - table.insert(inpstat, dictize(idc, v)) - end - - QuestHelper:ReleaseTable(idc) - end - - local decomp = QH_LZW_Decompress(compressed, #inputdict, 8, inpstat) - - local ov = {} - for i = 1, #decomp do - Merger.Add(ov, inputdict:sub(decomp:byte(i) + 1, decomp:byte(i) + 1)) - end - return Merger.Finish(ov) -end - -QH_LZW_Prepare_Arghhacky = QH_LZW_Prepare -- need to rig up a better mechanism for this really -QH_LZW_Decompress_Dicts_Arghhacky = QH_LZW_Decompress_Dicts -- need to rig up a better mechanism for this really -QH_LZW_Decompress_Dicts_Prepared_Arghhacky = QH_LZW_Decompress_Dicts_Prepared -- need to rig up a better mechanism for this really - -function QH_Collect_LZW_Init(_, API) - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) - - Bitstream = API.Utility_Bitstream - QuestHelper: Assert(Bitstream) - - API.Utility_LZW = {Compress = QH_LZW_Compress, Decompress = QH_LZW_Decompress, Compress_Dicts = QH_LZW_Compress_Dicts, Decompress_Dicts = QH_LZW_Decompress_Dicts, Prepare = QH_LZW_Prepare, Compress_Dicts_Prepared = QH_LZW_Compress_Dicts_Prepared, Decompress_Dicts_Prepared = QH_LZW_Decompress_Dicts_Prepared} -end - --- old debug code :) - ---[[ -print("hello") - -QH_LZW_Compress("TOBEORNOTTOBEORTOBEORNOT", 256, 8) -]] - ---[[ -QuestHelper:TextOut("lulz") - -local inq = "ABABABABA" -local alpha = 253 -local bits = 7 - -str = QH_LZW_Compress(inq, alpha, bits) -tvr = "" -for i = 1, #str do - tvr = tvr .. string.format("%d ", strbyte(str, i)) -end -QuestHelper:TextOut(tvr) - -ret = QH_LZW_Decompress(str, alpha, bits) -QuestHelper:TextOut(ret) - -QuestHelper: Assert(inq == ret) -]] diff --git a/QHCollector/collect_merchant.lua b/QHCollector/collect_merchant.lua deleted file mode 100644 index 7969d75..0000000 --- a/QHCollector/collect_merchant.lua +++ /dev/null @@ -1,82 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_merchant.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_merchant.lua"] = GetTime() - --- http://www.penny-arcade.com/comic/2005/01/05/ - -local debug_output = false -if QuestHelper_File["collect_merchant.lua"] == "Development Version" then debug_output = true end - -local QHCM - -local IsMonsterGUID -local GetMonsterType -local GetItemType - -local function AddChatType(typ) - local target = UnitGUID("target") - if not target then return end - - if not IsMonsterGUID(target) then return end - - target = GetMonsterType(target) - - if not QHCM[target] then QHCM[target] = {} end - QHCM[target]["chat_" .. typ] = (QHCM[target]["chat_" .. typ] or 0) + 1 - return QHCM[target] -end - -local function MerchantShow() - local ct = GetMerchantNumItems() - for i = 1, ct do if not GetMerchantItemLink(i) then return end end -- We want to make sure it's cached, otherwise we'll return wonky data. Technically this biases things away from "yes he's a shopkeeper", but honestly, it doesn't matter that much. - - targ = AddChatType("shop") - if not targ then return end -- welllllp - - local ct = GetMerchantNumItems() - --QuestHelper:TextOut(string.format("nitems %d", ct)) - - for i = 1, ct do - local itemid = GetMerchantItemLink(i) - QuestHelper: Assert(itemid) - itemid = GetItemType(itemid) - local _, _, price, quant, avail, _, _ = GetMerchantItemInfo(i) - local dstr = {} - dstr.quant = quant - dstr.avail = avail - dstr.price = price - --if debug_output then QuestHelper:TextOut(dstr) end - if not targ.shop then targ.shop = {} end - if not targ.shop[itemid] then - targ.shop[itemid] = dstr - end - - targ.shop[itemid].count = (targ.shop[itemid].count or 0) + 1 - end -end - -local function GossipShow() - AddChatType("talk") -end - -local function QuestGreeting() - AddChatType("quest") -end - - -function QH_Collect_Merchant_Init(QHCData, API) - if not QHCData.monster then QHCData.monster = {} end - QHCM = QHCData.monster - - QH_Event("MERCHANT_SHOW", MerchantShow) - QH_Event("GOSSIP_SHOW", GossipShow) - QH_Event("QUEST_GREETING", QuestGreeting) - - IsMonsterGUID = API.Utility_IsMonsterGUID - GetMonsterType = API.Utility_GetMonsterType - GetItemType = API.Utility_GetItemType - QuestHelper: Assert(IsMonsterGUID) - QuestHelper: Assert(GetMonsterType) - QuestHelper: Assert(GetItemType) -end diff --git a/QHCollector/collect_merger.lua b/QHCollector/collect_merger.lua deleted file mode 100644 index b5a07f0..0000000 --- a/QHCollector/collect_merger.lua +++ /dev/null @@ -1,27 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_merger.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_merger.lua"] = GetTime() - - -local function Add(self, data, stoprepeat) -- NOTE: if you're getting errors about adding tables, you probably did Merger:Add instead of Merger.Add - if stoprepeat and #self > 0 and string.sub(self[#self], -#data) == data then return end - table.insert(self, data) - for i = #self - 1, 1, -1 do - if string.len(self[i]) > string.len(self[i + 1]) then break end - self[i] = self[i] .. table.remove(self, i + 1) - end -end -local function Finish(self, data) - for i = #self - 1, 1, -1 do - self[i] = self[i] .. table.remove(self) - end - return self[1] or "" -end - -QH_Merger_Add = Add -QH_Merger_Finish = Finish - -function QH_Collect_Merger_Init(_, API) - API.Utility_Merger = {Add = Add, Finish = Finish} -end diff --git a/QHCollector/collect_monster.lua b/QHCollector/collect_monster.lua deleted file mode 100644 index 3fb4e00..0000000 --- a/QHCollector/collect_monster.lua +++ /dev/null @@ -1,138 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_monster.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_monster.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_monster.lua"] == "Development Version" then debug_output = true end - -local QHCM - -local GetLoc -local Merger -local Patterns - -local IsMonsterGUID -local GetMonsterUID -local GetMonsterType - -local logon = GetTime() -- Because I'm incredibly paranoid, I'm waiting fifteen minutes after logon to assume they're not drunk. -local drunk_logon = true -local drunk_message = false - -local function SystemMessage(arg, arg2, arg3) - if strfind(arg, Patterns["DRUNK_MESSAGE_SELF2"]) or strfind(arg, Patterns["DRUNK_MESSAGE_SELF3"]) or strfind(arg, Patterns["DRUNK_MESSAGE_SELF4"]) or strfind(arg, Patterns["DRUNK_MESSAGE_ITEM_SELF2"]) or strfind(arg, Patterns["DRUNK_MESSAGE_ITEM_SELF3"]) or strfind(arg, Patterns["DRUNK_MESSAGE_ITEM_SELF4"]) then - drunk_message = true - elseif strfind(arg, Patterns["DRUNK_MESSAGE_SELF1"]) or strfind(arg, Patterns["DRUNK_MESSAGE_ITEM_SELF1"]) then - drunk_message = false - end -end - -local InteractDistances = {28, 11, 10, 0} -- There's actually a 4, but it's also 28 and it's kind of handy to be able to do it this way. - -local recentlySeenCritters = {} -- We try not to repeatedly record critters frequently. - --- Kind of a nasty system here, built for efficiency and simplicity. All newly-seen critters go into Recent. When Recent reaches a certain size (100?) everything in NextTrash is deleted and NextTrash is replaced with Recent. Badabing, badaboom. -local recentlySeenCritters_NextTrash = {} -local recentlySeenCritters_Recent = {} - -local function AccumulateFrequency(target, name, data) - if not target[name] then target[name] = {} end - target[name][data] = (target[name][data] or 0) + 1 - --local key = name .. "_" .. tostring(data) - --target[key] = (target[key] or 0) + 1 -end - -local function MouseoverUnit() - if logon and logon + 60 * 15 < GetTime() then - logon = nil - drunk_logon = false - end - - -- First off, we see if it's "interesting". - -- The original code for this filtered out critters. I don't, because critters are cute, and rare. - if UnitExists("mouseover") and UnitIsVisible("mouseover") and not UnitIsPlayer("mouseover") and not UnitPlayerControlled("mouseover") then - local guid = UnitGUID("mouseover") - - if not IsMonsterGUID(guid) then return end -- pet that isn't controlled by a player? NPC pet? It's kind of unclear, but I'm getting some, so, FIXED - local creatureid = GetMonsterUID(guid) - - if not recentlySeenCritters[creatureid] then - recentlySeenCritters_Recent[creatureid] = true - recentlySeenCritters[creatureid] = true - - -- register the critter here - local cid = GetMonsterType(guid) - - if not QHCM[cid] then QHCM[cid] = {} end - local critter = QHCM[cid] - - if cid < 30621 or cid > 30625 then AccumulateFrequency(critter, "name", UnitName("mouseover")) end -- The exceptions are for Herald Volasj's minions, which are named after your partymembers. - AccumulateFrequency(critter, "reaction", UnitReaction("mouseover", "player")) - if not drunk_logon and not drunk_message then - AccumulateFrequency(critter, "level", UnitLevel("mouseover")) - end - - local minrange = InteractDistances[1] - local maxrange = 255 - -- Now we try to derive a bound for how far away it is - for i = #InteractDistances - 1, 1, -1 do - if CheckInteractDistance("mouseover", i) then - minrange = InteractDistances[i + 1] - maxrange = InteractDistances[i] - break - end - end - QuestHelper: Assert(minrange >= 0 and minrange < 256 and maxrange >= 0 and maxrange < 256) - local data = {} - data.loc = GetLoc() - data.minrange = minrange - data.maxrange = maxrange - if not critter.encounters then critter.encounters = {} end - table.insert(critter.encounters, data) - --Merger.Add(critter, string.format("(%s %s %s),", GetLoc(), tostring(minrange), tostring(maxrange))) --strchar(minrange, maxrange)) - - if #recentlySeenCritters_Recent >= 100 then - for k, v in recentlySeenCritters_NextTrash do - recentlySeenCritters[v] = nil - end - - recentlySeenCritters_NextTrash = recentlySeenCritters_Recent - recentlySeenCritters_Recent = {} -- BAM, garbage collection! - end - end - end -end - -function QH_Collect_Monster_Init(QHCData, API) - if not QHCData.monster then QHCData.monster = {} end - QHCM = QHCData.monster - - QH_Event("UPDATE_MOUSEOVER_UNIT", MouseoverUnit) - QH_Event("CHAT_MSG_SYSTEM", SystemMessage) - - Patterns = API.Patterns - QuestHelper: Assert(Patterns) - - API.Patterns_Register("DRUNK_MESSAGE_SELF1", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_SELF2", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_SELF3", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_SELF4", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_ITEM_SELF1", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_ITEM_SELF2", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_ITEM_SELF3", "|c.*|r") - API.Patterns_Register("DRUNK_MESSAGE_ITEM_SELF4", "|c.*|r") - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) - - IsMonsterGUID = API.Utility_IsMonsterGUID - GetMonsterUID = API.Utility_GetMonsterUID - GetMonsterType = API.Utility_GetMonsterType - QuestHelper: Assert(IsMonsterGUID) - QuestHelper: Assert(GetMonsterUID) - QuestHelper: Assert(GetMonsterType) -end diff --git a/QHCollector/collect_notifier.lua b/QHCollector/collect_notifier.lua deleted file mode 100644 index 6d49346..0000000 --- a/QHCollector/collect_notifier.lua +++ /dev/null @@ -1,29 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_notifier.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_notifier.lua"] = GetTime() - -local NotificationsPending = {} - -local function OnUpdate() - while #NotificationsPending > 0 and GetTime() >= NotificationsPending[1].time do - NotificationsPending[1].func() - table.remove(NotificationsPending, 1) -- okay okay n^2 deal with it - end -end - -local function AddItem(time, func) - QuestHelper: Assert(time) - QuestHelper: Assert(func) - table.insert(NotificationsPending, {time = time, func = func}) - table.sort(NotificationsPending, function (a, b) return a.time < b.time end) -- haha who cares about efficiency anyway, NOT ME that is for certain -end - -function QH_Collect_Notifier_Init(_, API) - API.Utility_Notifier = AddItem - - API.Registrar_OnUpdateHook(OnUpdate) -end - --- grrrr -QH_AddNotifier = AddItem diff --git a/QHCollector/collect_object.lua b/QHCollector/collect_object.lua deleted file mode 100644 index ea29c2f..0000000 --- a/QHCollector/collect_object.lua +++ /dev/null @@ -1,109 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_object.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_object.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_object.lua"] == "Development Version" then debug_output = true end - -local QHCO - -local GetLoc -local Merger -local Patterns - -local minetypes = { - mine = UNIT_SKINNABLE_ROCK, - herb = UNIT_SKINNABLE_HERB, - eng = UNIT_SKINNABLE_BOLTS, - skin = UNIT_SKINNABLE_LEATHER, -} - -local function Tooltipy(self) - -- objects are a bitch since they have no unique ID or any standard way to detect them (that I know of). - -- So we kind of guess at it. - if self:GetAnchorType() == "ANCHOR_NONE" then -- Theoretically this function no longer exists as of 2010-12-14. - if self:GetItem() or self:GetUnit() or self:GetSpell() then return end - -- rglrglrglrglrglrgl - - local skintype = nil - - local lines = GameTooltip:NumLines() - - if not skintype then - local cline = 2 - - -- the painful process of checking to see if it might be a game object - -- first, look for a "requires" line - - if not (_G["GameTooltipTextLeft" .. cline] and _G["GameTooltipTextLeft" .. cline]:IsShown()) then return end - - do - local gt = _G["GameTooltipTextLeft" .. cline]:GetText() - if string.match(gt, Patterns.LOCKED_WITH_ITEM) or string.match(gt, Patterns.LOCKED_WITH_SPELL) or string.match(gt, Patterns.LOCKED_WITH_SPELL_KNOWN) then cline = cline + 1 end - end - - if not (_G["GameTooltipTextLeft" .. cline] and _G["GameTooltipTextLeft" .. cline]:IsShown()) then return end - - local r, g, b, a = _G["GameTooltipTextLeft" .. cline]:GetTextColor() - r, g, b, a = math.floor(r * 255 + 0.5), math.floor(g * 255 + 0.5), math.floor(b * 255 + 0.5), math.floor(a * 255 + 0.5) - if not (r == 255 and g == 210 and b == 0 and a == 255) then return end -- not a quest item, which I guess we care about - cline = cline + 1 - - if not (_G["GameTooltipTextLeft" .. cline] and _G["GameTooltipTextLeft" .. cline]:IsShown()) then return end - - local r, g, b, a = _G["GameTooltipTextLeft" .. cline]:GetTextColor() - r, g, b, a = math.floor(r * 255 + 0.5), math.floor(g * 255 + 0.5), math.floor(b * 255 + 0.5), math.floor(a * 255 + 0.5) - if not (r == 255 and g == 255 and b == 255 and a == 255) or not _G["GameTooltipTextLeft" .. cline]:GetText():match("^ - ") then return end -- not a quest item, which I guess we care about - - -- alright good enough - end - - local name = _G["GameTooltipTextLeft1"]:GetText() - - if string.match(name, Patterns.CORPSE_TOOLTIP) then return end -- no corpses plzkthx - - if debug_output then QuestHelper:TextOut("Parsing " .. name) end - - if not QHCO[name] then QHCO[name] = {} end - local qhci = QHCO[name] - - -- We have no unique identifier, so I'm just going to record every position we see. That said, I wonder if it's a good idea to add a cooldown. - -- Obviously, we also have no possible range data, so, welp. - local loc = GetLoc() - local contained = false - for _, v in pairs(qhci) do - if v.delayed then - if v.delayed == loc.delayed and - v.c == loc.c and v.z == loc.z and - v.x == loc.x and v.y == loc.y then - contained = true - break - end - end - end - if not contained then table.insert(qhci, loc) end - --Merger.Add(qhci, "(" .. GetLoc() .. ")", true) - end -end - -function QH_Collect_Object_Init(QHCData, API) - if not QHCData.object then QHCData.object = {} end - QHCO = QHCData.object - - API.Registrar_TooltipHook(Tooltipy) - - Patterns = API.Patterns - QuestHelper: Assert(Patterns) - - API.Patterns_Register("CORPSE_TOOLTIP", "[^%s]+") - API.Patterns_Register("LOCKED_WITH_ITEM", "[^%s]+") - API.Patterns_Register("LOCKED_WITH_SPELL", "[^%s]+") - API.Patterns_Register("LOCKED_WITH_SPELL_KNOWN", "[^%s]+") - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) -end diff --git a/QHCollector/collect_patterns.lua b/QHCollector/collect_patterns.lua deleted file mode 100644 index 601c7c8..0000000 --- a/QHCollector/collect_patterns.lua +++ /dev/null @@ -1,21 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_patterns.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_patterns.lua"] = GetTime() - -local patterns = {} - -function MakePattern(label, newpat) - if not newpat then newpat = ".*" end - if not patterns[label] then patterns[label] = "^" .. string.gsub(_G[label], "%%s", newpat) .. "$" end -end - -function MakeNumberSnag(label) - if not patterns[label] then patterns[label] = string.gsub(_G[label], "%%d", "([0-9,.]+)") end -end - -function QH_Collect_Patterns_Init(QHCData, API) - API.Patterns = patterns - API.Patterns_Register = MakePattern - API.Patterns_RegisterNumber = MakeNumberSnag -end diff --git a/QHCollector/collect_quest.lua b/QHCollector/collect_quest.lua deleted file mode 100644 index 13a03c4..0000000 --- a/QHCollector/collect_quest.lua +++ /dev/null @@ -1,439 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_quest.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_quest.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_quest.lua"] == "Development Version" then debug_output = true end - -local IsMonsterGUID -local GetMonsterType - -local GetQuestType -local GetItemType - -local GetLoc -local GetSpecBolus - -local QHCQ - -local deebey - -local function RegisterQuestData(category, location, GetQuestLogWhateverInfo) - local index = 1 - local localspot - while true do - local ilink = GetQuestLogItemLink(category, index) - if not ilink then break end - - if not localspot then if not location["items_" .. category] then location["items_" .. category] = {} end localspot = location["items_" .. category] end - - local name, tex, num, qual, usa = GetQuestLogWhateverInfo(index) - localspot[GetItemType(ilink)] = num - - --QuestHelper:TextOut(string.format("%s:%d - %d %s %s", category, index, num, tostring(ilink), tostring(name))) - - index = index + 1 - end -end - -local complete_suffix = string.gsub(string.gsub(string.gsub(ERR_QUEST_OBJECTIVE_COMPLETE_S, "%%s", ""), "%)", "%%)"), "%(", "%%(") -function pin() - QuestHelper:TextOut("^.*: (%d+)/(%d+)(" .. complete_suffix .. ")?$") -end - --- qlookup[questname][objectivename] = {{qid = qid, objid = objid}} -local qlookups = {} - -local function ScanQuests() - - local selected - local index = 1 - - local dbx = {} - - qlookups = {} - - while true do - if not GetQuestLogTitle(index) then break end - - local qlink = GetQuestLink(index) - if qlink then - --QuestHelper:TextOut(qlink) - --QuestHelper:TextOut(string.gsub(qlink, "|", "||")) - local id, level = GetQuestType(qlink) - local title, _, tag, groupcount, _, _, _, daily = GetQuestLogTitle(index) - - if not qlookups[title] then qlookups[title] = {} end -- gronk - - --QuestHelper:TextOut(string.format("%s - %d %d", qlink, id, level)) - - if not QHCQ[id] then - --if true then - if not selected then selected = GetQuestLogSelection() end - SelectQuestLogEntry(index) - - QHCQ[id] = {} - QHCQ[id].level = level - - RegisterQuestData("reward", QHCQ[id], GetQuestLogRewardInfo) - RegisterQuestData("choice", QHCQ[id], GetQuestLogChoiceInfo) - - --QuestHelper:TextOut(string.format("%d", GetNumQuestLeaderBoards(index))) - if not QHCQ[id]["criteria"] then QHCQ[id]["criteria"] = {} end - - for i = 1, GetNumQuestLeaderBoards(index) do - local desc, typ = GetQuestLogLeaderBoard(i, index) - local criterion = { text = desc, type = typ } - QHCQ[id]["criteria"][tostring(i)] = criterion - --QHCQ[id][string.format("criteria_%d_text", i)] = desc - --QHCQ[id][string.format("criteria_%d_type", i)] = type - --QuestHelper:TextOut(string.format("%s, %s", desc, type)) - end - - QHCQ[id].name = title - QHCQ[id].tag = tag - QHCQ[id].groupcount = (groupcount or -1) - QHCQ[id].daily = (not not daily) - - if GetQuestLogSpecialItemInfo then - local typ = GetQuestLogSpecialItemInfo(index) - if typ then typ = GetItemType(typ) end - QHCQ[id].special_item = typ or false - end - end - - dbx[id] = {} - - - --QuestHelper:TextOut(string.format("%d", GetNumQuestLeaderBoards(index))) - - for i = 1, GetNumQuestLeaderBoards(index) do - local desc, typ, done = GetQuestLogLeaderBoard(i, index) - - -- Some quests have faulty objectives where there is literally NO information... Ignore those objectives. - if desc and typ ~= "log" then - if not qlookups[title][desc] then qlookups[title][desc] = {} end - table.insert(qlookups[title][desc], {qid = id, obj = i}) - - -- If we wanted to parse everything here, we'd do something very complicated. - -- Fundamentally, we don't. We only care if numeric values change or if something goes from "not done" to "done". - -- Luckily, the patterns are identical in all cases for this (I think.) - local have, needed = string.match(desc, "^.*: (%d+)/(%d+)$") - have = tonumber(have) - needed = tonumber(needed) - - --[[QuestHelper:TextOut(desc) - QuestHelper:TextOut("^.*: (%d+)/(%d+)(" .. complete_suffix .. ")?$") - QuestHelper:TextOut(string.gsub(desc, complete_suffix, "")) - QuestHelper:TextOut(string.format("%s %s", tostring(have), tostring(needed)))]] - if not have or not needed then - have = done and 1 or 0 - needed = 1 -- okay so we don't really use this unless we're debugging, shut up >:( - end - - dbx[id][i] = have - end - end - end - - index = index + 1 - end - - if selected then SelectQuestLogEntry(selected) end -- abort abort bzzt bzzt bzzt awoooooooga dive, dive, dive - - return dbx -end - -local eventy = {} - -local function Looted(message) - local ltype = GetItemType(message, true) - - -- Oddly, we get an ltype that has a nil value once in a while, so we ignore it and return. - -- Only seems to occur when rolling for something. - if ltype == nil then return end - - -- Just in case... - if type(ltype) ~= "number" then - error(string.format("Expected a number but got a %s.", type(ltype)) .. "The value is:" .. ltype) - end - table.insert(eventy, {time = GetTime(), event = {type = "item", value = ltype}}) - --if debug_output then QuestHelper:TextOut(string.format("Added event %s", string.format("I%di", ltype))) end -end - -local function Combat(_, event, _, _, _, _, _, guid) - if event ~= "UNIT_DIED" then return end - if not IsMonsterGUID(guid) then return end - local mtype = GetMonsterType(guid, true) - table.insert(eventy, {time = GetTime(), event = { type = "monster", value = mtype}}) - --if debug_output then QuestHelper:TextOut(string.format("Added event %s", string.format("M%dm", mtype))) end -end - -local changed = false -local first = true - -local function Init() - first = true -end - -local function LogChanged() - changed = true -end - -local function WatchUpdate() -- we're currently ignoring the ID of the quest that was updated for simplicity's sake. - changed = true -end - -local function AppendMember(tab, key, dat) - if not tab[key] then tab[key] = {} end - table.insert(tab[key], dat) - --tab[key] = (tab[key] or "") .. dat -end - -local function StartOrEnd(se, id) - local targuid = UnitGUID("target") - local chunk = {} - if targuid and IsMonsterGUID(targuid) then - chunk.m = GetMonsterType(targuid) - end - chunk.loc = GetLoc() - chunk.spec = GetSpecBolus() - - if not QHCQ[id][se] then QHCQ[id][se] = {} end - - table.insert(QHCQ[id][se], chunk) - --AppendMember(QHCQ[id], se, chunk) - --AppendMember(QHCQ[id], se .. "_spec", GetSpecBolus()) -end - -local abandoncomplete = "" -local abandoncomplete_timestamp = nil - -local GetQuestReward_Orig = GetQuestReward -GetQuestReward = function (...) - abandoncomplete = "complete" - abandoncomplete_timestamp = GetTime() - GetQuestReward_Orig(...) -end - -local AbandonQuest_Orig = AbandonQuest -AbandonQuest = function () - abandoncomplete = "abandon" - abandoncomplete_timestamp = GetTime() - AbandonQuest_Orig() -end - -local function UpdateQuests() - - do -- this should once and for all fix this issue - local foverride = true - for _, _ in pairs(deebey) do - foverride = false - end - if UnitLevel("player") == 1 then - foverride = false - end - if foverride then foverride = true end - end - - if first then deebey = ScanQuests() first = false end - if not changed then return end - changed = false - - local tim = GetTime() - - local noobey = ScanQuests() - - local traverse = {} - - local dsize, nsize = QuestHelper:TableSize(deebey), QuestHelper:TableSize(noobey) - - for k, _ in pairs(deebey) do traverse[k] = true end - for k, _ in pairs(noobey) do traverse[k] = true end - - --[[ - if QuestHelper:TableSize(deebey) ~= QuestHelper:TableSize(noobey) then - QuestHelper:TextOut(string.format("%d %d", QuestHelper:TableSize(deebey), QuestHelper:TableSize(noobey))) - end]] - - while #eventy > 0 and eventy[1].time < GetTime() - 1 do table.remove(eventy, 1) end -- slurp - local token - local debugtok - - local diffs = 0 - - for k, _ in pairs(traverse) do - if not deebey[k] then - -- Quest was acquired - if debug_output then QuestHelper:TextOut(string.format("Acquired! Questid %d", k)) end - StartOrEnd("start", k) - diffs = diffs + 1 - - elseif not noobey[k] then - -- Quest was dropped or completed - if abandoncomplete == "complete" and abandoncomplete_timestamp + 30 >= GetTime() then - if debug_output then QuestHelper:TextOut(string.format("Completed! Questid %d", k)) end - StartOrEnd("end", k) - abandoncomplete = "" - else - if debug_output then QuestHelper:TextOut(string.format("Dropped! Questid %d", k)) end - end - - diffs = diffs + 1 - - else - QuestHelper: Assert(#deebey[k] == #noobey[k], string.format("%d vs %d, %d", #deebey[k], #noobey[k], k)) - for i = 1, #deebey[k] do - - if noobey[k][i] > deebey[k][i] then - if not token then - token = {} - token["events"] = {} - for k, v in pairs(eventy) do table.insert(token.events, v.event) end - debugtok = token - token["loc"] = GetLoc() - --token = token .. "(" .. GetLoc() .. ")" - end - - local ttok = token - if noobey[k][i] - 1 ~= deebey[k][i] then - --ttok = string.format("C%dc", noobey[k][i] - deebey[k][i]) .. ttok - if not ttok["Cdc"] then ttok["Cdc"] = {} end - table.insert(ttok["Cdc"], noobey[k][i] - deebey[k][i]) - end - - if not QHCQ[k]["criteria"] then QHCQ[k]["criteria"] = {} end - - if not QHCQ[k]["criteria"][tostring(i)] then QHCQ[k]["criteria"][tostring(i)] = {} end - if not QHCQ[k]["criteria"][tostring(i)]["satisfied"] then QHCQ[k]["criteria"][tostring(i)]["satisfied"] = {} end - table.insert(QHCQ[k]["criteria"][tostring(i)]["satisfied"], ttok) - --AppendMember(QHCQ[k], string.format("criteria_%d_satisfied", i), ttok) - - if debug_output then QuestHelper:TextOut(string.format("Updated! Questid %d item %d count %d tok %s", k, i, noobey[k][i] - deebey[k][i], debugtok)) end - diffs = diffs + 1 - end - end - end - end - - deebey = noobey - - --QuestHelper: Assert(diffs <= 5, string.format("excessive quest diffs - delta is %d, went from %d to %d", diffs, dsize, nsize)) - --QuestHelper:TextOut(string.format("done in %f", GetTime() - tim)) -end - -local enable_quest_hints = GetBuildInfo():match("0%.1%..*") or (GetBuildInfo():match("3%..*") and not GetBuildInfo():match("3%.0%..*")) -QH_filter_hints = false - -local function MouseoverUnit() - QH_filter_hints = false - if not enable_quest_hints then return end - - if GameTooltip:GetUnit() and UnitExists("mouseover") and UnitIsVisible("mouseover") and not UnitIsPlayer("mouseover") and not UnitPlayerControlled("mouseover") then - local guid = UnitGUID("mouseover") - - if not IsMonsterGUID(guid) then return end - - guid = GetMonsterType(guid) - - if GetQuestLogSpecialItemInfo then - for _, v in pairs(qlookups) do - for _, block in pairs(v) do - for _, tv in ipairs(block) do - if not QHCQ[tv.qid]["criteria"] then QHCQ[tv.qid]["criteria"] = {} end - if not QHCQ[tv.qid]["criteria"][tostring(tv.obj)] then QHCQ[tv.qid]["criteria"][tostring(tv.obj)] = {} end - if not QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"] then QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"] = {} end - if not QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["true"] then - QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["true"] = {} - QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"] = {} - end - - QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"][guid] = (QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"][guid] or 0) + 1 - end - end - end - - local line = 2 - local qs - local qe - - while _G["GameTooltipTextLeft" .. line] and _G["GameTooltipTextLeft" .. line]:IsShown() do - local r, g, b, a = _G["GameTooltipTextLeft" .. line]:GetTextColor() - r, g, b, a = math.floor(r * 255 + 0.5), math.floor(g * 255 + 0.5), math.floor(b * 255 + 0.5), math.floor(a * 255 + 0.5) - --print(r, g, b, a) - - if r == 255 and g == 210 and b == 0 and a == 255 then - if not qs then qs = line end - else - if qs and not qe then qe = line end - end - line = line + 1 - end - - if qs and not qe then qe = line end - if qe then qe = qe - 1 end - - if qs and qe then - local cquest = nil - - QH_filter_hints = true - - for i = qs, qe do - local lin = _G["GameTooltipTextLeft" .. i]:GetText() - - if cquest and cquest[lin] then - local titem_block = cquest[lin] - for _, titem in pairs(titem_block) do - local tv = titem - QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"][guid] = (QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"][guid] or 0) - 1 - QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["false"][guid] = (QHCQ[tv.qid]["criteria"][tostring(tv.obj)]["monster"]["true"][guid] or 0) + 1 - end - elseif qlookups[lin] then - cquest = qlookups[lin] - else - QH_filter_hints = false - --QuestHelper: Assert() - end - end - end - end - end -end - -function QH_Collect_Quest_Init(QHCData, API) - if not QHCData.quest then QHCData.quest = {} end - QHCQ = QHCData.quest - - GetQuestType = API.Utility_GetQuestType - GetItemType = API.Utility_GetItemType - IsMonsterGUID = API.Utility_IsMonsterGUID - GetMonsterType = API.Utility_GetMonsterType - GetSpecBolus = API.Utility_GetSpecBolus - QuestHelper: Assert(GetQuestType) - QuestHelper: Assert(GetItemType) - QuestHelper: Assert(IsMonsterGUID) - QuestHelper: Assert(GetMonsterType) - QuestHelper: Assert(GetSpecBolus) - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - deebey = ScanQuests() - - QH_Event("UNIT_QUEST_LOG_CHANGED", LogChanged) - QH_Event("QUEST_LOG_UPDATE", UpdateQuests) - QH_Event("QUEST_WATCH_UPDATE", WatchUpdate) - - QH_Event("CHAT_MSG_LOOT", Looted) - QH_Event("COMBAT_LOG_EVENT_UNFILTERED", Combat) - - API.Registrar_TooltipHook(MouseoverUnit) - - -- Here's a pile of events that seem to trigger during startup that also don't seem like would trigger while questing. - -- We'll lose a few quest updates from this, but that's OK. - QH_Event("PLAYER_ENTERING_WORLD", Init) - QH_Event("UNIT_MODEL_CHANGED", Init) - QH_Event("GUILDBANK_UPDATE_WITHDRAWMONEY", Init) - QH_Event("UPDATE_TICKET", Init) -end diff --git a/QHCollector/collect_spec.lua b/QHCollector/collect_spec.lua deleted file mode 100644 index 011a463..0000000 --- a/QHCollector/collect_spec.lua +++ /dev/null @@ -1,75 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_spec.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_spec.lua"] = GetTime() - -local Bitstream - -local classlookup = { - ["DEATHKNIGHT"] = "K", - ["DRUID"] = "D", - ["HUNTER"] = "H", - ["MAGE"] = "M", - ["PALADIN"] = "N", - ["PRIEST"] = "P", - ["ROGUE"] = "R", - ["SHAMAN"] = "S", - ["WARLOCK"] = "L", - ["WARRIOR"] = "W" -}; - -local racelookup = { - ["Draenei"] = "R", - ["Gnome"] = "G", - ["Dwarf"] = "D", - ["Human"] = "H", - ["NightElf"] = "E", - ["Worgen"] = "W", - - ["Orc"] = "O", - ["Troll"] = "T", - ["Tauren"] = "N", - ["Undead"] = "U", - ["BloodElf"] = "B", - ["Goblin"] = "L" - -- lol i spelled nub -} - -local function GetSpecBolus() - local _, id = UnitClass("player") - local level = UnitLevel("player") - local _, race = UnitRace("player") - - --[[ assert(racelookup[race]) ]] - - --local bso = Bitstream.Output(8) - local talents = {} - - local points = (GetUnspentTalentPoints() or 0) - local talents_learned = false - for t = 1, GetNumTalentTabs() do -- come on. Is this ever not going to be 3? Seriously? Perhaps someday, but not as of Cat. - local _, tab, _, _, p, _, _, yn = GetTalentTabInfo(t) - p = p or 0 - talents_learned = true - talents[tab] = {} - for ta = 1, GetNumTalents(t) do - local talent, _, _, _, rank, _ = GetTalentInfo(t, ta) - if talent then talents[tab][talent] = rank end - end - end - - local spec = {} - spec.talents = talents - spec.class = id - spec.race = race - spec.level = level - --return string.format("(2%s,%s,%02d)", classlookup[id], racelookup[race] or "", level) .. talstr - return spec -end - -function QH_Collect_Spec_Init(_, API) - Bitstream = API.Utility_Bitstream - QuestHelper: Assert(Bitstream) - - API.Utility_GetSpecBolus = GetSpecBolus -end diff --git a/QHCollector/collect_traveled.lua b/QHCollector/collect_traveled.lua deleted file mode 100644 index 730d8d2..0000000 --- a/QHCollector/collect_traveled.lua +++ /dev/null @@ -1,220 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_traveled.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_traveled.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_traveled.lua"] == "Development Version" then debug_output = true end - ---[[ - -Meaningful symbols it generates: - -%d,%d,%d,%d|COMPRESSED - -First four values: continent ID as per client, X coordinate in yards as per client via Astrolabe, Y coordinate in yards as per client via Astrolabe, faction ID (Alliance/Horde) -Compressed data is complicated lzw'ed hideousness. -Version number is probably contained in the |, I'll change that when I need to change meaning. -User is assumed to start facing right, all turns are 90 degrees. - -Allowed values, post-lookup-table listed below, are: - -^ - forward -< - turn left and move forward -> - turn right and move forward -v - turn around and move forward -C - combo indicator, each one indicates that another next UDLR is part of a single move (the toggles are zero-time anyway) -S - swim toggle -X - taxi toggle -M - mount toggle -Y - flying mount toggle -D - dead/ghost toggle - -]] - -local QHCT -local Merger -local LZW -local Bolus - -local cc, cx, cy, cd = nil, nil, nil, nil -local flags = {} - -local nx, ny = nil, nil - -local function round(x) return math.floor(x + 0.5) end -local function dist(x, y) return math.abs(x) + math.abs(y) end -- fuck it, manhattan distance - --- ++ is turning right -local dx = {1, 0, -1, 0} -local dy = {0, 1, 0, -1} - -local function InitWorking() - QHCT.working = {} - QHCT.working.prefix = {} -end - -local function AddDataPrefix(data) - table.insert(QHCT.working.prefix, data) - --QHCT.working.prefix = QHCT.working.prefix .. data -end - -local function AddData(data) - table.insert(QHCT.working, data) - --Merger.Add(QHCT.working, data) -end - -local function FinishData() - return Merger.Finish(QHCT.working) -end - -local function TestDirection(nd, kar) - if nd < 1 then nd = nd + 4 end - if nd > 4 then nd = nd - 4 end - - if dist(cx + dx[nd] - nx , cy + dy[nd] - ny) < dist(cx - nx, cy - ny) then - AddData(kar) - cd = nd - cx = cx + dx[cd] - cy = cy + dy[cd] - return true - else - return false - end -end - -local function CompressAndComplete(ki) - --QuestHelper:TextOut(string.format("%d tokens", #QHCT.compressing[ki].data)) - local tim = GetTime() - local lzwed = LZW.Compress_Dicts(QHCT.compressing[ki].data, "^<>vCSXMYD") - if debug_output then - QuestHelper:TextOut(string.format("%d tokens: compressed to %d in %f", #QHCT.compressing[ki].data, #lzwed, GetTime() - tim)) - end - - if not QHCT.done then QHCT.done = {} end - table.insert(QHCT.done, QHCT.compressing[ki].prefix .. lzwed) - QHCT.compressing[ki] = nil -end - -local function CompressFromKey(ki) - QH_Timeslice_Add(function () CompressAndComplete(ki) end, "lzw") -end - -local function CompileData() - local data = FinishData() - local prefix = QHCT.working.prefix - - InitWorking() - - if #data > 0 then - if not QHCT.compressing then QHCT.compressing = {} end - local ki = GetTime() - while QHCT.compressing[ki] do ki = ki + 1 end -- if this ever triggers, I'm shocked - - QHCT.compressing[ki] = {data = data, prefix = prefix} - - CompressFromKey(ki) - end -end - -local function AppendFlag(flagval, flagid) - flagval = not not flagval - flags[flagid] = not not flags[flagid] - if flagval ~= flags[flagid] then - if debug_output then - --QuestHelper:TextOut(string.format("Status toggle %s", flagid)) - end - flags[flagid] = flagval - AddData(flagid) - end -end - -local function QH_Collect_Traveled_Point(c, x, y, rc, rz) - if not c or not x or not y then return end - - nx, ny = round(x), round(y) - if c ~= cc or dist(nx - cx, ny - cy) > 10 then - if debug_output then - QuestHelper:TextOut(string.format("finishing thanks to differences, %s,%s,%s vs %s,%s,%s (%s)", tostring(cc), tostring(cx), tostring(cy), tostring(c), tostring(nx), tostring(ny), cc and tostring(dist(nx - cx, ny - cy)) or "lol")) - end - CompileData() - - cc, cx, cy, cd = c, nx, ny, 1 - swim, mount, flying, taxi = false, false, false, false - local b = Bolus(c, x, y, rc, rz) - b.faction = QuestHelper:PlayerFaction() - AddDataPrefix(Bolus(c, x, y, rc, rz) .. strchar(tostring(QuestHelper:PlayerFaction()))) -- The playerfaction can be removed, as it's now encoded in the collection shard. Not removing it for compatibility reasons. - end - - AppendFlag(IsMounted(), 'M') - AppendFlag(IsFlying(), 'Y') - AppendFlag(IsSwimming(), 'S') - AppendFlag(UnitOnTaxi("player"), 'X') - AppendFlag(UnitIsDeadOrGhost("player"), 'D') - - for x = 1, dist(nx - cx, ny - cy) - 1 do - AddData('C') - end - - -- first we go forward as much as is reasonable - while TestDirection(cd, '^') do end - - if TestDirection(cd + 1, '>') then -- if we can go right, we do so, then we go forward again - while TestDirection(cd, '^') do end - -- In theory, if the original spot was back-and-to-the-right of us, we could need to go right *again* and then forward *again*. So we do. - if TestDirection(cd + 1, '>') then - while TestDirection(cd, '^') do end - end - elseif TestDirection(cd - 1, '<') then -- the same logic applies for left. - while TestDirection(cd, '^') do end - if TestDirection(cd - 1, '<') then - while TestDirection(cd, '^') do end - end - else - -- And we also test back, just in case. - if TestDirection(cd + 2, 'v') then - while TestDirection(cd, '^') do end - end - end - - QuestHelper: Assert(cx == nx and cy == ny) - -- Done! -end - -local GetRawLocation - -local function OnUpdate() - QH_Collect_Traveled_Point(GetRawLocation()) -end - -function QH_Collect_Traveled_Init(QHCData, API) --- We're actually just going to disable this for now. ---[[ - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) -- I need to get rid of this stupid space hack someday - - LZW = API.Utility_LZW - QuestHelper: Assert(LZW) - - Bolus = API.Callback_LocationBolus - QuestHelper: Assert(Bolus) - - if not QHCData.traveled then QHCData.traveled = {} end - QHCT = QHCData.traveled - - if not QHCT.working then InitWorking() end - - if QHCT.compressing then for k, v in pairs(QHCT.compressing) do - CompressFromKey(k) - end end - - GetRawLocation = API.Callback_RawLocation - API.Registrar_OnUpdateHook(OnUpdate)]] -end - ---[[ -function hackeryflush() - CompileData() - cc = nil -end -]] diff --git a/QHCollector/collect_upgrade.lua b/QHCollector/collect_upgrade.lua deleted file mode 100644 index 6e38bdf..0000000 --- a/QHCollector/collect_upgrade.lua +++ /dev/null @@ -1,103 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_upgrade.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_upgrade.lua"] = GetTime() - -function QH_Collector_Upgrade(chunk) - QuestHelper: Assert(not chunk.compressed) - - if chunk.version == 1 then - -- We basically just want to clobber all our old route data, it's not worth storing - it's all good data, it's just that we don't want to preserve relics of the old location system. - chunk.traveled = nil - - chunk.version = 2 - end - - if chunk.version == 2 then - -- Originally I split the zones based on locale. Later I just split everything based on locale. Discarding old data rather than doing the gymnastics needed to preserve it. - -- This is turning into a routine. :D - chunk.zone = nil - - chunk.version = 3 - end - - if chunk.version == 3 then - -- Screwed up the item collection code in instances. Obliterate old data, try again. - if chunk.item then - for id, dat in pairs(chunk.item) do - dat.equip_no = nil - dat.equip_yes = nil - end - end - - chunk.version = 4 - end - - if chunk.version == 4 then - -- Munged the shops rather badly. Whoopsydaisy. - if chunk.monster then - local nv = {} - for id, dat in pairs(chunk.monster) do - if type(dat) == "table" then - nv[id] = dat - end - end - chunk.monster = nv - end - - chunk.version = 5 - end - - if chunk.version == 5 then - -- Horrible things involving objects. Let's preserve what we can. - if chunk.object then - local new_obj = {} - for k, v in pairs(chunk.object) do - local keep = false - for tk, _ in pairs(v) do - if type(tk) == "string" and tk:match("[a-z]+_loot") then - keep = true - break - end - end - - if keep then new_obj[k] = v end - end - - chunk.object = new_obj - end - - chunk.version = 6 - end - - if chunk.version == 6 then - -- I just screwed this up really - -- Note that a few versions back (I'll have to check which) the standard bolus format changed. Since I can't actually *fix* it, I'm just ignoring it, but there's an implicit format change in there. I'll catch it and deal with it in the processing system. - chunk.warp = nil - chunk.routing_dump = nil -- and this shouldn't have been getting dumped anyway - - chunk.version = 7 - end - - if chunk.version == 7 then - -- botched the achievement code, fixed the achievement code (maybe?) - chunk.achievement = nil - - chunk.version = 8 - end -end - -function QH_Collector_UpgradeAll(Collector) --- So, I screwed up the compression code, and there's no way to know what version was compressed . . . except that we thankfully didn't change the version number on that change. Any untagged compression will therefore be the version number that this was loaded with. - for _, v in pairs(Collector) do - --[[ QuestHelper:Assert(type(v) == "table") ]] - if not v.version then - QuestHelper: Assert(QuestHelper_Collector_Version) -- This is going to fail somehow. I just know it. Seriously, this right here will be proof that, today, the gods hate me. - v.version = QuestHelper_Collector_Version - end - - if not v.compressed then - QH_Collector_Upgrade(v) - end - end -end diff --git a/QHCollector/collect_util.lua b/QHCollector/collect_util.lua deleted file mode 100644 index 459adb2..0000000 --- a/QHCollector/collect_util.lua +++ /dev/null @@ -1,53 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_util.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_util.lua"] = GetTime() - -local function IsMonsterGUID(guid) - QuestHelper: Assert(strlen(guid) == 18, "guid len " .. guid) -- 64 bits, plus the 0x prefix - QuestHelper: Assert(guid:sub(1, 2) == "0x", "guid 0x-prefix " .. guid) - return guid:sub(5, 5) == "3" or guid:sub(5, 5) == "5" -end - -local function GetMonsterUID(guid) - QuestHelper: Assert(strlen(guid) == 18, "guid len " .. guid) -- 64 bits, plus the 0x prefix - QuestHelper: Assert(guid:sub(1, 2) == "0x", "guid 0x-prefix " .. guid) - QuestHelper: Assert(guid:sub(5, 5) == "3" or guid:sub(5, 5) == "5", "guid 3-prefix " .. guid) -- It *shouldn't* be a player or a pet by the time we've gotten here. If so, something's gone wrong. - return guid:sub(9, 18) -- here's our actual identifier -end - -local function GetMonsterType(guid) - QuestHelper: Assert(strlen(guid) == 18, "guid len " .. guid) -- 64 bits, plus the 0x prefix - QuestHelper: Assert(guid:sub(1, 2) == "0x", "guid 0x-prefix " .. guid) - QuestHelper: Assert(guid:sub(5, 5) == "3" or guid:sub(5, 5) == "5", "guid 3-prefix " .. guid) -- It *shouldn't* be a player or a pet by the time we've gotten here. If so, something's gone wrong. - if GetBuildInfo():sub(1, 3) == "3.2" then - return tonumber(guid:sub(9, 12), 16) -- here's our actual identifier - else - return tonumber(guid:sub(7, 10), 16) -- 3.3 and in the future, including 0.3.0 - end -end - -local function GetItemType(link, vague) - QuestHelper:Assert(link, "Item did not have a link! Say WHAT?") - local result = tonumber(string.match(link, - (vague and "" or "^") .. "|cff%x%x%x%x%x%x|Hitem:(%d+):[%d:-]+|h%[[^%]]*%]|h|r".. (vague and "" or "$") - )) - QuestHelper:Assert(result, "Item does not have a type ('" .. link .. "')") - return result -end - -local function GetQuestType(link) - return tonumber(string.match(link, - "^|cff%x%x%x%x%x%x|Hquest:(%d+):[%d-]+|h%[[^%]]*%]|h|r$" - )), tonumber(string.match(link, - "^|cff%x%x%x%x%x%x|Hquest:%d+:([%d-]+)|h%[[^%]]*%]|h|r$" - )) -end - -function QH_Collect_Util_Init(_, API) - API.Utility_IsMonsterGUID = IsMonsterGUID - API.Utility_GetMonsterUID = GetMonsterUID - API.Utility_GetMonsterType = GetMonsterType - API.Utility_GetItemType = GetItemType - API.Utility_GetQuestType = GetQuestType -end diff --git a/QHCollector/collect_warp.lua b/QHCollector/collect_warp.lua deleted file mode 100644 index 2d8f902..0000000 --- a/QHCollector/collect_warp.lua +++ /dev/null @@ -1,74 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_warp.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_warp.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_warp.lua"] == "Development Version" then debug_output = true end - -local QHCW - -local GetLoc -local Merger -local RawLocation - -local lastloc_bolus -local last_delayed, last_rc, last_rz, last_rx, last_ry -local last_valid - -local last_warp = 0 - -local function valid(d, rc, rz, rx, ry) - return not d and rc and rz and rx and ry -end - -local function OnUpdate() - local bolus = GetLoc() - local now_delayed, now_rc, now_rz, now_rx, now_ry = RawLocation() - local now_valid = valid(RawLocation()) - - if last_valid and now_valid then - local leapy = false - if last_rc ~= now_rc or last_rz ~= now_rz then - leapy = true - else - local dx, dy = last_rx - now_rx, last_ry - now_ry - dx, dy = dx * dx, dy * dy - if dx + dy > 0.01 * 0.01 then - leapy = true - end - end - - if leapy then - if debug_output then QuestHelper:TextOut("Warpy!") end - end - - if last_warp + 10 < GetTime() and leapy then - if debug_output then QuestHelper:TextOut("REAL Warpy!") end - local warpy = { last = lastloc_bolus, current = bolus } - table.insert(QHCW, warpy) - --Merger.Add(QHCW, "(" .. lastloc_bolus .. ")(" .. bolus .. ")") - last_warp = GetTime() - end - end - - lastloc_bolus = bolus - - last_delayed, last_rc, last_rz, last_rx, last_ry, last_valid = now_delayed, now_rc, now_rz, now_rx, now_ry, now_valid -end - -function QH_Collect_Warp_Init(QHCData, API) - if not QHCData.warp then QHCData.warp = {} end - QHCW = QHCData.warp - - API.Registrar_OnUpdateHook(OnUpdate) - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - RawLocation = API.Callback_Location_Raw - QuestHelper: Assert(RawLocation) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) -end diff --git a/QHCollector/collect_zone.lua b/QHCollector/collect_zone.lua deleted file mode 100644 index 34728ba..0000000 --- a/QHCollector/collect_zone.lua +++ /dev/null @@ -1,65 +0,0 @@ -local GetTime = QuestHelperCollector_GetTime - -QuestHelper_File["collect_zone.lua"] = "4.0.1.$svnversion$" -QuestHelper_Loadtime["collect_zone.lua"] = GetTime() - -local debug_output = false -if QuestHelper_File["collect_zone.lua"] == "Development Version" then debug_output = true end - -local QHCZ - -local GetLoc -local Merger - -local function DoZoneUpdate(label, debugverbose) - local zname = string.format("%s@@%s@@%s", GetZoneText(), GetRealZoneText(), GetSubZoneText()) -- I don't *think* any zones will have a @@ in them :D - if zname == "@@@@" then return end -- denied - if not QHCZ[zname] then QHCZ[zname] = {} end - if not QHCZ[zname][label] then QHCZ[zname][label] = {} end - local znl = QHCZ[zname][label] - - if debugverbose and debug_output then - --QuestHelper:TextOut("zoneupdate " .. zname .. " type " .. label) - end - - QHCZ[zname].mapname = GetMapInfo() - - local loc = GetLoc() - if loc.delayed == 128 and loc.c == 0 and loc.z == 0 and loc.x == -128 and loc.y == -128 then return end - --if loc == "€\000\000\000€\000\000\000€€€" then return end -- this is kind of the "null value" - local found = false - - -- Commented out, 'cause this module isn't really loaded anymore. I'll remove it after the next commit. - --Merger.Add(znl, loc, true) -end - -local function OnEvent() - DoZoneUpdate("border", true) -end - -local lastupdate = 0 -local function OnUpdate() - if lastupdate + 15 <= GetTime() then - DoZoneUpdate("update") - lastupdate = GetTime() - end -end - -function QH_Collect_Zone_Init(QHCData, API) - do return end -- we really don't need this anymore - - if not QHCData.zone then QHCData.zone = {} end - QHCZ = QHCData.zone - - QH_Event("ZONE_CHANGED", OnEvent) - QH_Event("ZONE_CHANGED_INDOORS", OnEvent) - QH_Event("ZONE_CHANGED_NEW_AREA", OnEvent) - - --API.Registrar_OnUpdateHook(OnUpdate) - - GetLoc = API.Callback_LocationBolusCurrent - QuestHelper: Assert(GetLoc) - - Merger = API.Utility_Merger - QuestHelper: Assert(Merger) -end diff --git a/QHCollector/utility.lua b/QHCollector/utility.lua deleted file mode 100644 index 4ee3316..0000000 --- a/QHCollector/utility.lua +++ /dev/null @@ -1,454 +0,0 @@ -function QuestHelperCollector_GetTime() - return debugprofilestop() / 1000 -end - -local GetTime = QuestHelperCollector_GetTime - -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(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, 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 diff --git a/QuestHelper/QuestHelper.toc b/QuestHelper/QuestHelper.toc index 41e1f58..69b82cd 100644 --- a/QuestHelper/QuestHelper.toc +++ b/QuestHelper/QuestHelper.toc @@ -8,9 +8,9 @@ ## Notes-esMX: Calcula la mejor ruta a seguir para usted. ## Notes-koKR: 노선에 λŒ€ν•œ 계산을 μˆ˜ν–‰ν•©λ‹ˆλ‹€. ## Version: 4.0.1.$svnversion$ -## Dependencies: QHData-base, QHCollector +## Dependencies: QHData-base ## OptionalDeps: Cartographer_Waypoints, TomTom, Cartographer_InstanceMaps, !Swatter, tekticles, UnicodeFont, ClearFont2 -## SavedVariables: QuestHelper_Pref QuestHelper_UID QuestHelper_SaveDate QuestHelper_Errors QuestHelper_Collector_Version QHDB_Export +## SavedVariables: QuestHelper_Pref QuestHelper_UID QuestHelper_SaveDate QuestHelper_Errors QuestHelper_Collector QuestHelper_Collector_Version QHDB_Export ## SavedVariablesPerCharacter: QuestHelper_KnownFlightRoutes QuestHelper_Home QuestHelper_CharVersion QuestHelper_Flight_Updates ## X-Website: http://www.quest-helper.com/ ## X-Embeds: AstrolabeQH, ChatThrottleLib @@ -98,7 +98,7 @@ lang\zhcn.lua lang\zhtw.lua # oh shut up -#collect_notifier.lua +collect_notifier.lua # Memory management, depends on nothing, calls nothing. I don't mention when things depend on this - it's not as extensively used as it used to be, but it's still under basic-utilities. recycle.lua @@ -179,28 +179,28 @@ objtips.lua textviewer.lua help.lua -#collect_achievement.lua -#collect_lzw.lua -#collect_traveled.lua -#collect_location.lua -#collect_zone.lua -#collect_hearth.lua -#collect_merger.lua -#collect_monster.lua -#collect_item.lua -#collect_object.lua -#collect_loot.lua -#collect_patterns.lua -#collect_flight.lua -#collect_util.lua -#collect_quest.lua -#collect_equip.lua -#collect_spec.lua -#collect_bitstream.lua -#collect_upgrade.lua -#collect_merchant.lua -#collect_warp.lua -#collect.lua +collect_achievement.lua +collect_lzw.lua +collect_traveled.lua +collect_location.lua +collect_zone.lua +collect_hearth.lua +collect_merger.lua +collect_monster.lua +collect_item.lua +collect_object.lua +collect_loot.lua +collect_patterns.lua +collect_flight.lua +collect_util.lua +collect_quest.lua +collect_equip.lua +collect_spec.lua +collect_bitstream.lua +collect_upgrade.lua +collect_merchant.lua +collect_warp.lua +collect.lua cartographer.lua tomtom.lua