Nenue@27: --- ${PACKAGE_NAME} Nenue@27: -- @file-author@ Nenue@27: -- @project-revision@ @project-hash@ Nenue@27: -- @file-revision@ @file-hash@ Nenue@27: -- Created: 4/13/2016 7:48 PM Nenue@27: local B = select(2,...).frame Nenue@27: local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') Nenue@27: local Default, Quest = T.DefaultHandler, T.Quest Nenue@27: local print = B.print('Tracker') Nenue@27: local lprint = B.print('Line') Nenue@33: local iprint = B.print('Info') Nenue@29: local Bonus = T.Bonus Nenue@27: Nenue@29: local UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo = UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo Nenue@29: local GetMapNameByID, GetCurrentMapAreaID = GetMapNameByID, GetCurrentMapAreaID Nenue@38: local tinsert, ipairs, pairs, tostring, wipe = tinsert, ipairs, pairs, tostring, table.wipe Nenue@29: local GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime = GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime Nenue@38: local TASK_DISPLAY_TEST = 1 -- 1: normal (is nearby or on the map) 2: strict (is nearby) 3: data exists Nenue@29: Nenue@40: --- Holds data for recently completed tasks Nenue@40: local completedTasks = {} Nenue@40: Nenue@29: --- Returns a tasks table modified to include recently completed objectives Nenue@29: local InternalGetTasksTable = function() Nenue@38: local print = Bonus.print Nenue@29: local char = UnitName("player") Nenue@29: local realm = GetRealmName() Nenue@29: local tasks = GetTasksTable() Nenue@29: Nenue@29: for questID, data in pairs(Bonus.Info) do Nenue@38: print('GetTasksTable', questID, #data.objectives) Nenue@29: for i, o in ipairs(data.objectives) do Nenue@38: print('GetTasksTable', questID, i, o.text) Nenue@29: end Nenue@29: end Nenue@29: Nenue@40: for questID, data in pairs(completedTasks) do Nenue@29: if questID > 0 then Nenue@29: local found = false Nenue@29: for i = 1, #tasks do Nenue@29: if tasks[i] == questID then Nenue@29: found = true Nenue@29: break Nenue@29: end Nenue@29: end Nenue@29: -- if it's not part of the current table, then try to insert it where it was last found Nenue@29: if not found then Nenue@29: if data.watchIndex < #tasks then Nenue@29: tinsert(tasks, data.watchIndex, data) Nenue@29: else Nenue@29: tinsert(tasks, data) Nenue@29: end Nenue@29: end Nenue@29: end Nenue@29: end Nenue@29: return tasks Nenue@29: end Nenue@29: Nenue@29: --- Returns an entry from the composed tasks table if possible, otherwise makes an API pull Nenue@40: Nenue@29: local InternalGetTaskInfo = function(questID) Nenue@29: if completedTasks[questID] then Nenue@40: -- if it's a recently completed task, use the information stored for it Nenue@29: return true, true, #completedTasks[questID].objectives Nenue@29: else Nenue@29: return GetTaskInfo(questID) Nenue@29: end Nenue@29: end Nenue@29: Nenue@29: --- Same as above but for the objective entries Nenue@29: local InternalGetQuestObjectiveInfo = function(questID, objectiveIndex) Nenue@29: if ( completedTasks[questID] ) then Nenue@29: print('using internal data') Nenue@29: return completedTasks[questID].objectives[objectiveIndex], completedTasks[questID].objectiveType, true; Nenue@29: else Nenue@29: return GetQuestObjectiveInfo(questID, objectiveIndex, false); Nenue@29: end Nenue@29: end Nenue@29: Nenue@29: --- end redundant copy of silliness Nenue@29: ------------------------------------------------------------------------------------------ Nenue@29: Nenue@29: Bonus.Completed = {} Nenue@29: Bonus.POI = {} Nenue@29: Bonus.Scenario = {} Nenue@29: Bonus.QuestBlock = {} Nenue@29: Bonus.WatchInfo = {} Nenue@38: Nenue@38: local function CanShowTask(isInArea, isOnMap, existingTask, numObjectives) Nenue@38: if TASK_DISPLAY_TEST == 1 then Nenue@38: return (isInArea) Nenue@38: elseif TASK_DISPLAY_TEST == 2 then Nenue@38: return (isInArea and(isOnMap and existingTask)) Nenue@38: elseif TASK_DISPLAY_TEST == 3 then Nenue@38: return true Nenue@38: end Nenue@38: end Nenue@38: Nenue@29: function Bonus:GetNumWatched () Nenue@38: Nenue@38: local print = self.print Nenue@29: print(self.name, self) Nenue@29: Nenue@29: local tasks = InternalGetTasksTable() Nenue@29: local numWatched = 0 Nenue@29: local numAll = 0 Nenue@33: local existingTasks = {} Nenue@38: wipe(self.WatchList) Nenue@38: print('|cFF'..self.internalColor..'Bonus.GetNumWatched()|r', #tasks) Nenue@38: print('InternalGetTaskInfo') Nenue@38: Nenue@29: for i, questID in ipairs(tasks) do Nenue@29: local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(questID) Nenue@38: local existingTask = self.InfoBlock[questID] Nenue@29: local displayObjectiveHeader = false; Nenue@40: local displayTask = CanShowTask(isInArea, isOnMap, existingTask) Nenue@40: if displayTask then Nenue@38: print('TaskInfo', '|cFF00FF00showable objective list', questID) Nenue@29: self.Info[questID] = self.Info[questID] or {} Nenue@29: Nenue@29: local t = self.Info[questID] Nenue@33: if (isOnMap or isInArea) and existingTask then Nenue@33: t.areaID = GetCurrentMapAreaID() Nenue@33: local _ Nenue@33: t.mapName, _, _, t.isMicroDungeon, t.microDungeonMapName = GetMapInfo() Nenue@38: print('InternalGetTaskInfo', 'map data', t.areaID, t.mapName) Nenue@33: end Nenue@29: Nenue@29: local taskTitle Nenue@38: t.id = questID Nenue@33: t.objectives = {} Nenue@40: local isComplete = true; Nenue@29: for objectiveIndex = 1, numObjectives do Nenue@29: local text, objectiveType, finished, displayAsObjective = InternalGetQuestObjectiveInfo(questID, objectiveIndex, false); Nenue@29: displayObjectiveHeader = displayObjectiveHeader or displayAsObjective; Nenue@29: if not taskTitle then Nenue@29: if objectiveType == 'progressbar' and not text:match('^%d%+\\%d+') then Nenue@29: taskTitle = text Nenue@29: text = '' Nenue@29: end Nenue@29: end Nenue@29: Nenue@29: Nenue@38: print('TaskObjective', text, objectiveType, finished, displayAsObjective) Nenue@29: t.objectives[objectiveIndex] = t.objectives[objectiveIndex] or {} Nenue@29: local o = t.objectives[objectiveIndex] Nenue@29: Nenue@34: o.index = objectiveIndex Nenue@29: o.text = text Nenue@34: o.type = objectiveType Nenue@29: o.finished = finished Nenue@29: o.displayAsObjective = displayAsObjective Nenue@40: isComplete = (isComplete and finished) Nenue@29: end Nenue@29: Nenue@33: T.SetRewards(t, questID) Nenue@33: Nenue@29: -- didn't get a name from progress bar? what about area name Nenue@29: if not taskTitle then Nenue@29: if isInArea then Nenue@29: taskTitle = GetMapNameByID(GetCurrentMapAreaID()) Nenue@29: end Nenue@29: end Nenue@34: t.numObjectives = numObjectives Nenue@33: t.isInArea = isInArea Nenue@33: t.isOnMap = isOnMap Nenue@33: t.existingTask = existingTask Nenue@33: t.questID = questID Nenue@33: t.id = questID Nenue@33: t.taskIndex = i Nenue@29: t.title = taskTitle Nenue@40: t.isComplete = isComplete Nenue@38: self.WatchList[i] = t Nenue@38: elseif existingTask then Nenue@38: print('TaskInfo', '|cFFFF4400hideable task', questID) Nenue@38: existingTask:Hide() Nenue@29: end Nenue@29: Nenue@40: Nenue@40: print ('TaskInfo', i, '|cFFFFFF00'.. questID..'|r', '('..(isInArea and '|cFF88FF88' or '|cFF666666') .. 'isInArea|r', 'AND', (isOnMap and '|cFF88FF88' or '|cFF666666') .. 'isOnMap|r)', 'OR', (existingTask and '|cFF88FF88' or '|cFF666666') .. 'existingTask|r', (displayTask and '|cFF00FF00show|r' or '|cFFFF4400hide|r')) Nenue@29: end Nenue@29: Nenue@36: Nenue@38: self.numWatched = #self.WatchList Nenue@38: self.numAll = #existingTasks Nenue@38: return self.numWatched, self.numWatched, self.WatchList Nenue@29: end Nenue@29: Nenue@40: Bonus.OnEvent = function(block, event, ...) Nenue@40: if event == 'QUEST_LOG_UPDATE' then Nenue@40: local info = block.info Nenue@40: Nenue@40: local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(info.questID) Nenue@40: if not CanShowTask(isInArea, isOnMap, block, numObjectives) then Nenue@40: block:Hide() Nenue@40: end Nenue@40: end Nenue@40: end Nenue@40: Nenue@40: Bonus.GetBlock = function(self, index) Nenue@40: local block = Default.GetBlock(self, index) Nenue@40: block:SetScript('OnEvent', self.OnEvent) Nenue@40: block:RegisterEvent('QUEST_LOG_UPDATE') Nenue@40: return block Nenue@40: end Nenue@40: Nenue@29: --- info cleanup done when turn-ins are detected Nenue@33: Bonus.OnTurnIn = function(self, block, questID, xp, money) Nenue@38: --[=[ Nenue@33: local info = self.Info[questID] Nenue@33: if info.rewardInfo and #info.rewardInfo >= 1 then Nenue@33: for i, reward in ipairs(info.rewardInfo) do Nenue@29: --[[ Nenue@29: type = 'item', Nenue@29: index = i , Nenue@29: name = name, Nenue@29: texture = texture, Nenue@29: count = count, Nenue@29: quality = quality, Nenue@29: isUsable = isUsable Nenue@29: ]] Nenue@29: print(' reward ', i, ' ', reward.type, reward.name, reward.count) Nenue@29: Nenue@29: end Nenue@29: end Nenue@29: Nenue@34: print('|cFFFF8800'..block:GetName()..':OnTurnIn call', questID, xp, money) Nenue@34: local savedTasks = B.Conf.TasksLog or {} Nenue@29: Nenue@33: info.completedTime = GetTime() Nenue@33: info.animate = true Nenue@34: T.SetAnimate(self.updateReasonModule) Nenue@34: savedTasks[questID] = { Nenue@34: id = questID, Nenue@34: title = info.title, Nenue@34: finished = true, Nenue@34: numObjectives = info.numObjectives, Nenue@34: objectives = info.objectives, Nenue@34: rewardInfo = info.rewardInfo, Nenue@34: } Nenue@34: B.Conf.TasksLog = savedTasks Nenue@34: Nenue@34: print(' ## CONF TASKLOG ##') Nenue@34: for i, t in pairs(savedTasks[questID]) do Nenue@34: print(' |cFFFFFF00'.. tostring(i)..'|r', t) Nenue@34: Nenue@34: end Nenue@34: for o, j in ipairs(savedTasks[questID].objectives) do Nenue@34: print(' |cFF00FFFF#'.. o ..'|r', j.type, j.finished) Nenue@34: end Nenue@33: Nenue@33: print('adding', info.title, 'to cache') Nenue@38: --]=] Nenue@29: end Nenue@29: Nenue@29: Bonus.GetInfo = function(self, taskIndex) Nenue@29: print(self.name, self) Nenue@29: return self.WatchInfo[taskIndex] Nenue@29: end Nenue@29: Nenue@29: Nenue@29: Nenue@29: --- Update hooks Nenue@38: Bonus.UpdateObjectives = function(handler, block, blockSchema) Nenue@38: block.schema = blockSchema or 'default' Nenue@38: local info = block.info Nenue@38: block.title:SetText(info.title) Nenue@38: Nenue@38: Nenue@27: Default.UpdateObjectives(handler, block) Nenue@38: return blockSchema Nenue@27: end Nenue@27: Nenue@38: Bonus.UpdateLine = function(handler, block, data) Nenue@27: local info = block.info Nenue@27: local print = lprint Nenue@31: local text, attachment = '', nil Nenue@34: if data.type == 'progressbar' then Nenue@27: print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) Nenue@33: local percent = 100 Nenue@33: if not data.finished then Nenue@33: percent = GetQuestProgressBarPercent(info.questID) Nenue@33: end Nenue@34: data.value = percent Nenue@34: data.maxValue = 100 Nenue@34: Nenue@40: attachment = T.GetWidget(data, 'StatusBar', info.questID..'-'..data.index) Nenue@40: attachment:SetParent(block) Nenue@34: print(attachment:GetNumPoints()) Nenue@34: for i = 1, attachment:GetNumPoints() do Nenue@34: print(' ',attachment:GetPoint(i)) Nenue@34: end Nenue@34: Nenue@33: attachment.value = percent Nenue@33: attachment.maxValue = 100 Nenue@34: attachment.status:SetFormattedText(PERCENTAGE_STRING, percent) Nenue@38: --attachment:SetParent(handler.frame) Nenue@38: --print(attachment.status:GetText()) Nenue@27: print(' |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue) Nenue@27: end Nenue@34: text = data.text Nenue@38: return text, attachment, 'default' Nenue@27: end Nenue@27: Nenue@33: Bonus.Select = function(handler, block) Nenue@33: print(handler, block) Nenue@33: handler:OnTurnIn(block, block.info.questID) Nenue@27: end Nenue@27: Bonus.Remove = function(self) Nenue@27: Nenue@27: end