annotate ObjectiveInfo.lua @ 19:605e8f0e46db

ObjectiveCore / Style / Events / Frame - polishing the execution path for better performance - make use of the Blizzard_ObjectiveTracker bitfield values to ensure compatibility in possible secure hooks - avoid full updates when possible (using said bitfield values to indicate targeted sections) - extreme streamlining of event handling layout: specific reason updates are invoked from API hooks; broader updates are invoked by when the event listener catches something vague like 'QUEST_LOG_UPDATE'
author Nenue
date Wed, 06 Apr 2016 07:38:35 -0400
parents d1812fb10ae6
children d5ee940de273
rev   line source
Nenue@0 1 local B = select(2,...).frame
Nenue@18 2 local wipe, pairs, ipairs, min, max, unpack, format = table.wipe, pairs, ipairs, min, max, unpack, format
Nenue@18 3 local tinsert, tostring = tinsert, tostring
Nenue@18 4 local GetQuestTagInfo, GetQuestLogTitle = GetQuestTagInfo, GetQuestLogTitle
Nenue@18 5 local GetNumQuestLogEntries, GetNumQuestWatches, GetQuestLogCompletionText, IsQuestWatched, IsQuestHardWatched, GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown = GetNumQuestLogEntries, GetNumQuestWatches, GetQuestLogCompletionText, IsQuestWatched, IsQuestHardWatched, GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown
Nenue@18 6 local GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetTasksTable, GetNumQuestLogTasks, GetTaskInfo, GetQuestObjectiveInfo = GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetTasksTable, GetNumQuestLogTasks, GetTaskInfo, GetQuestObjectiveInfo
Nenue@18 7 local GetNumQuestLogRewardCurrencies, GetQuestLogRewardCurrencyInfo, GetNumQuestLogRewards, GetQuestLogRewardInfo, GetQuestLogRewardMoney, GetMoneyString = GetNumQuestLogRewardCurrencies, GetQuestLogRewardCurrencyInfo, GetNumQuestLogRewards, GetQuestLogRewardInfo, GetQuestLogRewardMoney, GetMoneyString
Nenue@0 8 local GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo = GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo
Nenue@16 9 local GetQuestWatchIndex, GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo = GetQuestWatchIndex, GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo
Nenue@18 10 local QuestHasPOIInfo, GetDistanceSqToQuest, GetQuestFactionGroup = QuestHasPOIInfo, GetDistanceSqToQuest, GetQuestFactionGroup
Nenue@18 11 local GetTrackedAchievements, GetNumTrackedAchievements, GetAchievementInfo = GetTrackedAchievements, GetNumTrackedAchievements, GetAchievementInfo
Nenue@0 12 local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
Nenue@14 13 local print = B.print('TrackerInfo')
Nenue@18 14 local QUEST_TAG_DUNGEON = QUEST_TAG_DUNGEON
Nenue@18 15 local QUEST_TAG_GROUP = QUEST_TAG_GROUP
Nenue@18 16 local QUEST_TAG_ACCOUNT = QUEST_TAG_ACCOUNT
Nenue@18 17 local QUEST_TAG_TCOORDS = QUEST_TAG_TCOORDS
Nenue@18 18 local LE_QUEST_FREQUENCY_DAILY = LE_QUEST_FREQUENCY_DAILY
Nenue@18 19 local LE_QUEST_FREQUENCY_WEEKLY = LE_QUEST_FREQUENCY_WEEKLY
Nenue@18 20 local FACTION_ALLIANCE, LE_QUEST_FACTION_HORDE, FACTION_HORDE, LE_QUEST_FACTION_HORDE = FACTION_ALLIANCE, LE_QUEST_FACTION_HORDE, FACTION_HORDE, LE_QUEST_FACTION_HORDE
Nenue@0 21
Nenue@19 22 local Tracker, Bonus, AutoQuest, Quest, Cheevs = mod.DefaultTracker, mod.Bonus, mod.AutoQuest, mod.Quest, mod.Cheevs
Nenue@0 23 --------------------------------------------------------------------
Nenue@0 24 --- Tracker-specific data retrieval functions
Nenue@0 25 --------------------------------------------------------------------
Nenue@13 26
Nenue@13 27
Nenue@13 28 -----------------------------
Nenue@13 29 --- AUTO_QUEST
Nenue@16 30 AutoQuest.LogInfo = {}
Nenue@16 31 AutoQuest.LogBlock = {}
Nenue@16 32 AutoQuest.QuestBlock = {}
Nenue@16 33 AutoQuest.WatchBlock = {}
Nenue@19 34 function AutoQuest:GetNumWatched ()
Nenue@19 35 print(self.name, self)
Nenue@19 36 self.numWatched = GetNumAutoQuestPopUps()
Nenue@19 37 return self.numWatched
Nenue@16 38 end
Nenue@16 39 AutoQuest.GetInfo = function(self, popupIndex)
Nenue@16 40
Nenue@16 41 local questID, type = GetAutoQuestPopUp(popupIndex)
Nenue@16 42 local questIndex = GetQuestLogIndexByID(questID)
Nenue@16 43 local questWatchIndex = GetQuestWatchIndex(questIndex)
Nenue@16 44
Nenue@16 45 local questInfo = Quest:GetInfo(questWatchIndex)
Nenue@16 46 self.Info[questID] = {
Nenue@16 47 title = questInfo.title,
Nenue@16 48 description = type,
Nenue@16 49 popupType = type,
Nenue@16 50 questID = questID,
Nenue@16 51 questIndex = questIndex,
Nenue@16 52 popupIndex = popupIndex,
Nenue@16 53 watchIndex = questWatchIndex,
Nenue@16 54 numObjectives = 0
Nenue@16 55 }
Nenue@16 56
Nenue@16 57
Nenue@16 58 return self.Info[questID]
Nenue@13 59 end
Nenue@13 60
Nenue@13 61 -----------------------------
Nenue@14 62 --- BONUS OBJECTIVE
Nenue@14 63 Bonus.TasksTable = {}
Nenue@14 64 Bonus.TasksPOI = {}
Nenue@14 65 Bonus.TaskScenario = {}
Nenue@14 66
Nenue@14 67 local taskData = {}
Nenue@14 68 Bonus.QuestBlock = {}
Nenue@16 69 Bonus.TaskWatch = {}
Nenue@19 70 function Bonus:GetNumWatched ()
Nenue@19 71 print(self.name, self)
Nenue@16 72 local tasks = GetTasksTable()
Nenue@14 73 local numTasks = 0
Nenue@16 74 Bonus.TaskWatch = {}
Nenue@16 75 print('|cFFFFFF00Bonus.GetNumWatched()|r', #tasks)
Nenue@16 76 for i, questID in ipairs(tasks) do
Nenue@16 77 local t = Bonus.StoreTask(questID)
Nenue@16 78 print (' taskIndex', i, 'questID', questID)
Nenue@16 79 print(' isComplete', t.isComplete)
Nenue@16 80 if (t.inInArea or t.isOnMap) and not t.isComplete then
Nenue@14 81 numTasks = numTasks + 1
Nenue@16 82 Bonus.TaskWatch[numTasks] = t
Nenue@14 83 end
Nenue@14 84 end
Nenue@14 85 Bonus.numAll = #Bonus.TasksTable
Nenue@14 86 Bonus.numWatched = numTasks
Nenue@14 87 return GetNumQuestLogTasks()
Nenue@14 88 end
Nenue@16 89
Nenue@16 90 Bonus.GetInfo = function(self, taskIndex)
Nenue@19 91 print(self.name, self)
Nenue@16 92 return Bonus.TaskWatch[taskIndex]
Nenue@16 93 end
Nenue@16 94
Nenue@16 95 Bonus.StoreTask = function(questID)
Nenue@16 96
Nenue@14 97 if not questID then
Nenue@16 98 print('|cFFFF4400invalid quest ID', questID)
Nenue@14 99 return
Nenue@14 100 end
Nenue@14 101
Nenue@16 102 Bonus.Info[questID] = Bonus.Info[questID] or {}
Nenue@16 103 local t = Bonus.Info[questID]
Nenue@16 104 local isInArea, isOnMap, numObjectives = GetTaskInfo(questID)
Nenue@16 105 t.questID = questID
Nenue@16 106 t.numObjectives = numObjectives
Nenue@16 107 t.isInArea = isInArea
Nenue@16 108 t.isOnMap = isOnMap
Nenue@14 109
Nenue@16 110 print(' isInArea', isInArea, 'isOnMap', isOnMap, 'numObj', numObjectives)
Nenue@16 111 local displayObjectives = false
Nenue@16 112 local isComplete = true
Nenue@16 113 if numObjectives >= 1 then
Nenue@16 114 print(' ', numObjectives,'objective rows')
Nenue@14 115 t.objectives = {}
Nenue@14 116 for i = 1, t.numObjectives do
Nenue@14 117 t.objectives[i] = {}
Nenue@14 118 local o = t.objectives[i]
Nenue@14 119 o.index = i
Nenue@16 120 --local text, objectiveType, finished, displayAsObjective =
Nenue@16 121 o.text, o.objectiveType, o.finished, o.displayAsObjective = GetQuestObjectiveInfo(questID, i, false)
Nenue@14 122
Nenue@14 123 print(i, '==>', o.text, o.objectiveType, o.finished, o.displayAsObjective)
Nenue@14 124 t.displayObjectives = t.displayObjectives or o.displayAsObjective
Nenue@14 125 t.isComplete = t.isComplete and o.finished
Nenue@14 126
Nenue@14 127 end
Nenue@14 128 end
Nenue@16 129
Nenue@16 130 t.displayObjectives = displayObjectives
Nenue@16 131
Nenue@16 132
Nenue@16 133 local rewards = {}
Nenue@16 134 t.numCurrencies = GetNumQuestLogRewardCurrencies(questID)
Nenue@16 135 for i = 1, t.numCurrencies do
Nenue@16 136 local name, texture, count = GetQuestLogRewardCurrencyInfo(i, questID)
Nenue@16 137 tinsert(rewards,{
Nenue@16 138 type = 'currency',
Nenue@16 139 index = i,
Nenue@16 140 name = name,
Nenue@16 141 texture = texture,
Nenue@16 142 count = count
Nenue@16 143 });
Nenue@16 144 end
Nenue@16 145 -- items
Nenue@16 146 t.numItems = GetNumQuestLogRewards(questID)
Nenue@16 147 for i = 1, t.numItems do
Nenue@16 148 local name, texture, count, quality, isUsable = GetQuestLogRewardInfo(i, questID)
Nenue@16 149 tinsert(rewards, {
Nenue@16 150 type = 'item',
Nenue@16 151 index = i ,
Nenue@16 152 name = name,
Nenue@16 153 texture = texture,
Nenue@16 154 count = count,
Nenue@16 155 quality = quality,
Nenue@16 156 isUsable = isUsable
Nenue@16 157 });
Nenue@16 158 end
Nenue@16 159 -- money
Nenue@16 160
Nenue@16 161 local money = GetQuestLogRewardMoney(questID)
Nenue@16 162 if ( money > 0 ) then
Nenue@16 163 tinsert(rewards, {
Nenue@16 164 type = 'money',
Nenue@16 165 name = GetMoneyString(money),
Nenue@16 166 texture = "Interface\\Icons\\inv_misc_coin_01",
Nenue@16 167 count = 0,
Nenue@16 168 });
Nenue@16 169 end
Nenue@16 170
Nenue@16 171 if #rewards >= 1 then
Nenue@16 172 t.rewardInfo = rewards
Nenue@16 173 end
Nenue@16 174
Nenue@14 175 Bonus.TasksTable[questID] = t
Nenue@14 176
Nenue@14 177 return t
Nenue@14 178 end
Nenue@14 179
Nenue@14 180 -----------------------------
Nenue@13 181 --- QUEST
Nenue@1 182 Quest.itemButtons = {}
Nenue@1 183 Quest.freeButtons = {}
Nenue@1 184 Quest.POI = {}
Nenue@5 185 Quest.QuestBlock = {}
Nenue@16 186 Quest.LogBlock = {}
Nenue@16 187 Quest.LogInfo = {}
Nenue@18 188
Nenue@19 189 function Quest:GetNumWatched ()
Nenue@19 190 print(self.name, self)
Nenue@19 191 self.numAll = GetNumQuestLogEntries()
Nenue@19 192 self.numWatched = GetNumQuestWatches()
Nenue@19 193 return self.numWatched, self.numAll
Nenue@0 194 end
Nenue@0 195 Quest.GetInfo = function (self, watchIndex)
Nenue@0 196 print('|cFF00DDFFQuest|r.|cFF0088FFGetInfo(|r'.. tostring(watchIndex)..'|r)')
Nenue@1 197 local questID, title, questIndex, numObjectives, requiredMoney, isComplete,
Nenue@0 198 startEvent, isAutoComplete, failureTime, timeElapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(watchIndex)
Nenue@13 199
Nenue@19 200 if not questIndex then
Nenue@19 201 return
Nenue@19 202 end
Nenue@19 203
Nenue@14 204 local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questIndex)
Nenue@18 205
Nenue@13 206
Nenue@0 207 if not questID then
Nenue@0 208 return
Nenue@0 209 end
Nenue@16 210 Quest.Info[questID] = Quest.Info[questID] or {}
Nenue@0 211
Nenue@16 212 local q = Quest.Info[questID]
Nenue@0 213 q.watchIndex = watchIndex
Nenue@0 214 q.type = 'Quest'
Nenue@0 215 q.questID = questID
Nenue@0 216 q.title = title
Nenue@13 217 q.level = level
Nenue@18 218 q.displayQuestID = displayQuestID
Nenue@18 219 q.suggestedGroup = suggestedGroup
Nenue@1 220 q.questLogIndex = questIndex
Nenue@0 221 q.numObjectives = numObjectives
Nenue@0 222 q.requiredMoney = requiredMoney
Nenue@0 223 q.isComplete = isComplete
Nenue@0 224 q.startEvent = startEvent
Nenue@0 225 q.isAutoComplete = isAutoComplete
Nenue@0 226 q.failureTime = failureTime
Nenue@0 227 q.timeElapsed = timeElapsed
Nenue@0 228 q.questType = questType
Nenue@0 229 q.isTask = isTask
Nenue@0 230 q.isStory = isStory
Nenue@0 231 q.isOnMap = isOnMap
Nenue@0 232 q.hasLocalPOI = hasLocalPOI
Nenue@18 233 q.frequency = frequency
Nenue@13 234 q.isComplete = isComplete
Nenue@13 235 q.isStory = isStory
Nenue@13 236 q.isTask = isTask
Nenue@14 237
Nenue@18 238 --- resolve icon type and template
Nenue@18 239 local tagID, tagName = GetQuestTagInfo(questID)
Nenue@18 240 if ( tagName ) then
Nenue@18 241 local factionGroup = GetQuestFactionGroup(questID);
Nenue@18 242 -- Faction-specific account quests have additional info in the tooltip
Nenue@18 243 if ( tagID == QUEST_TAG_ACCOUNT and factionGroup ) then
Nenue@18 244 local factionString = FACTION_ALLIANCE;
Nenue@18 245 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then
Nenue@18 246 factionString = FACTION_HORDE;
Nenue@18 247 end
Nenue@18 248 tagName = format("%s (%s)", tagName, factionString);
Nenue@18 249 end
Nenue@18 250 if ( QUEST_TAG_TCOORDS[tagID] ) then
Nenue@18 251 local questTypeIcon;
Nenue@18 252 if ( tagID == QUEST_TAG_ACCOUNT and factionGroup ) then
Nenue@18 253 q.typeTag = QUEST_TAG_TCOORDS["ALLIANCE"];
Nenue@18 254 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then
Nenue@18 255 q.typeTag= QUEST_TAG_TCOORDS["HORDE"];
Nenue@18 256 end
Nenue@18 257 else
Nenue@18 258 q.typeTag = QUEST_TAG_TCOORDS[tagID];
Nenue@18 259 end
Nenue@18 260 end
Nenue@14 261 end
Nenue@14 262
Nenue@18 263 if ( frequency == LE_QUEST_FREQUENCY_DAILY ) then
Nenue@18 264 q.frequencyTag = QUEST_TAG_TCOORDS["DAILY"]
Nenue@18 265 q.mainStyle = 'Daily'
Nenue@18 266 elseif ( frequency == LE_QUEST_FREQUENCY_WEEKLY ) then
Nenue@18 267 q.frequencyTag = QUEST_TAG_TCOORDS["WEEKLY"]
Nenue@18 268 q.mainStyle = 'Daily'
Nenue@18 269 end
Nenue@18 270 if ( isComplete and isComplete < 0 ) then
Nenue@18 271 q.completionTag = QUEST_TAG_TCOORDS["FAILED"]
Nenue@18 272 q.subStyle = 'Failed'
Nenue@18 273 elseif isComplete then
Nenue@18 274 q.completionTag = QUEST_TAG_TCOORDS["COMPLETED"]
Nenue@18 275 q.subStyle = 'Complete'
Nenue@18 276 end
Nenue@18 277 q.tagID = tagID
Nenue@18 278 q.tagName = tagName
Nenue@18 279
Nenue@18 280
Nenue@18 281
Nenue@13 282 --q.isBreadCrumb = isBreadCrumb
Nenue@1 283 q.completionText= GetQuestLogCompletionText(questIndex)
Nenue@1 284 q.numObjectives = GetNumQuestLeaderBoards(questIndex)
Nenue@0 285 q.objectives = {}
Nenue@0 286 for i = 1, q.numObjectives do
Nenue@1 287 local text, type, finished = GetQuestLogLeaderBoard(i, questIndex)
Nenue@0 288 q.objectives[i] = {
Nenue@14 289 index = i,
Nenue@0 290 type = type,
Nenue@0 291 text = text,
Nenue@0 292 finished = finished
Nenue@0 293 }
Nenue@0 294 if type == 'event' then
Nenue@0 295 elseif type == 'monster' then
Nenue@0 296 elseif type == 'object' then
Nenue@0 297 elseif type == 'reputation' then
Nenue@0 298 elseif type == 'item' then
Nenue@0 299 end
Nenue@0 300 end
Nenue@0 301
Nenue@1 302 local link, icon, charges = GetQuestLogSpecialItemInfo(questIndex)
Nenue@1 303 local start, duration, enable = GetQuestLogSpecialItemCooldown(questIndex)
Nenue@0 304 if link or icon or charges then
Nenue@0 305 q.specialItem = {
Nenue@1 306 questID = questID,
Nenue@1 307 questIndex = questIndex,
Nenue@0 308 link = link,
Nenue@0 309 charges = charges,
Nenue@0 310 icon = icon,
Nenue@0 311 start = start,
Nenue@0 312 duration = duration,
Nenue@0 313 enable = enable,
Nenue@0 314 }
Nenue@0 315 end
Nenue@0 316
Nenue@1 317 if QuestHasPOIInfo(questID) then
Nenue@1 318 local distance, onContinent = GetDistanceSqToQuest(questIndex)
Nenue@1 319 if distance ~= nil and distance > 0 then
Nenue@1 320 self.POI[questIndex] = {
Nenue@1 321 questIndex = questIndex,
Nenue@1 322 questID = questID,
Nenue@1 323 distance = distance,
Nenue@1 324 onContinent = onContinent
Nenue@1 325 }
Nenue@1 326 end
Nenue@1 327 end
Nenue@1 328
Nenue@18 329
Nenue@18 330 q.selected = (questID == GetSuperTrackedQuestID()) -- call directly so artifact data doesn't become an issue
Nenue@8 331 self.WatchInfo[watchIndex] = q
Nenue@1 332 self.LogInfo[questIndex] = q
Nenue@2 333 print('- logIndex =', questIndex, 'title =', title)
Nenue@0 334 return q
Nenue@0 335 end
Nenue@0 336
Nenue@1 337 Quest.GetClosest = function()
Nenue@1 338 local minID
Nenue@1 339 local minDist = math.huge
Nenue@1 340 for i = 1, Quest.GetNumWatched() do
Nenue@1 341 local info = Quest.GetInfo(i)
Nenue@1 342 if info.hasLocalPOI then
Nenue@1 343 local distance, onContinent = GetDistanceSqToQuest(info.questIndex)
Nenue@1 344 end
Nenue@1 345 end
Nenue@1 346 end
Nenue@1 347
Nenue@6 348
Nenue@0 349 Cheevs.GetNumWatched = function(self)
Nenue@0 350 Cheevs.trackedCheevs = {GetTrackedAchievements()}
Nenue@0 351 return GetNumTrackedAchievements()
Nenue@0 352 end
Nenue@0 353 Cheevs.GetInfo = function(self, index)
Nenue@0 354 local cheevID = Cheevs.trackedCheevs[index]
Nenue@0 355 local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy = GetAchievementInfo(cheevID)
Nenue@0 356
Nenue@0 357 self.Info[cheevID] = {}
Nenue@0 358 local c = self.Info[cheevID]
Nenue@0 359 c.type = 'Cheevs'
Nenue@0 360 c.watchIndex = index
Nenue@0 361 c.cheevID = cheevID
Nenue@0 362 c.title = name
Nenue@0 363 c.points, c.completed, c.month, c.day, c.year, c.description, c.flags, c.icon, c.rewardText, c.isGuildAch, c.wasEarnedByMe, c.earnedBy =
Nenue@0 364 points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy
Nenue@0 365 c.numObjectives = GetAchievementNumCriteria(cheevID)
Nenue@0 366 c.objectives = {}
Nenue@0 367 for i = 1, c.numObjectives do
Nenue@0 368 local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i)
Nenue@0 369 c.objectives[i] = {
Nenue@14 370 index = i,
Nenue@8 371 cheevID = cheevID,
Nenue@0 372 text = description,
Nenue@0 373 type = type,
Nenue@0 374 finished = completed,
Nenue@14 375 value = quantity,
Nenue@14 376 maxValue = requiredQuantity,
Nenue@0 377 characterName = characterName,
Nenue@0 378 flags = flags,
Nenue@0 379 assetID = assetID,
Nenue@0 380 quantityString = quantityString,
Nenue@0 381 criteriaID = criteriaID,
Nenue@0 382 }
Nenue@0 383 end
Nenue@3 384 print('Cheevs.|cFF0088FFGetInfo|r('..index..')', 'obj:', GetAchievementNumCriteria(cheevID), name, description)
Nenue@0 385
Nenue@0 386 self.WatchInfo[index] = c
Nenue@0 387 return self.Info[cheevID]
Nenue@0 388 end