Mercurial > wow > buffalo2
view ObjectiveCore.lua @ 22:9b3fa734abff
ObjectiveFrame
- polish quest rewards display
- implement money objectives
- set line metrics in UpdateLine
- set block metrics in UpdateBlock (sum of line metrics)
author | Nenue |
---|---|
date | Sat, 09 Apr 2016 07:32:45 -0400 |
parents | d5ee940de273 |
children |
line wrap: on
line source
--- ${PACKAGE_NAME} -- @file-author@ -- @project-revision@ @project-hash@ -- @file-revision@ @file-hash@ -- Created: 3/26/2016 1:51 AM local B, _G = select(2,...).frame, _G local pairs, setmetatable, type, tostring, band, format = _G.pairs, _G.setmetatable, _G.type, _G.tostring, bit.band, string.format local ipairs, tinsert, hooksecurefunc = _G.ipairs, _G.tinsert, _G.hooksecurefunc local PlaySoundFile, IsQuestTask, SortQuestWatches, GetCurrentMapAreaID, GetZoneText, GetMinimapZoneText = PlaySoundFile, IsQuestTask, SortQuestWatches, GetCurrentMapAreaID, GetZoneText, GetMinimapZoneText local AddQuestWatch, SetSuperTrackedQuestID, GetNumQuestWatches, AUTO_QUEST_WATCH, MAX_WATCHABLE_QUESTS = AddQuestWatch, SetSuperTrackedQuestID, GetNumQuestWatches, AUTO_QUEST_WATCH, MAX_WATCHABLE_QUESTS local QuestPOIUpdateIcons, GetCVar, IsPlayerInMicroDungeon, WorldMapFrame, GetCVarBool, SetMapToCurrentZone = QuestPOIUpdateIcons, GetCVar, IsPlayerInMicroDungeon, WorldMapFrame, GetCVarBool, SetMapToCurrentZone local AddAutoQuestPopUp = AddAutoQuestPopUp local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local print = B.print('Objectives') local ObjectiveTrackerFrame, VeneerObjectiveScroll, CreateFrame = _G.ObjectiveTrackerFrame, _G.VeneerObjectiveScroll, _G.CreateFrame local Wrapper = _G.VeneerObjectiveWrapper local Scroller = VeneerObjectiveWrapper.scrollArea local Scroll = _G.VeneerObjectiveScroll --- Performance values --[[ self:RegisterEvent("QUEST_LOG_UPDATE"); self:RegisterEvent("TRACKED_ACHIEVEMENT_LIST_CHANGED"); self:RegisterEvent("QUEST_WATCH_LIST_CHANGED"); self:RegisterEvent("QUEST_AUTOCOMPLETE"); self:RegisterEvent("QUEST_ACCEPTED"); self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED"); self:RegisterEvent("SCENARIO_UPDATE"); self:RegisterEvent("SCENARIO_CRITERIA_UPDATE"); self:RegisterEvent("TRACKED_ACHIEVEMENT_UPDATE"); self:RegisterEvent("ZONE_CHANGED_NEW_AREA"); self:RegisterEvent("ZONE_CHANGED"); self:RegisterEvent("QUEST_POI_UPDATE"); self:RegisterEvent("VARIABLES_LOADED"); self:RegisterEvent("QUEST_TURNED_IN"); self:RegisterEvent("PLAYER_MONEY"); ]] --- These are the bitfields used by Blizzard_ObjectiveTracker to determine which segments get parsed. --- They are replicated here so that plugins can make use of any securehook args involving this info. local OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST -- 0x0100 local OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP = OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP -- 0x0200 local OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE = OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE -- 0x0400 local OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO = OBJECTIVE_TRACKER_UPDATE_MODULE_SCENARIO -- 0x0800 local OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT = OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT -- 0x1000 local OBJECTIVE_TRACKER_UPDATE_STATIC = OBJECTIVE_TRACKER_UPDATE_STATIC -- 0x0000 local OBJECTIVE_TRACKER_UPDATE_ALL = OBJECTIVE_TRACKER_UPDATE_ALL -- 0xFFFF local OBJECTIVE_TRACKER_UPDATE_ID = OBJECTIVE_TRACKER_UPDATE_ID -- 0 local OBJECTIVE_TRACKER_UPDATE_QUEST = OBJECTIVE_TRACKER_UPDATE_QUEST -- 0x0001 local OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED = OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED -- 0x0002 local OBJECTIVE_TRACKER_UPDATE_TASK_ADDED = OBJECTIVE_TRACKER_UPDATE_TASK_ADDED -- 0x0004 local OBJECTIVE_TRACKER_UPDATE_SCENARIO = OBJECTIVE_TRACKER_UPDATE_SCENARIO -- 0x0008 local OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE = OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE -- 0x0010 local OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT -- 0x0020 local OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED -- 0x0040 local OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED = OBJECTIVE_TRACKER_UPDATE_SCENARIO_BONUS_DELAYED -- 0x0080 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_ALL -- default --- Used to determine which trackers are listening for money events mod.watchMoneyReasons = 0 --- Baseline defaults table; values defined in the files that they pertain to mod.defaults = {} --- Tracker display order mod.orderedNames = {'Bonus', 'AutoQuest', 'Quest', 'Cheevs'} --- ipairs() argument tables mod.orderedHandlers = setmetatable({}, {__mode = "k"}) mod.orderedTrackers = setmetatable({}, {__mode = "k"}) mod.indexedTrackers = setmetatable({}, {__mode = "k"}) --- pairs() argument tables mod.namedTrackers = setmetatable({}, {__mode = "k"}) local WRAPPER_ANCHOR_POINT = 'TOPRIGHT' local WRAPPER_OFFSET_X = 0 local WRAPPER_OFFSET_Y = -200 local WRAPPER_MAX_HEIGHT = 670 local WRAPPER_WIDTH = 280 local WRAPPER_HEADER_HEIGHT = 24 mod.defaults.Wrapper = { AnchorPoint = WRAPPER_ANCHOR_POINT, OffsetX = WRAPPER_OFFSET_X, OffsetY = WRAPPER_OFFSET_Y, Height = WRAPPER_MAX_HEIGHT, Width = WRAPPER_WIDTH, HeaderHeight = WRAPPER_HEADER_HEIGHT, TextSpacing = 3, TitleSpacing = 3, } --- Tracker module definitions begin here; innards dealing with data retreival and output are defined further in mod.DefaultHandler = { previousHeight = 0, name = "temp", displayName = "temp", updateReasonModule = 0xFF00, updateReasonEvent = 0x00FF, numWatched = 0, --- number of entries being handled numBlocks = 0, --- number of blocks created actualBlocks = 0, --- number of blocks in use freeBlocks = {}, --- block heap usedBlocks = {}, Info = {}, -- find data by ID BlockInfo = {}, -- find data by block ID Watched = {}, -- find watchIndex by data ID WatchInfo = {}, -- find data by watch index WatchBlock = {}, -- find block by watch index } mod.AutoQuest = { name = "AutoQuest", displayName = "Notice", updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, } mod.Quest = { name = "Quest", displayName = "Quests", updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, } mod.Cheevs = { name = "Cheevs", displayName = "Achievements", updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT, updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT + OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED, } mod.Bonus = { name = "Bonus", displayName = "Bonus Objectives", updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_TASK_ADDED } local Tracker_string = function (self) return self.name end local Tracker_call = function (self, reason) self:Update(reason) end local Handler_Initialize = function (self, name, index) print('Initializing |cFF00FFFF'..name..'|r module...') local handler = setmetatable(mod[name] or {}, { __tostring = Tracker_string, __call = Tracker_call }) if type(mod.orderedHandlers[index]) == 'table' then return mod.orderedHandlers[index] end print('|cFFFFFF00Acquiring locals') local preset = {} for k, _ in pairs(handler) do preset[k] = true end print('|cFFFF8800Inheriting') for k, v in pairs(self) do if not handler[k] then if type(v) == 'table' then -- assume all tables to be local data; don't inherit or ref handler[k] = {} else handler[k] = self[k] end print('copying', k) end end print('|cFFFF4400'..tostring(name)..'|r:') for k, v in pairs(handler) do print(format("%32s %8s %s", (preset[k] and '|cFFFFFFFF' or '|cFFFFFF00') .. k .. '|r', type(v), tostring(v))) end mod[name] = handler local trackerName = 'Veneer'..name..'Tracker' local handler = mod[name] local frame = CreateFrame('Frame', trackerName, _G.VeneerObjectiveScroll, 'VeneerTrackerTemplate') frame.title:SetText(handler.displayName) mod.SetBlockStyle(frame, 'Tracker', 'Normal') handler.frame = frame handler.trackerName = trackerName handler.lines = {} mod.orderedTrackers[index] = frame mod.namedTrackers[name] = frame mod.indexedTrackers[handler] = frame print('|cFFFF0088' .. trackerName .. '|r created for |cFF00FFFF' .. handler.displayName .. '|r module') mod.orderedHandlers[index] = handler return true end local Event = {} Event.QUEST_LOG_UPDATE = function() return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST + OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE end Event.QUEST_ACCEPTED = function(questLogIndex, questID) if ( IsQuestTask(questID) ) then return OBJECTIVE_TRACKER_UPDATE_TASK_ADDED, questID else if ( AUTO_QUEST_WATCH == "1" and GetNumQuestWatches() < MAX_WATCHABLE_QUESTS ) then AddQuestWatch(questLogIndex); SetSuperTrackedQuestID(questID); end return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST end end Event.QUEST_WATCH_LIST_CHANGED = function(questID, added) if ( added ) then if ( not IsQuestTask(questID) ) then return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID, added end else return OBJECTIVE_TRACKER_UPDATE_QUEST, questID, added end end Event.QUEST_POI_UPDATE = function() QuestPOIUpdateIcons(); if ( GetCVar("trackQuestSorting") == "proximity" ) then SortQuestWatches(); end return OBJECTIVE_TRACKER_UPDATE_ALL end Event.SUPER_TRACKED_QUEST_CHANGED = function() return OBJECTIVE_TRACKER_UPDATE_QUEST end Event.ZONE_CHANGED = function() local inMicroDungeon = IsPlayerInMicroDungeon(); if ( inMicroDungeon ~= mod.inMicroDungeon ) then if ( not WorldMapFrame:IsShown() and GetCVarBool("questPOI") ) then SetMapToCurrentZone(); -- update the zone to get the right POI numbers for the tracker end --SortQuestWatches(); mod.inMicroDungeon = inMicroDungeon; end end Event.QUEST_AUTOCOMPLETE = function(questId) AddAutoQuestPopUp(questId, "COMPLETE"); return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST + OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP end Event.SCENARIO_CRITERIA_UPDATE = function() return OBJECTIVE_TRACKER_UPDATE_SCENARIO end Event.SCENARIO_UPDATE = function(newStage) if ( newStage ) then return OBJECTIVE_TRACKER_UPDATE_SCENARIO_NEW_STAGE else return OBJECTIVE_TRACKER_UPDATE_SCENARIO end end Event.TRACKED_ACHIEVEMENT_UPDATE = function() return OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT end Event.TRACKED_ACHIEVEMENT_LIST_CHANGED = function(achievementID, added) if ( added ) then return OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT_ADDED, achievementID else return OBJECTIVE_TRACKER_UPDATE_ACHIEVEMENT end end Event.ZONE_CHANGED_NEW_AREA = function () if ( not WorldMapFrame:IsShown() and GetCVarBool("questPOI") ) then SetMapToCurrentZone(); -- update the zone to get the right POI numbers for the tracker end SortQuestWatches(); mod.currentZoneArea = GetCurrentMapAreaID() print('Updating zone ID to', mod.currentZoneArea, '=', GetZoneText(), GetMinimapZoneText()) return OBJECTIVE_TRACKER_UPDATE_TASK_ADDED end Event.PLAYER_MONEY = function() if mod.watchMoneyReasons > 0 then return mod.watchMoneyReasons end end Event.CRITERIA_COMPLETE = function() return OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE end Event.QUEST_TURN_IN = function(questID, xp, money) if ( IsQuestTask(questID) ) then mod.Bonus:OnTurnIn(questID, xp, money) print('updating bonus modules (code', OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, ',', questID, xp, money) return OBJECTIVE_TRACKER_UPDATE_MODULE_BONUS_OBJECTIVE, questID, xp, money else return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST, questID, xp, money end end mod.Event = Event --- Done once per ui load local BlizzHooks = { ['AddQuestWatch'] = 'AddQuestWatch', ['RemoveQuestWatch'] = 'RemoveQuestWatch', ['AbandonQuest'] = 'AbandonQuest', ['AcknowledgeAutoAcceptQuest'] = 'AcknowledgeAutoAcceptQuest', ['AddAutoQuestPopUp'] = 'AddAutoQuestPopUp', ['RemoveAutoQuestPopUp'] = 'RemoveAutoQuestPopUp', ['AddTrackedAchievement'] = 'AddTrackedAchievement', ['RemoveTrackedAchievement'] = 'RemoveTrackedAchievement', ['SetSuperTrackedQuestID'] = 'SetSuperTrackedQuestID' } local VeneerData mod.SetWatchMoney = function(watchMoney, reason) if watchMoney then if band(mod.watchMoneyReasons, reason) == 0 then mod.watchMoneyReasons = mod.watchMoneyReasons + reason; end else if band(mod.watchMoneyReasons, reason) > 0 then mod.watchMoneyReasons = mod.watchMoneyReasons - reason; end end end function mod:OnInitialize() local c = mod.Conf.Wrapper VeneerData = _G.VeneerData VeneerData.CallLog = VeneerData.CallLog or {} if not mod.isHooked then mod.isHooked = true for blizzFunc, veneerFunc in pairs(BlizzHooks) do if mod[veneerFunc] then hooksecurefunc(blizzFunc, mod[veneerFunc]) else hooksecurefunc(blizzFunc, function(...) print('|cFFFF0088securehook('..tostring(blizzFunc)..')|r args:', ...) tinsert(VeneerData.CallLog, {blizzFunc, ...}) end) end end end mod.Conf.TasksLog = mod.Conf.TasksLog or {} Scroller:SetScrollChild(Scroll) Scroller:SetWidth(c.Width) Scroll:SetWidth(c.Width) Scroll:ClearAllPoints() Scroll:SetPoint('TOP', Scroller, 'TOP') ObjectiveTrackerFrame:UnregisterAllEvents() ObjectiveTrackerFrame:Hide() end function mod:OnEvent (event, ...) local isHandled print('OnEvent(|cFF00FF00'.. event ..'|r):', ...) local reason, arg1, arg2, arg3 if Event[event] then if type(Event[event]) == 'function' then PlaySoundFile([[Interface\Addons\SharedMedia_MyMedia\sound\Info.ogg]]) reason, arg1, arg2, arg3 = Event[event](...) elseif type(Event[event]) == 'table' then PlaySoundFile([[Interface\Addons\SharedMedia_MyMedia\sound\Link.ogg]]) for i, action in ipairs(Event[event]) do if type(action) == 'function' then reason, arg1, arg2, arg3 = action(event, ...) else reason = action end if reason then mod:Update(reason, arg1, arg2, arg3) end end else PlaySoundFile([[Interface\Addons\SharedMedia_MyMedia\sound\Heart.ogg]]) reason = Event[event] end else PlaySoundFile([[Interface\Addons\SharedMedia_MyMedia\sound\Quack.ogg]]) end if reason then mod:Update(reason, arg1, arg2, arg3) else print('no reason value returned') PlaySoundFile([[Interface\Addons\SharedMedia_MyMedia\sound\Quack.ogg]]) end end --- Done any time the the minimize button is toggled up function mod:OnEnable() for id, name in ipairs(mod.orderedNames) do if not mod.orderedHandlers[id] then Handler_Initialize(mod.DefaultHandler, name, id) end end for event, action in pairs(Event) do print('|cFFFF0088listen to', event, 'for action|r', tostring(action)) Wrapper:RegisterEvent(event) end Wrapper:SetScript('OnEvent', mod.OnEvent) local c = mod.Conf.Wrapper --Wrapper:SetPoint(c.AnchorPoint, UIParent, c.AnchorPoint, c.OffsetX, c.OffsetY) --B.Conf.FramePosition[Wrapper:GetName()] = {c.AnchorPoint, c.AnchorPoint, c.OffsetX, c.OffsetY} Wrapper:SetWidth(c.Width) mod.InitializeWidgets() mod:Update() end function mod:OnDisable() Wrapper:UnregisterAllEvents() end