Mercurial > wow > buffalo2
view ObjectiveTracker/ObjectiveInfo.lua @ 37:e84d645c8ab8
- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used
- also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times
- schema handling polish
author | Nenue |
---|---|
date | Mon, 18 Apr 2016 07:56:23 -0400 |
parents | 4b3da1b221de |
children |
line wrap: on
line source
local B = select(2,...).frame local wipe, pairs, ipairs, min, max, unpack = table.wipe, pairs, ipairs, min, max, unpack local tinsert, tostring, format, mod = tinsert, tostring, format, mod local GetQuestTagInfo, GetQuestLogTitle = GetQuestTagInfo, GetQuestLogTitle local GetNumQuestLogEntries, GetNumQuestWatches, GetQuestLogCompletionText, IsQuestWatched, IsQuestHardWatched, GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown = GetNumQuestLogEntries, GetNumQuestWatches, GetQuestLogCompletionText, IsQuestWatched, IsQuestHardWatched, GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown local GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetTasksTable, GetNumQuestLogTasks, GetTaskInfo, GetQuestObjectiveInfo = GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetTasksTable, GetNumQuestLogTasks, GetTaskInfo, GetQuestObjectiveInfo local GetNumQuestLogRewardCurrencies, GetQuestLogRewardCurrencyInfo, GetNumQuestLogRewards, GetQuestLogRewardInfo, GetQuestLogRewardMoney, GetMoneyString = GetNumQuestLogRewardCurrencies, GetQuestLogRewardCurrencyInfo, GetNumQuestLogRewards, GetQuestLogRewardInfo, GetQuestLogRewardMoney, GetMoneyString local GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo = GetNumQuestLeaderBoards, GetAchievementNumCriteria, GetQuestLogLeaderBoard, GetAchievementCriteriaInfo local GetQuestWatchIndex, GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo = GetQuestWatchIndex, GetQuestLogIndexByID, GetSuperTrackedQuestID, SetSuperTrackedQuestID, GetQuestWatchInfo local QuestHasPOIInfo, GetDistanceSqToQuest, GetQuestFactionGroup = QuestHasPOIInfo, GetDistanceSqToQuest, GetQuestFactionGroup local GetTrackedAchievements, GetNumTrackedAchievements, GetAchievementInfo = GetTrackedAchievements, GetNumTrackedAchievements, GetAchievementInfo local GetMoney, floor = GetMoney, floor local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local print = B.print('Info') local QUEST_TAG_DUNGEON = QUEST_TAG_DUNGEON local QUEST_TAG_GROUP = QUEST_TAG_GROUP local QUEST_TAG_ACCOUNT = QUEST_TAG_ACCOUNT local QUEST_TAG_TCOORDS = QUEST_TAG_TCOORDS local LE_QUEST_FREQUENCY_DAILY = LE_QUEST_FREQUENCY_DAILY local LE_QUEST_FREQUENCY_WEEKLY = LE_QUEST_FREQUENCY_WEEKLY 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 local Tracker, Bonus, AutoQuest, Quest, Cheevs = T.DefaultTracker, T.Bonus, T.AutoQuest, T.Quest, T.Cheevs -------------------------------------------------------------------- --- Tracker-specific data retrieval functions -------------------------------------------------------------------- local DoQuestRewards= function(t, questID) local rewards = {} t.numCurrencies = GetNumQuestLogRewardCurrencies(questID) for i = 1, t.numCurrencies do local name, texture, count = GetQuestLogRewardCurrencyInfo(i, questID) tinsert(rewards,{ type = 'currency', index = i, name = name, texture = texture, count = count }); end -- items t.numItems = GetNumQuestLogRewards(questID) for i = 1, t.numItems do local name, texture, count, quality, isUsable = GetQuestLogRewardInfo(i, questID) tinsert(rewards, { type = 'item', index = i , name = name, texture = texture, count = count, quality = quality, isUsable = isUsable }); end -- money local money = GetQuestLogRewardMoney(questID) if ( money > 0 ) then tinsert(rewards, { type = 'money', name = GetMoneyString(money), texture = "Interface\\Icons\\inv_misc_coin_01", count = 0, }); end if #rewards >= 1 then t.rewardInfo = rewards end end ----------------------------- --- AUTO_QUEST AutoQuest.LogInfo = {} AutoQuest.LogBlock = {} AutoQuest.QuestBlock = {} AutoQuest.WatchBlock = {} function AutoQuest:GetNumWatched () print(self.name, self) Quest:GetNumWatched() self.numWatched = GetNumAutoQuestPopUps() return self.numWatched end AutoQuest.GetInfo = function(self, popupIndex) local questID, type = GetAutoQuestPopUp(popupIndex) local questLogIndex = GetQuestLogIndexByID(questID) local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex) self.Info[questID] = self.Info[questID] or {} local popup = self.Info[questID] popup.title = title popup.description = type popup.popupType = type popup.questID = questID popup.questLogIndex = questLogIndex popup.popupIndex = popupIndex self.Info[questID] = popup self.WatchInfo[popupIndex] = popup return self.Info[questID] end ----------------------------- --- BONUS OBJECTIVE -- The default UI pops them up as you enter their relevant areas, but the data is actually available at all times. -- The only requirement is that you've been to said area and progressed any of the objectives. -- Blizzard deal with this fact by caching any task data collected during session and masking out whatever gets completed. -- For the addon's module structure to work, GetNumWatched method also invokes a tasks table scan. -- That composes the table searched by GetInfo(). ------------------------------------------------------------------------------------------ --- These functions are copied from Blizzard_BonusObjectiveTracker.lua; -- It's kind of dumb, but this avoids the risk of code taint. --- Returns a tasks table modified to include recently completed objectives local UnitName, GetRealmName = UnitName, GetRealmName local InternalGetTasksTable = function() local savedTasks = T.Conf.TasksLog local char = UnitName("player") local realm = GetRealmName() local tasks = GetTasksTable() for questID, data in pairs(Bonus.Info) do print(' -- questID:', questID, #data.objectives) for i, o in ipairs(data.objectives) do print(' --', i, o.text) end end for questID, data in pairs(savedTasks) do if questID > 0 then local found = false for i = 1, #tasks do if tasks[i] == questID then found = true break end end -- if it's not part of the current table, then try to insert it where it was last found if not found then if data.watchIndex < #tasks then tinsert(tasks, data.watchIndex, data) else tinsert(tasks, data) end end end end return tasks end --- Returns an entry from the composed tasks table if possible, otherwise makes an API pull local InternalGetTaskInfo = function(questID) local completedTasks = T.Conf.TasksLog if completedTasks[questID] then return true, true, #completedTasks[questID].objectives else return GetTaskInfo(questID) end end --- Same as above but for the objective entries local InternalGetQuestObjectiveInfo = function(questID, objectiveIndex) local completedTasks = T.Conf.TasksLog if ( completedTasks[questID] ) then print('using internal data') return completedTasks[questID].objectives[objectiveIndex], completedTasks[questID].objectiveType, true; else return GetQuestObjectiveInfo(questID, objectiveIndex, false); end end --- end redundant copy of silliness ------------------------------------------------------------------------------------------ Bonus.Completed = {} Bonus.POI = {} Bonus.Scenario = {} Bonus.QuestBlock = {} Bonus.WatchInfo = {} function Bonus:GetNumWatched () print(self.name, self) local tasks = InternalGetTasksTable() local numWatched = 0 local numAll = 0 self.WatchInfo = {} print('|cFFFFFF00Bonus.GetNumWatched()|r', #tasks) print(' TasksTable pull:') for i, questID in ipairs(tasks) do local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(questID) local existingTask = self.QuestBlock[questID] local displayObjectiveHeader = false; local test = (isInArea or (isOnMap and existingTask)) --local test = true if test then self.Info[questID] = self.Info[questID] or {} local t = self.Info[questID] self.WatchInfo[i] = t t.isInArea = isInArea t.isOnMap = isOnMap t.existingTask = existingTask t.questID = questID t.objectives = {} t.taskIndex = i DoQuestRewards(t, questID) local taskTitle local taskFinished = true; for objectiveIndex = 1, numObjectives do local text, objectiveType, finished, displayAsObjective = InternalGetQuestObjectiveInfo(questID, objectiveIndex, false); displayObjectiveHeader = displayObjectiveHeader or displayAsObjective; if not taskTitle then if objectiveType == 'progressbar' and not text:match('^%d%+\\%d+') then taskTitle = text text = '' end end print(' --', text, objectiveType, finished, displayAsObjective) t.objectives[objectiveIndex] = t.objectives[objectiveIndex] or {} local o = t.objectives[objectiveIndex] o.objectiveIndex = objectiveIndex o.text = text o.objectiveType = objectiveType o.finished = finished o.displayAsObjective = displayAsObjective print(' |cFF00FF88*', objectiveIndex, text) end -- didn't get a name from progress bar? what about area name if not taskTitle then if isInArea then taskTitle = GetMapNameByID(GetCurrentMapAreaID()) end end t.title = taskTitle end print (' |cFF00FF88#', i, 'questID', questID, 'inArea', isInArea, 'onMap', isOnMap, 'existing', (existingTask and 'Y' or 'N'), (test and '|cFF00FF00show|r' or '|cFFFF0088hide|r')) end self.numAll = #tasks self.numWatched = #self.WatchInfo print(' stats:', self.numAll, 'active tasks,', self.numWatched, 'nearby or animating') --return #tasks return #self.WatchInfo end --- info cleanup done when turn-ins are detected Bonus.OnTurnIn = function(self, questID, xp, money) if #self.info.rewardInfo >= 1 then for i, reward in ipairs(self.info.rewardInfo) do --[[ type = 'item', index = i , name = name, texture = texture, count = count, quality = quality, isUsable = isUsable ]] print(' reward ', i, ' ', reward.type, reward.name, reward.count) end end print('|cFFFF8800'..self.name..':OnTurnIn call', questID, xp, money) local savedTasks = B.Conf.TasksLog self.Info[questID].completedTime = GetTime() self.Info[questID].animate = true T.SetAnimate(self.watchReasonModule) savedTasks[questID] = self.Info[questID] end Bonus.GetInfo = function(self, taskIndex) print(self.name, self) return self.WatchInfo[taskIndex] end Cheevs.GetNumWatched = function(self) print('|cFF00FF00' .. GetTime()) Cheevs.trackedCheevs = {GetTrackedAchievements()} return GetNumTrackedAchievements() end Cheevs.GetInfo = function(self, index) local cheevID = Cheevs.trackedCheevs[index] local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy = GetAchievementInfo(cheevID) self.Info[cheevID] = {} local c = self.Info[cheevID] c.type = 'Cheevs' c.watchIndex = index c.cheevID = cheevID c.title = name c.points, c.completed, c.month, c.day, c.year, c.description, c.flags, c.icon, c.rewardText, c.isGuildAch, c.wasEarnedByMe, c.earnedBy = points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy c.numObjectives = GetAchievementNumCriteria(cheevID) c.objectives = {} for i = 1, c.numObjectives do local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i) c.objectives[i] = { objectiveIndex = i, cheevID = cheevID, text = description, type = type, finished = completed, value = quantity, maxValue = requiredQuantity, characterName = characterName, flags = flags, assetID = assetID, quantityString = quantityString, criteriaID = criteriaID, } end print('Cheevs.|cFF0088FFGetInfo|r('..index..')', 'obj:', GetAchievementNumCriteria(cheevID), name, description) self.WatchInfo[index] = c return self.Info[cheevID] end