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"
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
)
25 for name
, sdata
in pairs(data
.sub
) do
26 self
:ObjectiveObjectDependsOn(obj
, QuestHelper
:LoadDebugObjective(name
, sdata
))
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
)
46 function QuestHelper
:GetQuestLogObjective(quest_index
, objective_index
)
47 local text
, category
, done
= GetQuestLogLeaderBoard(objective_index
, quest_index
)
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
)
68 QuestHelper
:TextOut("Unhandled event type: "..category
)
74 _
, _
, wanted
, have
, need
= string.find(text
, "^%s*(.-)%s*:%s*(.-)%s*/%s*(.-)%s*$")
76 _
, _
, wanted
= string.find(text
, "^%s*(.-)%s*$")
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
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
95 return title
, level
, qtype
, players
, header
, collapsed
, status
, daily
98 function QuestHelper
:GetQuestLevel(quest_name
)
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
)
114 function QuestHelper
:ItemIsForQuest(item_object
, item_name
)
115 if not item_object
.o
.quest
then
118 for quest
, lq
in pairs(self
.quest_log
) do
120 for i
, lo
in ipairs(lq
.goal
) do
121 if lo
.category
== "item" and lo
.wanted
== item_name
then
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
140 self
.party_levels
= party_levels
143 local level_average
= UnitLevel("player")
146 if not QuestHelper_Pref
.solo
then
148 local level
= UnitLevel("party"..n
)
150 if level
and level
> 0 then
151 level_average
= level_average
+ level
157 level_average
= level_average
/ users
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.
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
180 players
= qtype
== nil and 1 or 5
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
]
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
205 if GetQuestLogTimeLeft() then
206 -- Quest has a timer, so give it a higher than normal priority.
207 self
:SetObjectivePriority(quest
, 2)
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.
223 quest
.index
= index
-- guhhh
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
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
245 lo
.reason
= QHFormat("OBJECTIVE_REASON", verb
, wanted
, title
)
247 lo
.reason
= QHFormat("OBJECTIVE_REASON_FALLBACK", wanted
, title
)
250 lo
.category
= category
255 if have
~= need
then -- If the objective isn't complete, watch it.
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())
271 self
:AppendObjectivePosition(lo
.objective
, self
:PlayerPosition())
275 if lo
.have
== need
then -- The objective was done, but now its not.
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
)
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
)
297 lq
.reason
= QHFormat("OBJECTIVE_REASON_TURNIN", title
)
299 self
:AddObjectiveWatch(quest
, lq
.reason
)
305 for quest
, lq
in pairs(quests
) do
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)
319 self
:RemoveObjectiveWatch(quest
, lq
.reason
)
326 QH_Timeslice_Bonus(15)
329 SelectQuestLogEntry(original_entry
)
331 if QuestHelper_Pref
.track
then
332 self
.tracker
:update()