Automated update from: http://smariot.hopto.org/translate
[QuestHelper.git] / questlog.lua
blobb99b3b474f4c1f7f27f3e57b3d6b9afd618a47b8
1 QuestHelper_File["questlog.lua"] = "Development Version"
2 QuestHelper_Loadtime["questlog.lua"] = GetTime()
4 --[[QuestHelper.debug_objectives =
6 ["Harbinger of Doom"] =
8 cat="quest", what="Harbinger of Doom", sub=
10 ["Slay Harbinger Skyriss"] =
12 cat="monster", what="Harbinger Skyriss"
16 }]]
18 function QuestHelper:LoadDebugObjective(name, data)
19 local obj = self:GetObjective(data.cat, data.what)
21 self:SetObjectivePriority(obj, 3)
22 self:AddObjectiveWatch(obj, name)
24 if data.sub then
25 for name, sdata in pairs(data.sub) do
26 self:ObjectiveObjectDependsOn(obj, QuestHelper:LoadDebugObjective(name, sdata))
27 end
28 end
30 return obj
31 end
33 local ITEM_PATTERN, REPUTATION_PATTERN, MONSTER_PATTERN, OBJECT_PATTERN = false, false, false, false
35 local function buildPatterns()
36 if not ITEM_PATTERN then
37 ITEM_PATTERN = QuestHelper:convertPattern(QUEST_OBJECTS_FOUND)
38 REPUTATION_PATTERN = QuestHelper:convertPattern(QUEST_FACTION_NEEDED)
39 MONSTER_PATTERN = QuestHelper:convertPattern(QUEST_MONSTERS_KILLED)
40 OBJECT_PATTERN = QuestHelper:convertPattern(QUEST_OBJECTS_FOUND)
41 PLAYER_PATTERN = QuestHelper:convertPattern(QUEST_PLAYERS_KILLED)
42 replacePattern = nil
43 end
44 end
46 function QuestHelper:GetQuestLogObjective(quest_index, objective_index)
47 local text, category, done = GetQuestLogLeaderBoard(objective_index, quest_index)
49 buildPatterns()
51 local wanted, verb, have, need
53 if category == "monster" then
54 wanted, have, need = MONSTER_PATTERN(text)
55 verb = QHText("SLAY_VERB")
56 elseif category == "item" then
57 wanted, have, need = ITEM_PATTERN(text)
58 verb = QHText("ACQUIRE_VERB")
59 elseif category == "reputation" then
60 wanted, have, need = REPUTATION_PATTERN(text)
61 elseif category == "object" then
62 wanted, have, need = OBJECT_PATTERN(text)
63 elseif category == "event" then
64 wanted, have, need = text, 0, 1
65 elseif category == "player" then
66 wanted, have, need = PLAYER_PATTERN(text)
67 else
68 QuestHelper:TextOut("Unhandled event type: "..category)
69 end
71 if not wanted then
72 verb = nil
74 _, _, wanted, have, need = string.find(text, "^%s*(.-)%s*:%s*(.-)%s*/%s*(.-)%s*$")
75 if not wanted then
76 _, _, wanted = string.find(text, "^%s*(.-)%s*$")
77 have, need = 0, 1
78 end
79 end
81 if not need then need = 1 end
82 if done then have = need end
84 return category, verb, wanted or text, tonumber(have) or have, tonumber(need) or need
85 end
87 function QuestHelper:FixedGetQuestLogTitle(index)
88 local title, level, qtype, players, header, collapsed, status, daily = GetQuestLogTitle(index)
90 if title and level then
91 local _, _, real_title = string.find(title, "^%["..level.."[^%s]-%]%s?(.+)$")
92 title = real_title or title
93 end
95 return title, level, qtype, players, header, collapsed, status, daily
96 end
98 function QuestHelper:GetQuestLevel(quest_name)
99 local index = 1
100 while true do
101 local title, level, _, _, header = self:FixedGetQuestLogTitle(index)
102 if not title then return 0 end
103 if not header and title == quest_name then
104 local original_entry = GetQuestLogSelection()
105 SelectQuestLogEntry(index)
106 local hash = self:HashString(select(2, GetQuestLogQuestText()))
107 SelectQuestLogEntry(original_entry)
108 return level, hash
110 index = index + 1
114 function QuestHelper:ItemIsForQuest(item_object, item_name)
115 if not item_object.o.quest then
116 return nil
117 else
118 for quest, lq in pairs(self.quest_log) do
119 if lq.goal then
120 for i, lo in ipairs(lq.goal) do
121 if lo.category == "item" and lo.wanted == item_name then
122 return quest
128 return nil
131 local first_time = true
133 function QuestHelper:ScanQuestLog()
134 local original_entry = GetQuestLogSelection()
135 local quests = self.quest_log
137 local party_levels = self.party_levels
138 if not party_levels then
139 party_levels = {}
140 self.party_levels = party_levels
143 local level_average = UnitLevel("player")
144 local users = 1
146 if not QuestHelper_Pref.solo then
147 for n=1,4 do
148 local level = UnitLevel("party"..n)
150 if level and level > 0 then
151 level_average = level_average + level
152 users = users + 1
157 level_average = level_average / users
159 for n = 1,5 do
160 party_levels[n] = level_average+15-15*math.pow(n/users, 0.4)
163 for i, quest in pairs(quests) do
164 -- Will set this to false if the player still has it.
165 quest.removed = true
168 local index = 1
169 while true do
170 local title, level, qtype, players, header, collapsed, status, daily = self:FixedGetQuestLogTitle(index)
171 --QuestHelper:TextOut(string.format("Gathering quests - %s %s", tostring(title), tostring(level)))
173 if not title then break end
175 if players and players <= 0 then
176 players = nil
179 if not players then
180 players = qtype == nil and 1 or 5
181 else
182 players = math.min(5, math.max(1, players))
185 -- Quest was failed if status is -1.
186 if not header and status ~= -1 then
187 SelectQuestLogEntry(index)
188 local hash = self:HashString(select(2, GetQuestLogQuestText()))
189 local quest = self:GetQuest(title, level, hash)
190 local lq = quests[quest]
191 local is_new = false
193 local ignored = party_levels[players]+QuestHelper_Pref.level < level
195 if self.quest_giver and self.quest_giver[title] then
196 quest.o.start = self.quest_giver[title]
197 self.quest_giver[title] = nil
200 if not lq then
201 lq = {}
203 quests[quest] = lq
205 if GetQuestLogTimeLeft() then
206 -- Quest has a timer, so give it a higher than normal priority.
207 self:SetObjectivePriority(quest, 2)
208 else
209 -- Use a normal priority.
210 self:SetObjectivePriority(quest, 3)
214 quest.o.id = self:GetQuestID(index)
216 -- Can't add the objective here, if we don't have it depend on the objectives
217 -- first it'll get added and possibly not be doable.
218 -- We'll add it after the objectives are determined.
219 is_new = true
222 lq.index = index
223 quest.index = index -- guhhh
224 lq.removed = false
226 if GetNumQuestLeaderBoards(index) > 0 then
227 if not lq.goal then lq.goal = {} end
228 for objective = 1, GetNumQuestLeaderBoards(index) do
229 local lo = lq.goal[objective]
230 if not lo then lo = {} lq.goal[objective] = lo end
232 local category, verb, wanted, have, need = self:GetQuestLogObjective(index, objective)
234 if not wanted or not string.find(wanted, "[^%s]") then
235 self.defered_quest_scan = true
236 elseif not lo.objective then
237 -- objective is new.
238 lo.objective = self:GetObjective(category, wanted)
239 lo.objective.o.quest = true -- If I ever decide to prune the DB, I'll have the stuff actually used in quests marked.
240 self:ObjectiveObjectDependsOn(quest, lo.objective)
242 lo.objective.quest = quest
244 if verb then
245 lo.reason = QHFormat("OBJECTIVE_REASON", verb, wanted, title)
246 else
247 lo.reason = QHFormat("OBJECTIVE_REASON_FALLBACK", wanted, title)
250 lo.category = category
251 lo.wanted = wanted
252 lo.have = have
253 lo.need = need
255 if have ~= need then -- If the objective isn't complete, watch it.
256 lo.objective:Share()
257 self:AddObjectiveWatch(lo.objective, lo.reason)
259 elseif lo.have ~= have then
260 if lo.objective.peer then
261 for u, l in pairs(lo.objective.peer) do
262 -- Peers don't know about our progress.
263 lo.objective.peer[u] = math.min(l, 2)
267 if have == need or (type(have) == "number" and have > lo.have) then
268 if category == "item" then
269 self:AppendItemObjectivePosition(lo.objective, wanted, self:PlayerPosition())
270 else
271 self:AppendObjectivePosition(lo.objective, self:PlayerPosition())
275 if lo.have == need then -- The objective was done, but now its not.
276 lo.objective:Share()
277 self:AddObjectiveWatch(lo.objective, lo.reason)
278 elseif have == need then -- The objective is now finished.
279 lo.objective:Unshare()
280 self:RemoveObjectiveWatch(lo.objective, lo.reason)
283 lo.have = have
286 if lo.objective then -- Might not have loaded the objective yet, if it wasn't in the local cache and we defered loading it.
287 lo.objective.filter_level = ignored
288 lo.objective.filter_done = true
289 self:SetObjectiveProgress(lo.objective, UnitName("player"), have, need)
292 else
293 quest.goal = nil
296 if is_new then
297 lq.reason = QHFormat("OBJECTIVE_REASON_TURNIN", title)
298 quest:Share()
299 self:AddObjectiveWatch(quest, lq.reason)
302 index = index + 1
305 for quest, lq in pairs(quests) do
306 if lq.removed then
307 if lq.goal then
308 for i, lo in ipairs(lq.goal) do
309 if lo.objective and lo.have ~= lo.need then
310 lo.objective:Unshare()
311 self:RemoveObjectiveWatch(lo.objective, lo.reason)
314 self:SetObjectiveProgress(lo.objective, UnitName("player"), nil, nil)
318 quest:Unshare()
319 self:RemoveObjectiveWatch(quest, lq.reason)
320 quests[quest] = nil
324 if first_time then
325 first_time = false
326 QH_Timeslice_Bonus(15)
329 SelectQuestLogEntry(original_entry)
331 if QuestHelper_Pref.track then
332 self.tracker:update()