Nenue@0: --- ${PACKAGE_NAME} Nenue@0: -- @file-author@ Nenue@0: -- @project-revision@ @project-hash@ Nenue@0: -- @file-revision@ @file-hash@ Nenue@0: -- Created: 3/26/2016 1:51 AM Nenue@0: local B = select(2,...).frame Nenue@14: local pairs, setmetatable, type, tostring = pairs, setmetatable, type, tostring Nenue@14: local format = string.format Nenue@16: local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') Nenue@0: local print = B.print('Objectives') Nenue@16: local ObjectiveTrackerFrame, VeneerObjectiveScroll, CreateFrame = ObjectiveTrackerFrame, VeneerObjectiveScroll, CreateFrame Nenue@0: Nenue@0: --[[ Nenue@0: Full quest info is available if: Nenue@0: - It's in the player quest log, or is available from the Gossip interface Nenue@0: - It's being shared from another player and is acceptible Nenue@0: - It's an auto-quest that is available in the current location Nenue@0: Partial quest info is availabe if: Nenue@0: - It's already completed (i.e. it appears in CompletedQuestInfo()). Nenue@0: - It's an scheduled interval quest (daily, weekly, etc.) Nenue@0: - It's contained in a quest link received from chat Nenue@0: Under any other circumstances, only minimal info can be pulled: Nenue@0: - Its availability to the player Nenue@0: - Its relation with the currently engaged NPC Nenue@0: - Its binary completion status Nenue@0: Nenue@0: ]] Nenue@16: Nenue@16: Nenue@16: --- Performance values Nenue@16: --[[ Nenue@16: self:RegisterEvent("QUEST_LOG_UPDATE"); Nenue@16: self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED"); Nenue@16: self:RegisterEvent("QUEST_WATCH_LIST_CHANGED"); Nenue@16: self:RegisterEvent("QUEST_AUTOCOMPLETE"); Nenue@16: self:RegisterEvent("QUEST_ACCEPTED"); Nenue@16: self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED"); Nenue@16: self:RegisterEvent("SCENARIO_UPDATE"); Nenue@16: self:RegisterEvent("SCENARIO_CRITERIA_UPDATE"); Nenue@16: self:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE"); Nenue@16: self:RegisterEvent("ZONE_CHANGED_NEW_AREA"); Nenue@16: self:RegisterEvent("ZONE_CHANGED"); Nenue@16: self:RegisterEvent("QUEST_POI_UPDATE"); Nenue@16: self:RegisterEvent("VARIABLES_LOADED"); Nenue@16: self:RegisterEvent("QUEST_TURNED_IN"); Nenue@16: self:RegisterEvent("PLAYER_MONEY"); Nenue@16: ]] Nenue@16: mod.Reason ={ Nenue@16: UPDATE_MASK_AUTOQUEST = 0x00000001, Nenue@16: UPDATE_MASK_QUEST = 0x00000002, Nenue@16: UPDATE_MASK_BONUS = 0x00000004, Nenue@16: UPDATE_MASK_CHEEVS = 0x00000008, Nenue@16: UPDATE_MASK_ALL = 0x00000017, Nenue@16: Nenue@16: QUEST_LOG_UPDATE = 0x00000003, Nenue@16: TRACKED_ACHIEVEMENT_LIST_CHANGED = 0x00000008, Nenue@16: QUEST_WATCH_LIST_CHANGED = 0x00000003, Nenue@16: QUEST_AUTOCOMPLETE = 0x00000003, Nenue@16: QUEST_ACCEPTED = 0x00000003, Nenue@16: SUPER_TRACKED_QUEST_CHANGED = 0x00000002, Nenue@16: SCENARIO_UPDATE = 0x00000004, Nenue@16: SCENARIO_CRITERIA_UPDATE = 0x00000004, Nenue@16: TRACKED_ACHIEVEMENT_UPDATE = 0x00000008, Nenue@16: ZONE_CHANGED_NEW_AREA = 0x00000017, Nenue@16: ZONE_CHANGED = 0x00000017, Nenue@16: QUEST_POI_UPDATE = 0x00000003, Nenue@16: QUEST_TURNED_IN = 0x00000003, Nenue@16: } Nenue@16: mod.MoneyReasons = 0 Nenue@0: Nenue@10: --- Baseline defaults Nenue@16: mod.defaults = {} Nenue@10: Nenue@0: --- list used to make things happen Nenue@16: mod.orderedNames = {'Bonus', 'AutoQuest', 'Quest', 'Cheevs'} Nenue@0: Nenue@0: --- ipairs() list of handlers for wrapper update Nenue@16: mod.orderedHandlers = {} Nenue@16: mod.orderedTrackers = {} Nenue@16: mod.indexedTrackers = {} Nenue@0: --- pairs() list of handler frames for tracker updates Nenue@16: mod.namedTrackers = {} Nenue@0: Nenue@0: --- Handler stubs Nenue@16: mod.AutoQuest = { Nenue@14: name = "AutoQuest", Nenue@16: displayName = "Notice", Nenue@0: } Nenue@16: mod.Quest = { Nenue@14: name = "Quest", Nenue@14: displayName = "Quests", Nenue@0: } Nenue@16: mod.Cheevs = { Nenue@14: name = "Cheevs", Nenue@14: displayName = "Achievements", Nenue@14: } Nenue@16: mod.Bonus = { Nenue@14: name = "Bonus", Nenue@14: displayName = "Bonus Objectives", Nenue@0: } Nenue@0: Nenue@0: --- Handler template Nenue@0: local CreateHandler = function (self, name, index) Nenue@0: print(self, name) Nenue@16: Nenue@16: local handler = setmetatable(mod[name] or {}, { Nenue@0: __tostring = function() return name end, Nenue@16: __call = function (self) mod.UpdateTracker(self) end Nenue@0: }) Nenue@16: if type(mod.orderedHandlers[index]) == 'table' then Nenue@16: return mod.orderedHandlers[index] Nenue@0: end Nenue@0: Nenue@0: print('take up locals first') Nenue@0: local preset = {} Nenue@16: for k,v in pairs(mod[name]) do Nenue@0: preset[k] = true Nenue@0: if type(v) == 'table' then Nenue@0: handler[k] = {} Nenue@0: else Nenue@0: handler[k] = v Nenue@0: end Nenue@0: end Nenue@0: Nenue@16: Nenue@0: print('resulting handler contents') Nenue@0: for k, v in pairs(self) do Nenue@0: if not handler[k] then Nenue@0: if type(v) == 'table' then Nenue@0: -- assume all tables to be local data; don't inherit or ref Nenue@0: handler[k] = {} Nenue@0: else Nenue@16: handler[k] = mod.Tracker[k] Nenue@0: end Nenue@0: else Nenue@0: print(name, 'has its own', k) Nenue@0: end Nenue@0: end Nenue@0: print('|cFFFF4400'..tostring(name)..'|r:') Nenue@0: for k, v in pairs(handler) do Nenue@16: print(format("%24s %8s %s", (preset[k] and '|cFFFFFFFF' or '|cFFFFFF00') .. k .. '|r', type(v), tostring(v))) Nenue@0: end Nenue@16: Nenue@16: mod[name] = handler Nenue@16: Nenue@16: mod.orderedHandlers[index] = handler Nenue@0: return true Nenue@0: end Nenue@0: Nenue@16: mod.Tracker = setmetatable({}, { Nenue@0: __call = CreateHandler, Nenue@0: __tostring = function() return 'DEFAULT_TRACKING_HANDLER' end Nenue@0: }) Nenue@16: local Tracker = mod.Tracker Nenue@0: Tracker.numWatched = 0 --- number of entries being handled Nenue@0: Tracker.numBlocks = 0 --- number of blocks created Nenue@0: Tracker.actualBlocks = 0 --- number of blocks in use Nenue@0: Nenue@0: Tracker.freeBlocks = {} --- block heap Nenue@0: Tracker.usedBlocks = {} Nenue@0: Nenue@0: Tracker.Watched = {} -- find by watchIndex Nenue@0: Tracker.Info = {} -- find by data ID Nenue@0: Tracker.BlockInfo = {} -- find by block ID Nenue@16: Tracker.WatchInfo = {} -- find data by watch index Nenue@16: Tracker.WatchBlock = {} -- find block by watch index Nenue@0: Nenue@0: Nenue@0: Nenue@0: Tracker.GetBlock = function(handler, blockIndex) Nenue@0: local block = handler.usedBlocks[blockIndex] Nenue@0: if not handler.usedBlocks[blockIndex] then Nenue@0: if #handler.freeBlocks >= 1 then Nenue@0: block = handler.freeBlocks[#handler.freeBlocks] Nenue@0: handler.freeBlocks[#handler.freeBlocks] = nil Nenue@0: else Nenue@16: block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, VeneerObjectiveScroll, 'VeneerTrackerBlock') Nenue@16: block.SetStyle = mod.SetBlockStyle Nenue@14: block.Select = handler.Select Nenue@14: block.Open = handler.Open Nenue@14: block.Remove = handler.Remove Nenue@14: block.Link = handler.Link Nenue@14: block:SetScript('OnMouseUp', handler.OnMouseUp) Nenue@14: block:SetScript('OnMouseDown', handler.OnMouseDown) Nenue@14: block:ClearAllPoints() Nenue@0: end Nenue@0: Nenue@0: handler.usedBlocks[blockIndex] = block Nenue@0: end Nenue@0: return handler.usedBlocks[blockIndex] Nenue@0: end Nenue@0: Nenue@16: function mod:OnInitialize() Nenue@14: self.InitializeWrapper() Nenue@3: self.InitializeXPTracker() Nenue@16: mod.SetEvents() Nenue@0: ObjectiveTrackerFrame:UnregisterAllEvents() Nenue@0: ObjectiveTrackerFrame:Hide() Nenue@0: end