Merge branch 'master' into achievements
[QuestHelper.git] / manager_achievement.lua
blob6cf08765af9cb6ba56c402dc2907dc158e316108
1 QuestHelper_File["manager_achievement.lua"] = "Development Version"
2 QuestHelper_Loadtime["manager_achievement.lua"] = GetTime()
4 local AchievementDB
6 -- 0 is a monster kill, asset is the monster ID
7 --X 1 is winning PvP objectives in a thorough manner (holding all bases, controlling all flags)
8 --X 7 is weapon skill, asset is probably a skill ID of some sort
9 --X 8 is another achievement, asset is achievement ID
10 --X 9 is completing quests globally
11 --X 10 is completing a daily quest every day
12 --X 11 is completing quests in specific areas
13 --X 14 is completing daily quests
14 --X 27 is a quest, asset is quest ID
15 --X 28 is getting a spell cast on you, asset is a spell ID
16 --X 29 is casting a spell (often crafting), asset is a spell ID
17 --X 30 is PvP objectives (flags, assaulting, defending)
18 --X 31 is PvP kills in battleground PvP locations
19 --X 32 is winning ranked arena matches in specific locations (asset is probably a location ID)
20 --X 34 is the Squashling (owning a specific pet?), asset is the spell ID
21 --X 35 is PvP kills while under the influence of something
22 --X 36 is acquiring items (soulbound), asset is an item ID
23 --X 37 is winning arenas
24 --X 41 is eating or drinking a specific item, asset is item ID
25 --X 42 is fishing things up, asset is item ID
26 -- 43 is exploration, asset is a location ID?
27 --X 45 is purchasing 7 bank slots
28 --X 46 is exalted rep, asset is presumably some kind of faction ID
29 --X 47 is 5 reputations to exalted
30 --X 49 is equipping items, asset is a slot ID (quality is presumably encoded into flags)
31 --X 52 is killing specific classes of player
32 --X 53 is kill-a-given-race, asset is race ID?
33 -- 54 is using emotes on targets, asset ID is likely the emote ID
34 --X 56 is being a wrecking ball in Alterac Valley
35 --X 62 is getting gold from quest rewards
36 --X 67 is looting gold
37 -- 68 is reading books
38 -- 70 is killing players in world PvP locations
39 -- 72 is fishing things from schools or wreckage
40 --X 73 is killing Mal'Ganis on Heroic. Why? Who can say.
41 --X 75 is obtaining mounts
42 -- 109 is fishing, either in general or in specific locations
43 -- 110 is casting spells on specific targets, asset ID is the spell ID
44 --X 112 is learning cooking recipes
45 --X 113 is honorable kills
46 local achievement_type_blacklist = {}
47 for _, v in pairs({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
48 achievement_type_blacklist[v] = true
49 end
51 local achievement_list = {}
53 --local crittypes = {}
54 --QuestHelper_ZorbaForgotToRemoveThis = {}
56 local qhdinfo = false
57 local qhdinfodump = {}
58 local function qhadumpy()
59 for k, v in pairs(qhdinfodump) do
60 local ct = 0
61 local some
62 for tk, tv in pairs(v) do
63 ct = ct + 1
64 some = tk
65 end
66 QuestHelper:TextOut(string.format("%d: %d, %s", k, ct, some))
67 end
68 end
70 local function registerAchievement(id)
71 --if db.achievements[id] then return end
73 local _, title, _, complete = GetAchievementInfo(id)
74 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
75 local prev = GetPreviousAchievement(id)
76 local record = false
78 --[[
79 db.achievements[id] = {
80 previous = prev,
81 compete = complete,
82 name = title,
83 criterialist = {}
85 local dbi = db.achievements[id]
88 if prev then
89 registerAchievement(prev)
90 end
92 local critcount = GetAchievementNumCriteria(id)
93 if critcount == 0 then record = true end
95 for i = 1, critcount do
96 local crit_name, crit_type, crit_complete, crit_quantity, crit_reqquantity, _, _, crit_asset, _, crit_id = GetAchievementCriteriaInfo(id, i)
98 if qhdinfo and not achievement_type_blacklist[crit_type] then
99 if not qhdinfodump[crit_type] then qhdinfodump[crit_type] = {} end
100 qhdinfodump[crit_type][title .. " --- " .. crit_name] = true
103 --[[
104 table.insert(dbi.criterialist, crit_id)
105 ass ert (not db.criteria[crit_id])
106 crittypes[crit_type] = (crittypes[crit_type] or 0) + 1]]
108 if not achievement_type_blacklist[crit_type] then record = true end
110 --[[
111 db.criteria[crit_id] = {
112 name = crit_name,
113 type = crit_type,
114 complete = crit_complete,
115 progress = crit_quantity,
116 progress_total = crit_reqquantity,
117 asset = crit_asset,
121 if record then achievement_list[id] = true end
124 local function createAchievementList()
125 for _, catid in pairs(GetCategoryList()) do
126 for d = 1, GetCategoryNumAchievements(catid) do
127 --if GetAchievementInfo(catid, d) == 2557 then print("loading tffs") end
128 --if GetAchievementInfo(catid, d) == 1312 then print("loading otot") end
130 registerAchievement(GetAchievementInfo(catid, d), db)
131 --assert(AchievementDB.achievements[2557])
132 --assert(AchievementDB.achievements[1312]) -- what what
137 qh_cal = createAchievementList
139 local achievement_stop_time = 0
141 local GetAchievementInfo = GetAchievementInfo
142 local GetAchievementNumCriteria = GetAchievementNumCriteria
143 local GetAchievementCriteriaInfo = GetAchievementCriteriaInfo
145 local function retrieveAchievement(id, db)
146 QH_Timeslice_Yield()
148 local _, _, _, complete = GetAchievementInfo(id)
149 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
151 db.achievements[id] = QuestHelper:CreateTable("collect_achievement achievement")
152 db.achievements[id].complete = complete
154 local dbi = db.achievements[id]
156 local critcount = GetAchievementNumCriteria(id)
158 --QuestHelper:TextOut(string.format("%d criteria", crit))
159 for i = 1, critcount do
160 QuestHelper: Assert(not db.criteria[crit_id])
161 local _, _, crit_complete, crit_quantity, crit_reqquantity, _, _, _, _, crit_id = GetAchievementCriteriaInfo(id, i)
163 db.criteria[crit_id] = QuestHelper:CreateTable("collect_achievement criteria")
164 db.criteria[crit_id].complete = crit_complete
165 db.criteria[crit_id].progress = crit_quantity
166 db.criteria[crit_id].parent = id
170 local function getAchievementDB()
171 local db = {}
172 db.achievements = {}
173 db.criteria = {}
175 local ct = 0
176 for k in pairs(achievement_list) do
177 retrieveAchievement(k, db)
178 ct = ct + 1
180 --QuestHelper: TextOut(tostring(ct))
182 return db
186 local registered = {}
187 local prescan = {}
189 function QH_AchievementManagerRegister(funky) -- I am imagining "funky" being said in the same tone of voice that "spicy" is in Puzzle Pirates
190 table.insert(registered, funky)
192 function QH_AchievementManagerRegister_Prescan(funky)
193 table.insert(prescan, funky)
196 local updating = false
197 local updating_continue = false
199 local function ScanAchievements()
200 while updating_continue do
201 updating_continue = false
203 for _, v in ipairs(prescan) do
207 local old = AchievementDB
208 local new = getAchievementDB()
210 for _, v in ipairs(registered) do
211 v(old, new)
214 AchievementDB = new
216 for k, v in pairs(old.achievements) do QuestHelper:ReleaseTable(v) end
217 for k, v in pairs(old.criteria) do QuestHelper:ReleaseTable(v) end
220 updating = false
223 local function OnEvent()
224 --print("oe", updating, AchievementDB)
225 if not updating and AchievementDB then
226 --print("cutea")
227 QH_Timeslice_Add(ScanAchievements, "criteria")
228 updating = true
230 updating_continue = true
232 --qhaach = OnEvent
234 QH_Event("CRITERIA_UPDATE", OnEvent)
235 QH_Event("ACHIEVEMENT_EARNED", OnEvent)
237 function QH_AchievementManagerRegister_Poke()
238 OnEvent()
241 function QH_AchievementManager_Init()
242 createAchievementList()
244 AchievementDB = getAchievementDB() -- 'coz we're lazy
245 --assert(AchievementDB.achievements[2556])
246 --assert(AchievementDB.achievements[2557])
247 --assert(AchievementDB.achievements[1312]) -- what what
249 for _, v in ipairs(registered) do -- basically initting everything linked to this
250 v(AchievementDB, AchievementDB)
255 if QuestHelper_File["manager_achievement.lua"] == "Development Version" then
256 -- woop woop woop
257 -- runnin' around like a headless chicken
258 -- collidin' with walls
259 -- fallin' over backwards, waving arms wildly
260 -- little bit of drool
261 -- you know how it goes
263 local the_data
265 local function eatAchievement(id)
266 local _, title, _, complete = GetAchievementInfo(id)
267 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
268 local prev = GetPreviousAchievement(id)
269 local record = false
272 if prev then
273 registerAchievement(prev)
276 local critcount = GetAchievementNumCriteria(id)
278 the_data[id] = {name = title}
280 for i = 1, critcount do
281 local _, crit_type, _, _, _, _, _, crit_asset, _, crit_id = GetAchievementCriteriaInfo(id, i)
282 table.insert(the_data[id], {cid = crit_id, type = crit_type, asset = crit_asset})
286 function dump_the_data_zorba_needs()
287 the_data = {}
288 QuestHelper_Errors.achievement_cruft = the_data
290 for _, catid in pairs(GetCategoryList()) do
291 for d = 1, GetCategoryNumAchievements(catid) do
292 eatAchievement(GetAchievementInfo(catid, d))
297 function dump_crits(id)
298 local critcount = GetAchievementNumCriteria(id)
299 print(string.format("%d criteria (%s)", critcount, tostring(achievement_list[id])))
301 for i = 1, critcount do
302 local _, crit_type = GetAchievementCriteriaInfo(id, i)
303 print(string.format("%d: %d", i, crit_type))