Mercurial > wow > worldplan
view WorldPlan.lua @ 34:0100d923d8c3
WorldPlan:
- Reward filter toggle changed to clear out other reward filters. The assumption being that one is most often looking only for that particular type of quest when they go to use it.
- Fixed filter bar info falling out of sync after player-triggered world map updates.
- Code stuff:
-- Quest pin shown-state management makes better use of OnShow OnHide handlers, SetShown is toggled and it all goes from there
-- WorldQuests module re-factored outside of the top level frame script.
ClassPlan:
- Available missions are now recorded; the mission list can be toggled between in-progress and available by clicking the heading.
author | Nenue |
---|---|
date | Wed, 02 Nov 2016 19:04:47 -0400 |
parents | be4db60219ca |
children | 26dfa661daa7 |
line wrap: on
line source
-- WorldPlan.lua -- Created: 8/16/2016 8:19 AM -- %file-revision% WorldPlanCore = { defaults = {}, modules = {}, FilterOptions = {}, UsedFilters = {}, QuestsByZone = {}, QuestsByID = {}, TaskQueue = {}, } local WorldPlan = WorldPlanCore local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local WP_VERSION = "1.0" local tinsert, pairs, floor = table.insert, pairs, floor local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS local BROKEN_ISLES_ID = 1007 local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID -- default color templates local DEFAULT_TYPE = { 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 = { PinSize = 14, Border = 2, TrackingBorder = 1, TagSize = 6, TimeleftStage = 0, showNumber = true, numberFontObject = 'WorldPlanFont' }, zone = { PinSize = 22, Border = 3, TrackingBorder = 2, TagSize = 12, TimeleftStage = 3, showNumber = true, numberFontObject = 'WorldPlanNumberFontThin' }, minimized = { PinSize = 6, Border = 0, TrackingBorder = 1, NoIcon = true, TimeleftStage = 1, showNumber = false, } } local defaults = { ShowAllProfessionQuests = false, DisplayContinentSummary = true, DisplayContinentPins = true, NotifyWhenNewQuests = true, EnablePins = true, FadeWhileGrouped = false, } -- operating flags local superTrackedID local currentMapName local hasNewQuestPins local isContinentMap local hasPendingQuestData local notifyPlayed local scanner, wmtt, WorldMapPOIFrame -- 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:Refresh() end function WorldPlan:print(...) local msg for i = 1, select('#', ...) do msg = (msg and (msg .. ' ') or '') .. tostring(select(i, ...)) end DEFAULT_CHAT_FRAME:AddMessage("|cFF0088FFWorldPlan|r: " .. msg) end local current_type_owner function WorldPlan:AddHandler (frame, defaults) print('|cFFFFFF00'..self:GetName()..':AddHandler()', frame:GetName()) tinsert(self.modules, frame) self.defaults[frame] = defaults frame.GetTypeInfo = function(frame, typeID) return self:GetTypeInfo(frame, typeID) end end function WorldPlan: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 DEFAULT_TYPE[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 WorldPlan = self WorldPlan:print('v'..WP_VERSION) self:RegisterEvent("QUESTLINE_UPDATE") self:RegisterEvent("QUEST_LOG_UPDATE") self:RegisterEvent("WORLD_MAP_UPDATE") 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:SetParent(WorldMapFrame) end function WorldPlan:OnShow() print(self:GetName()..':OnShow()') if self.isStale then self:Refresh() end hooksecurefunc(self, 'SetScript', function(...) self:print('|cFFFFFF00'..self:GetName()..':SetScript()|r', ...) end) end function WorldPlan:OnEvent (event, ...) print() print(event, 'init:', self.initialized) if event == 'ADDON_LOADED' then local addon = ... if addon == "Blizzard_FlightMap" then print('do mixin junk') self.OnFlightMapLoaded() end if IsLoggedIn() and not self.initialized then self:Setup() end else if event == 'WORLD_MAP_UPDATE' then self.currentMapID = GetCurrentMapAreaID() self.isContinentMap = (self.currentMapID == BROKEN_ISLES_ID) self:print('|cFFFF4400currentMapID =', self.currentMapID) --self.isStale = true end for i, module in ipairs(self.modules) do if module.OnEvent then print(' |cFF0088FF'..module:GetName() .. ':OnEvent()|r') module:OnEvent(event, ...) end 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 print('|cFF00FF00pushing global update') self.isStale = nil self:Refresh() else for i, module in ipairs(self.modules) do if module.isStale then print('|cFF00FF00internal '..module:GetName()..':Refresh()|r') module:Refresh() end end end end function WorldPlan:Setup () if not WorldPlanData then WorldPlanData = {key = 0 } end WorldPlanData.key = (WorldPlanData.key or 0) + 1 self.db = WorldPlanData self.db.WorldQuests = self.db.WorldQuests or {} db = self.db for k,v in pairs(defaults) do --[===[@non-debug@ if not db[k] then db[k] = v end --@end-non-debug@]===] --@debug@ db[k] = v --@end-debug@ end self.currentMapID = GetCurrentMapAreaID() for i, module in ipairs(self.modules) do module.db = self.db if module.Setup then module:Setup() end if not module.RegisterEvent then module.RegisterEvent = self.RegisterEvent end end self.initialized = true hooksecurefunc("UIDropDownMenu_Initialize", self.OnDropDownInitialize) 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) end function WorldPlan:AddTypeInfo(owner, id, info) self.Types[owner] = self.Types[owner] or {} self.Types[owner][id] = info print('Type('..owner:GetName()..')('..id..') = '.. tostring(info)) end function WorldPlan: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 = DEFAULT_TYPE else --print('## sent list definition', typeID) info = self.Types[owner][typeID] end if isContinentMap then extraInfo = info.continent --print('### continent subtype', extraInfo) else extraInfo = info.zone --print('### zone subtype', extraInfo) end return info, extraInfo end do local timeStates = { {maxSeconds = 60, r=1, g=0.25, b =0, format = function (minutes) return '|cFFFF4400'.. minutes .. 'm' end, }, {maxSeconds = 240, r=1, g=.5, b=0, format = function(minutes) return '|cFFFF4400'.. floor(minutes/60) .. 'h' end, }, {maxSeconds = 1440, r=1, g=1, b=0, format = function(minutes) return '|cFFFFFF00'.. floor(minutes/60) .. 'h' end, }, {maxSeconds = 10081, r=0, g=1, b=0, }, -- 7 days + 1 minute } -- Generates a timeleft string function WorldPlan:GetTimeInfo(timeLeft, limit) limit = limit or #timeStates for index = 1, limit do local state = timeStates[index] if timeLeft <= state.maxSeconds then local text if state.format then text = state.format(timeLeft) end return text, index end end return nil, nil end end function WorldPlan: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(self.modules) do if module.Refresh then print('|cFF00FF00external '..module:GetName()..':Refresh()|r') module:Refresh(forced) end end end -- insert visual options into the tracking button menu WorldPlan.OnDropDownInitialize = function (self, callback, dropType) if self ~= WorldMapFrameDropDown then return end local db = WorldPlan.db 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 = db.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 = db.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 = db.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 = db.DisplayContinentSummary info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) info.text = "Fade In Groups" 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 = db.FadeWhileGrouped info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) end -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -- data provider manipulations for the taxi map WorldPlan.OnFlightMapLoaded = function() if true then return end -- todo: figure out how to layer inside the map canvas local res = {} local t = {} for k,v in pairs(FlightMapFrame) do tinsert(res, tostring(k)) end table.sort(res) for i, k in ipairs(res) do print(k) end hooksecurefunc(FlightMapFrame, 'RefreshAll', function(self) print('|cFF0088FFWQDP RefreshAllData ', GetTime()) WorldPlan:GetPinsForMap(self:GetMapID()) for pin in self:EnumerateAllPins() do if pin.worldQuest then --print('got pin #', pin.questID) local wp = self.QuestsByID[pin.questID] if wp then wp:ClearAllPoints() wp:SetParent(FlightMapFrame.ScrollContainer) wp:SetFrameStrata('MEDIUM') wp:SetPoint('CENTER', pin, 'CENTER') wp:Show() end end end end) end SLASH_WORLDPLAN1 = "/worldplan" SLASH_WORLDPLAN2 = "/wp" SlashCmdList.WORLDPLAN = function() print('command pop') WorldPlan:GetPinsForMap() WorldPlan:RefreshPins() SetTimedCallbackForAllPins(0, function(self) self.FadeIn:Play() self.FlashIn:Play() end) SetTimedCallbackForAllPins(5, function(self) self.PendingFade:Play() end) SetTimedCallbackForAllPins(8, function(self) self.PendingFade:Stop() end) end --%end-debug%