1 QuestHelper_File
["collect_achievement.lua"] = "Development Version"
2 QuestHelper_Loadtime
["collect_achievement.lua"] = GetTime()
11 --X 0 is a monster kill, asset is the monster ID
12 --X 1 is winning PvP objectives in a thorough manner (holding all bases, controlling all flags)
13 --X 7 is weapon skill, asset is probably a skill ID of some sort
14 --X 8 is another achievement, asset is achievement ID
15 --X 9 is completing quests globally
16 --X 10 is completing a daily quest every day
17 --X 11 is completing quests in specific areas
18 --X 14 is completing daily quests
19 --X 27 is a quest, asset is quest ID
20 --X 28 is getting a spell cast on you, asset is a spell ID
21 --X 29 is casting a spell (often crafting), asset is a spell ID
22 --X 30 is PvP objectives (flags, assaulting, defending)
23 --X 31 is PvP kills in battleground PvP locations
24 --X 32 is winning ranked arena matches in specific locations (asset is probably a location ID)
25 --X 34 is the Squashling (owning a specific pet?), asset is the spell ID
26 --X 35 is PvP kills while under the influence of something
27 --X 36 is acquiring items (soulbound), asset is an item ID
28 --X 37 is winning arenas
29 --X 41 is eating or drinking a specific item, asset is item ID
30 --X 42 is fishing things up, asset is item ID
31 --X 43 is exploration, asset is a location ID?
32 --X 45 is purchasing 7 bank slots
33 --X 46 is exalted rep, asset is presumably some kind of faction ID
34 --X 47 is 5 reputations to exalted
35 --X 49 is equipping items, asset is a slot ID (quality is presumably encoded into flags)
36 --X 52 is killing specific classes of player
37 --X 53 is kill-a-given-race, asset is race ID?
38 -- 54 is using emotes on targets, asset ID is likely the emote ID
39 --X 56 is being a wrecking ball in Alterac Valley
40 --X 62 is getting gold from quest rewards
41 --X 67 is looting gold
42 -- 68 is reading books
43 -- 70 is killing players in world PvP locations
44 -- 72 is fishing things from schools or wreckage
45 --X 73 is killing Mal'Ganis on Heroic. Why? Who can say.
46 --X 75 is obtaining mounts
47 -- 109 is fishing, either in general or in specific locations
48 -- 110 is casting spells on specific targets, asset ID is the spell ID
49 --X 112 is learning cooking recipes
50 --X 113 is honorable kills
51 local achievement_type_blacklist
= {}
52 for _
, v
in pairs({0, 1, 7, 8, 9, 10, 11, 14, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 41, 42, 46, 47, 49, 52, 53, 56, 62, 67, 73, 75, 112, 113}) do
53 achievement_type_blacklist
[v
] = true
56 local achievement_list
= {}
58 --local crittypes = {}
59 --QuestHelper_ZorbaForgotToRemoveThis = {}
62 local qhdinfodump
= {}
63 local function qhadumpy()
64 for k
, v
in pairs(qhdinfodump
) do
67 for tk
, tv
in pairs(v
) do
71 QuestHelper
:TextOut(string.format("%d: %d, %s", k
, ct
, some
))
75 local function registerAchievement(id
)
76 --if db.achievements[id] then return end
78 local _
, title
, _
, complete
= GetAchievementInfo(id
)
79 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
80 local prev
= GetPreviousAchievement(id
)
84 db.achievements[id] = {
90 local dbi = db.achievements[id]
94 registerAchievement(prev
)
97 local critcount
= GetAchievementNumCriteria(id
)
98 if critcount
== 0 then record
= true end
100 for i
= 1, critcount
do
101 local crit_name
, crit_type
, crit_complete
, crit_quantity
, crit_reqquantity
, _
, _
, crit_asset
, _
, crit_id
= GetAchievementCriteriaInfo(id
, i
)
103 if qhdinfo
and not achievement_type_blacklist
[crit_type
] then
104 if not qhdinfodump
[crit_type
] then qhdinfodump
[crit_type
] = {} end
105 qhdinfodump
[crit_type
][title
.. " --- " .. crit_name
] = true
109 table.insert(dbi.criterialist, crit_id)
110 ass ert (not db.criteria[crit_id])
111 crittypes[crit_type] = (crittypes[crit_type] or 0) + 1]]
113 if not achievement_type_blacklist
[crit_type
] then record
= true end
116 db.criteria[crit_id] = {
119 complete = crit_complete,
120 progress = crit_quantity,
121 progress_total = crit_reqquantity,
126 if record
then achievement_list
[id
] = true end
129 function createAchievementList()
130 for _
, catid
in pairs(GetCategoryList()) do
131 for d
= 1, GetCategoryNumAchievements(catid
) do
132 registerAchievement(GetAchievementInfo(catid
, d
), db
)
137 local achievement_stop_time
= 0
139 local GetAchievementInfo
= GetAchievementInfo
140 local GetAchievementNumCriteria
= GetAchievementNumCriteria
141 local GetAchievementCriteriaInfo
= GetAchievementCriteriaInfo
143 local function retrieveAchievement(id
, db
)
146 local _
, _
, _
, complete
= GetAchievementInfo(id
)
147 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
149 db
.achievements
[id
] = QuestHelper
:CreateTable("collect_achievement achievement")
150 db
.achievements
[id
].complete
= complete
152 local dbi
= db
.achievements
[id
]
154 local critcount
= GetAchievementNumCriteria(id
)
156 --QuestHelper:TextOut(string.format("%d criteria", crit))
157 for i
= 1, critcount
do
158 QuestHelper
: Assert(not db
.criteria
[crit_id
])
159 local _
, _
, crit_complete
, crit_quantity
, crit_reqquantity
, _
, _
, _
, _
, crit_id
= GetAchievementCriteriaInfo(id
, i
)
161 db
.criteria
[crit_id
] = QuestHelper
:CreateTable("collect_achievement criteria")
162 db
.criteria
[crit_id
].complete
= crit_complete
163 db
.criteria
[crit_id
].progress
= crit_quantity
164 db
.criteria
[crit_id
].parent
= id
168 local function getAchievementDB()
174 for k
in pairs(achievement_list
) do
175 retrieveAchievement(k
, db
)
178 --QuestHelper: TextOut(tostring(ct))
183 local updating
= false
185 local function ScanAchievements()
186 local cloc
= GetLoc() -- yoink
188 --QuestHelper:TextOut("Scanning")
189 local newADB
= getAchievementDB()
190 --QuestHelper:TextOut("GADB done")
191 local oldADB
= AchievementDB
194 for k
, v
in pairs(newADB
.achievements
) do
195 if v
.complete
~= oldADB
.achievements
[k
].complete
then
196 changes
= changes
+ 1
199 for k
, v
in pairs(newADB
.criteria
) do
200 if v
.complete
and not oldADB
.criteria
[k
].complete
then
201 changes
= changes
+ 1
205 if changes
< 10 then -- if someone gets 10 criteria at once, well, I guess that's just what happens
206 for k
, v
in pairs(newADB
.achievements
) do
207 if v
.complete
~= oldADB
.achievements
[k
].complete
then
208 QuestHelper
: Assert(v
.complete
and not oldADB
.achievements
[k
].complete
)
209 if not QHCA
[k
] then QHCA
[k
] = {} end
210 QHCA
[k
].achieved
= (QHCA
[k
].achieved
or "") .. cloc
212 --QuestHelper:TextOut(string.format("Achievement complete, %s", select(2, GetAchievementInfo(k))))
216 for k
, v
in pairs(newADB
.criteria
) do
217 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)
218 --QuestHelper:TextOut(string.format("Criteria complete, %d", k))
219 --QuestHelper:TextOut(string.format("Criteria complete, %s", select(1, GetAchievementCriteriaInfo(k))))
220 if not QHCA
[v
.parent
] then QHCA
[v
.parent
] = {} end
221 QHCA
[v
.parent
][k
] = (QHCA
[v
.parent
][k
] or "") .. cloc
222 elseif v
.progress
> oldADB
.criteria
[k
].progress
then
223 --QuestHelper:TextOut(string.format("Criteria progress, %d", k))
224 --QuestHelper:TextOut(string.format("Criteria progress, %s", select(1, GetAchievementCriteriaInfo(k))))
229 AchievementDB
= newADB
231 for k
, v
in pairs(oldADB
.achievements
) do QuestHelper
:ReleaseTable(v
) end
232 for k
, v
in pairs(oldADB
.criteria
) do QuestHelper
:ReleaseTable(v
) end
234 updating
= false -- This prevents error spam.
235 --QuestHelper:TextOut("Done scan")
238 local function OnEvent()
239 if not updating
and AchievementDB
then
240 QH_Timeslice_Add(ScanAchievements
, "criteria")
246 function QH_Collect_Achievement_Init(QHCData
, API
)
247 if not QHCData
.achievement
then QHCData
.achievement
= {} end
248 QHCA
= QHCData
.achievement
250 createAchievementList()
251 AchievementDB
= getAchievementDB() -- 'coz we're lazy
253 GetLoc
= API
.Callback_LocationBolusCurrent
254 QuestHelper
: Assert(GetLoc
)
256 Merger
= API
.Utility_Merger
257 QuestHelper
: Assert(Merger
)
259 QH_Event("CRITERIA_UPDATE", OnEvent
)
260 QH_Event("ACHIEVEMENT_EARNED", OnEvent
)
262 OnEvent() -- kick it into its first update cycle