Nenue@28: --- ${PACKAGE_NAME} Nenue@28: -- @file-author@ Nenue@28: -- @project-revision@ @project-hash@ Nenue@28: -- @file-revision@ @file-hash@ Nenue@28: -- Created: 3/26/2016 1:51 AM Nenue@28: local B, _G = select(2,...).frame, _G Nenue@28: local pairs, setmetatable, type, tostring, band, format = _G.pairs, _G.setmetatable, _G.type, _G.tostring, bit.band, string.format Nenue@28: local ipairs, tinsert, hooksecurefunc = _G.ipairs, _G.tinsert, _G.hooksecurefunc Nenue@28: local PlaySoundFile, IsQuestTask, SortQuestWatches, GetCurrentMapAreaID, GetZoneText, GetMinimapZoneText = PlaySoundFile, IsQuestTask, SortQuestWatches, GetCurrentMapAreaID, GetZoneText, GetMinimapZoneText Nenue@28: local QuestPOIUpdateIcons, GetCVar, IsPlayerInMicroDungeon, WorldMapFrame, GetCVarBool, SetMapToCurrentZone = QuestPOIUpdateIcons, GetCVar, IsPlayerInMicroDungeon, WorldMapFrame, GetCVarBool, SetMapToCurrentZone Nenue@28: local AddAutoQuestPopUp = AddAutoQuestPopUp Nenue@28: local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') Nenue@28: local print = B.print('Objectives') Nenue@28: local ObjectiveTrackerFrame, VeneerObjectiveScroll, CreateFrame = _G.ObjectiveTrackerFrame, _G.VeneerObjectiveScroll, _G.CreateFrame Nenue@28: local Wrapper = _G.VeneerObjectiveWrapper Nenue@28: local Scroller = VeneerObjectiveWrapper.scrollArea Nenue@28: local Scroll = _G.VeneerObjectiveScroll Nenue@28: local unitLevel = UnitLevel('player') Nenue@28: Nenue@28: --- Performance values Nenue@28: --[[ Nenue@28: self:RegisterEvent("QUEST_LOG_UPDATE"); Nenue@28: self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED"); Nenue@28: self:RegisterEvent("QUEST_WATCH_LIST_CHANGED"); Nenue@28: self:RegisterEvent("QUEST_AUTOCOMPLETE"); Nenue@28: self:RegisterEvent("QUEST_ACCEPTED"); Nenue@28: self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED"); Nenue@28: self:RegisterEvent("SCENARIO_UPDATE"); Nenue@28: self:RegisterEvent("SCENARIO_CRITERIA_UPDATE"); Nenue@28: self:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE"); Nenue@28: self:RegisterEvent("ZONE_CHANGED_NEW_AREA"); Nenue@28: self:RegisterEvent("ZONE_CHANGED"); Nenue@28: self:RegisterEvent("QUEST_POI_UPDATE"); Nenue@28: self:RegisterEvent("VARIABLES_LOADED"); Nenue@28: self:RegisterEvent("QUEST_TURNED_IN"); Nenue@28: self:RegisterEvent("PLAYER_MONEY"); Nenue@28: ]] Nenue@28: Nenue@28: Nenue@28: --- These are the bitfields used by Blizzard_ObjectiveTracker to determine which segments get parsed. Nenue@28: --- They are replicated here so that plugins can make use of any securehook args involving this info. Nenue@28: local OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST -- 0x0100 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP = OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP -- 0x0200 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE = OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE -- 0x0400 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO = OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO -- 0x0800 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT = OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT -- 0x1000 Nenue@28: Nenue@28: Nenue@28: local OBJECTIVE_TRACKER_UPDATE_STATIC = OBJECTIVE_TRACKER_UPDATE_STATIC -- 0x0000 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_ALL = OBJECTIVE_TRACKER_UPDATE_ALL -- 0xFFFF Nenue@28: local OBJECTIVE_TRACKER_UPDATE_ID = OBJECTIVE_TRACKER_UPDATE_ID -- 0 Nenue@28: Nenue@28: local OBJECTIVE_TRACKER_UPDATE_QUEST = OBJECTIVE_TRACKER_UPDATE_QUEST -- 0x0001 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED = OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED -- 0x0002 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_TASK_ADDED = OBJECTIVE_TRACKER_UPDATE_TASK_ADDED -- 0x0004 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_SCENARIO = OBJECTIVE_TRACKER_UPDATE_SCENARIO -- 0x0008 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE = OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE -- 0x0010 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT -- 0x0020 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED -- 0x0040 Nenue@28: local OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED = OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED -- 0x0080 Nenue@28: Nenue@28: local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_ALL -- default Nenue@28: --- Used to determine which trackers are listening for money events Nenue@28: Nenue@28: T.strings = {} Nenue@28: T.strings.CLICK_TO_ACCCEPT = 'Click to Accept' Nenue@28: T.strings.CLICK_TO_COMPLETE = 'Click to complete' Nenue@28: T.colors ={ Nenue@28: enable = true, Nenue@28: } Nenue@28: Nenue@28: T.watchMoneyReasons = 0 Nenue@28: Nenue@28: --- Baseline defaults table; values defined in the files that they pertain to Nenue@28: T.defaults = {} Nenue@28: Nenue@34: Nenue@28: --- Tracker display order Nenue@28: T.orderedNames = {'Bonus', 'AutoQuest', 'Quest', 'Cheevs'} Nenue@28: Nenue@28: --- ipairs() argument tables Nenue@28: T.orderedHandlers = setmetatable({}, {__mode = "k"}) Nenue@28: T.orderedTrackers = setmetatable({}, {__mode = "k"}) Nenue@28: T.indexedTrackers = setmetatable({}, {__mode = "k"}) Nenue@28: Nenue@28: --- pairs() argument tables Nenue@28: T.namedTrackers = setmetatable({}, {__mode = "k"}) Nenue@28: Nenue@28: local WRAPPER_ANCHOR_POINT = 'TOPRIGHT' Nenue@28: local WRAPPER_OFFSET_X = 0 Nenue@28: local WRAPPER_OFFSET_Y = -200 Nenue@28: local WRAPPER_MAX_HEIGHT = 670 Nenue@28: local WRAPPER_WIDTH = 280 Nenue@28: local WRAPPER_HEADER_HEIGHT = 24 Nenue@28: Nenue@28: T.defaults.Wrapper = { Nenue@28: AnchorPoint = WRAPPER_ANCHOR_POINT, Nenue@28: OffsetX = WRAPPER_OFFSET_X, Nenue@28: OffsetY = WRAPPER_OFFSET_Y, Nenue@28: Height = WRAPPER_MAX_HEIGHT, Nenue@28: Width = WRAPPER_WIDTH, Nenue@28: HeaderHeight = WRAPPER_HEADER_HEIGHT, Nenue@28: TextSpacing = 3, Nenue@33: TextIndent = 4, Nenue@28: TitleSpacing = 3, Nenue@33: TitleIndent = 4, Nenue@28: } Nenue@28: Nenue@28: Nenue@28: Nenue@28: --- Tracker module definitions begin here; innards dealing with data retreival and output are defined further in Nenue@28: T.DefaultHandler = { Nenue@28: previousHeight = 0, Nenue@28: Nenue@28: name = "temp", Nenue@28: displayName = "temp", Nenue@28: updateReasonModule = 0xFF00, Nenue@28: updateReasonEvent = 0x00FF, Nenue@28: Nenue@28: numWatched = 0, --- number of entries being handled Nenue@28: numBlocks = 0, --- number of blocks created Nenue@28: actualBlocks = 0, --- number of blocks in use Nenue@34: Info = {}, --- stored watch list information, keyed by whatever unique ID is involved for that tracker Nenue@34: Watched = {}, --- stores whether the given unique ID is tracked Nenue@28: Nenue@34: freeBlocks = {}, --- blocks hidden due to list shrinkage Nenue@34: usedBlocks = {}, --- block in use Nenue@34: BlockInfo = {}, --- by block creation offset, used by framescript Nenue@37: WatchList = {}, --- ordered manifest of watched items Nenue@28: Nenue@34: --- Indexes Nenue@37: InfoBlock = {}, --- by unique ID Nenue@34: LogBlock = {}, --- by API log offset, used by GetBlock if possible Nenue@34: WatchBlock = {}, --- block by internal offset, used in GetBlock scope Nenue@34: WatchInfo = {}, --- info by internal offset, used in Update scope Nenue@28: } Nenue@28: Nenue@28: T.AutoQuest = { Nenue@28: name = "AutoQuest", Nenue@28: displayName = "Notice", Nenue@28: updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, Nenue@28: updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, Nenue@38: internalColor = '00FFFF', Nenue@29: LogInfo = {}, Nenue@29: QuestBlock = {}, Nenue@28: } Nenue@28: T.Quest = { Nenue@28: name = "Quest", Nenue@28: displayName = "Quests", Nenue@28: updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, Nenue@28: updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, Nenue@38: internalColor = '0088FF', Nenue@28: itemButtons = {}, Nenue@28: freeButtons = {}, Nenue@29: LogInfo = {}, Nenue@29: QuestBlock = {}, Nenue@28: } Nenue@28: T.Cheevs = { Nenue@28: name = "Cheevs", Nenue@28: displayName = "Achievements", Nenue@37: schema = 'achievement', Nenue@28: updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT, Nenue@28: updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT + Nenue@28: OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED, Nenue@38: internalColor = '00FF88', Nenue@28: } Nenue@28: T.Bonus = { Nenue@28: name = "Bonus", Nenue@28: displayName = "Bonus Objectives", Nenue@28: updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, Nenue@29: updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_TASK_ADDED, Nenue@38: internalColor = '00FF00', Nenue@29: QuestBlock = {}, Nenue@28: } Nenue@28: Nenue@28: T.Scenario = { Nenue@28: name = 'Scenario', Nenue@28: displayName = 'Scenario Objectives', Nenue@28: updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO, Nenue@38: updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE + OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED, Nenue@38: internalColor = '88FF00', Nenue@28: } Nenue@38: local lastLabel Nenue@38: local Tracker_debug = function(handler, channel) Nenue@38: local func = B.print(channel) Nenue@38: local color = handler.internalColor Nenue@38: return function(label, ...) Nenue@38: if lastLabel == label then Nenue@38: label = label:gsub('%a', ' ').. ' ' Nenue@38: else Nenue@38: lastLabel = label Nenue@38: label = '|cFF'..color..label..':|r' Nenue@38: end Nenue@38: func(label, ...) Nenue@38: end Nenue@38: end Nenue@28: local Tracker_string = function (self) Nenue@28: return self.name Nenue@28: end Nenue@28: local Tracker_call = function (self, reason) Nenue@28: self:Update(reason) Nenue@28: end Nenue@28: local Handler_Initialize = function (self, name, index) Nenue@28: local c = T.Conf.Wrapper Nenue@28: print('Initializing |cFF00FFFF'..name..'|r module...') Nenue@28: Nenue@28: local handler = setmetatable(T[name] or {}, { Nenue@28: __tostring = Tracker_string, Nenue@28: __call = Tracker_call Nenue@28: }) Nenue@28: if type(T.orderedHandlers[index]) == 'table' then Nenue@28: return T.orderedHandlers[index] Nenue@28: end Nenue@28: Nenue@28: print('|cFFFFFF00Acquiring locals') Nenue@28: local preset = {} Nenue@28: for k, _ in pairs(handler) do Nenue@28: preset[k] = true Nenue@28: end Nenue@28: Nenue@28: Nenue@28: print('|cFFFF8800Inheriting') Nenue@28: for k, v in pairs(self) do Nenue@28: if not handler[k] then Nenue@28: if type(v) == 'table' then Nenue@28: -- assume all tables to be local data; don't inherit or ref Nenue@28: handler[k] = {} Nenue@28: else Nenue@28: handler[k] = self[k] Nenue@28: end Nenue@28: print('copying', k) Nenue@28: end Nenue@28: end Nenue@28: print('|cFFFF4400'..tostring(name)..'|r:') Nenue@28: for k, v in pairs(handler) do Nenue@28: print(format("%32s %8s %s", (preset[k] and '|cFFFFFFFF' or '|cFFFFFF00') .. k .. '|r', type(v), tostring(v))) Nenue@28: end Nenue@28: Nenue@28: T[name] = handler Nenue@28: Nenue@28: local trackerName = 'Veneer'..name..'Tracker' Nenue@28: local handler = T[name] Nenue@28: local frame = CreateFrame('Frame', trackerName, _G.VeneerObjectiveScroll, 'VeneerTrackerTemplate') Nenue@28: frame.title:SetText(handler.displayName) Nenue@28: frame:SetWidth(c.Width) Nenue@30: frame.previousOffset = 0 Nenue@29: Nenue@28: handler.frame = frame Nenue@29: handler.numBlocks = 0 Nenue@29: handler.actualBlocks = 0 Nenue@28: handler.trackerName = trackerName Nenue@28: handler.lines = {} Nenue@28: T.orderedTrackers[index] = frame Nenue@28: T.namedTrackers[name] = frame Nenue@28: T.indexedTrackers[handler] = frame Nenue@28: print('|cFFFF0088' .. trackerName .. '|r created for |cFF00FFFF' .. handler.displayName .. '|r module') Nenue@28: Nenue@38: handler.print = Tracker_debug(handler, 'Tracker') Nenue@38: handler.lprint = Tracker_debug(handler, 'Line') Nenue@38: handler.bprint = Tracker_debug(handler, 'Block') Nenue@38: Nenue@28: T.orderedHandlers[index] = handler Nenue@28: return true Nenue@28: end Nenue@28: Nenue@28: local Event = {} Nenue@28: Event.QUEST_LOG_UPDATE = function() Nenue@28: return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST + OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE Nenue@28: end Nenue@30: local GetNumQuestWatches, AddQuestWatch, SetSuperTrackedQuestID = GetNumQuestWatches, AddQuestWatch, SetSuperTrackedQuestID Nenue@30: Event.QUEST_ACCEPTED = function(questLogIndex, questID, added) Nenue@28: if ( IsQuestTask(questID) ) then Nenue@38: return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED + OBJECTIVE_TRACKER_UPDATE_TASK_ADDED, questID, added Nenue@28: else Nenue@38: return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID, added Nenue@28: end Nenue@38: AddQuestWatch(questID) Nenue@28: end Nenue@28: Nenue@30: Event.QUEST_REMOVED = function(questLogIndex, questID) Nenue@30: return OBJECTIVE_TRACKER_UPDATE_QUEST, questID, false Nenue@30: end Nenue@30: Nenue@28: Event.QUEST_WATCH_LIST_CHANGED = function(questID, added) Nenue@37: if ( added == true ) then Nenue@28: if ( not IsQuestTask(questID) ) then Nenue@28: return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID, added Nenue@28: end Nenue@37: elseif questID then Nenue@37: return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID, added Nenue@38: else Nenue@38: return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST Nenue@28: end Nenue@28: end Nenue@28: Nenue@28: Event.QUEST_POI_UPDATE = function() Nenue@28: QuestPOIUpdateIcons(); Nenue@28: if ( GetCVar("trackQuestSorting") == "proximity" ) then Nenue@28: SortQuestWatches(); Nenue@28: end Nenue@28: return OBJECTIVE_TRACKER_UPDATE_ALL Nenue@28: end Nenue@37: Event.SUPER_TRACKED_QUEST_CHANGED = function(questID) Nenue@37: return OBJECTIVE_TRACKER_UPDATE_QUEST, questID Nenue@28: end Nenue@28: Event.ZONE_CHANGED = function() Nenue@28: local inMicroDungeon = IsPlayerInMicroDungeon(); Nenue@28: if ( inMicroDungeon ~= T.inMicroDungeon ) then Nenue@28: if ( not WorldMapFrame:IsShown() and GetCVarBool("questPOI") ) then Nenue@28: SetMapToCurrentZone(); -- update the zone to get the right POI numbers for the tracker Nenue@28: end Nenue@28: --SortQuestWatches(); Nenue@28: T.inMicroDungeon = inMicroDungeon; Nenue@28: end Nenue@33: return OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE + OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO Nenue@28: end Nenue@28: Event.QUEST_AUTOCOMPLETE = function(questId) Nenue@28: AddAutoQuestPopUp(questId, "COMPLETE"); Nenue@28: return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST + OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP Nenue@28: end Nenue@28: Event.SCENARIO_CRITERIA_UPDATE = function() Nenue@28: return OBJECTIVE_TRACKER_UPDATE_SCENARIO Nenue@28: end Nenue@28: Event.SCENARIO_UPDATE = function(newStage) Nenue@28: if ( newStage ) then Nenue@28: return OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE Nenue@28: else Nenue@28: return OBJECTIVE_TRACKER_UPDATE_SCENARIO Nenue@28: end Nenue@28: end Nenue@28: Event.TRACKED_ACHIEVEMENT_UPDATE = function() Nenue@28: return OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT Nenue@28: end Nenue@28: Event.TRACKED_ACHIEVEMENT_LIST_CHANGED = function(achievementID, added) Nenue@37: return OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED, achievementID, added Nenue@28: end Nenue@28: Event.ZONE_CHANGED_NEW_AREA = function () Nenue@28: if ( not WorldMapFrame:IsShown() and GetCVarBool("questPOI") ) then Nenue@28: SetMapToCurrentZone(); -- update the zone to get the right POI numbers for the tracker Nenue@28: end Nenue@28: SortQuestWatches(); Nenue@28: T.currentZoneArea = GetCurrentMapAreaID() Nenue@28: print('Updating zone ID to', T.currentZoneArea, '=', GetZoneText(), GetMinimapZoneText()) Nenue@28: Nenue@28: Nenue@28: return OBJECTIVE_TRACKER_UPDATE_TASK_ADDED Nenue@28: end Nenue@28: Nenue@28: Nenue@28: Event.PLAYER_MONEY = function() Nenue@28: if T.watchMoneyReasons > 0 then Nenue@28: return T.watchMoneyReasons Nenue@28: end Nenue@28: end Nenue@28: Event.CRITERIA_COMPLETE = function() Nenue@28: return OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE Nenue@28: end Nenue@28: Event.QUEST_TURN_IN = function(questID, xp, money) Nenue@28: if ( IsQuestTask(questID) ) then Nenue@28: T.Bonus:OnTurnIn(questID, xp, money) Nenue@28: print('updating bonus modules (code', OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, ',', questID, xp, money) Nenue@28: return OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, questID, xp, money Nenue@28: else Nenue@28: return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, questID, xp, money Nenue@28: end Nenue@28: end Nenue@28: T.Event = Event Nenue@28: Nenue@28: --- Done once per ui load Nenue@28: local BlizzHooks = { Nenue@34: ['AcceptQuest'] = 'AcceptQuest', Nenue@28: ['AddQuestWatch'] = 'AddQuestWatch', Nenue@28: ['RemoveQuestWatch'] = 'RemoveQuestWatch', Nenue@28: ['AbandonQuest'] = 'AbandonQuest', Nenue@28: ['AcknowledgeAutoAcceptQuest'] = 'AcknowledgeAutoAcceptQuest', Nenue@28: ['AddAutoQuestPopUp'] = 'AddAutoQuestPopUp', Nenue@28: ['RemoveAutoQuestPopUp'] = 'RemoveAutoQuestPopUp', Nenue@28: ['AddTrackedAchievement'] = 'AddTrackedAchievement', Nenue@28: ['RemoveTrackedAchievement'] = 'RemoveTrackedAchievement', Nenue@28: ['SetSuperTrackedQuestID'] = 'SetSuperTrackedQuestID' Nenue@28: } Nenue@28: local VeneerData Nenue@28: Nenue@28: T.SetWatchMoney = function(watchMoney, reason) Nenue@28: if watchMoney then Nenue@28: if band(T.watchMoneyReasons, reason) == 0 then Nenue@28: T.watchMoneyReasons = T.watchMoneyReasons + reason; Nenue@28: end Nenue@28: else Nenue@28: if band(T.watchMoneyReasons, reason) > 0 then Nenue@28: T.watchMoneyReasons = T.watchMoneyReasons - reason; Nenue@28: end Nenue@28: end Nenue@28: end Nenue@28: Nenue@32: local iprint = B.print('Info') Nenue@32: T.SetRewards = function(t, questID) Nenue@34: local previousSelection = GetQuestLogSelection() Nenue@32: Nenue@32: SelectQuestLogEntry(GetQuestLogIndexByID(questID)) Nenue@32: local numQuestChoices = GetNumQuestLogChoices(); Nenue@32: local skillName, skillIcon, skillPoints = GetQuestLogRewardSkillPoints(); Nenue@32: local xp = GetQuestLogRewardXP(); Nenue@32: local playerTitle = GetQuestLogRewardTitle(); Nenue@32: ProcessQuestLogRewardFactions(); Nenue@34: if previousSelection then Nenue@34: SelectQuestLogEntry(previousSelection) Nenue@34: end Nenue@34: Nenue@32: local rewards = {} Nenue@32: local texture, name, isTradeskillSpell, isSpellLearned, hideSpellLearnText, isBoostSpell, garrFollowerID = GetQuestLogRewardSpell(questID) Nenue@32: if name then Nenue@32: tinsert(rewards,{ Nenue@32: type = 'spell', Nenue@32: name = name, Nenue@32: texture = texture, Nenue@32: }) Nenue@32: end Nenue@32: Nenue@32: t.numCurrencies = GetNumQuestLogRewardCurrencies(questID) Nenue@32: for i = 1, t.numCurrencies do Nenue@32: local name, texture, count = GetQuestLogRewardCurrencyInfo(i, questID) Nenue@32: tinsert(rewards,{ Nenue@32: type = 'currency', Nenue@32: index = i, Nenue@32: name = name, Nenue@32: texture = texture, Nenue@32: count = count Nenue@32: }); Nenue@32: end Nenue@32: -- items Nenue@32: t.numItems = GetNumQuestLogRewards(questID) Nenue@32: for i = 1, t.numItems do Nenue@32: local name, texture, count, quality, isUsable = GetQuestLogRewardInfo(i, questID) Nenue@32: tinsert(rewards, { Nenue@32: type = 'item', Nenue@32: index = i , Nenue@32: name = name, Nenue@32: texture = texture, Nenue@32: count = count, Nenue@32: quality = quality, Nenue@32: isUsable = isUsable Nenue@32: }); Nenue@32: end Nenue@32: -- money Nenue@32: Nenue@32: local money = GetQuestLogRewardMoney(questID) Nenue@32: if ( money > 0 ) then Nenue@32: tinsert(rewards, { Nenue@32: type = 'money', Nenue@32: name = GetMoneyString(money), Nenue@32: texture = "Interface\\Icons\\inv_misc_coin_01", Nenue@32: count = 0, Nenue@32: }); Nenue@32: end Nenue@32: Nenue@32: if #rewards >= 1 then Nenue@32: t.rewardInfo = rewards Nenue@32: end Nenue@32: end Nenue@32: Nenue@28: local Play = function(file) if Devian and Devian.InWorkspace() then PlaySoundFile(file) end end Nenue@28: Nenue@37: local tprint = B.print('Tracker') Nenue@34: T.OnHookedFunc = function(name, ...) Nenue@37: tprint('|cFFFF8800securehook:|r', name, '|cFF00FFFFargs:|r', ...) Nenue@37: local updateReason, arg1, arg2, arg3 = T[name](...) Nenue@34: if updateReason then Nenue@37: print('|cFF00FFFFupdate reason:|r', updateReason, arg1, arg2, arg3) Nenue@37: T:Update(updateReason, arg1, arg2, arg3) Nenue@34: end Nenue@34: end Nenue@34: Nenue@28: function T:OnEvent (event, ...) Nenue@28: local isHandled Nenue@28: local reason, arg1, arg2, arg3 Nenue@28: if Event[event] then Nenue@28: if type(Event[event]) == 'function' then Nenue@28: Play([[Interface\Addons\SharedMedia_MyMedia\sound\Info.ogg]]) Nenue@28: reason, arg1, arg2, arg3 = Event[event](...) Nenue@28: else Nenue@37: Play([[Interface\Addons\SharedMedia_MyMedia\sound\Heart.ogg]]) Nenue@28: reason = Event[event] Nenue@28: end Nenue@28: else Nenue@30: print('no event handler set for', event) Nenue@30: Play([[Interface\Addons\SharedMedia_MyMedia\sound\IM.ogg]]) Nenue@28: end Nenue@28: if reason then Nenue@38: tprint('OnEvent(|cFF00FF00'.. event ..'|r):', ...) Nenue@28: T:Update(reason, arg1, arg2, arg3) Nenue@28: else Nenue@38: tprint('OnEvent(|cFFFF4400'.. event ..'|r):', ...) Nenue@38: tprint('no detected reason') Nenue@28: Play([[Interface\Addons\SharedMedia_MyMedia\sound\Quack.ogg]]) Nenue@28: end Nenue@38: local args = (reason or '0') Nenue@38: if arg1 then args = args .. ', ' .. tostring(arg1) end Nenue@38: if arg2 then args = args .. ', ' .. tostring(arg2) end Nenue@38: if arg3 then args = args .. ', ' .. tostring(arg3) end Nenue@38: tprint('OnEvent(|cFF00FF00'.. event ..'|r):', ..., '|cFFFFFF00=> Update (|r', args,'|cFFFFFF00)|r') Nenue@28: Nenue@28: end Nenue@28: Nenue@28: Nenue@28: function T:OnInitialize() Nenue@28: local c = T.Conf.Wrapper Nenue@28: VeneerData = _G.VeneerData Nenue@28: VeneerData.CallLog = VeneerData.CallLog or {} Nenue@28: if not T.isHooked then Nenue@28: T.isHooked = true Nenue@28: for blizzFunc, veneerFunc in pairs(BlizzHooks) do Nenue@28: if T[veneerFunc] then Nenue@34: hooksecurefunc(blizzFunc, function(...) return T.OnHookedFunc(blizzFunc, ...) end) Nenue@28: else Nenue@28: hooksecurefunc(blizzFunc, function(...) Nenue@28: print('|cFFFF0088securehook('..tostring(blizzFunc)..')|r args:', ...) Nenue@28: tinsert(VeneerData.CallLog, {blizzFunc, ...}) Nenue@28: end) Nenue@28: end Nenue@28: end Nenue@28: end Nenue@28: Nenue@28: T.Conf.TasksLog = T.Conf.TasksLog or {} Nenue@28: Nenue@28: ObjectiveTrackerFrame:UnregisterAllEvents() Nenue@28: ObjectiveTrackerFrame:Hide() Nenue@33: _G.MinimapCluster:Hide() Nenue@28: Nenue@28: for id, name in ipairs(T.orderedNames) do Nenue@28: if not T.orderedHandlers[id] then Nenue@28: Handler_Initialize(T.DefaultHandler, name, id) Nenue@28: end Nenue@28: end Nenue@28: self:SetSize(c.Width, 40) Nenue@28: T.InitializeWidgets() Nenue@28: end Nenue@28: Nenue@28: --- Done any time the the minimize button is toggled up Nenue@28: function T:OnEnable() Nenue@28: Nenue@28: print(B.Conf.VeneerObjectiveWrapper.enabled) Nenue@34: Nenue@28: Nenue@28: for event, action in pairs(Event) do Nenue@28: print('|cFFFF0088listen to', event, 'for action|r', tostring(action)) Nenue@28: Wrapper:RegisterEvent(event) Nenue@28: end Nenue@28: Nenue@28: local c = T.Conf.Wrapper Nenue@30: Wrapper.previousHeight = 0 Nenue@28: Scroller:SetScrollChild(Scroll) Nenue@28: Scroller:SetWidth(c.Width) Nenue@28: Scroll:SetWidth(c.Width) Nenue@28: Scroll:ClearAllPoints() Nenue@28: Scroll:SetPoint('TOP', Scroller, 'TOP') Nenue@28: self:SetScript('OnEvent', T.OnEvent) Nenue@28: Nenue@28: Scroller:Show() Nenue@28: Nenue@28: local from, target, to, x, y = Wrapper:GetPoint(1) Nenue@38: print(from, target, to, x,y) Nenue@28: Nenue@28: Nenue@38: T.UpdateSchema('tracker', 'default') Nenue@28: -- run once to prime the data structure Nenue@28: T.UpdateActionButtons() Nenue@28: end Nenue@28: Nenue@28: function T:OnDisable() Nenue@28: self:UnregisterAllEvents() Nenue@28: Scroller:Hide() Nenue@28: end Nenue@28: