Mercurial > wow > worldplan
view WorldPlan.lua @ 110:f6ef9a9f5476
nop out `WorldMap_SetupWorldQuestButton` since we aren't using them visually
author | Nenue |
---|---|
date | Tue, 25 Jul 2017 12:38:27 -0400 |
parents | caa482329919 |
children | e8b6c5433128 |
line wrap: on
line source
-- WorldPlan.lua -- Created: 8/16/2016 8:19 AM -- %file-revision% local addonFileName, db = ... local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local WP_VERSION = "1.4" local tinsert, pairs, floor = tinsert, pairs, floor local tremove, ipairs, wipe, unpack = tremove, ipairs, wipe, unpack local select, type, tostring, tonumber = select, type, tostring, tonumber local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS local BROKEN_ISLES_ID = 1007 local GetCurrentMapAreaID = GetCurrentMapAreaID local GetTime, IsLoggedIn = GetTime, IsLoggedIn local DEBUG_HISTORY = {} local ofunc = {} -- Define tables here so the pointers match up WorldPlanCore = { defaults = {}, modules = {}, TaskQueue = {}, } WorldPlanPOIMixin = {} WorldPlanSummaryMixin = {} db.filtersDirty = true db.questsDirty = true db.OrderedModules = {} db.LoadedModules = {} db.UsedFilters = {} db.QuestsByZone = {} db.QuestsByID = {} db.TasksByID = {} db.FreePins = {} db.UsedPins = {} db.UpdatedPins = {} db.ReportChunks = {} db.Bounties = {} db.BountiesByQuestID = {} db.BountiesByFactionID = {} db.IgnoreTimers = {} db.CLTriggers = { wq = function(arg2, extraArgs) if arg2 and WorldPlanQuests[arg2] then self:print('WorldPlanQuests:'..arg2..'()') WorldPlanQuests[arg2](WorldPlanQuests) else self:print('WorldPlanQuests:Refresh(true)') WorldPlanQuests:Refresh(true) end end, flightmap = function(arg2, extraArgs) if not extraArgs then return end local val1, val2, val3 = extraArgs:match("(%S+)%s*(%S*)%s*(%S*)") if arg2 == 'scale' then if tonumber(val1) and tonumber(val2) and tonumber(val3) then db.Config.FlightMapScalingLimits = {tonumber(val1), tonumber(val2), tonumber(val3)} self:print('FlightMapFrame scaling limits updated:', unpack(db.Config.FlightMapScalingLimits)) else self:print('FlightMapFrame scaling limits:', unpack(db.Config.FlightMapScalingLimits)) end elseif arg2 == 'alpha' then if tonumber(val1) and tonumber(val2) and tonumber(val3) then db.Config.FlightMapAlphaLimits = {tonumber(val1), tonumber(val2), tonumber(val3)} self:print('FlightMapFrame alpha limits updated:', unpack(db.Config.FlightMapAlphaLimits)) else self:print('FlightMapFrame alpha limits:', unpack(db.Config.FlightMapAlphaLimits)) end end end, filter = function(arg2) if arg2 and WorldPlanSummary[arg2] then self:print('WorldPlanSummary:'..arg2..'()') WorldPlanSummary[arg2](WorldPlanSummary) else self:print('WorldPlanSummary:Refresh(true)') WorldPlanSummary:Refresh(true) end end, log = function() if WorldPlanDebug:IsShown() then WorldPlanDebug:SetShown(false) else WorldPlanDebug:SetShown(true) end end, debug = function() if WorldPlanData then WorldPlanData.DebugEnabled = (not WorldPlanData.DebugEnabled) self:print(WorldPlanData.DebugEnabled and "Debugger on." or "Debugger off.") end end } -- default color templates db.DefaultType = { a = 1, r = 1, g = 1, b = 1, x = 0, y = 0, desaturated = true, pinMask = "Interface\\Minimap\\UI-Minimap-Background", rewardMask = "Interface\\Minimap\\UI-Minimap-Background", texture = "Interface\\BUTTONS\\YELLOWORANGE64", continent = { iconWidth = 14, borderWidth = 2, highlightWidth = 1, TagSize = 8, maxAlertLevel = 0, showNumber = true, numberFontObject = 'WorldPlanFont' }, zone = { iconWidth = 18, borderWidth = 2, highlightWidth = 2, TagSize = 12, maxAlertLevel = 3, showNumber = true, numberFontObject = 'WorldPlanNumberFontThin' }, minimized = { r = 0, g = 0, b = 0, a = 0.1, iconWidth = 8, borderWidth = 0, alpha = 0.5, highlightWidth = 0, maxAlertLevel = 0, NoIcon = true, TagSize = 8, TimeleftStage = 1, showNumber = false, alpha = 0.1, } } db.DefaultConfig = { ShowAllProfessionQuests = false, DisplayContinentSummary = true, DisplayContinentPins = true, NotifyWhenNewQuests = true, EnablePins = true, FadeWhileGrouped = false, FlightMapAlphaLimits = {1, .7, 1}, FlightMapScalingLimits = {1, 3, 1.5}, --UntrackedColor = {}, --TrackedColor = {}, --CriteriaColor = {}, --RewardColorGold = {}, --RewardColorReagent = {}, --RewardColorArtifactPower = {}, --RewardColorCurrency = {}, IgnoreTimers = {}, } -- tracking menu toggler local DropDown_OnClick = function(self) local key = self.value if key then if WorldPlanData[key] then WorldPlanData[key] = nil else WorldPlanData[key] = true end end _G.WorldPlan:OnConfigUpdate() end -- insert visual options into the tracking button menu local DropDown_Initialize = function (self, callback, dropType) if self ~= WorldMapFrameDropDown then return end local config = WorldPlanData local info = UIDropDownMenu_CreateInfo() info.text = "" info.isTitle = true UIDropDownMenu_AddButton(info) info.text = "|cFF00AAFFWorldPlan|r" info.isTitle = true UIDropDownMenu_AddButton(info) info.isTitle = nil info.disabled = nil info.keepShownOnClick = true info.tooltipOnButton = 1 info.text = "Enable" info.isNotRadio = true info.value = "EnablePins" info.checked = config.EnablePins info.tooltipTitle = "Enable World Quest Overlays" info.tooltipText = "Toggle the detail layers here." info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) info.text = "Display All Profession Quests" info.isNotRadio = true info.value = "ShowAllProfessionQuests" info.checked = config.ShowAllProfessionQuests info.tooltipTitle = "Hidden Quests" info.tooltipText = "Display work order and profession-related quests that are skipped by the default UI." info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) info.text = "Show Continent Pins" info.isNotRadio = true info.value = "DisplayContinentPins" info.checked = config.DisplayContinentPins info.tooltipTitle = "Continent Pins" info.tooltipText = "Display quest pins on the continent map (may get cramped)." info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) info.text = "Show Summary" info.isNotRadio = true info.value = "DisplayContinentSummary" info.tooltipTitle = "Summary Bar" info.tooltipText = "Display a summary of active world quests. Note: requires directly viewing Broken Isle and Dalaran maps to gain complete info." info.checked = config.DisplayContinentSummary info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) --[[ info.text = "Nudge Pins" info.isNotRadio = true info.value = "NudgePins" info.tooltipTitle = "Pin Nudging" info.tooltipText = "Adjust the position of quest pins that overlap." info.checked = config.NudgePins info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) info.text = "Fade Whiled Grouped" info.isNotRadio = true info.value = "FadeWhileGrouped" info.tooltipTitle = "Group Fade" info.tooltipText = "Reduce pin alpha when grouped, so player dots are easier to see." info.checked = config.FadeWhileGrouped info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) --]] end local function Handler_UpdateFader(self, sinceLast, isActive) if isActive then self.toAlpha = 1 self.Backdrop:Show() else self.toAlpha = self.fadeOpacity self.Backdrop:Hide() end local cAlpha = self:GetAlpha() if cAlpha ~= self.toAlpha then if cAlpha > self.toAlpha then cAlpha = cAlpha - sinceLast*4 if cAlpha <= self.toAlpha then cAlpha = self.toAlpha end else cAlpha = cAlpha + sinceLast*4 if cAlpha >= self.toAlpha then cAlpha = self.toAlpha end end end self:SetAlpha(cAlpha) end function db.print(...) for i = 1, select('#', ...) do tinsert(db.ReportChunks, tostring(select(i, ...))) end end function db.log(msg) WorldPlanData.Debug = WorldPlanData.Debug or {} tinsert(WorldPlanData.Debug, msg) tinsert(DEBUG_HISTORY, msg) if WorldPlanDebug:IsShown() then WorldPlanDebug:Update() end end WorldPlanDebugMixin = { OnLoad = function(self) self:SetFont("Interface\\Addons\\Devian\\font\\SourceCodePro-Regular.ttf", 13, 'NORMAL') self:SetJustifyH('LEFT') self:SetFading(false) self:SetMaxLines(2048) self.loadedMessages = 0 end, OnShow = function(self) if self.loadedMessages < #DEBUG_HISTORY then self:Update() end end, Update = function(self) for i = self.loadedMessages, #DEBUG_HISTORY do self:AddMessage(DEBUG_HISTORY[i]) self.loadedMessages = i end end , OnMouseWheel = function(self, delta) local up = delta > 0 if IsControlKeyDown() then if up then self:ScrollToTop() else self:ScrollToBottom() end elseif IsShiftKeyDown() then if up then self:PageUp() else self:PageDown() end else if up then self:ScrollUp() else self:ScrollDown() end end end } function WorldPlanCore:OnConfigUpdate() for _, module in ipairs(db.OrderedModules) do if module.OnConfigUpdate then module:OnConfigUpdate() end end db.currentMapID = nil db.BountyUpdate = true self:SetCurrentMap('CONFIG_UPDATE') self:Refresh() end function WorldPlanCore:print(...) db.print(...) end function WorldPlanCore:AddHandler (frame) if not db.LoadedModules[frame] then print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName(), self.initialized) db.LoadedModules[frame] = true tinsert(db.OrderedModules, frame) if frame.defaults then db.DefaultConfig[frame:GetName()] = frame.defaults end frame.UpdateAlpha = Handler_UpdateFader frame.owningFrame = self else print('|cFFFF4400'..self:GetName()..':AddHandler()', frame:GetName()) end end function WorldPlanCore:OnLoad () self.Types = setmetatable({}, { __newindex = function(t, k, v) if type(v) == 'table' then print('adding owner', k) v = setmetatable(v, { __newindex = function(t2,k2,v2) if type(v2) == 'table' then --print('adding type', k2) v2 = setmetatable(v2, {__index = function(t3,k3) --print('##deferring to default key', k3) return db.DefaultType[k3] end}) end rawset(t2,k2,v2) end}) end rawset(t,k,v) end }) self.Types[self] = {} for index, color in pairs(ITEM_QUALITY_COLORS) do self:AddTypeInfo(self, index, { r = color.r, g = color.g, b = color.b, hex = color.hex, }) end db.print('v'..WP_VERSION) self:RegisterEvent("QUESTLINE_UPDATE") self:RegisterEvent("QUEST_LOG_UPDATE") self:RegisterEvent("WORLD_MAP_UPDATE") self:RegisterEvent("SPELLS_CHANGED") self:RegisterEvent('PLAYER_ENTERING_WORLD') self:RegisterEvent("WORLD_QUEST_COMPLETED_BY_SPELL") self:RegisterEvent("SUPER_TRACKED_QUEST_CHANGED") self:RegisterEvent("SKILL_LINES_CHANGED") self:RegisterEvent("ARTIFACT_XP_UPDATE") self:RegisterEvent("ADDON_LOADED") self:RegisterEvent("PLAYER_LOGIN") --self:SetParent(WorldMapFrame) ofunc[WorldMap_SetupWorldQuestButton] = WorldMap_SetupWorldQuestButton WorldMap_SetupWorldQuestButton = nop end function WorldPlanCore:OnShow() --print(self:GetName()..':OnShow()') --hooksecurefunc(self, 'SetScript', function(...) self:print('|cFFFFFF00'..self:GetName()..':SetScript()|r', ...) end) end local BROKEN_ISLE_MAPS = { [1007] = true, -- Broken Isle [1014] = true, -- Dalaran [1021] = true, -- Broken Shoree [1024] = true, -- Highmountain [1015] = true, -- Azsuna [1017] = true, -- Azsuna [1018] = true, -- Val'Sharah [1033] = true, -- Suramar [1077] = true, -- Dreamgrove [1096] = true, -- Eye of Azshara [1080] = true, -- Thunder Totem [1072] = true, -- True Shot Lodge, } function WorldPlanCore:SetCurrentMap(event) local mapAreaID, isContinent = GetCurrentMapAreaID() if not mapAreaID then return end print('SetCurrentMap()', event, mapAreaID) local isBrokenIsle = BROKEN_ISLE_MAPS[mapAreaID] local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() local isMapOpen = WorldMapFrame:IsShown() local isNewMap = (mapAreaID ~= db.currentMapID) or (isMapOpen ~= db.isMapOpen) or (db.isMicroDungeon ~= isMicroDungeon) or (db.isContinentMap ~= isContinent) db.isMicroDungeon = isMicroDungeon db.isMapOpen = isMapOpen db.currentMapID = mapAreaID db.isContinentMap = isContinent db.isBrokenIsle = isBrokenIsle for _, module in ipairs(db.OrderedModules) do if module.OnMapInfo then if module.Debug then module:Debug(event) end print(' |cFF00FFFF'..module:GetName() .. ':OnMapInfo()|r') module:OnMapInfo(isBrokenIsle, isContinent, mapAreaID, isNewMap, isMapOpen) end end end function WorldPlanCore:OnEvent (event, ...) print('|cFF00FF88'..self:GetName().. ':OnEvent()|r', event, GetTime(), 'init:', self.initialized) if event == 'ADDON_LOADED' then if IsLoggedIn() and not self.initialized then self:Setup() end else if (event == 'WORLD_MAP_UPDATE') or (event == 'PLAYER_ENTERING_WORLD') or (event == 'PLAYER_LOGIN') then print('|cFFFF4400currentMapID =', db.currentMapID, ...) if event == 'PLAYER_ENTERING_WORLD' then -- start from scratch db.isMicroDungeon = nil db.isMapOpen = nil db.currentMapID = nil db.isContinentMap = nil db.isBrokenIsle = nil end self:SetCurrentMap(event .. ' ' .. GetTime()) end end end function WorldPlanCore:OnNext(func) tinsert(self.TaskQueue, func) --self:print('|cFF00FF00adding scheduled task #', #self.TaskQueue) end function WorldPlanCore:OnUpdate() if #self.TaskQueue >= 1 then local func = tremove(self.TaskQueue, 1) --self:print('|cFF00FF00running scheduled task #', #self.TaskQueue) func() end if self.isStale then -- these need to happen in load order for i, module in ipairs(db.OrderedModules) do if module:IsVisible() and module.isStale then print('|cFF00FF00internal '..module:GetName()..':Refresh()|r') module:Refresh() end end self.isStale = nil end if #db.ReportChunks >= 1 then DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FF"..addonFileName.."|r: " .. table.concat(db.ReportChunks, ', ')) wipe(db.ReportChunks) end if self.dataFlush then self:FireCallbacks() end end function WorldPlanCore:Setup () print('|cFFFFFF00'..self:GetName()..':Setup()|r') if not WorldPlanData then WorldPlanData = {key = 0} end -- debug info WorldPlanData.key = (WorldPlanData.key or 0) + 1 WorldPlanData.Debug = WorldPlanData.Debug or {} local guid = UnitGUID('player') WorldPlanData.IgnoreTimers = WorldPlanData.IgnoreTimers or {} WorldPlanData.IgnoreTimers[guid] = WorldPlanData.IgnoreTimers[guid] or {} for _, msg in ipairs(WorldPlanData.Debug) do tinsert(DEBUG_HISTORY, msg) end tinsert(DEBUG_HISTORY, '--SESSION BREAK--') wipe(WorldPlanData.Debug) db.IgnoreTimers = WorldPlanData.IgnoreTimers db.Config = WorldPlanData for k,v in pairs(db.DefaultConfig) do --[===[@non-debug@ if not db.Config[k] then db.Config[k] = v end --@end-non-debug@]===] --@debug@ db.Config[k] = v --@end-debug@ end db.currentMapID = GetCurrentMapAreaID() for i, module in ipairs(db.OrderedModules) do db.Config[module:GetName()] = db.Config[module:GetName()] or {} if module.Setup then module:Setup() end if not module.RegisterEvent then module.RegisterEvent = self.RegisterEvent end if module.OnConfigUpdate then module:OnConfigUpdate() end end self.initialized = true hooksecurefunc("UIDropDownMenu_Initialize", DropDown_Initialize) hooksecurefunc("WorldMapTrackingOptionsDropDown_OnClick", function(button) print("|cFF0088FFWorldMapTrackingOptionsDropDown_OnClick|r") local value = button.value if (value == "worldQuestFilterOrderResources" or value == "worldQuestFilterArtifactPower" or value == "worldQuestFilterProfessionMaterials" or value == "worldQuestFilterGold" or value == "worldQuestFilterEquipment") then self:Refresh(true) end end) hooksecurefunc("WorldMapFrame_Update", function() print('|cFFFF4400WorldMapFrame_Update|r') for _,module in ipairs(db.OrderedModules) do if module.OnWorldMapFrameUpdate then print(' |cFFFF4400'..module:GetName()..'|r') module:OnWorldMapFrameUpdate() end end end) SLASH_WORLDPLAN1 = "/worldplan" SLASH_WORLDPLAN2 = "/wp" SlashCmdList.WORLDPLAN = function(args) local arg1, arg2, extraArgs = args:match("(%S+)%s*(%S*)%s*(.*)") if db.CLTriggers[arg1] then db.CLTriggers[arg1](arg2, extraArgs) else self:print('Refreshing data.') self:Refresh(true) end end end -- registers a template table function WorldPlanCore:AddTypeInfo(owner, id, info) self.Types[owner] = self.Types[owner] or {} self.Types[owner][id] = info print('Type('..owner:GetName()..')('..id..') = '.. tostring(info)) end -- recall a template table, with situational details filled in function WorldPlanCore:GetTypeInfo(owner, typeID) local info, extraInfo if not owner then --print('## deferring to default type list') else --print('## pulling for', owner:GetName(), 'id =', typeID) end owner = owner or self if (not typeID) or (not self.Types[owner][typeID]) then --print('## sending list default') info = db.DefaultType else --print('## sent list definition', typeID) info = self.Types[owner][typeID] end local subType = 'continent' if ( FlightMapFrame and FlightMapFrame:IsVisible() and FlightMapFrame:IsZoomedIn() ) or ( not db.isContinentMap ) or ( db.useContinentType == false ) then subType = 'zone' end return info, info[subType] or db.DefaultType[subType] end function WorldPlanCore:Refresh (forced) print('|cFFFFFF00'..self:GetName()..':Refresh()|r forced:', forced, 'init:', self.initialized) if not self.initialized then return end for i, module in ipairs(db.OrderedModules) do if module.Refresh then print('|cFF00FF00external '..module:GetName()..':Refresh()|r') module:Refresh('WORLDPLAN_REFRESH') end end self.isStale = nil end -------------------------------------------------------------------------------------------------------------------- ------------------- function WorldPlanCore:GetQuestPins(zoneID) return db.UsedPins end function WorldPlanCore:RegisterDataCallback(func) self.callbacks = self.callbacks or {} self.callbacks[func] = func end function WorldPlanCore:FireCallbacks() self.callbacks = self.callbacks or {} for func in pairs(self.callbacks) do func() end self.dataFlush = nil end function WorldPlanCore:SetHook(base, arg1, arg2) if type(base) == 'table' then end end --%end-debug%