1 QuestHelper_File
["questlog.lua"] = "Development Version"
3 --[[QuestHelper.debug_objectives =
5 ["Harbinger of Doom"] =
7 cat="quest", what="Harbinger of Doom", sub=
9 ["Slay Harbinger Skyriss"] =
11 cat="monster", what="Harbinger Skyriss"
17 function QuestHelper
:LoadDebugObjective(name
, data
)
18 local obj
= self
:GetObjective(data
.cat
, data
.what
)
20 self
:SetObjectivePriority(obj
, 3)
21 self
:AddObjectiveWatch(obj
, name
)
24 for name
, sdata
in pairs(data
.sub
) do
25 self
:ObjectiveObjectDependsOn(obj
, QuestHelper
:LoadDebugObjective(name
, sdata
))
32 local ITEM_PATTERN
, REPUTATION_PATTERN
, MONSTER_PATTERN
, OBJECT_PATTERN
= false, false, false, false
34 local function buildPatterns()
35 if not ITEM_PATTERN
then
36 ITEM_PATTERN
= QuestHelper
:convertPattern(QUEST_OBJECTS_FOUND
)
37 REPUTATION_PATTERN
= QuestHelper
:convertPattern(QUEST_FACTION_NEEDED
)
38 MONSTER_PATTERN
= QuestHelper
:convertPattern(QUEST_MONSTERS_KILLED
)
39 OBJECT_PATTERN
= QuestHelper
:convertPattern(QUEST_OBJECTS_FOUND
)
40 PLAYER_PATTERN
= QuestHelper
:convertPattern(QUEST_PLAYERS_KILLED
)
45 function QuestHelper
:GetQuestLogObjective(quest_index
, objective_index
)
46 local text
, category
, done
= GetQuestLogLeaderBoard(objective_index
, quest_index
)
50 local wanted
, verb
, have
, need
52 if category
== "monster" then
53 wanted
, have
, need
= MONSTER_PATTERN(text
)
54 verb
= QHText("SLAY_VERB")
55 elseif category
== "item" then
56 wanted
, have
, need
= ITEM_PATTERN(text
)
57 verb
= QHText("ACQUIRE_VERB")
58 elseif category
== "reputation" then
59 wanted
, have
, need
= REPUTATION_PATTERN(text
)
60 elseif category
== "object" then
61 wanted
, have
, need
= OBJECT_PATTERN(text
)
62 elseif category
== "event" then
63 wanted
, have
, need
= text
, 0, 1
64 elseif category
== "player" then
65 wanted
, have
, need
= PLAYER_PATTERN(text
)
67 QuestHelper
:TextOut("Unhandled event type: "..category
)
73 _
, _
, wanted
, have
, need
= string.find(text
, "^%s*(.-)%s*:%s*(.-)%s*/%s*(.-)%s*$")
75 _
, _
, wanted
= string.find("^%s*(.-)%s*$")
80 if not need
then need
= 1 end
81 if done
then have
= need
end
83 return category
, verb
, wanted
or text
, tonumber(have
) or have
, tonumber(need
) or need
86 function QuestHelper
:FixedGetQuestLogTitle(index
)
87 local title
, level
, qtype
, players
, header
, collapsed
, status
, daily
= GetQuestLogTitle(index
)
89 if title
and level
then
90 local _
, _
, real_title
= string.find(title
, "^%["..level
.."[^%s]-%]%s?(.+)$")
91 title
= real_title
or title
94 return title
, level
, qtype
, players
, header
, collapsed
, status
, daily
97 function QuestHelper
:GetQuestLevel(quest_name
)
100 local title
, level
, _
, _
, header
= self
:FixedGetQuestLogTitle(index
)
101 if not title
then return 0 end
102 if not header
and title
== quest_name
then
103 local original_entry
= GetQuestLogSelection()
104 SelectQuestLogEntry(index
)
105 local hash
= self
:HashString(select(2, GetQuestLogQuestText()))
106 SelectQuestLogEntry(original_entry
)
113 function QuestHelper
:ItemIsForQuest(item_object
, item_name
)
114 if not item_object
.o
.quest
then
117 for quest
, lq
in pairs(self
.quest_log
) do
119 for i
, lo
in ipairs(lq
.goal
) do
120 if lo
.category
== "item" and lo
.wanted
== item_name
then
130 local first_time
= true
132 function QuestHelper
:ScanQuestLog()
133 local original_entry
= GetQuestLogSelection()
134 local quests
= self
.quest_log
136 local party_levels
= self
.party_levels
137 if not party_levels
then
139 self
.party_levels
= party_levels
142 local level_average
= UnitLevel("player")
145 if not QuestHelper_Pref
.solo
then
147 local level
= UnitLevel("party"..n
)
149 if level
and level
> 0 then
150 level_average
= level_average
+ level
156 level_average
= level_average
/ users
159 party_levels
[n
] = level_average
+15-15*math
.pow(n
/users
, 0.4)
162 for i
, quest
in pairs(quests
) do
163 -- Will set this to false if the player still has it.
169 local title
, level
, qtype
, players
, header
, collapsed
, status
, daily
= self
:FixedGetQuestLogTitle(index
)
171 if not title
then break end
173 if players
and players
<= 0 then
178 players
= qtype
== nil and 1 or 5
180 players
= math
.min(5, math
.max(1, players
))
183 -- Quest was failed if status is -1.
184 if not header
and status
~= -1 then
185 SelectQuestLogEntry(index
)
186 local hash
= self
:HashString(select(2, GetQuestLogQuestText()))
187 local quest
= self
:GetQuest(title
, level
, hash
)
188 local lq
= quests
[quest
]
191 local ignored
= party_levels
[players
]+QuestHelper_Pref
.level
< level
193 if self
.quest_giver
and self
.quest_giver
[title
] then
194 quest
.o
.start
= self
.quest_giver
[title
]
195 self
.quest_giver
[title
] = nil
203 if GetQuestLogTimeLeft() then
204 -- Quest has a timer, so give it a higher than normal priority.
205 self
:SetObjectivePriority(quest
, 2)
207 -- Use a normal priority.
208 self
:SetObjectivePriority(quest
, 3)
212 quest
.o
.id
= self
:GetQuestID(index
)
214 -- Can't add the objective here, if we don't have it depend on the objectives
215 -- first it'll get added and possibly not be doable.
216 -- We'll add it after the objectives are determined.
223 if GetNumQuestLeaderBoards(index
) > 0 then
224 if not lq
.goal
then lq
.goal
= {} end
225 for objective
= 1, GetNumQuestLeaderBoards(index
) do
226 local lo
= lq
.goal
[objective
]
227 if not lo
then lo
= {} lq
.goal
[objective
] = lo
end
229 local category
, verb
, wanted
, have
, need
= self
:GetQuestLogObjective(index
, objective
)
231 if not wanted
or not string.find(wanted
, "[^%s]") then
232 self
.defered_quest_scan
= true
233 elseif not lo
.objective
then
235 lo
.objective
= self
:GetObjective(category
, wanted
)
236 lo
.objective
.o
.quest
= true -- If I ever decide to prune the DB, I'll have the stuff actually used in quests marked.
237 self
:ObjectiveObjectDependsOn(quest
, lo
.objective
)
239 lo
.objective
.quest
= quest
242 lo
.reason
= QHFormat("OBJECTIVE_REASON", verb
, wanted
, title
)
244 lo
.reason
= QHFormat("OBJECTIVE_REASON_FALLBACK", wanted
, title
)
247 lo
.category
= category
252 if have
~= need
then -- If the objective isn't complete, watch it.
254 self
:AddObjectiveWatch(lo
.objective
, lo
.reason
)
256 elseif lo
.have
~= have
then
257 if lo
.objective
.peer
then
258 for u
, l
in pairs(lo
.objective
.peer
) do
259 -- Peers don't know about our progress.
260 lo
.objective
.peer
[u
] = math
.min(l
, 2)
264 if have
== need
or (type(have
) == "number" and have
> lo
.have
) then
265 if category
== "item" then
266 self
:AppendItemObjectivePosition(lo
.objective
, wanted
, self
:PlayerPosition())
268 self
:AppendObjectivePosition(lo
.objective
, self
:PlayerPosition())
272 if lo
.have
== need
then -- The objective was done, but now its not.
274 self
:AddObjectiveWatch(lo
.objective
, lo
.reason
)
275 elseif have
== need
then -- The objective is now finished.
276 lo
.objective
:Unshare()
277 self
:RemoveObjectiveWatch(lo
.objective
, lo
.reason
)
283 if lo
.objective
then -- Might not have loaded the objective yet, if it wasn't in the local cache and we defered loading it.
284 lo
.objective
.filter_level
= ignored
285 lo
.objective
.filter_done
= true
286 self
:SetObjectiveProgress(lo
.objective
, UnitName("player"), have
, need
)
294 lq
.reason
= QHFormat("OBJECTIVE_REASON_TURNIN", title
)
296 self
:AddObjectiveWatch(quest
, lq
.reason
)
302 for quest
, lq
in pairs(quests
) do
305 for i
, lo
in ipairs(lq
.goal
) do
306 if lo
.objective
and lo
.have
~= lo
.need
then
307 lo
.objective
:Unshare()
308 self
:RemoveObjectiveWatch(lo
.objective
, lo
.reason
)
311 self
:SetObjectiveProgress(lo
.objective
, UnitName("player"), nil, nil)
316 self
:RemoveObjectiveWatch(quest
, lq
.reason
)
323 QH_Timeslice_Bonus(15)
326 SelectQuestLogEntry(original_entry
)
328 if QuestHelper_Pref
.track
then
329 self
.tracker
:update()