From 0e458d6b47f79cb8a94d9f0cf4da43b7f8288ac3 Mon Sep 17 00:00:00 2001 From: Tekkub Stoutwrithe Date: Tue, 16 Oct 2007 09:20:43 +0000 Subject: [PATCH] TourGuide - Moved guide and tag parser to own file, totally rewrote tag parsing ***UNTESTED*** git-svn-id: https://tekkub-wow.googlecode.com/svn/trunk/TourGuide@644 86fe6d9a-1522-0410-a387-bf9db416f0a0 --- Parser.lua | 117 ++++++++++++++++++++++++++++++++++++++++++++++ QuestTracking.lua | 2 +- StatusFrame.lua | 7 ++- TourGuide.lua | 137 ------------------------------------------------------ TourGuide.toc | 1 + 5 files changed, 124 insertions(+), 140 deletions(-) create mode 100644 Parser.lua diff --git a/Parser.lua b/Parser.lua new file mode 100644 index 0000000..a407049 --- /dev/null +++ b/Parser.lua @@ -0,0 +1,117 @@ + + +local actiontypes = { + A = "ACCEPT", + C = "COMPLETE", + T = "TURNIN", + K = "KILL", + R = "RUN", + t = "TRAIN", + H = "HEARTH", + h = "SETHEARTH", + G = "GRIND", + F = "FLY", + f = "GETFLIGHTPOINT", + N = "NOTE", + B = "BUY", + b = "BOAT", + U = "USE", +} + + +function TourGuide:GetObjectiveTag(tag, i) + self:Debug(11, "GetObjectiveTag", tag, i) + i = i or self.current + + if tag == "O" then return tags:find("|O|") + elseif tag == "L" then + local _, _, lootitem, lootqty = tags:find("|L|(%d+)%s?(%d*)|") + lootqty = tonumber(lootqty) or 1 + + return lootitem, lootqty + end + + local tags = self.tags[i] + if tags then return select(3, tags:find("|"..tag.."|([^|]*)|?")) end +end + + +local myclass = UnitClass("player") +local titlematches = {"For", "A", "The", "Or", "In", "Then", "From", "To"} +local function ParseQuests(...) + local accepts, turnins, completes = {}, {}, {} + local uniqueid = 1 + local actions, quests, tags = {}, {}, {} + local i, haserrors = 1, false + + for j=1,select("#", ...) do + local text = select(j, ...) + local _, _, class = text:find("|C|([^|]+)|") + + if text ~= "" and (not class or class == myclass) then + local _, _, action, quest, tag = text:find("^(%a) ([^|]*)(.*)") + assert(actiontypes[action], "Unknown action: "..text) + quest = quest:trim() + if not (action == "A" or action =="C" or action =="T") then + quest = quest.."@"..uniqueid.."@" + uniqueid = uniqueid + 1 + end + + actions[i], quests[i], tags[i] = actiontypes[action], quest, tag + + i = i + 1 + + -- Debuggery + if not string.find(text, "|NODEBUG|") then + if action == "A" then accepts[quest] = true + elseif action == "T" then turnins[quest] = true + elseif action == "C" then completes[quest] = true end + + if action == "A" or action == "C" or action == "T" then + -- Catch bad Title Case + for _,word in pairs(titlematches) do + if quest:find("[^:]%s"..word.."%s") or quest:find("[^:]%s"..word.."$") or quest:find("[^:]%s"..word.."@") then + TourGuide:DebugF(1, "%s %s -- Contains bad title case", action, quest) + haserrors = true + end + end + + if quest:find("[“”’]") then + TourGuide:DebugF(1, "%s %s -- Contains bad char", action, quest) + haserrors = true + end + end + + local _, _, comment = string.find(text, "(|[NLUC]V?|[^|]+)$") or string.find(text, "(|[NLUC]V?|[^|]+) |[NLUC]V?|") + if comment then + TourGuide:Debug(1, "Unclosed comment: ".. comment) + haserrors = true + end + end + end + end + + -- More debug + for quest in pairs(accepts) do if not turnins[quest] then TourGuide:DebugF(1, "Quest has no 'turnin' objective: %s", quest) end end + for quest in pairs(turnins) do if not accepts[quest] then TourGuide:DebugF(1, "Quest has no 'accept' objective: %s", quest) end end + for quest in pairs(completes) do if not accepts[quest] and not turnins[quest] then TourGuide:DebugF(1, "Quest has no 'accept' and 'turnin' objectives: %s", quest) end end + + if haserrors and TourGuide:IsDebugEnabled() then TourGuide:Print("This guide contains errors") end + + return actions, quests, tags +end + + +function TourGuide:LoadGuide(name) + if not name then return end + + self.db.char.currentguide = name + if not self.guides[name] then self.db.char.currentguide = self.guidelist[1] end + self:DebugF(1, "Loading guide: %s", name) + self.guidechanged = true + local _, _, zonename = name:find("^(.*) %(.*%)$") + self.zonename = zonename + self.actions, self.quests, self.tags = ParseQuests(string.split("\n", self.guides[self.db.char.currentguide]())) +end + + diff --git a/QuestTracking.lua b/QuestTracking.lua index 71d1707..89a1bfd 100644 --- a/QuestTracking.lua +++ b/QuestTracking.lua @@ -19,7 +19,7 @@ end function TourGuide:PLAYER_LEVEL_UP(event, newlevel) - local level = self:GetObjectiveTag("LV") + local level = tonumber((self:GetObjectiveTag("LV"))) self:Debug(1, "PLAYER_LEVEL_UP", newlevel, level) if level and newlevel >= level then self:SetTurnedIn() end end diff --git a/StatusFrame.lua b/StatusFrame.lua index 2d279b5..59afc62 100644 --- a/StatusFrame.lua +++ b/StatusFrame.lua @@ -133,11 +133,14 @@ function TourGuide:UpdateStatusFrame() local action, name, quest = self:GetObjectiveInfo(i) local turnedin, logi, complete = self:GetObjectiveStatus(i) local note, useitem, optional, lootitem, lootqty = self:GetObjectiveTag("N", i), self:GetObjectiveTag("U", i), self:GetObjectiveTag("O", i), self:GetObjectiveTag("L", i) - local level = self:GetObjectiveTag("LV", i) + local level = tonumber((self:GetObjectiveTag("LV", i))) local needlevel = level and level > UnitLevel("player") self:Debug(11, "UpdateStatusFrame", i, action, name, note, logi, complete, turnedin, quest, useitem, optional, lootitem, lootqty, lootitem and GetItemCount(lootitem) or 0, level, needlevel) local hasuseitem = useitem and self:FindBagSlot(useitem) + -- Test for completed objectives and mark them done + if (action == "RUN" or action == "FLY" or action == "HEARTH" or action == "BOAT") and (GetSubZoneText() == name or GetZoneText() == name) then return self:SetTurnedIn(i, true) end + if action == "KILL" or action == "NOTE" then if not optional and lootitem and GetItemCount(lootitem) >= lootqty then return self:SetTurnedIn(i, true) end @@ -249,7 +252,7 @@ end) local function ShowTooltip(self) - local tip = TourGuide.notes[TourGuide.current] + local tip = TourGuide:GetObjectiveTag("N") if not tip then return end GameTooltip:SetOwner(self, "ANCHOR_NONE") diff --git a/TourGuide.lua b/TourGuide.lua index 8fe817d..97ccfee 100644 --- a/TourGuide.lua +++ b/TourGuide.lua @@ -31,25 +31,6 @@ TourGuide.icons = setmetatable({ }, {__index = function() return "Interface\\Icons\\INV_Misc_QuestionMark" end}) -local actiontypes = { - A = "ACCEPT", - C = "COMPLETE", - T = "TURNIN", - K = "KILL", - R = "RUN", - t = "TRAIN", - H = "HEARTH", - h = "SETHEARTH", - G = "GRIND", - F = "FLY", - f = "GETFLIGHTPOINT", - N = "NOTE", - B = "BUY", - b = "BOAT", - U = "USE", -} - - function TourGuide:Initialize() self.db = self:InitializeDB("TourGuideAlphaDB", { char = { @@ -144,124 +125,6 @@ function TourGuide:GetObjectiveStatus(i) end -function TourGuide:GetObjectiveTag(tag, i) - self:Debug(11, "GetObjectiveTag", tag, i) - i = i or self.current - if tag == "LV" then return self.levels[i] - elseif tag == "N" then return self.notes[i] - elseif tag == "U" then return self.useitems[i] - elseif tag == "O" then return self.optional[i] - elseif tag == "Z" then return self.zones[i] - elseif tag == "L" then - local _, _, lootitem, lootqty = string.find(self.lootitems[i] or "", "(%d+)%s?(%d*)") - lootqty = tonumber(lootqty) or 1 - - return lootitem, lootqty - end - - local tags = self.tags[i] - if not tags then return end - local found, _, value = tags:find("|"..tag.."|([^|]*)|?") - if found then return value or true end -end - - -local myclass = UnitClass("player") -local titlematches = {"For", "A", "The", "Or", "In", "Then", "From", "To"} -local function ParseQuests(...) - local accepts, turnins, completes = {}, {}, {} - local uniqueid = 1 - local actions, notes, quests, useitems, optionals, lootitems, levels, zones, tags = {}, {}, {}, {}, {}, {}, {}, {}, {} - local i, haserrors = 1, false - - for j=1,select("#", ...) do - local text = select(j, ...) - local _, _, class = text:find("|C|([^|]+)|") - - if text ~= "" and (not class or class == myclass) then - local _, _, action, quest, tag = text:find("^(%a) ([^|]*)(.*)") - assert(actiontypes[action], "Unknown action: "..text) - quest = quest:trim() - if not (action == "A" or action =="C" or action =="T") then - quest = quest.."@"..uniqueid.."@" - uniqueid = uniqueid + 1 - end - - actions[i], quests[i], tags[i] = actiontypes[action], quest, tag - - local _, _, note = string.find(text, "|N|([^|]+)|") - if note then notes[i] = note end - - local _, _, level = string.find(text, "|LV|(%d+)|") - if level then levels[i] = tonumber(level) end - - local _, _, useitem = string.find(text, "|U|(%d+)|") - if useitem then useitems[i] = useitem end - - local _, _, zone = string.find(text, "|Z|([^|]+)|") - if zone then zones[i] = zone end - - local _, _, lootitem = string.find(text, "|L|(%d+%s?%d*)|") - if lootitem then lootitems[i] = lootitem end - - if string.find(text, "|O|") then optionals[i] = true end - - i = i + 1 - - -- Debuggery - if not string.find(text, "|NODEBUG|") then - if action == "A" then accepts[quest] = true - elseif action == "T" then turnins[quest] = true - elseif action == "C" then completes[quest] = true end - - if action == "A" or action == "C" or action == "T" then - -- Catch bad Title Case - for _,word in pairs(titlematches) do - if quest:find("[^:]%s"..word.."%s") or quest:find("[^:]%s"..word.."$") or quest:find("[^:]%s"..word.."@") then - TourGuide:DebugF(1, "%s %s -- Contains bad title case", action, quest) - haserrors = true - end - end - - if quest:find("[“”’]") then - TourGuide:DebugF(1, "%s %s -- Contains bad char", action, quest) - haserrors = true - end - end - - local _, _, comment = string.find(text, "(|[NLUC]V?|[^|]+)$") or string.find(text, "(|[NLUC]V?|[^|]+) |[NLUC]V?|") - if comment then - TourGuide:Debug(1, "Unclosed comment: ".. comment) - haserrors = true - end - end - end - end - - -- More debug - for quest in pairs(accepts) do if not turnins[quest] then TourGuide:DebugF(1, "Quest has no 'turnin' objective: %s", quest) end end - for quest in pairs(turnins) do if not accepts[quest] then TourGuide:DebugF(1, "Quest has no 'accept' objective: %s", quest) end end - for quest in pairs(completes) do if not accepts[quest] and not turnins[quest] then TourGuide:DebugF(1, "Quest has no 'accept' and 'turnin' objectives: %s", quest) end end - - if haserrors and TourGuide:IsDebugEnabled() then TourGuide:Print("This guide contains errors") end - - return actions, notes, quests, useitems, optionals, lootitems, levels, zones, tags -end - - -function TourGuide:LoadGuide(name) - if not name then return end - - self.db.char.currentguide = name - if not self.guides[name] then self.db.char.currentguide = self.guidelist[1] end - self:DebugF(1, "Loading guide: %s", name) - self.guidechanged = true - local _, _, zonename = name:find("^(.*) %(.*%)$") - self.zonename = zonename - self.actions, self.notes, self.quests, self.useitems, self.optional, self.lootitems, self.levels, self.zones, self.tags = ParseQuests(string.split("\n", self.guides[self.db.char.currentguide]())) -end - - function TourGuide:SetTurnedIn(i, value, noupdate) if not i then i = self.current diff --git a/TourGuide.toc b/TourGuide.toc index e49e51d..04e3f5f 100644 --- a/TourGuide.toc +++ b/TourGuide.toc @@ -20,6 +20,7 @@ OptionHouse.lua WidgetWarlock.lua TourGuide.lua +Parser.lua Mapping.lua StatusFrame.lua OHFrame.lua -- 2.11.4.GIT