Take a shot at reducing the onload memory spike. I think it might be kind of futile.
[QuestHelper.git] / collect_achievement.lua
blob385a289ae6dc1d16550b5ff6cc24d65ab44d40fd
1 QuestHelper_File["collect_achievement.lua"] = "Development Version"
2 QuestHelper_Loadtime["collect_achievement.lua"] = GetTime()
4 local Collect_Achievement = {}
6 --X 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 --X 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({0, 1, 7, 8, 9, 10, 11, 14, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 41, 42, 43, 45, 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 function registerAchievement(id)
57 --if db.achievements[id] then return end
59 local _, title, _, complete = GetAchievementInfo(id)
60 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
61 local prev = GetPreviousAchievement(id)
62 local record = false
64 --[[
65 db.achievements[id] = {
66 previous = prev,
67 compete = complete,
68 name = title,
69 criterialist = {}
71 local dbi = db.achievements[id]
74 if prev then
75 registerAchievement(prev)
76 end
78 local critcount = GetAchievementNumCriteria(id)
79 if critcount == 0 then record = true end
81 for i = 1, critcount do
82 local crit_name, crit_type, crit_complete, crit_quantity, crit_reqquantity, _, _, crit_asset, _, crit_id = GetAchievementCriteriaInfo(id, i)
84 --if not QuestHelper_ZorbaForgotToRemoveThis[string.format("%d", crit_type)] then QuestHelper_ZorbaForgotToRemoveThis[string.format("%d", crit_type)] = {} end
85 --QuestHelper_ZorbaForgotToRemoveThis[string.format("%d", crit_type)][title .. " --- " .. mega[1]] = crit_asset
87 --[[
88 table.insert(dbi.criterialist, crit_id)
89 ass ert (not db.criteria[crit_id])
90 crittypes[crit_type] = (crittypes[crit_type] or 0) + 1]]
92 if not achievement_type_blacklist[crit_type] then record = true end
94 --[[
95 db.criteria[crit_id] = {
96 name = crit_name,
97 type = crit_type,
98 complete = crit_complete,
99 progress = crit_quantity,
100 progress_total = crit_reqquantity,
101 asset = crit_asset,
105 if record then achievement_list[id] = true end
108 function createAchievementList()
109 for _, catid in pairs(GetCategoryList()) do
110 for d = 1, GetCategoryNumAchievements(catid) do
111 registerAchievement(GetAchievementInfo(catid, d), db)
116 local achievement_stop_time = 0
118 local function retrieveAchievement(id, db)
119 QH_Timeslice_Yield()
121 local _, _, _, complete = GetAchievementInfo(id)
122 --QuestHelper:TextOut(string.format("Registering %d (%s)", id, title))
124 db.achievements[id] = QuestHelper:CreateTable("collect_achievement achievement")
125 db.achievements[id].complete = complete
127 local dbi = db.achievements[id]
129 local critcount = GetAchievementNumCriteria(id)
131 --QuestHelper:TextOut(string.format("%d criteria", crit))
132 for i = 1, critcount do
133 local _, _, crit_complete, crit_quantity, crit_reqquantity, _, _, _, _, crit_id = GetAchievementCriteriaInfo(id, i)
135 db.criteria[crit_id] = QuestHelper:CreateTable("collect_achievement criteria")
136 db.criteria[crit_id].complete = crit_complete
137 db.criteria[crit_id].progress = crit_quantity
141 local function getAchievementDB()
142 local db = {}
143 db.achievements = {}
144 db.criteria = {}
146 for k in pairs(achievement_list) do
147 retrieveAchievement(k, db)
150 return db
153 local updating = false
155 local function ScanAchievements()
156 local newADB = getAchievementDB()
157 local oldADB = Collect_Achievement.AchievementDB
159 for k, v in pairs(newADB.achievements) do
160 if v.complete ~= oldADB.achievements[k].complete then
161 assert(v.complete and not oldADB.achievements[k].complete)
162 --QuestHelper:TextOut(string.format("Achievement complete, %s", select(2, GetAchievementInfo(k))))
166 for k, v in pairs(newADB.criteria) do
167 if v.complete ~= oldADB.criteria[k].complete then
168 assert(v.complete and not oldADB.criteria[k].complete)
169 --QuestHelper:TextOut(string.format("Criteria complete, %d", k))
170 --QuestHelper:TextOut(string.format("Criteria complete, %s", select(1, GetAchievementCriteriaInfo(k))))
171 elseif v.progress > oldADB.criteria[k].progress then
172 --QuestHelper:TextOut(string.format("Criteria progress, %d", k))
173 --QuestHelper:TextOut(string.format("Criteria progress, %s", select(1, GetAchievementCriteriaInfo(k))))
177 Collect_Achievement.AchievementDB = newADB
179 for k, v in pairs(oldADB.achievements) do QuestHelper:ReleaseTable(v) end
180 for k, v in pairs(oldADB.criteria) do QuestHelper:ReleaseTable(v) end
182 updating = false -- This prevents error spam.
185 local function OnEvent()
186 if not updating and Collect_Achievement.AchievementDB then
187 QH_Timeslice_Add(ScanAchievements, "criteria")
188 updating = true
192 function QH_Collect_Achievement_Init(_, API)
193 -- We're actually going to turn this off for now, it's no longer achieving anything useful (i.e. testing)
194 if true then return end
196 createAchievementList()
197 Collect_Achievement.AchievementDB = getAchievementDB() -- 'coz we're lazy
199 API.Registrar_EventHook("CRITERIA_UPDATE", OnEvent)
200 API.Registrar_EventHook("ACHIEVEMENT_EARNED", OnEvent)
202 OnEvent() -- kick it into its first update cycle