Mercurial > wow > buffalo2
changeset 43:9480bd904f4c
- file name organizing
author | Nenue |
---|---|
date | Mon, 25 Apr 2016 13:51:58 -0400 |
parents | c73051785f19 |
children | 756e8aeb040b |
files | ObjectiveTracker/AchievementData.lua ObjectiveTracker/Achievements.lua ObjectiveTracker/AutoQuestPopupData.lua ObjectiveTracker/AutoQuestPopups.lua ObjectiveTracker/Block.lua ObjectiveTracker/BonusObjectiveData.lua ObjectiveTracker/BonusObjectives.lua ObjectiveTracker/Data.lua ObjectiveTracker/DefaultTracker.lua ObjectiveTracker/Layout.lua ObjectiveTracker/ObjectiveTracker.xml ObjectiveTracker/QuestData.lua ObjectiveTracker/Quests.lua ObjectiveTracker/ScenarioData.lua ObjectiveTracker/Scenarios.lua ObjectiveTracker/TrackerBlock.lua ObjectiveTracker/TrackerFrame.lua ObjectiveTracker/Update.lua ObjectiveTracker/Widgets.lua |
diffstat | 19 files changed, 2409 insertions(+), 2385 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/AchievementData.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,206 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/13/2016 7:48 PM +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local band = bit.band +local RemoveTrackedAchievement, GetAchievementLink = RemoveTrackedAchievement, GetAchievementLink +local AchievementFrame_ToggleAchievementFrame, AchievementFrame_SelectAchievement = AchievementFrame_ToggleAchievementFrame, AchievementFrame_SelectAchievement +local GetTime, GetAchievementNumCriteria, GetAchievementCriteriaInfo = GetTime, GetAchievementNumCriteria, GetAchievementCriteriaInfo +local GetNumTrackedAchievements, GetTrackedAchievements, GetAchievementInfo = GetNumTrackedAchievements, GetTrackedAchievements, GetAchievementInfo +local Default, Cheevs = T.DefaultHandler, T.Cheevs +local wipe = table.wipe +local print, bprint, lprint, iprint = B.print('Tracker'), B.print('Block'), B.print('Line'), B.print('iprint') + +--- Frame data +Cheevs.UpdateObjectives = function(handler, block, block_schema) + -- if completed on another character, only show the heading for CHATLINK + if block.info.completed then + return 0, block_schema + end + + if block.info.description then + handler:AddLine(block, block.info.description, nil, 'defalut') + end + local attachments = Default.UpdateObjectives(handler, block, block_schema) + + return attachments, block_schema +end + +Cheevs.UpdateLine = function(handler, block, data) + local print = lprint + local attachment + local text + local lineSchema = 'default' + print(' ', data.objectiveIndex,'|cFF'..handler.internalColor..'-|r', data.objectiveType, data.text) + if data.type == CRITERIA_TYPE_ACHIEVEMENT then + if data.value == 1 then + return nil, nil + end + + text = data.text + lineSchema = (data.quantity == 1) and 'achievement_complete' or 'achievement' + elseif band(data.flags, 0x00000001) > 0 then + attachment = T.GetWidget(data, 'StatusBar', data.criteriaID) + attachment.format = "%d/%d" + attachment.value = data.value + attachment.maxValue = data.maxValue + attachment:SetParent(block) + + print(attachment:GetNumPoints()) + for i = 1, attachment:GetNumPoints() do + print(' ',attachment:GetPoint(i)) + end + attachment.status:SetFormattedText("%d/%d", data.value, data.maxValue) + attachment:SetPoint('TOP', line, 'TOP') + lineSchema = 'progressbar' + else + + text = format("%d/%d %s", data.value, data.maxValue, data.text) + lineSchema = 'default' + end + print(' |cFF'..handler.internalColor..'UpdateLine:|r', data.type, data.quantityString, 'qty:', data.quantity, 'assetID:', data.assetID) + return text, attachment, lineSchema +end + +Cheevs.Select = function(self, block) + Cheevs.Link(self, block) + T:Update(self.updateReasonModule, block.info.cheevID) +end + +Cheevs.Remove = function(self, block) + + RemoveTrackedAchievement(block.info.cheevID) +end +Cheevs.OnMouseUp = function(self, button) + + Default.OnMouseUp(self, button) +end +Cheevs.Link = function(self, block) + local achievementLink = GetAchievementLink(block.info.cheevID); + if ( achievementLink ) then + _G.ChatEdit_InsertLink(achievementLink); + end +end + +--- Data accessors +Cheevs.GetNumWatched = function(self, targetID, isNew) + local trackedList = {GetTrackedAchievements() } + local numWatched, numAll = #trackedList, #self.WatchList + print(' |cFF'..self.internalColor..'GetNumWatched:|r',self.name, numWatched, ' ('..numAll..' recorded)') + local start = 1 + local limit = max(numAll, #trackedList) + if targetID then + if not isNew and self.Info[targetID] then + -- if it's only an update, we can limit the scope + start = self.Info[targetID].watchIndex + print(' |cFF'..self.internalColor..'GetNumWatched: limit selection to['..start..'-'..limit..']') + if self.InfoBlock[targetID] then + self.InfoBlock[targetID]:Hide() + end + + end + end + + for index = start, limit do + if index > numWatched then + self.WatchList[index] = nil + print(' % dropping watch entry #'..index) + else + local cheevID = trackedList[index] + if not self.Info[cheevID] then + self.Info[cheevID] = self:GetInfo(cheevID, index) + else + print(' |cFF'..self.internalColor..'GetInfo:', cheevID, 'already pulled') + end + self:GetObjectives(cheevID) + + local info = self.Info[cheevID] + local watchBlock = self.WatchBlock[cheevID] + + self.Info[cheevID].watchIndex = index + self.WatchList[index] = info + end + end + + numAll = #self.WatchList + return numWatched, numAll, self.WatchList +end +Cheevs.GetInfo = function(self, cheevID, watchIndex) + --- step 1: confirm primary data and begin an entry if needed + local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy = GetAchievementInfo(cheevID) + if not id then return nil end + + print(' |cFF'..self.internalColor..'GetInfo: pulling', id..',', name, earnedBy) + + + self.Info[cheevID] = self.Info[cheevID] or {} + local c = self.Info[cheevID] + local rewards = {} + + c.schema = 'achievement' + c.rewardInfo = rewards + c.type = 'Cheevs' + c.title = name + c.points = points + c.completed = completed + c.month = month + c.day = day + c.year = year + c.description = description + c.flags = flags + c.icon = icon + c.rewardText = rewardText + c.isGuildAch = isGuildAch + c.wasEarnedByMe = wasEarnedByMe + c.earnedBy = earnedBy + + local tagInfo = {} + c.tagInfo = tagInfo + c.watchIndex = watchIndex + c.id = cheevID + c.cheevID = cheevID + + self.Info[cheevID] = c + self.WatchInfo[watchIndex] = c + return c +end + +Cheevs.GetObjectives = function(self, cheevID) + local c = self.Info[cheevID] + c.numObjectives = GetAchievementNumCriteria(cheevID) + c.objectives = c.objectives or {} + for i = 1, c.numObjectives do + local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i) + local line = c.objectives[i] or {} + line.objectiveIndex = i + line.cheevID = cheevID + line.text = description + line.type = type + line.finished = completed + line.value = quantity + line.maxValue = requiredQuantity + line.characterName = characterName + line.flags = flags + line.assetID = assetID + line.quantityString = quantityString + line.criteriaID = criteriaID + c.objectives[i] = line + + print(' |cFF'..self.internalColor..'GetObjectives:|r', i, format('|cFF0088FF%02X|r(%d)', type, type), format('|cFF88FF00%01X|r', flags or 0), '|cFF00FF00'..tostring(quantity)..'|r/|cFF00FF00'.. tostring(requiredQuantity)..'|r', '"|cFF88FF00'..tostring(description)..'|r"') + end +end + + +Cheevs.Open = function(self, block) + + if ( not _G.AchievementFrame ) then + _G.AchievementFrame_LoadUI(); + end + if ( not _G.AchievementFrame:IsShown() ) then + _G.AchievementFrame_ToggleAchievementFrame(); + end + _G.AchievementFrame_SelectAchievement(block.info.cheevID); +end
--- a/ObjectiveTracker/Achievements.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/13/2016 7:48 PM -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local band = bit.band -local RemoveTrackedAchievement, GetAchievementLink = RemoveTrackedAchievement, GetAchievementLink -local AchievementFrame_ToggleAchievementFrame, AchievementFrame_SelectAchievement = AchievementFrame_ToggleAchievementFrame, AchievementFrame_SelectAchievement -local GetTime, GetAchievementNumCriteria, GetAchievementCriteriaInfo = GetTime, GetAchievementNumCriteria, GetAchievementCriteriaInfo -local GetNumTrackedAchievements, GetTrackedAchievements, GetAchievementInfo = GetNumTrackedAchievements, GetTrackedAchievements, GetAchievementInfo -local Default, Cheevs = T.DefaultHandler, T.Cheevs -local wipe = table.wipe -local print, bprint, lprint, iprint = B.print('Tracker'), B.print('Block'), B.print('Line'), B.print('iprint') - ---- Frame data -Cheevs.UpdateObjectives = function(handler, block, block_schema) - -- if completed on another character, only show the heading for CHATLINK - if block.info.completed then - return 0, block_schema - end - - if block.info.description then - handler:AddLine(block, block.info.description, nil, 'defalut') - end - local attachments = Default.UpdateObjectives(handler, block, block_schema) - - return attachments, block_schema -end - -Cheevs.UpdateLine = function(handler, block, data) - local print = lprint - local attachment - local text - local lineSchema = 'default' - print(' ', data.objectiveIndex,'|cFF'..handler.internalColor..'-|r', data.objectiveType, data.text) - if data.type == CRITERIA_TYPE_ACHIEVEMENT then - if data.value == 1 then - return nil, nil - end - - text = data.text - lineSchema = (data.quantity == 1) and 'achievement_complete' or 'achievement' - elseif band(data.flags, 0x00000001) > 0 then - attachment = T.GetWidget(data, 'StatusBar', data.criteriaID) - attachment.format = "%d/%d" - attachment.value = data.value - attachment.maxValue = data.maxValue - attachment:SetParent(block) - - print(attachment:GetNumPoints()) - for i = 1, attachment:GetNumPoints() do - print(' ',attachment:GetPoint(i)) - end - attachment.status:SetFormattedText("%d/%d", data.value, data.maxValue) - attachment:SetPoint('TOP', line, 'TOP') - lineSchema = 'progressbar' - else - - text = format("%d/%d %s", data.value, data.maxValue, data.text) - lineSchema = 'default' - end - print(' |cFF'..handler.internalColor..'UpdateLine:|r', data.type, data.quantityString, 'qty:', data.quantity, 'assetID:', data.assetID) - return text, attachment, lineSchema -end - -Cheevs.Select = function(self, block) - Cheevs.Link(self, block) - T:Update(self.updateReasonModule, block.info.cheevID) -end - -Cheevs.Remove = function(self, block) - - RemoveTrackedAchievement(block.info.cheevID) -end -Cheevs.OnMouseUp = function(self, button) - - Default.OnMouseUp(self, button) -end -Cheevs.Link = function(self, block) - local achievementLink = GetAchievementLink(block.info.cheevID); - if ( achievementLink ) then - _G.ChatEdit_InsertLink(achievementLink); - end -end - ---- Data accessors -Cheevs.GetNumWatched = function(self, targetID, isNew) - local trackedList = {GetTrackedAchievements() } - local numWatched, numAll = #trackedList, #self.WatchList - print(' |cFF'..self.internalColor..'GetNumWatched:|r',self.name, numWatched, ' ('..numAll..' recorded)') - local start = 1 - local limit = max(numAll, #trackedList) - if targetID then - if not isNew and self.Info[targetID] then - -- if it's only an update, we can limit the scope - start = self.Info[targetID].watchIndex - print(' |cFF'..self.internalColor..'GetNumWatched: limit selection to['..start..'-'..limit..']') - if self.InfoBlock[targetID] then - self.InfoBlock[targetID]:Hide() - end - - end - end - - for index = start, limit do - if index > numWatched then - self.WatchList[index] = nil - print(' % dropping watch entry #'..index) - else - local cheevID = trackedList[index] - if not self.Info[cheevID] then - self.Info[cheevID] = self:GetInfo(cheevID, index) - else - print(' |cFF'..self.internalColor..'GetInfo:', cheevID, 'already pulled') - end - self:GetObjectives(cheevID) - - local info = self.Info[cheevID] - local watchBlock = self.WatchBlock[cheevID] - - self.Info[cheevID].watchIndex = index - self.WatchList[index] = info - end - end - - numAll = #self.WatchList - return numWatched, numAll, self.WatchList -end -Cheevs.GetInfo = function(self, cheevID, watchIndex) - --- step 1: confirm primary data and begin an entry if needed - local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy = GetAchievementInfo(cheevID) - if not id then return nil end - - print(' |cFF'..self.internalColor..'GetInfo: pulling', id..',', name, earnedBy) - - - self.Info[cheevID] = self.Info[cheevID] or {} - local c = self.Info[cheevID] - local rewards = {} - - c.schema = 'achievement' - c.rewardInfo = rewards - c.type = 'Cheevs' - c.title = name - c.points = points - c.completed = completed - c.month = month - c.day = day - c.year = year - c.description = description - c.flags = flags - c.icon = icon - c.rewardText = rewardText - c.isGuildAch = isGuildAch - c.wasEarnedByMe = wasEarnedByMe - c.earnedBy = earnedBy - - local tagInfo = {} - c.tagInfo = tagInfo - c.watchIndex = watchIndex - c.id = cheevID - c.cheevID = cheevID - - self.Info[cheevID] = c - self.WatchInfo[watchIndex] = c - return c -end - -Cheevs.GetObjectives = function(self, cheevID) - local c = self.Info[cheevID] - c.numObjectives = GetAchievementNumCriteria(cheevID) - c.objectives = c.objectives or {} - for i = 1, c.numObjectives do - local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i) - local line = c.objectives[i] or {} - line.objectiveIndex = i - line.cheevID = cheevID - line.text = description - line.type = type - line.finished = completed - line.value = quantity - line.maxValue = requiredQuantity - line.characterName = characterName - line.flags = flags - line.assetID = assetID - line.quantityString = quantityString - line.criteriaID = criteriaID - c.objectives[i] = line - - print(' |cFF'..self.internalColor..'GetObjectives:|r', i, format('|cFF0088FF%02X|r(%d)', type, type), format('|cFF88FF00%01X|r', flags or 0), '|cFF00FF00'..tostring(quantity)..'|r/|cFF00FF00'.. tostring(requiredQuantity)..'|r', '"|cFF88FF00'..tostring(description)..'|r"') - end -end - - -Cheevs.Open = function(self, block) - - if ( not _G.AchievementFrame ) then - _G.AchievementFrame_LoadUI(); - end - if ( not _G.AchievementFrame:IsShown() ) then - _G.AchievementFrame_ToggleAchievementFrame(); - end - _G.AchievementFrame_SelectAchievement(block.info.cheevID); -end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/AutoQuestPopupData.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,63 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/13/2016 7:49 PM +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local print = B.print('Info') +local lprint = B.print('Line') +local AutoQuest, Quest = T.AutoQuest, T.Quest +local ShowQuestOffer, ShowQuestComplete, RemoveAutoQuestPopUp = ShowQuestOffer, ShowQuestComplete, RemoveAutoQuestPopUp +local GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetQuestLogIndexByID, GetQuestLogTitle = GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetQuestLogIndexByID, GetQuestLogTitle +--- Data retrieval +function AutoQuest:GetNumWatched () + if true then return 0, 0, nil end + 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.questID = questID + popup.id = questID + popup.title = title + popup.description = type + popup.popupType = type + popup.logIndex = questLogIndex + popup.popupIndex = popupIndex + + self.Info[questID] = popup + self.WatchInfo[popupIndex] = popup + + + return self.Info[questID] +end + +AutoQuest.UpdateObjectives = function(handler, block) + local print = lprint + if block.info.type == 'OFFER' then + block.status:SetText(T.strings.CLICK_TO_ACCEPT) + end +end + +AutoQuest.Select = function(handler, block) + + if block.info.popupType == 'OFFER' then + ShowQuestOffer(block.info.logIndex) + else + ShowQuestComplete(block.info.logIndex) + end + RemoveAutoQuestPopUp(block.info.questID) +end + +AutoQuest.Link = T.Quest.Link
--- a/ObjectiveTracker/AutoQuestPopups.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/13/2016 7:49 PM -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local print = B.print('Info') -local lprint = B.print('Line') -local AutoQuest, Quest = T.AutoQuest, T.Quest -local ShowQuestOffer, ShowQuestComplete, RemoveAutoQuestPopUp = ShowQuestOffer, ShowQuestComplete, RemoveAutoQuestPopUp -local GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetQuestLogIndexByID, GetQuestLogTitle = GetNumAutoQuestPopUps, GetAutoQuestPopUp, GetQuestLogIndexByID, GetQuestLogTitle ---- Data retrieval -function AutoQuest:GetNumWatched () - if true then return 0, 0, nil end - 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.questID = questID - popup.id = questID - popup.title = title - popup.description = type - popup.popupType = type - popup.logIndex = questLogIndex - popup.popupIndex = popupIndex - - self.Info[questID] = popup - self.WatchInfo[popupIndex] = popup - - - return self.Info[questID] -end - -AutoQuest.UpdateObjectives = function(handler, block) - local print = lprint - if block.info.type == 'OFFER' then - block.status:SetText(T.strings.CLICK_TO_ACCEPT) - end -end - -AutoQuest.Select = function(handler, block) - - if block.info.popupType == 'OFFER' then - ShowQuestOffer(block.info.logIndex) - else - ShowQuestComplete(block.info.logIndex) - end - RemoveAutoQuestPopUp(block.info.questID) -end - -AutoQuest.Link = T.Quest.Link
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/Block.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,191 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/24/2016 11:30 AM +--- These functions deal with propagating and managing block/line templates +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local _G, ipairs, max, tostring = _G, ipairs, max, tostring +local tinsert, tremove, tContains = table.insert, table.remove, tContains +local Default = T.DefaultHandler +local CreateFrame = CreateFrame +local print = B.print('Layout') +local bprint = B.print('Block') +local lprint = B.print('Layout') +local fprint = B.print('Frame') +local used, free + +local blockFadeOut_OnPlay = function(self) + fprint(self:GetName(), '|cFF00FF00PLAY|r', debugstack(1,3,1)) +end +local blockFadeOut_OnFinished = function(self) + fprint(self:GetName(), '|cFF00FF00FINISHED|r', debugstack(1,3, 1)) +end + +local tMove = function(source, dest, frame) + -- if it's already in the stack, sanity check source stack + local removed + if tContains(dest, frame) then + for i, entry in ipairs(source) do + if entry == frame then + removed = i + tremove(source, i) + break + end + end + -- still need to resolve position + for i, entry in ipairs(dest) do + if entry == frame then + bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. i..']') + return i + end + end + else + -- if it's not, then pull from source stack + for i, entry in ipairs(source) do + if entry == frame then + removed = i + tremove(source, i) + break + end + end + tinsert(dest, frame) + bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. #dest..']') + return #dest + end +end + + +--- Creates or retrieves a complete line data object +function Default:GetLine (block, lineIndex) + local print = lprint + local blockIndex = block.index + local lines = block.lines + if not lineIndex then + lineIndex = block.currentLine + 1 + print(' |cFFFFFF00generating a frame') + end + + block.numLines = max(block.numLines, lineIndex) + + if not lines[lineIndex] then + print(' |cFF00FF88created line #'..lineIndex..' from for '..self.name..' block #'..blockIndex) + lines[lineIndex] = CreateFrame('Frame', 'Vn'..self.name .. blockIndex..'ObjectiveLine'..lineIndex, block, 'VeneerTrackerObjective') + local line = lines[lineIndex] + line.index = lineIndex + line.height = 0 + line.schema = '' + B.SetConfigLayers(line) + + if debug then + for _, region in ipairs(lines[lineIndex].debug) do + region:Show() + end + end + + end + return lines[lineIndex] +end + + + +--- Creates or retrieves a complete block frame object +--- todo: make it use data index to avoid re-coloring every block +function Default:GetBlock (index) + local print = bprint + print('|cFF0088FF'..self.name..':GetBlock', index) + local block = self.InfoBlock[index] + local used = self.usedBlocks + local free = self.freeBlocks + + if block then + print(block.info.id, index) + end + + -- if the frame entry is still good, sort heaps + if block and block.info.id == index then + block.posIndex = tMove(free, used, block) + print(' |cFFFFFF00using '..self.name..'|r.|cFF00FFBBusedBlocks['..tostring(block.posIndex)..'] ('.. block:GetName()..', "'..tostring(block.info.title)..'")') + else + local source = 'cache' + if #self.freeBlocks >= 1 then + block = tremove(self.freeBlocks) + print(' |cFF00FF00 assigning from free heap', block:GetName()) + else + + local blockIndex = (#self.usedBlocks + #self.freeBlocks) + 1 + block = CreateFrame('Frame', 'Veneer'..tostring(self)..'Block'..blockIndex, self.frame, 'VeneerTrackerBlock') + --block:SetParent() + block.schema = '' + block.lines = {} + block.numLines = 0 + block.currentLine = 0 + block.attachmentHeight = 0 + block.offset = 0 + B.SetConfigLayers(block) + --- methods for event handlers + block.Select = self.Select + block.Open = self.Open + block.Remove = self.Remove + block.Link = self.Link + block.clickZone:SetScript('OnMouseUp', function(frame, ...) self.OnMouseUp(block, ...) end) + block.clickZone:SetScript('OnMouseDown', function(frame, ...) self.OnMouseDown(block, ...) end) + block:ClearAllPoints() + block.index = blockIndex + block.blockFadeOut:SetScript('OnPlay', blockFadeOut_OnPlay) + source = 'new' + end + self.InfoBlock[index] = block + block.posIndex = tMove(free, used, block) + print(' |cFF00FF00('..source..')|r |cFF0088FF'..self.name..'|r.|cFF00FFBBusedBlocks['..block.posIndex..'] =|r', block:GetName()) + end + block.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished) + block:SetScript('OnHide', function(self) + fprint(self:GetName(), '|cFF00FF00HIDE|r', debugstack(1,3,1)) + if(self.DebugTab:IsShown()) then + self.DebugTab:Hide() + end + self.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished) + self.isAnimating = nil + end) + print(' used/free: |cFFFFFF00' .. #self.usedBlocks .. '|r/|cFF00FFFF'..#self.freeBlocks ..'|r') + return block +end + +--- begins a blockFadeOut animation and fires FreeBlock when that's done +function Default:ClearBlock (block) + -- double ensure multiple finish scripts from firing + if block.isAnimating then + return + end + block.isAnimating = true + block.blockFadeOut:SetScript('OnFinished', nil) + block.blockFadeOut:SetScript('OnFinished', function(anim) + --@debug@ + fprint(anim:GetName(), '|cFFFFFF00FINISHED|r', debugstack())--@end-debug@ + anim:SetScript('OnFinished', blockFadeOut_OnFinished) + self:FreeBlock(block) + block.isAnimating = nil + end) + block.blockFadeOut:Play() +end + +--- fired by OnFinished scripts; does the actual table swapping +function Default:FreeBlock(block) + bprint('|cFFFF4400FreeBlock|r', block:GetName()) + local used = self.usedBlocks + local free = self.freeBlocks + tMove(used, free, block) + + bprint(' |cFFFF4444used/free:|r |cFFFFFF00' .. #used .. '|r/|cFF00FFFF'..#free ..'|r') + + block:Hide() + local animations = {block:GetAnimationGroups() } + for i, animGroup in ipairs(animations) do + bprint(' animGroup', i, animGroup:GetName()) + animGroup:Stop() + end + + T:Update(self.updateReasonsModule) +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/BonusObjectiveData.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,311 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/13/2016 7:48 PM +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local Default, Quest = T.DefaultHandler, T.Quest +local print = B.print('Tracker') +local lprint = B.print('Line') +local iprint = B.print('Info') +local Bonus = T.Bonus + +local UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo = UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo +local GetMapNameByID, GetCurrentMapAreaID = GetMapNameByID, GetCurrentMapAreaID +local tinsert, ipairs, pairs, tostring, wipe = tinsert, ipairs, pairs, tostring, table.wipe +local GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime = GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime +local TASK_DISPLAY_TEST = 1 -- 1: normal (is nearby or on the map) 2: strict (is nearby) 3: data exists + +--- Holds data for recently completed tasks +local completedTasks = {} + +--- Returns a tasks table modified to include recently completed objectives +local InternalGetTasksTable = function() + local print = Bonus.print + local char = UnitName("player") + local realm = GetRealmName() + local tasks = GetTasksTable() + + for questID, data in pairs(Bonus.Info) do + print('GetTasksTable', questID, #data.objectives) + for i, o in ipairs(data.objectives) do + print('GetTasksTable', questID, i, o.text) + end + end + + for questID, data in pairs(completedTasks) 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) + if completedTasks[questID] then + -- if it's a recently completed task, use the information stored for it + 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) + 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 = {} + +local function CanShowTask(isInArea, isOnMap, existingTask, numObjectives) + if TASK_DISPLAY_TEST == 1 then + return (isInArea) + elseif TASK_DISPLAY_TEST == 2 then + return (isInArea and(isOnMap and existingTask)) + elseif TASK_DISPLAY_TEST == 3 then + return true + end +end + +function Bonus:GetNumWatched () + + local print = self.print + print(self.name, self) + + local tasks = InternalGetTasksTable() + local numWatched = 0 + local numAll = 0 + local existingTasks = {} + wipe(self.WatchList) + print('|cFF'..self.internalColor..'Bonus.GetNumWatched()|r', #tasks) + print('InternalGetTaskInfo') + + for i, questID in ipairs(tasks) do + local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(questID) + local existingTask = self.InfoBlock[questID] + local displayObjectiveHeader = false; + local displayTask = CanShowTask(isInArea, isOnMap, existingTask) + if displayTask then + print('TaskInfo', '|cFF00FF00showable objective list', questID) + self.Info[questID] = self.Info[questID] or {} + + local t = self.Info[questID] + if (isOnMap or isInArea) and existingTask then + t.areaID = GetCurrentMapAreaID() + local _ + t.mapName, _, _, t.isMicroDungeon, t.microDungeonMapName = GetMapInfo() + print('InternalGetTaskInfo', 'map data', t.areaID, t.mapName) + end + + local taskTitle + t.id = questID + t.objectives = {} + local isComplete = 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('TaskObjective', text, objectiveType, finished, displayAsObjective) + t.objectives[objectiveIndex] = t.objectives[objectiveIndex] or {} + local o = t.objectives[objectiveIndex] + + o.index = objectiveIndex + o.text = text + o.type = objectiveType + o.finished = finished + o.displayAsObjective = displayAsObjective + isComplete = (isComplete and finished) + end + + T.SetRewards(t, questID) + + -- 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.numObjectives = numObjectives + t.isInArea = isInArea + t.isOnMap = isOnMap + t.existingTask = existingTask + t.questID = questID + t.id = questID + t.taskIndex = i + t.title = taskTitle + t.isComplete = isComplete + self.WatchList[i] = t + elseif existingTask then + print('TaskInfo', '|cFFFF4400hideable task', questID) + existingTask:Hide() + end + + + 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')) + end + + + self.numWatched = #self.WatchList + self.numAll = #existingTasks + return self.numWatched, self.numWatched, self.WatchList +end + +Bonus.OnEvent = function(block, event, ...) + if event == 'QUEST_LOG_UPDATE' then + local info = block.info + + local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(info.questID) + if not CanShowTask(isInArea, isOnMap, block, numObjectives) then + block:Hide() + end + end +end + +Bonus.GetBlock = function(self, index) + local block = Default.GetBlock(self, index) + block:SetScript('OnEvent', self.OnEvent) + block:RegisterEvent('QUEST_LOG_UPDATE') + return block +end + +--- info cleanup done when turn-ins are detected +Bonus.OnTurnIn = function(self, block, questID, xp, money) + --[=[ + local info = self.Info[questID] + if info.rewardInfo and #info.rewardInfo >= 1 then + for i, reward in ipairs(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'..block:GetName()..':OnTurnIn call', questID, xp, money) + local savedTasks = B.Conf.TasksLog or {} + + info.completedTime = GetTime() + info.animate = true + T.SetAnimate(self.updateReasonModule) + savedTasks[questID] = { + id = questID, + title = info.title, + finished = true, + numObjectives = info.numObjectives, + objectives = info.objectives, + rewardInfo = info.rewardInfo, + } + B.Conf.TasksLog = savedTasks + + print(' ## CONF TASKLOG ##') + for i, t in pairs(savedTasks[questID]) do + print(' |cFFFFFF00'.. tostring(i)..'|r', t) + + end + for o, j in ipairs(savedTasks[questID].objectives) do + print(' |cFF00FFFF#'.. o ..'|r', j.type, j.finished) + end + + print('adding', info.title, 'to cache') + --]=] +end + +Bonus.GetInfo = function(self, taskIndex) + print(self.name, self) + return self.WatchInfo[taskIndex] +end + + + +--- Update hooks +Bonus.UpdateObjectives = function(handler, block, blockSchema) + block.schema = blockSchema or 'default' + local info = block.info + block.title:SetText(info.title) + + + Default.UpdateObjectives(handler, block) + return blockSchema +end + +Bonus.UpdateLine = function(handler, block, data) + local info = block.info + local print = lprint + local text, attachment = '', nil + if data.type == 'progressbar' then + print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) + local percent = 100 + if not data.finished then + percent = GetQuestProgressBarPercent(info.questID) + end + data.value = percent + data.maxValue = 100 + + attachment = T.GetWidget(data, 'StatusBar', info.questID..'-'..data.index) + attachment:SetParent(block) + print(attachment:GetNumPoints()) + for i = 1, attachment:GetNumPoints() do + print(' ',attachment:GetPoint(i)) + end + + attachment.value = percent + attachment.maxValue = 100 + attachment.status:SetFormattedText(PERCENTAGE_STRING, percent) + --attachment:SetParent(handler.frame) + --print(attachment.status:GetText()) + print(' |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue) + end + text = data.text + return text, attachment, 'default' +end + +Bonus.Select = function(handler, block) + print(handler, block) + handler:OnTurnIn(block, block.info.questID) +end +Bonus.Remove = function(self) + +end \ No newline at end of file
--- a/ObjectiveTracker/BonusObjectives.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,311 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/13/2016 7:48 PM -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local Default, Quest = T.DefaultHandler, T.Quest -local print = B.print('Tracker') -local lprint = B.print('Line') -local iprint = B.print('Info') -local Bonus = T.Bonus - -local UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo = UnitName, GetRealmName, GetQuestObjectiveInfo, GetTasksTable, GetTaskInfo -local GetMapNameByID, GetCurrentMapAreaID = GetMapNameByID, GetCurrentMapAreaID -local tinsert, ipairs, pairs, tostring, wipe = tinsert, ipairs, pairs, tostring, table.wipe -local GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime = GetQuestProgressBarPercent, PERCENTAGE_STRING, GetTime -local TASK_DISPLAY_TEST = 1 -- 1: normal (is nearby or on the map) 2: strict (is nearby) 3: data exists - ---- Holds data for recently completed tasks -local completedTasks = {} - ---- Returns a tasks table modified to include recently completed objectives -local InternalGetTasksTable = function() - local print = Bonus.print - local char = UnitName("player") - local realm = GetRealmName() - local tasks = GetTasksTable() - - for questID, data in pairs(Bonus.Info) do - print('GetTasksTable', questID, #data.objectives) - for i, o in ipairs(data.objectives) do - print('GetTasksTable', questID, i, o.text) - end - end - - for questID, data in pairs(completedTasks) 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) - if completedTasks[questID] then - -- if it's a recently completed task, use the information stored for it - 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) - 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 = {} - -local function CanShowTask(isInArea, isOnMap, existingTask, numObjectives) - if TASK_DISPLAY_TEST == 1 then - return (isInArea) - elseif TASK_DISPLAY_TEST == 2 then - return (isInArea and(isOnMap and existingTask)) - elseif TASK_DISPLAY_TEST == 3 then - return true - end -end - -function Bonus:GetNumWatched () - - local print = self.print - print(self.name, self) - - local tasks = InternalGetTasksTable() - local numWatched = 0 - local numAll = 0 - local existingTasks = {} - wipe(self.WatchList) - print('|cFF'..self.internalColor..'Bonus.GetNumWatched()|r', #tasks) - print('InternalGetTaskInfo') - - for i, questID in ipairs(tasks) do - local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(questID) - local existingTask = self.InfoBlock[questID] - local displayObjectiveHeader = false; - local displayTask = CanShowTask(isInArea, isOnMap, existingTask) - if displayTask then - print('TaskInfo', '|cFF00FF00showable objective list', questID) - self.Info[questID] = self.Info[questID] or {} - - local t = self.Info[questID] - if (isOnMap or isInArea) and existingTask then - t.areaID = GetCurrentMapAreaID() - local _ - t.mapName, _, _, t.isMicroDungeon, t.microDungeonMapName = GetMapInfo() - print('InternalGetTaskInfo', 'map data', t.areaID, t.mapName) - end - - local taskTitle - t.id = questID - t.objectives = {} - local isComplete = 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('TaskObjective', text, objectiveType, finished, displayAsObjective) - t.objectives[objectiveIndex] = t.objectives[objectiveIndex] or {} - local o = t.objectives[objectiveIndex] - - o.index = objectiveIndex - o.text = text - o.type = objectiveType - o.finished = finished - o.displayAsObjective = displayAsObjective - isComplete = (isComplete and finished) - end - - T.SetRewards(t, questID) - - -- 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.numObjectives = numObjectives - t.isInArea = isInArea - t.isOnMap = isOnMap - t.existingTask = existingTask - t.questID = questID - t.id = questID - t.taskIndex = i - t.title = taskTitle - t.isComplete = isComplete - self.WatchList[i] = t - elseif existingTask then - print('TaskInfo', '|cFFFF4400hideable task', questID) - existingTask:Hide() - end - - - 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')) - end - - - self.numWatched = #self.WatchList - self.numAll = #existingTasks - return self.numWatched, self.numWatched, self.WatchList -end - -Bonus.OnEvent = function(block, event, ...) - if event == 'QUEST_LOG_UPDATE' then - local info = block.info - - local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(info.questID) - if not CanShowTask(isInArea, isOnMap, block, numObjectives) then - block:Hide() - end - end -end - -Bonus.GetBlock = function(self, index) - local block = Default.GetBlock(self, index) - block:SetScript('OnEvent', self.OnEvent) - block:RegisterEvent('QUEST_LOG_UPDATE') - return block -end - ---- info cleanup done when turn-ins are detected -Bonus.OnTurnIn = function(self, block, questID, xp, money) - --[=[ - local info = self.Info[questID] - if info.rewardInfo and #info.rewardInfo >= 1 then - for i, reward in ipairs(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'..block:GetName()..':OnTurnIn call', questID, xp, money) - local savedTasks = B.Conf.TasksLog or {} - - info.completedTime = GetTime() - info.animate = true - T.SetAnimate(self.updateReasonModule) - savedTasks[questID] = { - id = questID, - title = info.title, - finished = true, - numObjectives = info.numObjectives, - objectives = info.objectives, - rewardInfo = info.rewardInfo, - } - B.Conf.TasksLog = savedTasks - - print(' ## CONF TASKLOG ##') - for i, t in pairs(savedTasks[questID]) do - print(' |cFFFFFF00'.. tostring(i)..'|r', t) - - end - for o, j in ipairs(savedTasks[questID].objectives) do - print(' |cFF00FFFF#'.. o ..'|r', j.type, j.finished) - end - - print('adding', info.title, 'to cache') - --]=] -end - -Bonus.GetInfo = function(self, taskIndex) - print(self.name, self) - return self.WatchInfo[taskIndex] -end - - - ---- Update hooks -Bonus.UpdateObjectives = function(handler, block, blockSchema) - block.schema = blockSchema or 'default' - local info = block.info - block.title:SetText(info.title) - - - Default.UpdateObjectives(handler, block) - return blockSchema -end - -Bonus.UpdateLine = function(handler, block, data) - local info = block.info - local print = lprint - local text, attachment = '', nil - if data.type == 'progressbar' then - print(' |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID))) - local percent = 100 - if not data.finished then - percent = GetQuestProgressBarPercent(info.questID) - end - data.value = percent - data.maxValue = 100 - - attachment = T.GetWidget(data, 'StatusBar', info.questID..'-'..data.index) - attachment:SetParent(block) - print(attachment:GetNumPoints()) - for i = 1, attachment:GetNumPoints() do - print(' ',attachment:GetPoint(i)) - end - - attachment.value = percent - attachment.maxValue = 100 - attachment.status:SetFormattedText(PERCENTAGE_STRING, percent) - --attachment:SetParent(handler.frame) - --print(attachment.status:GetText()) - print(' |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue) - end - text = data.text - return text, attachment, 'default' -end - -Bonus.Select = function(handler, block) - print(handler, block) - handler:OnTurnIn(block, block.info.questID) -end -Bonus.Remove = function(self) - -end \ No newline at end of file
--- a/ObjectiveTracker/Data.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -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 --------------------------------------------------------------------- - - - - ------------------------------ ---- AUTO_QUEST ------------------------------ ---- 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. -
--- a/ObjectiveTracker/DefaultTracker.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,277 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/17/2016 7:33 AM ---- Baseline update work -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local Devian = Devian -local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band -local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove -local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent -local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText -local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent -local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs -local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame -local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow -local print = B.print('Tracker') -local oprint = B.print('Objectives') -local bprint = B.print('Block') -local tprint = B.print('Tracker') -local lprint = B.print('Line') -local unitLevel = 1 -local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON -local debug = false - ---- FRAMES -local Wrapper = _G.VeneerObjectiveWrapper -local Scroller = Wrapper.scrollArea -local Scroll = _G.VeneerObjectiveScroll -local orderedHandlers = T.orderedHandlers -local orderedNames = T.orderedNames - - ---- Placing the Update functions here since they shouldn't be messing with schema stuff -local currentPosition, anchorFrame, anchorPoint ---- Positioning and stuff -local tick = 0 -local initReason = OBJECTIVE_TRACKER_UPDATE_ALL -local requiresInit -function T:Update (reason, ...) - if not B.Conf.VeneerObjectiveWrapper.enabled then - return - end - tick = tick + 1 - local print = tprint - local hasStuff = false - local insertingStuff = false - - if initReason then - reason = initReason - initReason = nil - elseif not reason then - reason = OBJECTIVE_TRACKER_UPDATE_ALL - end - print(format('|cFFBB0066Update:|r |cFFFF%04X%d|r ', tick, lshift(reason, 4)), reason, ...) - currentPosition = 0 - - for id, handler in pairs(T.orderedHandlers) do - local frame = handler.frame - - print('') - if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then - insertingStuff = handler:UpdateTracker(reason, ...) - else - print(' |cFFFF4400Update:|r skipping',handler.name) - end - - if handler.numWatched >= 1 then - hasStuff = true - currentPosition = currentPosition + 1 - Default.AddTracker(handler, frame, currentPosition) - frame.wasEmpty = nil - else - frame.destinationOffset = 0 - if not frame.wasEmpty and not frame.fadeOut:IsPlaying() then - frame.fadeOut:Play() - end - frame.wasEmpty = true - end - end - - -- do these whenever there is content or content is being added - if hasStuff or insertingStuff then - T:FinishWrapper() - end - Quest.GetClosest() - --T.UpdateActionButtons(reason) -end - -Default.UpdateTracker = function (handler, reason, id, isNew) - local print = handler.print - local frame = handler.frame - local blockIndex = 0 - print('MODULE:'..handler.name, 'message:', reason, 'id:', id, (isNew and '|cFF88FF88' or '|cFF555555')..'isNew|r') - handler.updateReason = reason - local numWatched, numAll, watchTable = handler:GetNumWatched(id, isNew) - - if numWatched >= 1 then - if watchTable then - print(' WatchList', ' n ID Obj wID Log Blk') - for i, w in ipairs(watchTable) do - print(' WatchList', format('%2d => %6d %3d %3d %3s %s', i, w.id, w.numObjectives, w.watchIndex, (w.logIndex or ''), (handler.InfoBlock[w.id] and handler.InfoBlock[w.id]:GetName() or ''))) - end - end - end - - handler.numWatched = numWatched - handler.numAll = numAll - handler.numBlocks = 0 - handler.currentBlock = 0 - handler.currentAnchor = frame.titlebg - for blockIndex = 1, numWatched do - local currentBlock = handler:UpdateBlock(blockIndex, id, isNew) - if currentBlock then - handler:AddBlock(currentBlock) - else - print(' |cFF'..handler.internalColor..'finished|r @', blockIndex) - break -- done with quest stuff - end - end - - local numBlocks = handler.numBlocks - local used = handler.usedBlocks - local free = handler.freeBlocks - print(format('#### %s ## |cFFFF8800%04X|r --- blocks |cFFFF8800%d|r, (used/free: |cFFFF8800%d|r/|cFFFF8800%d|r)', handler.name, band(reason, handler.updateReasonModule + handler.updateReasonEvents, reason), numBlocks, #used, #free)) - - return numWatched, numAll -end - -Default.UpdateBlock = function (handler, index) - local print = bprint - if not index then - return - end - local info = handler.WatchList[index] -- should match up with whatever the internal watch list has - if not info then - return - end - print(' Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..index..'|r|cFF0099FF', info.id ,'|r') - local frame = handler.frame - local block = handler:GetBlock(info.id) - - block.handler = handler - block.info = info - - info.blockIndex = index - local keyInfo - if info.id then - keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'InfoBlock[' .. info.id .. '] = *' .. block:GetName():gsub('%D', '') - handler.InfoBlock[info.id] = block - end - if info.logIndex then - keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'LogBlock[' .. info.logIndex .. '] = ' .. block:GetName():gsub('%D', '') - handler.LogBlock[info.logIndex] = block - end - if info.watchIndex then - keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'WatchBlock[' .. info.watchIndex .. '] = ' .. block:GetName():gsub('%D', '') - handler.WatchBlock[info.watchIndex] = block - end - if keyInfo then print(' assigned', keyInfo) end - handler.BlockInfo[index] = info - block.endPoint = block.titlebg - block.attachmentHeight = 0 - block.currentLine = 0 - local attachments, override_schema = handler:UpdateObjectives(block, block.schema) - - block.title:SetText(info.title) - - if info.specialItem and not info.itemButton then - print(' - |cFF00FFFFgenerating item button for info set') - info.itemButton = T.SetItemButton(block, info) - else - --info.itemButton = nil - end - - local tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 - - - if info.selected then - block.SelectionOverlay:Show() - else - block.SelectionOverlay:Hide() - end - - if info.tagInfo then - tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative) - tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative) - tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative) - end - - if info.schema then - block.schema = info.schema - end - return block -end - -Default.UpdateObjectives = function(handler, block, block_schema, displayObjectives) - local print = lprint - displayObjectives = displayObjectives or true - block_schema = block_schema or block.schema - local info = block.info - print(' |cFF00FF00default.objectives', block:GetName()) - -- reset the starting positions - local text, attachment, template - local numAttachments = 0 - - if info.objectives and displayObjectives then - for i, data in ipairs(info.objectives) do - text, attachment, template = handler:UpdateLine(block, data) - if text or attachment then - local line = handler:GetLine(block) - line.height = 0 - print(' |cFF88FF00#', i, data.type, text, attachment) - handler:AddLine(block, text, attachment, template) - end - if attachment then - numAttachments = numAttachments + 1 - end - end - end - - if block.currentLine < block.numLines then - print(' - cull', block.currentLine, block.numLines) - for i = block.currentLine + 1, block.numLines do - print(' - hide |cFFFF0088'..i..'|r', block.lines[i]) - block.lines[i]:ClearAllPoints() - block.lines[i]:Hide() - end - end - - if block.currentLine > 0 then - block.attachmentHeight = block.attachmentHeight - print(' |cFF00FF00attachment:', block.attachmentHeight) - end - return numAttachments, block_schema -end - -Default.UpdateLine = function(handler, block, data) - return block.info.description, nil, 'default' -end - -Default.Select = function(handler, block) - T:Update() -end -Default.Open = function(handler, block) - T:Update(handler.updateReasonModule) -end -Default.Remove = function(handler, block) - T:Update(handler.updateReasonModule) -end -Default.Report = function(handler, block) - print('Stats:', handler.numWatched,'items tracked,', handler.numBlocks,'blocks assigned.') -end - -Default.OnMouseUp = function(self, button) - print(self.handler.name, self.mainStyle, self.subStyle) - if button == 'LeftButton' then - if IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow() then - self.Link(self.handler, self) - elseif IsModifiedClick("QUESTWATCHTOGGLE") then - self.Remove(self.handler, self) - else - self.Select(self.handler, self) - end - elseif button == 'RightButton' then - self.Open(self.handler, self) - end - self.initialButton = nil - self.modChatLink = nil - self.modQuestWatch = nil - --T:Update(self.handler.updateReasonModule) - print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r') -end -Default.OnMouseDown = function(self, button) - print(self.info.title) -end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/Layout.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,689 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 3/30/2016 12:49 AM +--- Everything that involves directly placing elements on the screen goes here. Sizing, spacing, tiling, etc. +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band +local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove +local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent +local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText +local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent +local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs +local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame +local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow +local band, bor = bit.band, bit.bor +local print = B.print('Layout') +local oprint = B.print('Objectives') +local bprint = B.print('Block') +local tprint = B.print('Tracker') +local lprint = B.print('Layout') +local unitLevel = 1 + +local REWARD_POPUP = _G.VeneerRewardsPopOut +local ANIM_STATE = 'Animation: %04X' +local INIT_STATE = 'Init: %04X' + +--- Bitfields of import +--- control value for everything +local OBJECTIVE_TRACKER_UPDATE_REASON = _G.OBJECTIVE_TRACKER_UPDATE_REASON +--- flags reason categories where frame layout requires initializing (starts high) +local initReason = 0xFFFF +--- flags reason categories where frame anchor updates must be delayed because of an ongoing animation (starts low) +local animateReason = 0x0000 + +--- FRAMES +local Wrapper = _G.VeneerObjectiveWrapper +local Scroller = Wrapper.scrollArea +local Scroll = _G.VeneerObjectiveScroll +local orderedHandlers = T.orderedHandlers +local orderedNames = T.orderedNames + +--- FRAME TEMP VARIABLES +local wrapperWidth, wrapperHeight = 0, 0 +local scrollWidth, scrollHeight + +--- SCHEMA VARIABLES +local schemaName, lastSchema = { + tracker = '', + block = '', + line = '' +}, {} +local trackerSchema, blockSchema, lineSchema + +local itemButtonSize, itemButtonSpacing = 36, 1 +local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed +local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE' +local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 } +local rewardSize = 24 + +local headerHeight, headerColor, headerSpacing = 16, {1,.75,0,1}, 2 +local headerbg = {'VERTICAL', 1, 1, 0.5, 0.5, 1, 1, 0.5, 0} +local headerFont, headerSize, headerOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 14, 'OUTLINE' + +local titlebg = {'HORIZONTAL', 1, 0, .7, 0, 1, 0, .7, .2} +local titleFont, titleSize, titleOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE' +local titleColor = {0,.7,1,1} + +local textbg = {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 } +local textFont, textSize, textOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE' +local textColor = {1,1,1,1 } + +local widgetTextFont, widgetTextSize, widgetTextOutline = [[Interface\Addons\SharedMedia_MyMedia\font\XOIREQE.TTF]], 11, 'OUTLINE' +local widgetTextColor = {1,1,1,1 } +local widgetHeight, widgetBorder = 17, 1 + + +local selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225} +local titleSpacing, textSpacing, blockSpacing = 3, 3, 1 +local titleIndent, textIndent,selectionIndent = 2, 5, 50 +--- END SCHEMA +local blockPosition + + +local SetAnimate = function(reason, animate) + print('comparing', animateReason, reason) + if animate then + if band(animateReason, reason) == 0 then + animateReason = animateReason + reason + end + else + if band(animateReason, reason) > 0 then + animateReason = animateReason - reason + end + end + Wrapper.AnimState:SetFormattedText(ANIM_STATE, animateReason) +end + + +--- schema swapper +T.UpdateSchema = function(layer, newSchema) + if not (T.Conf.Schema[layer] and T.Conf.Schema[layer][newSchema]) then + return + elseif schemaName[layer] == newSchema then + return + end + lastSchema[layer] = schemaName[layer] + schemaName[layer] = newSchema + local c = T.Conf.Schema[layer][newSchema] + + if layer == 'tracker' then + headerHeight, headerSpacing = c.headerHeight, c.headerSpacing + headerColor = c.headerColor + headerbg = c.headerbg + headerFont, headerSize, headerOutline = unpack(c.headerFont) + trackerSchema = newSchema + elseif layer == 'block' then + titlebg = c.titlebg + titleFont, titleSize, titleOutline = unpack(c.titleFont) + selectionbg = c.selectionbg + titleSpacing, textSpacing, blockSpacing = c.titleSpacing, c.textSpacing, c.blockSpacing + titleIndent, textIndent,selectionIndent = c.titleIndex, c.textIndex, c.selectionIndent + titleColor = c.titleColor + print(unpack(c.titleColor)) + rewardSize = 24 + textFont, textSize, textOutline = unpack(c.textFont) + textbg = c.textbg + textIndent = c.textIndent + rewardSize = c.rewardSize + blockSchema = newSchema + elseif layer == 'line' then + textColor = c.textColor + lineSchema = newSchema + elseif layer == 'widget' then + widgetTextColor = c.textSpacing + widgetTextFont, widgetTextSize, widgetTextOutline = unpack(c.textFont) + end + tprint('|cFFFF0088 Schema:|r', layer, lastSchema[layer], '->', newSchema) +end +-- todo: figure out why objectives go invisible +local anchorPoint, anchorFrame +local abs, GetTime = math.abs, GetTime +Default.AddTracker = function(handler, frame, index) + local isInitialized = true + if initReason and (band(initReason, handler.updateReason) > 0 ) then + isInitialized = false + initReason = initReason - handler.updateReason + print('|cFF00FF00%%% initialization status update:', format('%04X', initReason)) + + frame.SlideIn:SetScript('OnPlay', function() + SetAnimate(handler.updateReasonModule, true) + end) + + frame.SlideIn:SetScript('OnFinished', function() + SetAnimate(handler.updateReasonModule, false) + end) + + if initReason == 0 then + initReason = nil + end + end + + if index == 1 then + print('|cFF00FF00### beginning wrapper layout -----------------') + anchorPoint, anchorFrame = 'TOP', Scroll + wrapperHeight = 18 + end + + frame.destinationOffset = -wrapperHeight + print(frame.destinationOffset, frame.previousOffset) + if isInitialized and (abs(frame.previousOffset - frame.destinationOffset) > 0.9) and frame:IsVisible() then + if frame.wasEmpty then + frame.previousOffset = -Wrapper:GetHeight() + end + + local postFrame, postPoint = anchorFrame, anchorPoint + local delta = frame.destinationOffset - frame.previousOffset + local _, _, _, _, offset = frame:GetPoint(1) + print(' |cFF00FFBBpushing', frame:GetName(), delta, 'pixels, from', frame.previousOffset, '(', offset, ')') + frame.SlideIn.translation:SetTarget(frame) + frame.SlideIn.translation:SetOffset(0, delta) + frame.SlideIn:Play() + --for i, b in ipairs(handler.usedBlocks) do + --b.SlideIn.translation:SetOffset(0, delta) + -- b.SlideIn:Play() + --end + local start = GetTime() + frame.SlideIn:SetScript('OnFinished', function() + print(' |cFF00BBFF'..frame:GetName(), 'moved', delta, 'over duration of ', GetTime()-start) + frame:SetParent(Scroll) + frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) + frame.previousOffset = frame.destinationOffset + frame.SlideIn:SetScript('OnFinished', nil) + if Wrapper.destinationHeight then + Wrapper:SetHeight(Wrapper.destinationHeight) + Scroller:SetHeight(Wrapper.destinationHeight) + Scroll:SetHeight(Wrapper.destinationHeight) + Wrapper.previousHeight = Wrapper.destinationHeight + Wrapper.destinationHeight = nil + end + + end) + else + print(' |cFF00BBFFpinning '..handler.name..' to', anchorFrame:GetName(), anchorPoint, '|rcurrent frame height:', frame.height) + print(' |cFFFF0088total height:', wrapperHeight) + frame:ClearAllPoints() + frame:Show() + frame:SetParent(Scroll) + frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) + frame:SetPoint('LEFT', Scroll, 'LEFT') + frame:SetPoint('RIGHT', Scroll, 'RIGHT') + frame.previousOffset = frame.destinationOffset + handler.initialized = true + end + + frame.title:SetFont(headerFont, headerSize, headerOutline) + frame.titlebg:SetHeight(headerHeight) + frame.title:SetTextColor(unpack(headerColor)) + + if frame.height ~= frame.previousHeight then + frame:SetHeight(frame.height) + end + + if frame.wasEmpty then + frame.headerFade:Play() + frame.wasEmpty = nil + end + + wrapperHeight = wrapperHeight + frame.height + anchorFrame = handler.frame + anchorPoint = 'BOTTOM' + +end + +Default.AddBlock = function(self, block, blockIndex) + local blockIndex = blockIndex or (self.currentBlock + 1) + local print = bprint + local tracker = self.frame + local info = block.info + + block.index = blockIndex + -- if animating, skip this segment + if not block.isAnimating then + print('blockschema', blockSchema, block.schema) + if blockSchema ~= block.schema then + T.UpdateSchema('block', block.schema) + print(' ### activating block schema:|cFF0088FF', block.schema) + end + + block:SetWidth(T.Conf.Wrapper.Width) + block.title:SetSpacing(titleSpacing) + block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing) + block.title:SetPoint('LEFT', block, 'LEFT', titleIndent, 0) + block.title:SetTextColor(unpack(titleColor)) + block.titlebg:SetTexture(1,1,1,1) + block.titlebg:SetGradientAlpha(unpack(titlebg)) + block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0) + block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing) + block.status:SetSpacing(textSpacing) + block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing) + block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0) + block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0) + block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0) + block.statusbg:SetTexture(1,1,1,1) + block.statusbg:SetGradientAlpha(unpack(textbg)) + block.SelectionOverlay:SetGradientAlpha(unpack(selectionbg)) + block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0) + block.SelectionOverlay:SetPoint('BOTTOMRIGHT') + + local anchor, target, point, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 + for i, tile in ipairs(block.rewardTile) do + --print(rewardSize) + tile:SetSize(rewardSize, rewardSize) + tile:ClearAllPoints() + tile:SetPoint(anchor, target, point, x, y) + block.rewardLabel[i]:SetPoint('TOP', tile, 'TOP', 0, 0) + anchor, target, point, x, y = 'TOPRIGHT', tile, 'TOPLEFT', -2, 0 + end + + + local titleHeight = floor(block.title:GetHeight()+.5) + local titlebgHeight = titleHeight + titleSpacing*2 + block.titlebg:SetHeight(titlebgHeight) + + local statusHeight = floor(block.status:GetHeight()+.5) + local statusbgHeight = statusHeight + textSpacing*2 + local attachmentHeight =floor(block.attachmentHeight + .5) + + self.print('AddBlock', 'anchor to|cFF0088FF', self.currentAnchor:GetName()) + self.print('AddBlock', 'attachment:|cFF00FF00', attachmentHeight, '|rtitle:|cFF00FF00', titlebgHeight, '|r('.. titleHeight..')') + if attachmentHeight > 0 then + attachmentHeight = attachmentHeight + textSpacing + end + + block.height = titlebgHeight + attachmentHeight + block:SetHeight(block.height) + end + + if block.debug then + local func = (B.Conf.GuidesMode == true) and 'Show' or 'Hide' + for _, region in ipairs(block.debug) do + region[func]() + end + end + + --- Handler vars + if blockIndex == 1 then + tracker.previousHeight = tracker.height + tracker.height = headerHeight + blockPosition = -headerHeight + self.print('AddBlock', 'new layout: headerHeight:|cFF00FF00', headerHeight, '|rpreviousHeight:|cFF00FF00', tracker.previousHeight) + else + blockPosition = blockPosition + self.print('AddBlock', 'advancing: height:|cFF8888FF', tracker.height) + end + self.currentBlock = blockIndex + self.currentAnchor = block + + block:SetPoint('TOPLEFT', self.frame, 'TOPLEFT', 0, blockPosition) + block:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) + self.numBlocks = self.numBlocks + 1 + print(' |cFFFFFF00'..tracker.height..'|r', '|cFF00FF00'..block:GetName()..'|r', block.height, tracker.height) + tracker.height = tracker.height + block.height + blockPosition = blockPosition - block.height + + block:Show() + + + if Devian and Devian.InWorkspace() then + block.DebugTab:SetParent(UIParent) + block.DebugTab:SetPoint('TOPRIGHT', block, 'TOPLEFT', 0, 0) + block.DebugTab.status:SetText(tostring(block.schema) .. ' @|cFF00FF00' .. tostring(block.posIndex) .. '|r #|cFFFFFF00'.. tostring(info.logIndex or info.id) .. '|r'.. + ' H|cFFFFFF00' .. tostring(block.height) .. ' L|cFF00FFFF' .. tostring(block.numLines) ..'|r') + block.DebugTab:Show() + end +end + +--- Used as an iterator of sorts for cascaded tag icon placements (the daily/faction/account icons) +Default.AddTag = function (handler, block, tagInfo, tagPoint, tagAnchor, tagRelative) + local print = bprint + + for order, tagName in ipairs(block.info.tagInfo) do + local tag = block[tagName] + if block.tagCoords[tagName] and tag then + tag:SetTexCoord(unpack(block.tagCoords[tagName])) + tag:Show() + tag:SetPoint(tagPoint, tagAnchor, tagRelative, 0, 0) + tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', tag, 'TOPLEFT' + else + block[tagName]:Hide() + end + end + + return tagPoint, tagAnchor, tagRelative +end + + +--- Adds the given line to the current content and advances the anchor pointer to that new line for the following call. +Default.AddLine = function(handler, block, text, attachment, template) + local print = lprint + local lineIndex = block.currentLine + 1 + local line = handler:GetLine(block, lineIndex) + + line.index = lineIndex + template = template or 'default' + if template and lineSchema ~= template then + print(' |cFF00FF00change schema', template) + T.UpdateSchema('line', template) + end + line.status:SetSpacing(textSpacing) + line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) + line.status:SetPoint('RIGHT', line, 'RIGHT',0, 0) + line.status:SetTextColor(unpack(textColor)) + line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) + line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) + line:SetPoint('LEFT', block, 'LEFT') + line:SetPoint('RIGHT', block, 'RIGHT') + line:Show() + line:SetScript('OnMouseUp', function(self, button) + handler.OnMouseUp(block, button) + end) + + + handler.print('AddLine', '|cFF00FFFF'..tostring(line.schema)..'|r', line:GetName()) + --[[ + for i = 1, line:GetNumPoints() do + tprint(' - ', line:GetPoint(i)) + end + tprint(' - ', line:GetSize()) + tprint(' - ', line:GetParent(), line:GetParent():IsVisible()) + tprint(' - ', line:IsVisible()) + --]] + + + + + -- fill in the text, then derive pixel-rounded height + line.status:SetText(text) + line.height = floor(line.status:GetStringHeight()+.5) + + -- For progressbar and timer lines, status text may be used as the title heading + if attachment then + attachment:SetPoint('TOP', line, 'TOP') + attachment:SetPoint('LEFT', line, 'LEFT', textIndent, 0) + attachment:SetPoint('RIGHT', line, 'RIGHT') + print(' |cFFFF0088doing things with a widget', attachment:GetSize()) + line.height = attachment:GetHeight() + if text then + line.height = max(line.height, line.status:GetStringHeight()) + end + if attachment.status:GetText() then + line.height = max(line.height, attachment.status:GetStringHeight()) + end + attachment:Show() + end + + line:SetHeight(line.height) + block.attachmentHeight = block.attachmentHeight + line.height + textSpacing + + local debug_points = '' + for i = 1, line:GetNumPoints() do + local point, parent, anchor = line:GetPoint(i) + debug_points = debug_points .. tostring(parent:GetName()) .. ', ' .. anchor .. ' ' + end + + print(' |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, + "|cFF0088FFpoint:|r", debug_points, "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) + block.currentLine = lineIndex + block.endPoint = line -- edge used for the next block + + return lineIndex +end + + + +---------- +--- Top level methods + + +T.UpdateItemButtonAnchor = function (block, itemButton) + local print = bprint + print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()') + if itemButton.questID ~= block.info.questID then + print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID) + -- something happened between this and last frame, go back and set new probes + return T.UpdateActionButtons() + end + + local previousItem = itemButton.previousItem + local upper_bound = Scroller:GetTop() + Scroller.snap_upper + local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize + local point, anchor, relative + + if block:GetBottom() < lower_bound then + print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5)) + if previousItem then + print('adjusting', previousItem:GetName()) + previousItem:ClearAllPoints() + previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing) + end + itemButton:ClearAllPoints() + itemButton.x = Wrapper:GetLeft() -4 + itemButton.y = Wrapper:GetBottom() + point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT' + Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing + + elseif block:GetTop() > upper_bound then + print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5)) + itemButton:ClearAllPoints() + if previousItem then + print('latch onto another piece') + point, anchor, relative ='TOP', previousItem, 'BOTTOM' + itemButton.x = 0 + itemButton.y = -itemButtonSpacing + else + print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop()) + point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' + itemButton.x = Scroller:GetLeft() -4 + itemButton.y = Scroller:GetTop() + end + itemButton:Show() + Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing) + else + print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5)) + itemButton:ClearAllPoints() + itemButton.x = block:GetLeft() - itemButtonSpacing + itemButton.y = block:GetTop() + point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' + end + + itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y) + itemButton:Show() +end + +T.UpdateItemButtonCooldown = function(button) + +end + +function T:FinishWrapper () + if wrapperHeight > Wrapper.previousHeight then + Wrapper:SetHeight(wrapperHeight) + Scroller:SetHeight(wrapperHeight*3) + Scroll:SetHeight(wrapperHeight) + Wrapper.previousHeight = wrapperHeight + Wrapper.destinationHeight = wrapperHeight + end + Scroller:SetVerticalScroll(B.Conf.ObjectiveScroll or 0) + print('|cFF00FF00### end of wrapper layout', Wrapper:GetSize()) + print(' |cFF00FF00Scroller:', Scroller:GetSize()) + print(' |cFF00FF00Scroll:', Scroll:GetSize()) + for i = 1, Wrapper:GetNumPoints() do + print('|cFF00FF00 ', Wrapper:GetPoint(i)) + end + for i = 1, Scroller:GetNumPoints() do + print('|cFF00FF00 ', Scroller:GetPoint(i)) + end + for i = 1, Scroll:GetNumPoints() do + print('|cFF00FF00 ', Scroll:GetPoint(i)) + end + + if Devian and Devian.InWorkspace() then + Wrapper.AnimState:SetFormattedText(ANIM_STATE, animateReason) + Wrapper.AnimState:Show() + end + + Wrapper:Show() + Scroller:Show() + Scroll:Show() +end + + +----------------------------------------- +-- Criteria frames + +--[[ + text = description, + type = type, + finished = completed, + quantity = quantity, + requiredQuantity = requiredQuantity, + characterName = characterName, + flags = flags, + assetID = assetID, + quantityString = quantityString, + criteriaID = criteriaID, +]] +T.WidgetRegistry = {} +local wr = T.WidgetRegistry + +--- WidgetTemplate 'OnShow' +local wrapperWidth, textIndent +T.InitializeWidget = setmetatable({}, { + __call = function(t, frame, isNew, ...) + -- todo: config pull + if not wrapperWidth then + wrapperWidth = T.Conf.Wrapper.Width + textIndent = T.Conf.Wrapper.TextIndent + end + + tprint('Initialize', frame:GetName(), isNew, ...) + frame:SetWidth(wrapperWidth - textIndent * 2) + frame:SetScript('OnEvent', T.UpdateWidget[frame.widgetType]) + frame:RegisterEvent('QUEST_LOG_UPDATE') + frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') + frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') + frame:RegisterEvent('CRITERIA_UPDATE') + frame:RegisterEvent('CRITERIA_COMPLETE') + frame:RegisterEvent('CRITERIA_EARNED') + t[frame.widgetType](frame, isNew) + T.UpdateWidget[frame.widgetType](frame, isNew) + end, +}) + +--- WidgetTemplate 'OnEvent' +T.UpdateWidget = setmetatable({}, { + __call = function(t, frame, isNew, ...) + tprint('Update', frame:GetName(), isNew, ...) + if not frame.widgetType then + return + end + + return t[frame.widgetType](frame, isNew) + end +}) + + +local progressHeight = 17 +local progressBorder = 1 +local progressFont = _G.VeneerCriteriaFontNormal + +local lprint = B.print('Line') +T.InitializeWidget.StatusBar = function(self, isNew) + local print = lprint + local c = T.Conf.Wrapper + + tprint(self:GetName(), isNew) + if isNew then + self:SetMinMaxValues(0, self.maxValue) + + self:SetHeight(widgetHeight) + self.height = widgetHeight + + self.status:SetFont(widgetTextFont, widgetTextSize, widgetTextOutline) + self.status:SetTextColor(unpack(widgetTextColor)) + end + self:SetValue(self.value) + + self.status:SetText(self.objective.quantityString) +end + +T.UpdateWidget.StatusBar = function (self) + local value, maxValue = self.value, self.maxValue + print('update vals:') + for k,v in pairs(self) do + print(k, v) + end + self.width = self.width or self:GetWidth() + self:SetValue(self.value) + local format = self.format or '%d/%d' + self.status:SetFormattedText(format, value, maxValue) + local progress = (value / maxValue) + if progress > 0 then + print('color:', 1-progress*2 , progress*2 - 1,0,1) + print('width:', (self.width -progressBorder * 2) * progress) + self:SetStatusBarColor(1-progress*2 , progress*2,0,1) + end +end + + +T.InitializeWidget.Hidden = function (self) + self.height = 0 +end +T.UpdateWidget.Hidden = function (self) + self.height= 0 +end + + +--- Queue any active item buttons for update for that frame +local iprint = B.print('ItemButton') +local Quest = T.Quest +local IsQuestWatched, InCombatLockdown = IsQuestWatched, InCombatLockdown +T.UpdateActionButtons = function(updateReason) + local print = iprint + Scroller.snap_upper = 0 + Scroller.snap_lower = 0 + local print = B.print('ItemButton') + if updateReason then + print = B.print('IB_'..updateReason) + end + + local previousItem + for questID, itemButton in pairs(Quest.itemButtons) do + local info= T.Quest.Info[questID] + + print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) + local block = T.Quest.QuestBlock[questID] + if block then + -- Dispatch the probe + if IsQuestWatched(info.logIndex) then + itemButton.previousItem = previousItem + print(' |cFFFFFF00probing', block:GetName()) + block:SetScript('OnUpdate', function() + if block:GetBottom() and not InCombatLockdown() then + print(' '..block:GetName()..' |cFF00FF00probe hit!') + T.UpdateItemButtonAnchor(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope + block:SetScript('OnUpdate', nil) + + end + end) + previousItem = itemButton + else + print('hidden block or unwatched quest') + itemButton.previousItem = nil + itemButton:Hide() + end + elseif itemButton:IsVisible() then + print(' |cFFFF0088hiding unwatched quest button', itemButton:GetName()) + itemButton.previousItem = nil + itemButton:Hide() + else + print(' |cFFBBBBBBignoring hidden log quest button', itemButton:GetName()) + end + end +end + +Default.FadeOutBlock = function (handler, blockIndex) + +end \ No newline at end of file
--- a/ObjectiveTracker/ObjectiveTracker.xml Mon Apr 25 03:32:34 2016 -0400 +++ b/ObjectiveTracker/ObjectiveTracker.xml Mon Apr 25 13:51:58 2016 -0400 @@ -85,7 +85,7 @@ </Layer> <Layer level="OVERLAY"> - <FontString name="$parentAnimState" inherits="VeneerStatusFont" parentKey="AnimState"> + <FontString name="$parentAnimState" inherits="VeneerStatusFont" parentKey="AnimState" hidden="true"> <Anchors> <Anchor point="TOPRIGHT" relativePoint="BOTTOMRIGHT" x="0" y="-5" /> </Anchors> @@ -380,9 +380,9 @@ </AnimationGroup> <AnimationGroup name="$parent_BlockFade" parentKey="blockFadeOut" ignoreFramerateThrottle="true" looping="NONE"> <Alpha duration="0.25" order="1" fromAlpha="1" toAlpha="0" /> - <Translation duration="0.25" order="1" offsetX="260" offsetY="0" smoothing="OUT" /> - <Scale order="1" duration="0.25" fromScaleX="1" fromScaleY="1" toScaleX="0.1" toScaleY="0.1"> - <Origin point="TOP"> + <!--<Translation duration="0.25" order="1" offsetX="260" offsetY="0" smoothing="OUT" />--> + <Scale order="1" duration="0.25" scaleX="0.1" scaleY="0.1"> + <Origin point="CENTER"> <Offset x="0" y="0" /> </Origin> </Scale> @@ -674,16 +674,16 @@ <Script file="ObjectiveTracker.lua" /> <Script file="Schema.lua" /> - <Script file="Quests.lua" /> - <Script file="Achievements.lua" /> - <Script file="AutoQuestPopups.lua" /> - <Script file="BonusObjectives.lua" /> - <Script file="ScenarioObjectives.lua" /> + <Script file="QuestData.lua" /> + <Script file="AchievementData.lua" /> + <Script file="AutoQuestPopupData.lua" /> + <Script file="BonusObjectiveData.lua" /> + <Script file="ScenarioData.lua" /> <Script file="ExerienceBar.lua" /> - <Script file="TrackerFrame.lua" /> - <Script file="TrackerBlock.lua" /> + <Script file="Layout.lua" /> + <Script file="Block.lua" /> <Script file="RewardFrame.lua" /> - <Script file="DefaultTracker.lua" /> + <Script file="Update.lua" /> <Script file="Events.lua" /> <Script file="Widgets.lua" /> <!-- <Script file="ObjectiveStyle.lua" /> -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/QuestData.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,577 @@ +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band +local GetQuestWatchInfo, GetQuestLogCompletionText = GetQuestWatchInfo, GetQuestLogCompletionText +local GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle = GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle +local GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown +local GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches = GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches +local GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup = GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup +local QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY = QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY +local QUEST_TAG_TCOORDS, IsQuestSequenced = QUEST_TAG_TCOORDS, IsQuestSequenced +local Default, Quest = T.DefaultHandler, T.Quest +local format, wipe, select = format, table.wipe, select +local wipeall = B.wipeall +local lprint, iprint, tprint = B.print('Line'), B.print('Info'), B.print('Tracker') +local print = tprint +local fprint = B.print('Frame') + + +local superTrackQuestID, playerMoney, inScenario, showPOIs +Quest.Update = function(self, reason, ...) + local print = self.print + print('QuestTracker:Update() received') + T.UpdateActionButtons() + Default.Update(self, reason, ...) +end + +T.Quest.numButtons = 0 +local usedButtons = T.Quest.itemButtons +local freeButtons = T.Quest.freeButtons + +Quest.UpdateObjectives = function(self, block) + local print = lprint + print('|cFF'..self.internalColor..'UpdateObjectives()') + local info = block.info + + print((info.isAccount and 'isAccount' or ''), (info.isFaction and 'isFaction' or ''), (info.isDaily and 'isDaily' or ''), (info.isWeekly and 'isWeekly' or ''), info.tagID, info.tagName) + + local displayObjectives = true + local block_schema = 'default' + if info.isAccount then + if info.isFaction then + print(' faction', info.tagID) + block_schema = 'faction_'..info.tagID + else + print(' account', info.isAccount, info.isFaction) + block_schema = 'account' + end + elseif info.isDaily then + print(' daily', info.frequency) + block_schema = 'daily' + elseif info.isWeekly then + print(' weekly', info.frequency) + block_schema = 'weekly' + end + local completionText + if info.isComplete then + if info.isAutoComplete then + local questID, popupType = GetAutoQuestPopUp(info.logIndex) + if popupType == 'COMPLETE' then + print(' :: auto-complete quest :: set the message') + self:AddLine(block, T.strings.CLICK_TO_COMPLETE, nil, 'complete') + end + else + if not completionText or info.completionText then + info.completionText = GetQuestLogCompletionText(info.logIndex) + end + end + self:AddLine(block, info.completionText, nil, 'complete') + displayObjectives = false + print('|cFF'..self.internalColor..' :: complete quest :: show instruction: "'.. tostring(info.completionText) .. '"') + end + + Default.UpdateObjectives(self, block, block_schema, displayObjectives) + return 0, block_schema +end + +Quest.UpdateLine = function(handler, block, data) + local objectiveType = data.type + return data.text, nil, objectiveType +end + +----------------------------- +--- QUEST +local tremove, tinsert = tremove, tinsert +local GetQuestLogIndexByID, IsQuestWatched = GetQuestLogIndexByID, IsQuestWatched +Quest.QuestBlock = {} +Quest.LogBlock = {} +Quest.LogInfo = {} + +Quest.OnRemoved = function(block) + +end + +Quest.GetBlock = function(self, index) + local block = Default.GetBlock(self, index) + block:SetScript('OnEvent', Quest.OnRemoved) + block:RegisterEvent('QUEST_REMOVED') + return block +end + +local GetQuestWatchIndex = GetQuestWatchIndex +local numAnimating = 0 +local blocksChecked = {} + +--- Get a total of things to show, and straighten out the index while we're at it +--- Return the number shown, total in log, and the info table to parse +Quest.GetNumWatched = function (self, id, added) + local print = self.print + B.print('Block')('########') + B.print('Block')('########') + superTrackQuestID = GetSuperTrackedQuestID() + playerMoney = GetMoney(); + inScenario = C_Scenario.IsInScenario(); + showPOIs = GetCVarBool("questPOI"); + local numAll = GetNumQuestLogEntries() + local numWatched = GetNumQuestWatches() + local bottomIndex = 1 + print('GetNumWatched', self.name, numWatched, 'of', numAll) + local start, limit = 1, numAll + + if id and not added then + -- if a particular id is supplied, add to checklist + if self.InfoBlock[id] then + blocksChecked[self.InfoBlock[id]] = self.InfoBlock[id] + end + end + + numAnimating = 0 + for logIndex = start, limit do + local reason1, reason2 = '', '' + local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) + local watchIndex = GetQuestWatchIndex(logIndex) + + --- Start of crazy audit flagging + if watchIndex and watchIndex >= bottomIndex then + -- do watch data pointers match? + local watchInfo = self.WatchInfo[watchIndex] + local watchBlock = self.WatchBlock[watchIndex] + if watchInfo and watchInfo.questID ~= questID then + print('GetNumWatched', 'trimming WatchInfo ['..watchIndex..'] =/=', questID) + self.WatchInfo[watchIndex] = nil + end + if watchBlock and watchBlock.info.questID ~= questID then + print('GetNumWatched', 'trimming WatchBlock ['..watchIndex..'] =/=', watchBlock:GetName()) + self.WatchBlock[watchIndex] = nil + blocksChecked[watchBlock] = watchBlock + end + end + + -- check log-block pointer + local logBlock = self.LogBlock[logIndex] + if logBlock then + -- check later that the block isn't for a dropped quest + if logBlock.info.questID ~= questID then + print('GetQuests', 'replace info', logBlock.info.questID, '->', questID) + self.LogBlock[logIndex] = nil + blocksChecked[logBlock] = logBlock + end + end + --- end of crazy audit flagging + + -- add to watch index if: the questID is non-zero + if questID ~= 0 then + self.Info[questID] = self:GetInfo(logIndex, watchIndex) + print('GetQuests', format('request info |cFF00FF00%2d|r |cFFFFFF00%6d|r |cFFFF4400%3s|r', logIndex, questID, tostring(watchIndex or ''))) + end + end + + --- After GetInfo pass, look for any non-conformant blocks and deal with them + for _, block in pairs(blocksChecked) do + local logIndex = GetQuestLogIndexByID(block.info.questID, 'player') + -- animating blocks have been evaluated + if not block.isAnimating then + if not logIndex then + self:ClearBlock(block) + elseif not IsQuestWatched(block.info.logIndex) then + self:ClearBlock(block) + end + end + blocksChecked[block] = nil + end + + self.numWatched = numWatched + self.numAll = numAll + + return numWatched, numAll, self.WatchList +end + + +--- Returns an iterable table from which tracker blocks can be filled out. Data includes: +-- All entry-layer GetXInfo return values +-- Manifest of line data to be displayed in relation to the tracked object +Quest.GetInfo = function (self, logIndex, watchIndex) + local print = iprint + local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) + if ( not questID ) then + tprint('GetNumWatched', logIndex, watchIndex, '|cFFFF2299no data|r') + return + end + + Quest.Info[questID] = Quest.Info[questID] or {} + local q = Quest.Info[questID] + q.questID = questID + q.id = questID + q.logIndex = logIndex + q.watchIndex = watchIndex + + local numObjectives, requiredMoney, isAutoComplete, failureTime, timeElapsed, questType + = 0, 0, nil, false, false, 0 + if watchIndex then + local _ + _,_,_, numObjectives, requiredMoney, _, _, isAutoComplete, + failureTime, timeElapsed, questType = GetQuestWatchInfo(watchIndex) + + -- ensure that the entry being populated isn't animating + if self.WatchBlock[watchIndex] then + local checkIndex = watchIndex + while self.WatchBlock[checkIndex + numAnimating] and self.WatchBlock[checkIndex + numAnimating].isAnimating do + print(self.WatchBlock[checkIndex + numAnimating]:GetName(), 'is in an animation sequence') + numAnimating = numAnimating + 1 + end + end + + self.WatchList[watchIndex + numAnimating] = q + --tprint(' |cFF88FF00GetInfo:|r set watch entry', watchIndex) + print('GetInfo:', logIndex, watchIndex, '|cFFFF2299'..title..'|r') + end + self.LogInfo[logIndex] = q + + q.numObjectives = numObjectives + q.requiredMoney = requiredMoney + q.failureTime = failureTime + q.timeElapsed = timeElapsed + + + + q.type = 'Quest' + q.title = title + q.level = level + q.displayQuestID = displayQuestID + q.suggestedGroup = suggestedGroup + + -- re-use Blizzard logic for consistency + local showQuest = true + if isTask then showQuest = false end + local watchMoney = false; + local tagID, typeTag, frequencyTag, completionTag, completionText + local isAccount, isFaction, isWeekly, isDaily = false, false, false, false + local isBreadcrumb = false + local questFailed = false + local watchMoney = false + local timerInfo, moneyInfo = false, false + local objectives = q.objectives or {} + + + -- Case 1: completed quest or "go to thing" breadcrumb + -- * 1 line containing the completion text + if ( isComplete and isComplete < 0 ) then + isComplete = false + questFailed = true + elseif ( numObjectives == 0 and playerMoney >= requiredMoney and not startEvent ) then + isComplete = true; + questFailed = false + if ( requiredMoney == 0 ) then + isBreadcrumb = true; + end + end + print('QuestFlags', (isComplete and 'isComplete' or ''), (questFailed and 'questFailed' or ''), (isBreadcrumb and 'isBreadcrumb' or '')) + + -- completion message? + local isSequenced = IsQuestSequenced(questID) + local temp_status = '' + if ( isComplete ) then + temp_status = 'COMPLETED_OBJECTIVES' + objectives = Quest.GetObjectives(questLogIndex, numObjectives, true, isSequenced, isStory) + if ( isAutoComplete ) then + temp_status = 'AUTOCOMPLETE_OBJECTIVES' + completionText = _G.QUEST_WATCH_CLICK_TO_COMPLETE + else + if ( isBreadcrumb ) then + temp_status = 'COMPLETE_BREADCRUMB' + completionText = GetQuestLogCompletionText(questLogIndex) + else + temp_status = 'COMPLETE_READY_FOR_TURN_IN' + completionText = _G.QUEST_WATCH_QUEST_READY + end + end + elseif ( questFailed ) then + temp_status = 'FAILED' + -- Case 2: failed quest + -- * 1 status line; hide other info + completionText = _G.FAILED + else + + temp_status = 'PROGRESS_OBJECTIVES' + -- Case 3: quest in progress + -- * Multiple objective lines + -- * Possible extra lines for money and timer data respectively + self.print(' QuestInfo', title, questType, isAutoComplete) + objectives = Quest.GetObjectives(logIndex, numObjectives, false, isSequenced, isStory) + q.objectives = objectives + + --- anything past here gets appended to existing objectives + + -- money + if ( requiredMoney > playerMoney ) then + + temp_status = temp_status .. '_MONEY' + local text = GetMoneyString(playerMoney).." / "..GetMoneyString(requiredMoney); + moneyInfo = { + type = 'money', + text = text, + finished = false, + requiredMoney = requiredMoney, + playerMoney = playerMoney, + } + tinsert(objectives, moneyInfo) + end + + -- time limit + if ( failureTime ) then + temp_status = temp_status .. '_TIMED' + if ( timeElapsed and timeElapsed <= failureTime ) then + timerInfo = { + type = 'timer', + finished = false, + timeElapsed = timeElapsed, + failureTime = failureTime, + } + tinsert(objectives, timerInfo) + end + end + end + q.objectives = objectives + q.moneyInfo = moneyInfo + q.timerInfo = timerInfo + q.completionText = completionText + + -- POI data + local POI = false + if ( showPOIs ) then + POI = { + questID = questID, + logIndex = logIndex, + watchIndex = watchIndex + } + local poiButton; + if ( hasLocalPOI ) then + + if ( isComplete ) then + POI.type = 'normal' + else + POI.type = 'numeric' + end + elseif ( isComplete ) then + POI.type = 'remote' + end + + local distance, onContinent = GetDistanceSqToQuest(logIndex) + if distance ~= nil and distance > 0 then + POI.distance = distance + POI.onContinent = onContinent + end + end + q.POI = POI + + --- Block Tags + -- completionTag - in progres, complete, failed, autocomplete + -- typeTag - account, faction, pvp, dungeon, group + -- frequencyTag - daily/weekly + local schema = 'default' + local questTagID, tagName = GetQuestTagInfo(questID) + local tagInfo = {} + local tagCoords = {} + local factionGroup = GetQuestFactionGroup(questID); + if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then + if( factionGroup ) then + tagID = "ALLIANCE" + schema = 'alliance' + if ( factionGroup == LE_QUEST_FACTION_HORDE ) then + tagID = "HORDE" + schema = 'horde' + end + isFaction = true + else + tagID = QUEST_TAG_ACCOUNT + isAccount = true + end + tagInfo['typeTag'] = tagID + tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] + elseif ( factionGroup) then + tagID = "ALLIANCE" + if ( factionGroup == LE_QUEST_FACTION_HORDE ) then + tagID = "HORDE" + end + isFaction = true + tagInfo['typeTag'] = tagID + tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] + end + + if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then + tagID = 'DAILY' + tagInfo['frequencyTag'] = tagID + tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] + isDaily = true + schema = 'daily' + elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then + tagID = 'WEEKLY' + tagInfo['frequencyTag'] = tagID + tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] + isWeekly = true + schema = 'weekly' + elseif( questTagID ) then + tagID = questTagID + end + + if( isComplete ) then + tagInfo['completionTag'] = 'COMPLETED' + elseif ( questFailed ) then + tagInfo['completionTag'] = 'FAILED' + end + tagCoords['completionTag'] = QUEST_TAG_TCOORDS[tagInfo['completionTag']] + + q.tagInfo = tagInfo + q.tagCoords = tagCoords + -- establishes the primary block tag for view compacting + q.tagID = tagID + q.tagName = tagName + + -- action button information + local link, icon, charges = GetQuestLogSpecialItemInfo(logIndex) + local start, duration, enable = GetQuestLogSpecialItemCooldown(logIndex) + if link or icon or charges then + q.specialItem = { + questID = questID, + logIndex = questLogIndex, + link = link, + charges = charges, + icon = icon, + start = start, + duration = duration, + enable = enable, + } + end + + if moneyInfo or timerInfo then + numObjectives = #objectives + end + + -- raw data + q.isComplete = isComplete + q.startEvent = startEvent + q.isAutoComplete = isAutoComplete + q.questType = questType + q.isTask = isTask + q.isStory = isStory + q.isOnMap = isOnMap + q.hasLocalPOI = hasLocalPOI + q.frequency = frequency + q.isComplete = isComplete + q.isStory = isStory + q.isTask = isTask + q.statusKey = temp_status + q.selected = (questID == superTrackQuestID) + + T.SetRewards(q, questID) + + q.questID = questID + q.logIndex = logIndex + q.watchIndex = watchIndex + q.id = questID + q.schema = schema + + if Devian and Devian.InWorkspace() then + print('QuestStatus', temp_status, '|cFF00FF00questLogIndex|r:', logIndex, title) + local temp ={} + local data_txt = '|cFF'..self.internalColor..'values:|r' + for k,v in pairs(q) do + if type(v) =='number' then + data_txt = data_txt .. ' |cFFFFFF00'..k..'|r: ' .. tostring(v) + elseif type(v) == 'table' then + tinsert(temp, k) + end + end + print('DataStatus',data_txt) + sort(temp, function(a,b) return a < b end) + for i, k in ipairs(temp) do + iprint('GetInfo', questID, ''..k..'|r') + for kk,v in pairs(q[k]) do + iprint('GetInfo', questID, kk, '=', v) + end + end + end + + return q +end + +Quest.GetObjectives = function(logIndex, numObjectives, isComplete, isSequenced, isStory) + local print = Quest.print + local objectives = {} + if not logIndex then + return + end + + for i = 1, numObjectives do + local text, type, finished = GetQuestLogLeaderBoard(i, logIndex) + + local progress = 0 + if finished then + progress = 1 + elseif text then + local quantity, maxQuantity = text:match('^(%d+)/(%d+)') + if quantity and maxQuantity then + progress = quantity / maxQuantity + --print('GetObjectives', 'calculated objective progress:', quantity, '/', maxQuantity, '=', progress) + end + end + + print('GetObjectives', format('|cFF88FF88#%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)), '('.. tostring(progress)..')') + + + objectives[i] = { + index = i, + type = type, + text = text, + finished = finished, + progress = progress + } + end + return objectives +end + +local huge, sqrt = math.huge, math.sqrt +Quest.GetClosest = function() + local minID, minTitle + local minDist = huge + local numQuests = GetNumQuestLogEntries() + for questIndex = 1, numQuests do + local distance, onContinent = GetDistanceSqToQuest(questIndex) + local title, level, _, _, _, _, _, _, questID = GetQuestLogTitle(questIndex) + if onContinent and distance < minDist then + minDist = distance + minTitle = title + minID = questID + end + end + + print('nearest quest is', minTitle, 'by', sqrt(minDist)) + return minID, minTitle, minDist +end + +Quest.OnTurnIn = function(self, questID, xp, money) +end + +Quest.Select = function (handler, block) + if block.info.isAutoComplete and block.info.isComplete then + ShowQuestComplete(block.info.logIndex) + else + SetSuperTrackedQuestID(block.info.questID) + end +end + +Quest.Link = function(handler, block) + local questLink = GetQuestLink(block.info.logIndex); + if ( questLink ) then + ChatEdit_InsertLink(questLink); + end +end + +Quest.Open = function(handler, block) + QuestMapFrame_OpenToQuestDetails(block.info.questID) +end + +Quest.Remove = function(handler, block) + print('removing', block.info.logIndex, 'from watcher') + RemoveQuestWatch(block.info.logIndex) +end
--- a/ObjectiveTracker/Quests.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,564 +0,0 @@ -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band -local GetQuestWatchInfo, GetQuestLogCompletionText = GetQuestWatchInfo, GetQuestLogCompletionText -local GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle = GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle -local GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown -local GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches = GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches -local GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup = GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup -local QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY = QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY -local QUEST_TAG_TCOORDS, IsQuestSequenced = QUEST_TAG_TCOORDS, IsQuestSequenced -local Default, Quest = T.DefaultHandler, T.Quest -local format, wipe, select = format, table.wipe, select -local wipeall = B.wipeall -local lprint, iprint, tprint = B.print('Line'), B.print('Info'), B.print('Tracker') -local print = tprint -local fprint = B.print('Frame') - - -local superTrackQuestID, playerMoney, inScenario, showPOIs -Quest.Update = function(self, reason, ...) - local print = self.print - print('QuestTracker:Update() received') - T.UpdateActionButtons() - Default.Update(self, reason, ...) -end - -T.Quest.numButtons = 0 -local usedButtons = T.Quest.itemButtons -local freeButtons = T.Quest.freeButtons - -Quest.UpdateObjectives = function(self, block) - local print = lprint - print('|cFF'..self.internalColor..'UpdateObjectives()') - local info = block.info - - print((info.isAccount and 'isAccount' or ''), (info.isFaction and 'isFaction' or ''), (info.isDaily and 'isDaily' or ''), (info.isWeekly and 'isWeekly' or ''), info.tagID, info.tagName) - - local displayObjectives = true - local block_schema = 'default' - if info.isAccount then - if info.isFaction then - print(' faction', info.tagID) - block_schema = 'faction_'..info.tagID - else - print(' account', info.isAccount, info.isFaction) - block_schema = 'account' - end - elseif info.isDaily then - print(' daily', info.frequency) - block_schema = 'daily' - elseif info.isWeekly then - print(' weekly', info.frequency) - block_schema = 'weekly' - end - local completionText - if info.isComplete then - if info.isAutoComplete then - local questID, popupType = GetAutoQuestPopUp(info.logIndex) - if popupType == 'COMPLETE' then - print(' :: auto-complete quest :: set the message') - self:AddLine(block, T.strings.CLICK_TO_COMPLETE, nil, 'complete') - end - else - if not completionText or info.completionText then - info.completionText = GetQuestLogCompletionText(info.logIndex) - end - end - self:AddLine(block, info.completionText, nil, 'complete') - displayObjectives = false - print('|cFF'..self.internalColor..' :: complete quest :: show instruction: "'.. tostring(info.completionText) .. '"') - end - - Default.UpdateObjectives(self, block, block_schema, displayObjectives) - return 0, block_schema -end - -Quest.UpdateLine = function(handler, block, data) - local objectiveType = data.type - return data.text, nil, objectiveType -end - ------------------------------ ---- QUEST -local tremove, tinsert = tremove, tinsert -local GetQuestLogIndexByID, IsQuestWatched = GetQuestLogIndexByID, IsQuestWatched -Quest.QuestBlock = {} -Quest.LogBlock = {} -Quest.LogInfo = {} - -Quest.OnRemoved = function(block) - -end - -Quest.GetBlock = function(self, index) - local block = Default.GetBlock(self, index) - block:SetScript('OnEvent', Quest.OnRemoved) - block:RegisterEvent('QUEST_REMOVED') - return block -end - -local watchesChecked = {} -local infosChecked = {} -local GetQuestWatchIndex = GetQuestWatchIndex ---- Get a total of things to show, and straighten out the index while we're at it ---- Return the number shown, total in log, and the info table to parse -local blocksChecked = {} -Quest.GetNumWatched = function (self, id, added) - local print = self.print - B.print('Block')('########') - B.print('Block')('########') - superTrackQuestID = GetSuperTrackedQuestID() - playerMoney = GetMoney(); - inScenario = C_Scenario.IsInScenario(); - showPOIs = GetCVarBool("questPOI"); - local numAll = GetNumQuestLogEntries() - local numWatched = GetNumQuestWatches() - local bottomIndex = 1 - print('GetNumWatched', self.name, numWatched, 'of', numAll) - local start, limit = 1, numAll - - if id and not added then - -- if a particular id is supplied, add to checklist - if self.InfoBlock[id] then - blocksChecked[self.InfoBlock[id]] = self.InfoBlock[id] - end - end - - --- Start complicated frame-recycling bullshit - for logIndex = start, limit do - local reason1, reason2 = '', '' - local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) - local watchIndex = GetQuestWatchIndex(logIndex) - - -- check if: the watch data pointers don't match - if watchIndex and watchIndex >= bottomIndex then - local watchInfo = self.WatchInfo[watchIndex] - local watchBlock = self.WatchBlock[watchIndex] - if watchInfo and watchInfo.questID ~= questID then - print('GetNumWatched', 'trimming WatchInfo ['..watchIndex..'] =/=', questID) - self.WatchInfo[watchIndex] = nil - end - if watchBlock and watchBlock.info.questID ~= questID then - print('GetNumWatched', 'trimming WatchBlock ['..watchIndex..'] =/=', watchBlock:GetName()) - self.WatchBlock[watchIndex] = nil - blocksChecked[watchBlock] = watchBlock - end - end - - -- check if: the logIndex pointer doesn't match - local logBlock = self.LogBlock[logIndex] - if logBlock and logBlock.info.questID ~= questID then - print('GetQuests', 'replace info', logBlock.info.questID, '->', questID) - self.LogBlock[logIndex] = nil - blocksChecked[logBlock] = logBlock - end - - -- add to watch index if: the questID is non-zero - if questID ~= 0 then - self.Info[questID] = self:GetInfo(logIndex, watchIndex) - print('GetQuests', format('request info |cFF00FF00%2d|r |cFFFFFF00%6d|r |cFFFF4400%3s|r', logIndex, questID, tostring(watchIndex or ''))) - end - end - - --- After GetInfo pass, look for any non-conformant blocks and deal with them - for _, block in pairs(blocksChecked) do - local logIndex = GetQuestLogIndexByID(block.info.questID, 'player') - -- free if: logIndex doesn't resolve - if not logIndex then - B.print('Block')('GetNumWatched', '|cFFBBFF00block has no index '.. block:GetName()..'|r') - self:ClearBlock(block) - -- hide if: logIndex isn't being watched - elseif not IsQuestWatched(block.info.logIndex) then - B.print('Block')('GetNumWatched', '|cFFBBFF00fade from list '.. block:GetName()..'|r') - -- todo: figure out why animation gets clobbered - self:ClearBlock(block) - end - blocksChecked[block] = nil - end - - self.numWatched = numWatched - self.numAll = numAll - - return numWatched, numAll, self.WatchList -end - - ---- Returns an iterable table from which tracker blocks can be filled out. Data includes: --- All entry-layer GetXInfo return values --- Manifest of line data to be displayed in relation to the tracked object -Quest.GetInfo = function (self, logIndex, watchIndex) - local print = iprint - local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) - if ( not questID ) then - tprint('GetNumWatched', logIndex, watchIndex, '|cFFFF2299no data|r') - return - end - - Quest.Info[questID] = Quest.Info[questID] or {} - local q = Quest.Info[questID] - q.questID = questID - q.id = questID - q.logIndex = logIndex - q.watchIndex = watchIndex - - local numObjectives, requiredMoney, isAutoComplete, failureTime, timeElapsed, questType - = 0, 0, nil, false, false, 0 - if watchIndex then - local _ - _,_,_, numObjectives, requiredMoney, _, _, isAutoComplete, - failureTime, timeElapsed, questType = GetQuestWatchInfo(watchIndex) - self.WatchList[watchIndex] = q - --tprint(' |cFF88FF00GetInfo:|r set watch entry', watchIndex) - print('GetInfo:', logIndex, watchIndex, '|cFFFF2299'..title..'|r') - end - self.LogInfo[logIndex] = q - - q.numObjectives = numObjectives - q.requiredMoney = requiredMoney - q.failureTime = failureTime - q.timeElapsed = timeElapsed - - - - q.type = 'Quest' - q.title = title - q.level = level - q.displayQuestID = displayQuestID - q.suggestedGroup = suggestedGroup - - -- re-use Blizzard logic for consistency - local showQuest = true - if isTask then showQuest = false end - local watchMoney = false; - local tagID, typeTag, frequencyTag, completionTag, completionText - local isAccount, isFaction, isWeekly, isDaily = false, false, false, false - local isBreadcrumb = false - local questFailed = false - local watchMoney = false - local timerInfo, moneyInfo = false, false - local objectives = q.objectives or {} - - - -- Case 1: completed quest or "go to thing" breadcrumb - -- * 1 line containing the completion text - if ( isComplete and isComplete < 0 ) then - isComplete = false - questFailed = true - elseif ( numObjectives == 0 and playerMoney >= requiredMoney and not startEvent ) then - isComplete = true; - questFailed = false - if ( requiredMoney == 0 ) then - isBreadcrumb = true; - end - end - print('QuestFlags', (isComplete and 'isComplete' or ''), (questFailed and 'questFailed' or ''), (isBreadcrumb and 'isBreadcrumb' or '')) - - -- completion message? - local isSequenced = IsQuestSequenced(questID) - local temp_status = '' - if ( isComplete ) then - temp_status = 'COMPLETED_OBJECTIVES' - objectives = Quest.GetObjectives(questLogIndex, numObjectives, true, isSequenced, isStory) - if ( isAutoComplete ) then - temp_status = 'AUTOCOMPLETE_OBJECTIVES' - completionText = _G.QUEST_WATCH_CLICK_TO_COMPLETE - else - if ( isBreadcrumb ) then - temp_status = 'COMPLETE_BREADCRUMB' - completionText = GetQuestLogCompletionText(questLogIndex) - else - temp_status = 'COMPLETE_READY_FOR_TURN_IN' - completionText = _G.QUEST_WATCH_QUEST_READY - end - end - elseif ( questFailed ) then - temp_status = 'FAILED' - -- Case 2: failed quest - -- * 1 status line; hide other info - completionText = _G.FAILED - else - - temp_status = 'PROGRESS_OBJECTIVES' - -- Case 3: quest in progress - -- * Multiple objective lines - -- * Possible extra lines for money and timer data respectively - self.print(' QuestInfo', title, questType, isAutoComplete) - objectives = Quest.GetObjectives(logIndex, numObjectives, false, isSequenced, isStory) - q.objectives = objectives - - --- anything past here gets appended to existing objectives - - -- money - if ( requiredMoney > playerMoney ) then - - temp_status = temp_status .. '_MONEY' - local text = GetMoneyString(playerMoney).." / "..GetMoneyString(requiredMoney); - moneyInfo = { - type = 'money', - text = text, - finished = false, - requiredMoney = requiredMoney, - playerMoney = playerMoney, - } - tinsert(objectives, moneyInfo) - end - - -- time limit - if ( failureTime ) then - temp_status = temp_status .. '_TIMED' - if ( timeElapsed and timeElapsed <= failureTime ) then - timerInfo = { - type = 'timer', - finished = false, - timeElapsed = timeElapsed, - failureTime = failureTime, - } - tinsert(objectives, timerInfo) - end - end - end - q.objectives = objectives - q.moneyInfo = moneyInfo - q.timerInfo = timerInfo - q.completionText = completionText - - -- POI data - local POI = false - if ( showPOIs ) then - POI = { - questID = questID, - logIndex = logIndex, - watchIndex = watchIndex - } - local poiButton; - if ( hasLocalPOI ) then - - if ( isComplete ) then - POI.type = 'normal' - else - POI.type = 'numeric' - end - elseif ( isComplete ) then - POI.type = 'remote' - end - - local distance, onContinent = GetDistanceSqToQuest(logIndex) - if distance ~= nil and distance > 0 then - POI.distance = distance - POI.onContinent = onContinent - end - end - q.POI = POI - - --- Block Tags - -- completionTag - in progres, complete, failed, autocomplete - -- typeTag - account, faction, pvp, dungeon, group - -- frequencyTag - daily/weekly - local schema = 'default' - local questTagID, tagName = GetQuestTagInfo(questID) - local tagInfo = {} - local tagCoords = {} - local factionGroup = GetQuestFactionGroup(questID); - if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then - if( factionGroup ) then - tagID = "ALLIANCE" - schema = 'alliance' - if ( factionGroup == LE_QUEST_FACTION_HORDE ) then - tagID = "HORDE" - schema = 'horde' - end - isFaction = true - else - tagID = QUEST_TAG_ACCOUNT - isAccount = true - end - tagInfo['typeTag'] = tagID - tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] - elseif ( factionGroup) then - tagID = "ALLIANCE" - if ( factionGroup == LE_QUEST_FACTION_HORDE ) then - tagID = "HORDE" - end - isFaction = true - tagInfo['typeTag'] = tagID - tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] - end - - if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then - tagID = 'DAILY' - tagInfo['frequencyTag'] = tagID - tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] - isDaily = true - schema = 'daily' - elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then - tagID = 'WEEKLY' - tagInfo['frequencyTag'] = tagID - tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] - isWeekly = true - schema = 'weekly' - elseif( questTagID ) then - tagID = questTagID - end - - if( isComplete ) then - tagInfo['completionTag'] = 'COMPLETED' - elseif ( questFailed ) then - tagInfo['completionTag'] = 'FAILED' - end - tagCoords['completionTag'] = QUEST_TAG_TCOORDS[tagInfo['completionTag']] - - q.tagInfo = tagInfo - q.tagCoords = tagCoords - -- establishes the primary block tag for view compacting - q.tagID = tagID - q.tagName = tagName - - -- action button information - local link, icon, charges = GetQuestLogSpecialItemInfo(logIndex) - local start, duration, enable = GetQuestLogSpecialItemCooldown(logIndex) - if link or icon or charges then - q.specialItem = { - questID = questID, - logIndex = questLogIndex, - link = link, - charges = charges, - icon = icon, - start = start, - duration = duration, - enable = enable, - } - end - - if moneyInfo or timerInfo then - numObjectives = #objectives - end - - -- raw data - q.isComplete = isComplete - q.startEvent = startEvent - q.isAutoComplete = isAutoComplete - q.questType = questType - q.isTask = isTask - q.isStory = isStory - q.isOnMap = isOnMap - q.hasLocalPOI = hasLocalPOI - q.frequency = frequency - q.isComplete = isComplete - q.isStory = isStory - q.isTask = isTask - q.statusKey = temp_status - q.selected = (questID == superTrackQuestID) - - T.SetRewards(q, questID) - - q.questID = questID - q.logIndex = logIndex - q.watchIndex = watchIndex - q.id = questID - q.schema = schema - - if Devian and Devian.InWorkspace() then - print('QuestStatus', temp_status, '|cFF00FF00questLogIndex|r:', logIndex, title) - local temp ={} - local data_txt = '|cFF'..self.internalColor..'values:|r' - for k,v in pairs(q) do - if type(v) =='number' then - data_txt = data_txt .. ' |cFFFFFF00'..k..'|r: ' .. tostring(v) - elseif type(v) == 'table' then - tinsert(temp, k) - end - end - print('DataStatus',data_txt) - sort(temp, function(a,b) return a < b end) - for i, k in ipairs(temp) do - iprint('GetInfo', questID, ''..k..'|r') - for kk,v in pairs(q[k]) do - iprint('GetInfo', questID, kk, '=', v) - end - end - end - - return q -end - -Quest.GetObjectives = function(logIndex, numObjectives, isComplete, isSequenced, isStory) - local print = Quest.print - local objectives = {} - if not logIndex then - return - end - - for i = 1, numObjectives do - local text, type, finished = GetQuestLogLeaderBoard(i, logIndex) - - local progress = 0 - if finished then - progress = 1 - elseif text then - local quantity, maxQuantity = text:match('^(%d+)/(%d+)') - if quantity and maxQuantity then - progress = quantity / maxQuantity - --print('GetObjectives', 'calculated objective progress:', quantity, '/', maxQuantity, '=', progress) - end - end - - print('GetObjectives', format('|cFF88FF88#%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)), '('.. tostring(progress)..')') - - - objectives[i] = { - index = i, - type = type, - text = text, - finished = finished, - progress = progress - } - end - return objectives -end - -local huge, sqrt = math.huge, math.sqrt -Quest.GetClosest = function() - local minID, minTitle - local minDist = huge - local numQuests = GetNumQuestLogEntries() - for questIndex = 1, numQuests do - local distance, onContinent = GetDistanceSqToQuest(questIndex) - local title, level, _, _, _, _, _, _, questID = GetQuestLogTitle(questIndex) - if onContinent and distance < minDist then - minDist = distance - minTitle = title - minID = questID - end - end - - print('nearest quest is', minTitle, 'by', sqrt(minDist)) - return minID, minTitle, minDist -end - -Quest.OnTurnIn = function(self, questID, xp, money) -end - -Quest.Select = function (handler, block) - if block.info.isAutoComplete and block.info.isComplete then - ShowQuestComplete(block.info.logIndex) - else - SetSuperTrackedQuestID(block.info.questID) - end -end - -Quest.Link = function(handler, block) - local questLink = GetQuestLink(block.info.logIndex); - if ( questLink ) then - ChatEdit_InsertLink(questLink); - end -end - -Quest.Open = function(handler, block) - QuestMapFrame_OpenToQuestDetails(block.info.questID) -end - -Quest.Remove = function(handler, block) - print('removing', block.info.logIndex, 'from watcher') - RemoveQuestWatch(block.info.logIndex) -end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/ScenarioData.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,14 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/13/2016 8:17 PM +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') + +local Scenario = T.Scenario + +Scenario.GetNumWatched = function() + if true then return 0, 0, nil end +end +
--- a/ObjectiveTracker/Scenarios.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/13/2016 8:17 PM -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') - -local Scenario = T.Scenario - -Scenario.GetNumWatched = function() - if true then return 0, 0, nil end -end -
--- a/ObjectiveTracker/TrackerBlock.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 4/24/2016 11:30 AM ---- These functions deal with propagating and managing block/line templates -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local _G, ipairs, max, tostring = _G, ipairs, max, tostring -local tinsert, tremove, tContains = table.insert, table.remove, tContains -local Default = T.DefaultHandler -local CreateFrame = CreateFrame -local print = B.print('Layout') -local bprint = B.print('Block') -local lprint = B.print('Layout') -local fprint = B.print('Frame') -local used, free - -local blockFadeOut_OnPlay = function(self) - fprint(self:GetName(), '|cFF00FF00PLAY|r', debugstack(1,3,1)) -end -local blockFadeOut_OnFinished = function(self) - fprint(self:GetName(), '|cFF00FF00FINISHED|r', debugstack(1,3, 1)) -end - -local tMove = function(source, dest, frame) - -- if it's already in the stack, sanity check source stack - local removed - if tContains(dest, frame) then - for i, entry in ipairs(source) do - if entry == frame then - removed = i - tremove(source, i) - break - end - end - -- still need to resolve position - for i, entry in ipairs(dest) do - if entry == frame then - bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. i..']') - return i - end - end - else - -- if it's not, then pull from source stack - for i, entry in ipairs(source) do - if entry == frame then - removed = i - tremove(source, i) - break - end - end - tinsert(dest, frame) - bprint('tMove result:', (removed and ('|cFFFF4400a|r['..removed .. '] is now ') or '') .. '|cFF00FF00b|r[' .. #dest..']') - return #dest - end -end - - ---- Creates or retrieves a complete line data object -Default.GetLine = function(handler, block, lineIndex) - local print = lprint - local blockIndex = block.index - local lines = block.lines - if not lineIndex then - lineIndex = block.currentLine + 1 - print(' |cFFFFFF00generating a frame') - end - - block.numLines = max(block.numLines, lineIndex) - - if not lines[lineIndex] then - print(' |cFF00FF88created line #'..lineIndex..' from for '..handler.name..' block #'..blockIndex) - lines[lineIndex] = CreateFrame('Frame', 'Vn'..handler.name .. blockIndex..'ObjectiveLine'..lineIndex, block, 'VeneerTrackerObjective') - local line = lines[lineIndex] - line.index = lineIndex - line.height = 0 - line.schema = '' - B.SetConfigLayers(line) - - if debug then - for _, region in ipairs(lines[lineIndex].debug) do - region:Show() - end - end - - end - return lines[lineIndex] -end - - - ---- Creates or retrieves a complete block frame object ---- todo: make it use data index to avoid re-coloring every block -Default.GetBlock = function(handler, index) - local print = bprint - print('|cFF0088FF'..handler.name..':GetBlock', index) - local block = handler.InfoBlock[index] - local used = handler.usedBlocks - local free = handler.freeBlocks - - if block then - print(block.info.id, index) - end - - -- if the frame entry is still good, sort heaps - if block and block.info.id == index then - block.posIndex = tMove(free, used, block) - print(' |cFFFFFF00using '..handler.name..'|r.|cFF00FFBBusedBlocks['..tostring(block.posIndex)..'] ('.. block:GetName()..', "'..tostring(block.info.title)..'")') - else - local source = 'cache' - if #handler.freeBlocks >= 1 then - block = tremove(handler.freeBlocks) - print(' |cFF00FF00 assigning from free heap', block:GetName()) - else - - local blockIndex = (#handler.usedBlocks + #handler.freeBlocks) + 1 - block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock') - --block:SetParent() - block.schema = '' - block.lines = {} - block.numLines = 0 - block.currentLine = 0 - block.attachmentHeight = 0 - block.offset = 0 - B.SetConfigLayers(block) - --- methods for event handlers - - block.Select = handler.Select - block.Open = handler.Open - block.Remove = handler.Remove - block.Link = handler.Link - block.clickZone:SetScript('OnMouseUp', function(self, ...) handler.OnMouseUp(block, ...) end) - block.clickZone:SetScript('OnMouseDown', function(self, ...) handler.OnMouseDown(block, ...) end) - block:ClearAllPoints() - block.index = blockIndex - - block.blockFadeOut:SetScript('OnPlay', blockFadeOut_OnPlay) - - source = 'new' - end - handler.InfoBlock[index] = block - block.posIndex = tMove(free, used, block) - print(' |cFF00FF00('..source..')|r |cFF0088FF'..handler.name..'|r.|cFF00FFBBusedBlocks['..block.posIndex..'] =|r', block:GetName()) - end - block.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished) - block:SetScript('OnHide', function(self) - fprint(self:GetName(), '|cFF00FF00HIDE|r', debugstack(1,3,1)) - if(self.DebugTab:IsShown()) then - self.DebugTab:Hide() - end - self.blockFadeOut:SetScript('OnFinished', blockFadeOut_OnFinished) - self.isAnimating = nil - end) - print(' used/free: |cFFFFFF00' .. #handler.usedBlocks .. '|r/|cFF00FFFF'..#handler.freeBlocks ..'|r') - return block -end - ---- begins a blockFadeOut animation and fires FreeBlock when that's done -Default.ClearBlock = function(handler, block) - if block.isAnimating then - return - end - - block.isAnimating = true - block.blockFadeOut:SetScript('OnFinished', nil) - block.blockFadeOut:SetScript('OnFinished', function(self) - fprint(self:GetName(), '|cFFFFFF00FINISHED|r', debugstack()) - handler:FreeBlock(block) - self:SetScript('OnFinished', blockFadeOut_OnFinished) - block.isAnimating = nil - end) - block.blockFadeOut:Play() -end - ---- remove a block from visible existence; not called directly -Default.FreeBlock = function(handler, block) - bprint('|cFFFF4400FreeBlock|r', block:GetName()) - local used = handler.usedBlocks - local free = handler.freeBlocks - tMove(used, free, block) - - bprint(' |cFFFF4444used/free:|r |cFFFFFF00' .. #used .. '|r/|cFF00FFFF'..#free ..'|r') - - block:Hide() - local animations = {block:GetAnimationGroups() } - for i, animGroup in ipairs(animations) do - bprint(' animGroup', i, animGroup:GetName()) - animGroup:Stop() - end -end - - - ---- Get a usable widget for the given achievement criteria set. --- Returns a frame object with dimensioning parameters needed to size the receiving tracker block -local wr = T.WidgetRegistry -T.GetWidget = function(data, objectiveType, objectiveKey) - local print = B.print('ObjectiveWidgets') - local widgetType = objectiveType - local widget - local isNew - if wr[widgetType] and wr[widgetType].used[objectiveKey] then - widget = wr[widgetType].used[objectiveKey] - print('|cFF00FF00Updating ('..objectiveKey..')', widget) - elseif not wr[widgetType] or #wr[widgetType].free == 0 then - -- creating a new frame - isNew = true - widget = CreateFrame(widgetType, 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) - print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) - T.UpdateSchema(widgetType, data.schema or 'default') - else - -- recycling for a different criteria set - isNew = true - widget = tremove(wr[widgetType].free) - print('|cFFFFFF00Acquiring released widget', widget:GetName()) - end - - for k,v in pairs(data) do - if not widget[k] then - widget[k] = v - tprint('widget', widget:GetName(), k, v) - end - end - - wr[widgetType].used[objectiveKey] = widget - widget.objective = data - widget.key = objectiveKey - T.InitializeWidget(widget, isNew) - return widget -end \ No newline at end of file
--- a/ObjectiveTracker/TrackerFrame.lua Mon Apr 25 03:32:34 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,698 +0,0 @@ ---- ${PACKAGE_NAME} --- @file-author@ --- @project-revision@ @project-hash@ --- @file-revision@ @file-hash@ --- Created: 3/30/2016 12:49 AM ---- Everything that involves directly placing elements on the screen goes here. Sizing, spacing, tiling, etc. -local B = select(2,...).frame -local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') -local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band -local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove -local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent -local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText -local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent -local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs -local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame -local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow -local band, bor = bit.band, bit.bor -local print = B.print('Layout') -local oprint = B.print('Objectives') -local bprint = B.print('Block') -local tprint = B.print('Tracker') -local lprint = B.print('Layout') -local unitLevel = 1 - -local REWARD_POPUP = _G.VeneerRewardsPopOut -local ANIM_STATE = 'Animation: %04X' -local INIT_STATE = 'Init: %04X' - ---- Bitfields of import ---- control value for everything -local OBJECTIVE_TRACKER_UPDATE_REASON = _G.OBJECTIVE_TRACKER_UPDATE_REASON ---- flags reason categories where frame layout requires initializing (starts high) -local initReason = 0xFFFF ---- flags reason categories where frame anchor updates must be delayed because of an ongoing animation (starts low) -local animateReason = 0x0000 - ---- FRAMES -local Wrapper = _G.VeneerObjectiveWrapper -local Scroller = Wrapper.scrollArea -local Scroll = _G.VeneerObjectiveScroll -local orderedHandlers = T.orderedHandlers -local orderedNames = T.orderedNames - ---- FRAME TEMP VARIABLES -local wrapperWidth, wrapperHeight = 0, 0 -local scrollWidth, scrollHeight - ---- SCHEMA VARIABLES -local schemaName, lastSchema = { - tracker = '', - block = '', - line = '' -}, {} -local trackerSchema, blockSchema, lineSchema - -local itemButtonSize, itemButtonSpacing = 36, 1 -local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed -local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE' -local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 } -local rewardSize = 24 - -local headerHeight, headerColor, headerSpacing = 16, {1,.75,0,1}, 2 -local headerbg = {'VERTICAL', 1, 1, 0.5, 0.5, 1, 1, 0.5, 0} -local headerFont, headerSize, headerOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 14, 'OUTLINE' - -local titlebg = {'HORIZONTAL', 1, 0, .7, 0, 1, 0, .7, .2} -local titleFont, titleSize, titleOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE' -local titleColor = {0,.7,1,1} - -local textbg = {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 } -local textFont, textSize, textOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE' -local textColor = {1,1,1,1 } - -local widgetTextFont, widgetTextSize, widgetTextOutline = [[Interface\Addons\SharedMedia_MyMedia\font\XOIREQE.TTF]], 11, 'OUTLINE' -local widgetTextColor = {1,1,1,1 } -local widgetHeight, widgetBorder = 17, 1 - - -local selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225} -local titleSpacing, textSpacing, blockSpacing = 3, 3, 1 -local titleIndent, textIndent,selectionIndent = 2, 5, 50 ---- END SCHEMA -local blockPosition - - -local SetAnimate = function(reason, animate) - print('comparing', animateReason, reason) - if animate then - if band(animateReason, reason) == 0 then - animateReason = animateReason + reason - end - else - if band(animateReason, reason) > 0 then - animateReason = animateReason - reason - end - end - Wrapper.AnimState:SetFormattedText(ANIM_STATE, animateReason) -end - - ---- schema swapper -T.UpdateSchema = function(layer, newSchema) - if not (T.Conf.Schema[layer] and T.Conf.Schema[layer][newSchema]) then - return - elseif schemaName[layer] == newSchema then - return - end - lastSchema[layer] = schemaName[layer] - schemaName[layer] = newSchema - local c = T.Conf.Schema[layer][newSchema] - - if layer == 'tracker' then - headerHeight, headerSpacing = c.headerHeight, c.headerSpacing - headerColor = c.headerColor - headerbg = c.headerbg - headerFont, headerSize, headerOutline = unpack(c.headerFont) - trackerSchema = newSchema - elseif layer == 'block' then - titlebg = c.titlebg - titleFont, titleSize, titleOutline = unpack(c.titleFont) - selectionbg = c.selectionbg - titleSpacing, textSpacing, blockSpacing = c.titleSpacing, c.textSpacing, c.blockSpacing - titleIndent, textIndent,selectionIndent = c.titleIndex, c.textIndex, c.selectionIndent - titleColor = c.titleColor - print(unpack(c.titleColor)) - rewardSize = 24 - textFont, textSize, textOutline = unpack(c.textFont) - textbg = c.textbg - textIndent = c.textIndent - rewardSize = c.rewardSize - blockSchema = newSchema - elseif layer == 'line' then - textColor = c.textColor - lineSchema = newSchema - elseif layer == 'widget' then - widgetTextColor = c.textSpacing - widgetTextFont, widgetTextSize, widgetTextOutline = unpack(c.textFont) - end - tprint('|cFFFF0088 Schema:|r', layer, lastSchema[layer], '->', newSchema) -end --- todo: figure out why objectives go invisible -local anchorPoint, anchorFrame -local abs, GetTime = math.abs, GetTime -Default.AddTracker = function(handler, frame, index) - local isInitialized = true - if initReason and (band(initReason, handler.updateReason) > 0 ) then - isInitialized = false - initReason = initReason - handler.updateReason - print('|cFF00FF00%%% initialization status update:', format('%04X', initReason)) - - frame.SlideIn:SetScript('OnPlay', function() - SetAnimate(handler.updateReasonModule, true) - end) - - frame.SlideIn:SetScript('OnFinished', function() - SetAnimate(handler.updateReasonModule, false) - end) - - if initReason == 0 then - initReason = nil - end - end - - if index == 1 then - print('|cFF00FF00### beginning wrapper layout -----------------') - anchorPoint, anchorFrame = 'TOP', Scroll - wrapperHeight = 18 - end - - frame.destinationOffset = -wrapperHeight - print(frame.destinationOffset, frame.previousOffset) - if isInitialized and (abs(frame.previousOffset - frame.destinationOffset) > 0.9) and frame:IsVisible() then - if frame.wasEmpty then - frame.previousOffset = -Wrapper:GetHeight() - end - - local postFrame, postPoint = anchorFrame, anchorPoint - local delta = frame.destinationOffset - frame.previousOffset - local _, _, _, _, offset = frame:GetPoint(1) - print(' |cFF00FFBBpushing', frame:GetName(), delta, 'pixels, from', frame.previousOffset, '(', offset, ')') - frame.SlideIn.translation:SetTarget(frame) - frame.SlideIn.translation:SetOffset(0, delta) - frame.SlideIn:Play() - --for i, b in ipairs(handler.usedBlocks) do - --b.SlideIn.translation:SetOffset(0, delta) - -- b.SlideIn:Play() - --end - local start = GetTime() - frame.SlideIn:SetScript('OnFinished', function() - print(' |cFF00BBFF'..frame:GetName(), 'moved', delta, 'over duration of ', GetTime()-start) - frame:SetParent(Scroll) - frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) - frame.previousOffset = frame.destinationOffset - frame.SlideIn:SetScript('OnFinished', nil) - if Wrapper.destinationHeight then - Wrapper:SetHeight(Wrapper.destinationHeight) - Scroller:SetHeight(Wrapper.destinationHeight) - Scroll:SetHeight(Wrapper.destinationHeight) - Wrapper.previousHeight = Wrapper.destinationHeight - Wrapper.destinationHeight = nil - end - - end) - else - print(' |cFF00BBFFpinning '..handler.name..' to', anchorFrame:GetName(), anchorPoint, '|rcurrent frame height:', frame.height) - print(' |cFFFF0088total height:', wrapperHeight) - frame:ClearAllPoints() - frame:Show() - frame:SetParent(Scroll) - frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset) - frame:SetPoint('LEFT', Scroll, 'LEFT') - frame:SetPoint('RIGHT', Scroll, 'RIGHT') - frame.previousOffset = frame.destinationOffset - handler.initialized = true - end - - frame.title:SetFont(headerFont, headerSize, headerOutline) - frame.titlebg:SetHeight(headerHeight) - frame.title:SetTextColor(unpack(headerColor)) - - if frame.height ~= frame.previousHeight then - frame:SetHeight(frame.height) - end - - if frame.wasEmpty then - frame.headerFade:Play() - frame.wasEmpty = nil - end - - wrapperHeight = wrapperHeight + frame.height - anchorFrame = handler.frame - anchorPoint = 'BOTTOM' - -end - -Default.AddBlock = function(self, block, blockIndex) - local blockIndex = blockIndex or (self.currentBlock + 1) - local print = bprint - local tracker = self.frame - local info = block.info - - block.index = blockIndex - - print('blockschema', blockSchema, block.schema) - if blockSchema ~= block.schema then - T.UpdateSchema('block', block.schema) - print(' ### activating block schema:|cFF0088FF', block.schema) - end - - block:SetWidth(T.Conf.Wrapper.Width) - block.title:SetSpacing(titleSpacing) - block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing) - block.title:SetPoint('LEFT', block, 'LEFT', titleIndent, 0) - block.title:SetTextColor(unpack(titleColor)) - block.titlebg:SetTexture(1,1,1,1) - block.titlebg:SetGradientAlpha(unpack(titlebg)) - block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0) - block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing) - block.status:SetSpacing(textSpacing) - block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing) - block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0) - block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0) - block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0) - block.statusbg:SetTexture(1,1,1,1) - block.statusbg:SetGradientAlpha(unpack(textbg)) - block.SelectionOverlay:SetGradientAlpha(unpack(selectionbg)) - block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0) - block.SelectionOverlay:SetPoint('BOTTOMRIGHT') - - local anchor, target, point, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 - for i, tile in ipairs(block.rewardTile) do - --print(rewardSize) - tile:SetSize(rewardSize, rewardSize) - tile:ClearAllPoints() - tile:SetPoint(anchor, target, point, x, y) - block.rewardLabel[i]:SetPoint('TOP', tile, 'TOP', 0, 0) - anchor, target, point, x, y = 'TOPRIGHT', tile, 'TOPLEFT', -2, 0 - end - - - local titleHeight = floor(block.title:GetHeight()+.5) - local titlebgHeight = titleHeight + titleSpacing*2 - block.titlebg:SetHeight(titlebgHeight) - - local statusHeight = floor(block.status:GetHeight()+.5) - local statusbgHeight = statusHeight + textSpacing*2 - local attachmentHeight =floor(block.attachmentHeight + .5) - - self.print('AddBlock', 'anchor to|cFF0088FF', self.currentAnchor:GetName()) - self.print('AddBlock', 'attachment:|cFF00FF00', attachmentHeight, '|rtitle:|cFF00FF00', titlebgHeight, '|r('.. titleHeight..')') - if attachmentHeight > 0 then - attachmentHeight = attachmentHeight + textSpacing - end - - block.height = titlebgHeight + attachmentHeight - block:SetHeight(block.height) - - if block.debug then - local func = (B.Conf.GuidesMode == true) and 'Show' or 'Hide' - for _, region in ipairs(block.debug) do - region[func]() - end - end - - --- Handler vars - if blockIndex == 1 then - tracker.previousHeight = tracker.height - tracker.height = headerHeight - blockPosition = -headerHeight - self.print('AddBlock', 'new layout: headerHeight:|cFF00FF00', headerHeight, '|rpreviousHeight:|cFF00FF00', tracker.previousHeight) - else - blockPosition = blockPosition - self.print('AddBlock', 'advancing: height:|cFF8888FF', tracker.height) - end - self.currentBlock = blockIndex - self.currentAnchor = block - - block:SetPoint('TOPLEFT', self.frame, 'TOPLEFT', 0, blockPosition) - block:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) - self.numBlocks = self.numBlocks + 1 - print(' |cFFFFFF00'..tracker.height..'|r', '|cFF00FF00'..block:GetName()..'|r', block.height, tracker.height) - tracker.height = tracker.height + block.height - blockPosition = blockPosition - block.height - - block:Show() - - - if Devian and Devian.InWorkspace() then - block.DebugTab:SetParent(UIParent) - block.DebugTab:SetPoint('TOPRIGHT', block, 'TOPLEFT', 0, 0) - block.DebugTab.status:SetText(tostring(block.schema) .. ' @|cFF00FF00' .. tostring(block.posIndex) .. '|r #|cFFFFFF00'.. tostring(info.logIndex or info.id) .. '|r'.. - ' H|cFFFFFF00' .. tostring(block.height) .. ' L|cFF00FFFF' .. tostring(block.numLines) ..'|r') - block.DebugTab:Show() - end -end - ---- Used as an iterator of sorts for cascaded tag icon placements (the daily/faction/account icons) -Default.AddTag = function (handler, block, tagInfo, tagPoint, tagAnchor, tagRelative) - local print = bprint - - for order, tagName in ipairs(block.info.tagInfo) do - local tag = block[tagName] - if block.tagCoords[tagName] and tag then - tag:SetTexCoord(unpack(block.tagCoords[tagName])) - tag:Show() - tag:SetPoint(tagPoint, tagAnchor, tagRelative, 0, 0) - tagPoint, tagAnchor, tagRelative = 'TOPRIGHT', tag, 'TOPLEFT' - else - block[tagName]:Hide() - end - end - - return tagPoint, tagAnchor, tagRelative -end - - ---- Adds the given line to the current content and advances the anchor pointer to that new line for the following call. -Default.AddLine = function(handler, block, text, attachment, template) - local print = lprint - local lineIndex = block.currentLine + 1 - local line = handler:GetLine(block, lineIndex) - - line.index = lineIndex - template = template or 'default' - if template and lineSchema ~= template then - print(' |cFF00FF00change schema', template) - T.UpdateSchema('line', template) - end - line.status:SetSpacing(textSpacing) - line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) - line.status:SetPoint('RIGHT', line, 'RIGHT',0, 0) - line.status:SetTextColor(unpack(textColor)) - line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing) - line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0) - line:SetPoint('LEFT', block, 'LEFT') - line:SetPoint('RIGHT', block, 'RIGHT') - line:Show() - line:SetScript('OnMouseUp', function(self, button) - handler.OnMouseUp(block, button) - end) - - - handler.print('AddLine', '|cFF00FFFF'..tostring(line.schema)..'|r', line:GetName()) - --[[ - for i = 1, line:GetNumPoints() do - tprint(' - ', line:GetPoint(i)) - end - tprint(' - ', line:GetSize()) - tprint(' - ', line:GetParent(), line:GetParent():IsVisible()) - tprint(' - ', line:IsVisible()) - --]] - - - - - -- fill in the text, then derive pixel-rounded height - line.status:SetText(text) - line.height = floor(line.status:GetStringHeight()+.5) - - -- For progressbar and timer lines, status text may be used as the title heading - if attachment then - attachment:SetPoint('TOP', line, 'TOP') - attachment:SetPoint('LEFT', line, 'LEFT', textIndent, 0) - attachment:SetPoint('RIGHT', line, 'RIGHT') - print(' |cFFFF0088doing things with a widget', attachment:GetSize()) - line.height = attachment:GetHeight() - if text then - line.height = max(line.height, line.status:GetStringHeight()) - end - if attachment.status:GetText() then - line.height = max(line.height, attachment.status:GetStringHeight()) - end - attachment:Show() - end - - line:SetHeight(line.height) - block.attachmentHeight = block.attachmentHeight + line.height + textSpacing - - local debug_points = '' - for i = 1, line:GetNumPoints() do - local point, parent, anchor = line:GetPoint(i) - debug_points = debug_points .. tostring(parent:GetName()) .. ', ' .. anchor .. ' ' - end - - print(' |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n |cFF0088FFsize:|r", line.height, - "|cFF0088FFpoint:|r", debug_points, "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N')) - block.currentLine = lineIndex - block.endPoint = line -- edge used for the next block - - return lineIndex -end - - - ----------- ---- Top level methods - - -T.UpdateItemButtonAnchor = function (block, itemButton) - local print = bprint - print('**|cFF0088FF'..itemButton:GetName(), '|r:Update()') - if itemButton.questID ~= block.info.questID then - print('** |cFFFF0088mismatched block assignment', itemButton.questID,'<~>', block.info.questID) - -- something happened between this and last frame, go back and set new probes - return T.UpdateActionButtons() - end - - local previousItem = itemButton.previousItem - local upper_bound = Scroller:GetTop() + Scroller.snap_upper - local lower_bound = Scroller:GetBottom() + Scroller.snap_lower + itemButtonSize - local point, anchor, relative - - if block:GetBottom() < lower_bound then - print('** ',block:GetName() ,'|cFFFFFF00bottom =', floor(block:GetBottom()+.5), 'threschold =', floor(lower_bound+.5)) - if previousItem then - print('adjusting', previousItem:GetName()) - previousItem:ClearAllPoints() - previousItem:SetPoint('BOTTOM', itemButton, 'TOP', 0, itemButtonSpacing) - end - itemButton:ClearAllPoints() - itemButton.x = Wrapper:GetLeft() -4 - itemButton.y = Wrapper:GetBottom() - point, anchor, relative = 'BOTTOMRIGHT', UIParent, 'BOTTOMLEFT' - Scroller.snap_lower = Scroller.snap_lower + itemButtonSize + itemButtonSpacing - - elseif block:GetTop() > upper_bound then - print('** ',block:GetName() ,'|cFFFFFF00top =', floor(block:GetTop()+.5), 'threschold =', floor(upper_bound+.5)) - itemButton:ClearAllPoints() - if previousItem then - print('latch onto another piece') - point, anchor, relative ='TOP', previousItem, 'BOTTOM' - itemButton.x = 0 - itemButton.y = -itemButtonSpacing - else - print('latch at corner', Scroller:GetLeft() -itemButtonSpacing, Scroller:GetTop()) - point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' - itemButton.x = Scroller:GetLeft() -4 - itemButton.y = Scroller:GetTop() - end - itemButton:Show() - Scroller.snap_upper = Scroller.snap_upper - (itemButtonSize + itemButtonSpacing) - else - print('** ',block:GetName() ,'|cFF00FF00span =', floor(block:GetBottom()+.5), floor(block:GetTop()+.5), 'threschold =', floor(lower_bound+.5)) - itemButton:ClearAllPoints() - itemButton.x = block:GetLeft() - itemButtonSpacing - itemButton.y = block:GetTop() - point, anchor, relative = 'TOPRIGHT', UIParent, 'BOTTOMLEFT' - end - - itemButton:SetPoint(point, anchor, relative, itemButton.x, itemButton.y) - itemButton:Show() -end - -T.UpdateItemButtonCooldown = function(button) - -end - -function T:FinishWrapper () - if wrapperHeight > Wrapper.previousHeight then - Wrapper:SetHeight(wrapperHeight) - Scroller:SetHeight(wrapperHeight*3) - Scroll:SetHeight(wrapperHeight) - Wrapper.previousHeight = wrapperHeight - Wrapper.destinationHeight = wrapperHeight - end - Scroller:SetVerticalScroll(B.Conf.ObjectiveScroll or 0) - print('|cFF00FF00### end of wrapper layout', Wrapper:GetSize()) - print(' |cFF00FF00Scroller:', Scroller:GetSize()) - print(' |cFF00FF00Scroll:', Scroll:GetSize()) - for i = 1, Wrapper:GetNumPoints() do - print('|cFF00FF00 ', Wrapper:GetPoint(i)) - end - for i = 1, Scroller:GetNumPoints() do - print('|cFF00FF00 ', Scroller:GetPoint(i)) - end - for i = 1, Scroll:GetNumPoints() do - print('|cFF00FF00 ', Scroll:GetPoint(i)) - end - - if Devian and Devian.InWorkspace() then - Wrapper.AnimState:SetFormattedText(ANIM_STATE, animateReason) - end - - Wrapper:Show() - Scroller:Show() - Scroll:Show() -end - - ------------------------------------------ --- Criteria frames - ---[[ - text = description, - type = type, - finished = completed, - quantity = quantity, - requiredQuantity = requiredQuantity, - characterName = characterName, - flags = flags, - assetID = assetID, - quantityString = quantityString, - criteriaID = criteriaID, -]] -T.WidgetRegistry = {} -local wr = T.WidgetRegistry - ---- WidgetTemplate 'OnLoad' -T.RegisterWidget = function(frame) - local print = B.print('ObjectiveWidgets') - local widgetType = frame.widgetType - if not wr[frame.widgetType] then - print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) - wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } - else - print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) - wr[widgetType].lastn = wr[widgetType].lastn + 1 - end -end ---- WidgetTemplate 'OnShow' -local wrapperWidth, textIndent -T.InitializeWidget = setmetatable({}, { - __call = function(t, frame, isNew, ...) - -- todo: config pull - if not wrapperWidth then - wrapperWidth = T.Conf.Wrapper.Width - textIndent = T.Conf.Wrapper.TextIndent - end - - tprint('Initialize', frame:GetName(), isNew, ...) - frame:SetWidth(wrapperWidth - textIndent * 2) - frame:SetScript('OnEvent', T.UpdateWidget[frame.widgetType]) - frame:RegisterEvent('QUEST_LOG_UPDATE') - frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE') - frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED') - frame:RegisterEvent('CRITERIA_UPDATE') - frame:RegisterEvent('CRITERIA_COMPLETE') - frame:RegisterEvent('CRITERIA_EARNED') - t[frame.widgetType](frame, isNew) - T.UpdateWidget[frame.widgetType](frame, isNew) - end, -}) - ---- WidgetTemplate 'OnEvent' -T.UpdateWidget = setmetatable({}, { - __call = function(t, frame, isNew, ...) - tprint('Update', frame:GetName(), isNew, ...) - if not frame.widgetType then - return - end - - return t[frame.widgetType](frame, isNew) - end -}) - - -local progressHeight = 17 -local progressBorder = 1 -local progressFont = _G.VeneerCriteriaFontNormal - -local lprint = B.print('Line') -T.InitializeWidget.StatusBar = function(self, isNew) - local print = lprint - local c = T.Conf.Wrapper - - tprint(self:GetName(), isNew) - if isNew then - self:SetMinMaxValues(0, self.maxValue) - - self:SetHeight(widgetHeight) - self.height = widgetHeight - - self.status:SetFont(widgetTextFont, widgetTextSize, widgetTextOutline) - self.status:SetTextColor(unpack(widgetTextColor)) - end - self:SetValue(self.value) - - self.status:SetText(self.objective.quantityString) -end - -T.UpdateWidget.StatusBar = function (self) - local value, maxValue = self.value, self.maxValue - print('update vals:') - for k,v in pairs(self) do - print(k, v) - end - self.width = self.width or self:GetWidth() - self:SetValue(self.value) - local format = self.format or '%d/%d' - self.status:SetFormattedText(format, value, maxValue) - local progress = (value / maxValue) - if progress > 0 then - print('color:', 1-progress*2 , progress*2 - 1,0,1) - print('width:', (self.width -progressBorder * 2) * progress) - self:SetStatusBarColor(1-progress*2 , progress*2,0,1) - end -end - - -T.InitializeWidget.Hidden = function (self) - self.height = 0 -end -T.UpdateWidget.Hidden = function (self) - self.height= 0 -end - - ---- Queue any active item buttons for update for that frame -local iprint = B.print('ItemButton') -local Quest = T.Quest -local IsQuestWatched, InCombatLockdown = IsQuestWatched, InCombatLockdown -T.UpdateActionButtons = function(updateReason) - local print = iprint - Scroller.snap_upper = 0 - Scroller.snap_lower = 0 - local print = B.print('ItemButton') - if updateReason then - print = B.print('IB_'..updateReason) - end - - local previousItem - for questID, itemButton in pairs(Quest.itemButtons) do - local info= T.Quest.Info[questID] - - print('|cFF00FFFF'.. questID .. '|r', itemButton:GetName()) - local block = T.Quest.QuestBlock[questID] - if block then - -- Dispatch the probe - if IsQuestWatched(info.logIndex) then - itemButton.previousItem = previousItem - print(' |cFFFFFF00probing', block:GetName()) - block:SetScript('OnUpdate', function() - if block:GetBottom() and not InCombatLockdown() then - print(' '..block:GetName()..' |cFF00FF00probe hit!') - T.UpdateItemButtonAnchor(block, itemButton, itemButton.previousItem) -- needs to be previousItem from this scope - block:SetScript('OnUpdate', nil) - - end - end) - previousItem = itemButton - else - print('hidden block or unwatched quest') - itemButton.previousItem = nil - itemButton:Hide() - end - elseif itemButton:IsVisible() then - print(' |cFFFF0088hiding unwatched quest button', itemButton:GetName()) - itemButton.previousItem = nil - itemButton:Hide() - else - print(' |cFFBBBBBBignoring hidden log quest button', itemButton:GetName()) - end - end -end - -Default.FadeOutBlock = function (handler, blockIndex) - -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ObjectiveTracker/Update.lua Mon Apr 25 13:51:58 2016 -0400 @@ -0,0 +1,289 @@ +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 4/17/2016 7:33 AM +--- Baseline update work +local B = select(2,...).frame +local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') +local Devian = Devian +local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band +local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove +local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent +local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText +local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent +local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs +local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame +local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow +local print = B.print('Tracker') +local oprint = B.print('Objectives') +local bprint = B.print('Block') +local tprint = B.print('Tracker') +local lprint = B.print('Line') +local unitLevel = 1 +local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON +local debug = false + +--- FRAMES +local Wrapper = _G.VeneerObjectiveWrapper +local Scroller = Wrapper.scrollArea +local Scroll = _G.VeneerObjectiveScroll +local orderedHandlers = T.orderedHandlers +local orderedNames = T.orderedNames + + +--- Placing the Update functions here since they shouldn't be messing with schema stuff +local currentPosition, anchorFrame, anchorPoint +--- Positioning and stuff +local tick = 0 +local initReason = OBJECTIVE_TRACKER_UPDATE_ALL +local requiresInit +function T:Update (reason, ...) + if not B.Conf.VeneerObjectiveWrapper.enabled then + return + end + tick = tick + 1 + local print = tprint + local hasStuff = false + local insertingStuff = false + + if initReason then + reason = initReason + initReason = nil + elseif not reason then + reason = OBJECTIVE_TRACKER_UPDATE_ALL + end + print(format('|cFFBB0066Update:|r |cFFFF%04X%d|r ', tick, lshift(reason, 4)), reason, ...) + currentPosition = 0 + + for id, handler in pairs(T.orderedHandlers) do + local frame = handler.frame + + print('') + if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then + insertingStuff = handler:UpdateTracker(reason, ...) + else + print(' |cFFFF4400Update:|r skipping',handler.name) + end + + if handler.numWatched >= 1 then + hasStuff = true + currentPosition = currentPosition + 1 + Default.AddTracker(handler, frame, currentPosition) + frame.wasEmpty = nil + else + frame.destinationOffset = 0 + if not frame.wasEmpty and not frame.fadeOut:IsPlaying() then + frame.fadeOut:Play() + end + frame.wasEmpty = true + end + end + + -- do these whenever there is content or content is being added + if hasStuff or insertingStuff then + T:FinishWrapper() + end + Quest.GetClosest() + T.UpdateActionButtons(reason) +end + +Default.UpdateTracker = function (handler, reason, id, isNew) + local print = handler.print + local frame = handler.frame + local blockIndex = 0 + print('MODULE:'..handler.name, 'message:', reason, 'id:', id, (isNew and '|cFF88FF88' or '|cFF555555')..'isNew|r') + handler.updateReason = reason + local numWatched, numAll, watchTable = handler:GetNumWatched(id, isNew) + + if numWatched >= 1 then + if watchTable then + print(' WatchList', ' n ID Obj wID Log Blk') + for i, w in ipairs(watchTable) do + print(' WatchList', format('%2d => %6d %3d %3d %3s %s', i, w.id, w.numObjectives, w.watchIndex, (w.logIndex or ''), (handler.InfoBlock[w.id] and handler.InfoBlock[w.id]:GetName() or ''))) + end + end + end + + handler.numWatched = numWatched + handler.numAll = numAll + handler.numBlocks = 0 + handler.currentBlock = 0 + handler.currentAnchor = frame.titlebg + for blockIndex = 1, numWatched do + local currentBlock = handler:UpdateBlock(blockIndex, id, isNew) + if currentBlock then + handler:AddBlock(currentBlock) + else + print(' |cFF'..handler.internalColor..'finished|r @', blockIndex) + break -- done with quest stuff + end + end + + local numBlocks = handler.numBlocks + local used = handler.usedBlocks + local free = handler.freeBlocks + print(format('#### %s ## |cFFFF8800%04X|r --- blocks |cFFFF8800%d|r, (used/free: |cFFFF8800%d|r/|cFFFF8800%d|r)', handler.name, band(reason, handler.updateReasonModule + handler.updateReasonEvents, reason), numBlocks, #used, #free)) + + return numWatched, numAll +end + +Default.UpdateBlock = function (handler, index) + --@debug@ + local print = bprint -- @end-debug@ + if not index then + return + end + local info = handler.WatchList[index] -- should match up with whatever the internal watch list has + if not info then + return + end + --@debug@ + print(' Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..index..'|r|cFF0099FF', info.id ,'|r')--@end-debug@ + local frame = handler.frame + local block = handler:GetBlock(info.id) + + if block.isAnimating then + -- Nothing to do, leave it as is + return block + end + + block.handler = handler + block.info = info + info.blockIndex = index + --@debug@ + local keyInfo--@end-debug@ + if info.id then + handler.InfoBlock[info.id] = block + --@debug@ + keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'InfoBlock[' .. info.id .. '] = *' .. block:GetName():gsub('%D', '') --@end-debug@ + end + if info.logIndex then + handler.LogBlock[info.logIndex] = block + --@debug@ + keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'LogBlock[' .. info.logIndex .. '] = ' .. block:GetName():gsub('%D', '')--@end-debug@ + end + if info.watchIndex then + handler.WatchBlock[info.watchIndex] = block + --@debug@ + keyInfo = (keyInfo and (keyInfo..', ') or '') .. 'WatchBlock[' .. info.watchIndex .. '] = ' .. block:GetName():gsub('%D', '')--@end-debug@ + end + --@debug@ + if keyInfo then print(' assigned', keyInfo) end--@end-debug@ + handler.BlockInfo[index] = info + block.endPoint = block.titlebg + block.attachmentHeight = 0 + block.currentLine = 0 + local attachments, override_schema = handler:UpdateObjectives(block, block.schema) + + block.title:SetText(info.title) + + if info.specialItem and not info.itemButton then + --@debug@ + print(' - |cFF00FFFFgenerating item button for info set')--@end-debug@ + info.itemButton = T.SetItemButton(block, info) + else + --info.itemButton = nil + end + + local tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2 + + + if info.selected then + block.SelectionOverlay:Show() + else + block.SelectionOverlay:Hide() + end + + if info.tagInfo then + tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative) + tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative) + tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative) + end + + if info.schema then + block.schema = info.schema + end + return block +end + +Default.UpdateObjectives = function(handler, block, block_schema, displayObjectives) + local print = lprint + displayObjectives = displayObjectives or true + block_schema = block_schema or block.schema + local info = block.info + print(' |cFF00FF00default.objectives', block:GetName()) + -- reset the starting positions + local text, attachment, template + local numAttachments = 0 + + if info.objectives and displayObjectives then + for i, data in ipairs(info.objectives) do + text, attachment, template = handler:UpdateLine(block, data) + if text or attachment then + local line = handler:GetLine(block) + line.height = 0 + print(' |cFF88FF00#', i, data.type, text, attachment) + handler:AddLine(block, text, attachment, template) + end + if attachment then + numAttachments = numAttachments + 1 + end + end + end + + if block.currentLine < block.numLines then + print(' - cull', block.currentLine, block.numLines) + for i = block.currentLine + 1, block.numLines do + print(' - hide |cFFFF0088'..i..'|r', block.lines[i]) + block.lines[i]:ClearAllPoints() + block.lines[i]:Hide() + end + end + + if block.currentLine > 0 then + block.attachmentHeight = block.attachmentHeight + print(' |cFF00FF00attachment:', block.attachmentHeight) + end + return numAttachments, block_schema +end + +Default.UpdateLine = function(handler, block, data) + return block.info.description, nil, 'default' +end + +Default.Select = function(handler, block) + T:Update() +end +Default.Open = function(handler, block) + T:Update(handler.updateReasonModule) +end +Default.Remove = function(handler, block) + T:Update(handler.updateReasonModule) +end +Default.Report = function(handler, block) + print('Stats:', handler.numWatched,'items tracked,', handler.numBlocks,'blocks assigned.') +end + +function Default:OnMouseUp (button) + print(self.handler.name, self.mainStyle, self.subStyle) + if button == 'LeftButton' then + if IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow() then + self.Link(self.handler, self) + elseif IsModifiedClick("QUESTWATCHTOGGLE") then + self.Remove(self.handler, self) + else + self.Select(self.handler, self) + end + elseif button == 'RightButton' then + self.Open(self.handler, self) + end + self.initialButton = nil + self.modChatLink = nil + self.modQuestWatch = nil + --T:Update(self.handler.updateReasonModule) + print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r') +end +function Default:OnMouseDown (button) + print(self.info.title) +end
--- a/ObjectiveTracker/Widgets.lua Mon Apr 25 03:32:34 2016 -0400 +++ b/ObjectiveTracker/Widgets.lua Mon Apr 25 13:51:58 2016 -0400 @@ -1,14 +1,16 @@ local B = select(2,...).frame local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local print = B.print('WidgetFactory') +local tprint = B.print('Tracker') local _G, UIParent = _G, UIParent local GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown -local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll -local tremove, tContains, pairs, ipairs, setmetatable, floor = tremove, tContains, pairs, ipairs, setmetatable, floor +local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame +local pairs, ipairs, floor = pairs, ipairs, floor local SetItemButtonTexture, SetItemButtonCount = SetItemButtonTexture, SetItemButtonCount -local ToggleWorldMap, GetTrackedAchievements, GetTasksTable = ToggleWorldMap, GetTrackedAchievements, GetTasksTable +local ToggleWorldMap = ToggleWorldMap -- GLOBALS: Veneer_QuestObjectiveItem_UpdateCooldown, Veneer_QuestObjectiveItem_OnUpdate ---- frame refs + +--- Functions for generating and recycling the miscellaneous interface widgets specified by quests local Wrapper = _G.VeneerObjectiveWrapper local Scroller = Wrapper.scrollArea local CloseButton = Wrapper.CloseButton @@ -113,6 +115,57 @@ ToggleWorldMap() end +--- Get a usable widget for the given achievement criteria set. +-- Returns a frame object with dimensioning parameters needed to size the receiving tracker block +local wr = T.WidgetRegistry +T.GetWidget = function(data, objectiveType, objectiveKey) + local print = B.print('ObjectiveWidgets') + local widgetType = objectiveType + local widget + local isNew + if wr[widgetType] and wr[widgetType].used[objectiveKey] then + widget = wr[widgetType].used[objectiveKey] + print('|cFF00FF00Updating ('..objectiveKey..')', widget) + elseif not wr[widgetType] or #wr[widgetType].free == 0 then + -- creating a new frame + isNew = true + widget = CreateFrame(widgetType, 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) + print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) + T.UpdateSchema(widgetType, data.schema or 'default') + else + -- recycling for a different criteria set + isNew = true + widget = tremove(wr[widgetType].free) + print('|cFFFFFF00Acquiring released widget', widget:GetName()) + end + + for k,v in pairs(data) do + if not widget[k] then + widget[k] = v + tprint('widget', widget:GetName(), k, v) + end + end + + wr[widgetType].used[objectiveKey] = widget + widget.objective = data + widget.key = objectiveKey + T.InitializeWidget(widget, isNew) + return widget +end + +local wr = T.WidgetRegistry +--- WidgetTemplate 'OnLoad' +T.RegisterWidget = function(frame) + local print = B.print('ObjectiveWidgets') + local widgetType = frame.widgetType + if not wr[frame.widgetType] then + print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) + wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } + else + print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) + wr[widgetType].lastn = wr[widgetType].lastn + 1 + end +end T.InitializeWidgets = function() local panelButtons = T.buttons