Mercurial > wow > worldplan
view WorldPlan.lua @ 30:8cb750e79952
WorldPlan:
- Reworking filters to utilize newly added CVars
author | Nenue |
---|---|
date | Fri, 28 Oct 2016 14:06:07 -0400 |
parents | c1612c2c1840 |
children | d0114b51cdea |
line wrap: on
line source
-- WorldPlan.lua -- Created: 8/16/2016 8:19 AM -- %file-revision% local addonName, db = ... local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" local POI_BORDER_MASK = "Interface\\Minimap\\UI-Minimap-Background" local POI_BORDER_FILL = "Interface\\BUTTONS\\YELLOWORANGE64" local POI_BORDER_BLUE = "Interface\\BUTTONS\\GRADBLUE" local POI_BORDER_RED = "Interface\\BUTTONS\\RedGrad64" local POI_BORDER_YELLOW = "Interface\\BUTTONS\\YELLOWORANGE64" local POI_BORDER_GREEN = "Interface\\BUTTONS\\GREENGRAD64" WorldPlanCore = { defaults = {}, modules = {}, } WorldPlanQuestsMixin = { QuestsByZone = {}, QuestsByID = {}, freePins = {}, } WorldPlanPOIMixin = {} WorldPlanFilterPinMixin = setmetatable({ QuestsByID = {}, freePins = {} }, {__tostring = function() return 'QuestHandler' end}) local WorldPlanFlightMapMixin = setmetatable({}, {__tostring = function() return 'FlightMapHandler' end}) local WorldQuests = WorldPlanQuestsMixin local WorldPlan = WorldPlanCore local QuestPOI = WorldPlanPOIMixin local FilterPin = WorldPlanFilterPinMixin local WP_VERSION = "1.0" local db local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end local fbprint = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or function() end local wipe, tremove, tinsert, pairs, floor, tContains = table.wipe, table.remove, table.insert, pairs, floor, tContains local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID local TQ_IsActive = C_TaskQuest.IsActive local ITEM_QUALITY_COLORS = ITEM_QUALITY_COLORS local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest local GameTooltip = GameTooltip local GetItemIcon = GetItemIcon local GetMapInfo, QuestPOIGetIconInfo = GetMapInfo, QuestPOIGetIconInfo local GetQuestTagInfo, HaveQuestData = GetQuestTagInfo, HaveQuestData local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, GetQuestLogRewardMoney local GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardInfo, GetQuestLogRewardCurrencyInfo, GetMoneyString local GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID = GetCurrentMapAreaID, GetMapNameByID, GetSuperTrackedQuestID local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo -- default color templates local ARTIFACT_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_ARTIFACT] local MONEY_COLOR = {hex ='|cFFFFFF00', r=1, g=1, b=0} local COMMON_COLOR = ITEM_QUALITY_COLORS[LE_ITEM_QUALITY_COMMON] local DEFAULT_TYPE = { a = 1, r = 1, g = 1, b = 1, x = 0, y = 0, desaturated = true, pinMask = POI_BORDER_MASK, rewardMask = POI_BORDER_MASK, texture = POI_BORDER_FILL, 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 = 4, Border = 0, TrackingBorder = 1, NoIcon = true, TimeleftStage = 1, showNumber = false, } } local POI_FILTER_STYLE = setmetatable({ continentBorder = 2, zoneBorder = 2, }, {__index = DEFAULT_TYPE}) local defaults = { defaultPinStyle = POI_DEFAULT_TYPE, rewardStyle = POI_REWARD_TYPE, filterStyle = POI_FILTER_STYLE, ShowAllProfessionQuests = false, DisplayContinentSummary = true, DisplayContinentPins = true, NotifyWhenNewQuests = true, EnablePins = true, FadeWhileGrouped = true, } -- Summary header structure local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL local POI_FILTER_OPTIONS = { { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" }, { filterKey= 'rewardType', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" }, { filterKey= 'rewardType', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\ICONS\\inv_misc_elvencoins" }, { filterKey= 'rewardType', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" }, { filterKey= 'rewardType', filterValue = REWARD_REAGENT, label = 'Materials', texture = 1417744 }, { filterKey= 'rewardType', filterValue = REWARD_CASH, label = 'Gold', texture = ICON_MONEY }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", }, } WorldPlanCore.BrokenIsleID = BROKEN_ISLES_ID WorldPlanCore.FilterStyle = POI_FILTER_STYLE WorldPlanCore.FilterOptions = {} WorldPlanCore.UsedFilters = {} -- operating flags local superTrackedID local currentMapName local hasNewQuestPins local isContinentMap local numPins = 0 local FilterInclusions = {rewardType = {}, worldQuestType = {}, factionID = {}} local NotificationTypes = {} local ZoneInfo = {} local SummaryHeaders = {} local FreePins = {} local NumPinFrames = 1 local hasPendingQuestData local notifyPlayed local scanner, wmtt, WorldMapPOIFrame local tasksQueue = {} local function OnNext (func) if #tasksQueue == 0 then _G.WorldPlan:SetScript('OnUpdate', function() local func = tremove(tasksQueue, 1) if func then func() end if #tasksQueue == 0 then _G.WorldPlan:SetScript('OnUpdate', nil) end end) end print('inserting task #', #tasksQueue+1, func) tinsert(tasksQueue, func) end -- update a masked texture without messing up its blending mask local SetMaskedTexture = function(region, file, mask) mask = mask or POI_BORDER_MASK region:SetMask(nil) region:SetTexture(file) region:SetMask(mask) end -- 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 WorldPlan:RefreshAll() 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 scanner = _G.WorldPlanTooltip wmtt = _G.WorldMapTooltip WorldMapPOIFrame = _G.WorldMapPOIFrame 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 end function WorldPlan:OnEvent (event, ...) print() print(event, 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 elseif event == 'WORLD_MAP_UPDATE' then self.currentMapID = GetCurrentMapAreaID() print('|cFFFF4400currentMapID =', self.currentMapID) self:Refresh() else for i, module in ipairs(self.modules) do if module.OnEvent then print('forwarding to', tostring(module)) module:OnEvent(event, ...) 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) 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 POI_DEFAULT_TYPE = db.defaultPinStyle POI_REWARD_TYPE = db.rewardStyle POI_FILTER_STYLE = db.filterStyle for i, module in ipairs(self.modules) do if module.Reset then print(module, 'Reset()') module:Reset() end end for i, module in ipairs(self.modules) do if module.Refresh then print(module, 'Refresh()') module:Refresh() end end for i, module in ipairs(self.modules) do if module.Cleanup then print(module, 'Cleanup()') module:Cleanup() end end end function WorldPlan:UpdateAnchors () for i, module in ipairs(self.modules) do if module.UpdateAnchors then module:UpdateAnchors() 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.DisplayContinentSummary info.func = DropDown_OnClick UIDropDownMenu_AddButton(info) end -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- local PinBaseIndex = 1600 local BROKEN_ISLES_ID, DALARAN_ID, AZSUNA_ID, VALSHARAH_ID, HIGHMOUNTAIN_ID, STORMHEIM_ID, SURAMAR_ID, EOA_ID = 1007, 1014, 1015,1018, 1024, 1017, 1033, 1096 -- maps where we do our own anchors local CONTINENT_MAPS = { [BROKEN_ISLES_ID] = BROKEN_ISLES_ID, } local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah", [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } function WorldQuests:Setup() for mapID, mapName in pairs(WORLD_QUEST_MAPS) do self.QuestsByZone[mapID] = {} end -- refresh positions any time blizzard does so (i.e. mousewheel zoom) hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() self:Refresh(true) end) -- hide the original world quest POIs hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function() for i = 1, NUM_WORLDMAP_TASK_POIS do local button = _G['WorldMapFrameTaskPOI'..i] if button and button.worldQuest then button:Hide() end end end) end local defaults = {} function WorldQuests:OnLoad() print('|cFF00FF88'..self:GetName()..':OnLoad') WorldPlan:AddHandler(self, defaults) local rgbWhite = {1, 1, 1} WorldPlan:AddTypeInfo(self, REWARD_REAGENT, { r = 0, g = 1, b = 1 }) WorldPlan:AddTypeInfo(self, REWARD_ARTIFACT_POWER, { r = 1, g = .25, b = .5, hasNumeric = true, numberRGB = rgbWhite }) WorldPlan:AddTypeInfo(self, REWARD_GEAR, { r = .1, g = .2, b = 1 }) WorldPlan:AddTypeInfo(self, REWARD_CURRENCY, { r = 1, g = 1, b = 0, hasNumeric = true, numberRGB = {1,1,0}, }) WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 0, g = 0, b = 0, }) for areaID, fileName in pairs(WORLD_QUEST_MAPS) do self.QuestsByZone[areaID] = {} end self:RegisterEvent('QUEST_LOG_UPDATE') self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') self:RegisterEvent('SKILL_LINES_CHANGED') end function WorldQuests:OnEvent (event, ...) local print = wqprint print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...) if event == 'QUEST_LOG_UPDATE' then local questID, added = ... if questID and added then local questPOI = self:AcquirePin(questID) self.hasUpdate, self.isPending = questPOI:RefreshData() else self:RefreshData() end print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.hasUpdate) elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then local questID = ... if questID and self.QuestsByID[questID] then self:ReleasePin(self.QuestsByID[questID]) end elseif event == 'SKILL_LINES_CHANGED' then self.hasUpdate = true end end function WorldQuests:OnUpdate() if self.hasUpdate then wqprint('|cFF00FF00pushing update') self:Refresh(true) end end local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation function WorldQuests:AcquirePin (questID, mapID) local pin = self.QuestsByID[questID] local isNew = false if not pin then isNew = true local numFree = #self.freePins if numFree >= 1 then pin = tremove(self.freePins, numFree) --print('|cFF00FF00Re-using', pin:GetName()) else local name = 'WorldPlanQuestMarker' .. NumPinFrames --print('|cFF00FF00Creating', name) pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') pin:SetFrameStrata('HIGH') pin.GetTypeInfo = function(frame, typeID) return self:GetTypeInfo(typeID) end NumPinFrames = NumPinFrames + 1 --pin.iconBorder:SetVertexColor(0,0,0,1) end pin:SetID(questID) pin.isNew = true pin.currentWidth = nil -- used by TaskPOI_x scripts pin.questID = questID pin.worldQuest = true self.QuestsByID[questID] = pin else --print('|cFF00FF00Using', pin:GetName()) end mapID = mapID or TQ_GetQuestZoneID(questID) self.QuestsByZone[mapID][questID] = pin return pin, isNew end -- remove from index and add it to the recycling heap function WorldQuests:ReleasePin (pin) local id = pin.questId if id then self.QuestsByID[id] = nil for i, zone in pairs(self.QuestsByZone) do print('-', i, zone[i]) zone[id] = nil end end pin:Hide() pin:ClearAllPoints() tinsert(self.freePins, pin) print('|cFFFF4400Clearing out', pin:GetName(),id) end -- create of update quest pins for a map and its underlying zones function WorldQuests:RefreshData (mapID) local print = wqprint mapID = mapID or GetCurrentMapAreaID() superTrackedID = GetSuperTrackedQuestID() if not mapID then -- info not available yet return end print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID()) if mapID == BROKEN_ISLES_ID then self.hasUpdate = false print('|cFF00FFFFContinent:|r', mapID, GetMapNameByID(mapID), superTrackedID) self.fullSearch = true for i = 1, MC_GetNumZones(mapID) do local submapID, name, depth = MC_GetZoneInfo(mapID, i) self:RefreshData(submapID) end self.fullSearch = nil elseif self.QuestsByZone[mapID] then local taskInfo = TQ_GetQuestsForPlayerByMapID(mapID) local numQuests = 0 if taskInfo and #taskInfo >= 1 then print('|cFF00FFFF Zone:|r', mapID, GetMapNameByID(mapID), #taskInfo) wipe(self.QuestsByZone[mapID]) ZoneInfo[mapID] = taskInfo qprint('|cFFFF4400START of', GetMapNameByID(mapID)) for taskID, info in pairs(taskInfo) do local questID = info.questId info.mapID = mapID local questPOI = self:AcquirePin(questID, mapID) local hasUpdate, isPending = questPOI:RefreshData(info) self.hasUpdate = (self.hasUpdate or hasUpdate) self.isPending = (self.isPending or isPending) numQuests = numQuests + 1 end qprint('|cFFFF4400END of', GetMapNameByID(mapID)) end end if not self.fullSearch then print(' hasUpdate:', self.hasUpdate, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) end end function WorldQuests:Refresh(forced) local print = wqprint print('|cFF00FF88'..self:GetName()..':Refresh()|r') if not WorldMapPOIFrame:IsVisible() then return end if forced then self:Reset() end self:UpdateAnchors() if forced then self:Cleanup () end end -- prepares elements for a map update function WorldQuests:Reset () local print = wqprint print('|cFF00FF88'..self:GetName()..':Reset()|r') for questID, pin in pairs(self.QuestsByID) do pin.used = nil end end -- update visibility states of all pins function WorldQuests:UpdateAnchors (submapID) local print = wqprint local db = WorldPlan.db local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() if isMicroDungeon then return end local currentMap = GetCurrentMapAreaID() local submapID = submapID or currentMap if submapID == BROKEN_ISLES_ID and (not db.DisplayContinentPins) then print('not updating map for reasons') return end print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins) local numZones = MC_GetNumZones(submapID) if numZones then for i = 1, numZones do local subMapID = MC_GetZoneInfo(submapID, i) self:UpdateAnchors(subMapID) end end local pins = self.QuestsByZone[submapID] if pins then local hostFrame = WorldMapPOIFrame local mapWidth, mapHeight = hostFrame:GetSize() for questID, pin in pairs(pins) do pin.hasUpdate = true pin:IsShowable() if pin.used then pin:SetFrameLevel(PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) print('level', PinBaseIndex+ (pin.whiteListed and 200 or 0) +numPins) pin:SetAnchor(WorldMapPOIFrame, currentMap, mapWidth, mapHeight) numPins = numPins + 1 end end end end -- shows, animates, or hides pins based on their current visibility flags local debug_show = {} local debug_animate = {} local debug_hide = {} function WorldQuests:Cleanup () local print = wqprint local showQuestPOI = db.EnablePins print('|cFFFFFF00'..tostring(self)..':Cleanup()|r') local mapID = GetCurrentMapAreaID() isContinentMap = (mapID == BROKEN_ISLES_ID) wipe(debug_show) wipe(debug_animate) wipe(debug_hide) -- continent or zone sizing local fadeGrouped = (db.FadeWhileGrouped and IsInGroup()) numPins = 0 for questID, pin in pairs(self.QuestsByID) do -- can we show it? if showQuestPOI and (pin.used) then pin.hasUpdate = true if fadeGrouped then pin:SetAlpha(0.25) else pin:SetAlpha(1) end -- is it a new quest? if pin.isNew then if not pin.isAnimating then pin.isAnimating = true OnNext(function() pin:ShowNew() end) if not notifyPlayed then for k,v in pairs(NotificationTypes) do if v[pin[k]] then notifyPlayed = true PlaySoundKitID(23404) end end end tinsert(debug_animate,questID) else print('animating? ', questID, 'filtered:', pin.filtered) end -- trap new but animating pins here else -- hard show existing pin print('refresh #', questID, 'filtered:', pin.filtered, 'hasUpdate', pin.hasUpdate) pin:Show() tinsert(debug_show,questID) end else if pin:IsShown() then tinsert(debug_hide,questID) end pin.isAnimating = nil pin.FadeIn:Stop() pin:Hide() end end print(' adding:', table.concat(debug_animate, ',' )) print(' refresh:', table.concat(debug_show, ',' )) print(' hiding:', table.concat(debug_hide, ',' )) hasNewQuestPins = nil notifyPlayed = nil self.hasUpdate = nil 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 local throttle = 0 local tooltip = CreateFrame ("GameTooltip", "VeneerWorldQuestsScanner", nil, "GameTooltipTemplate") local tooltipLine1 = _G['VeneerWorldQuestsScannerTextLeft1'] local tooltipLine3 = _G['VeneerWorldQuestsScannerTextLeft3'] local GetTime, mod = GetTime, mod function WorldQuests:FilterCheckByID(questID) local pin = WorldQuests:GetPinByQuestID(questID) return pin:IsShowable() end function QuestPOI:IsShowable () local print = wqprint local db = WorldPlan.db local qType = self.worldQuestType local rType = self.rewardType self.filtered = nil self.used = true print(' |cFFFF4400IsShowable()|r', self.title) if not self.passesBlizzFilters then self.filtered = true end if not TQ_IsActive(self.questID) then self.used = nil elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then if not (db.ShowAllProfessionQuests or (self.tradeskillLineIndex and GetProfessionInfo(self.tradeskillLineIndex))) then self.used = nil end end return self.used, self.filtered end function QuestPOI:UpdateTimer (timeLeft, timeType) print('|cFF0088FFUpdatePinTimer()|r') end --- Fixes icons upon size update function QuestPOI:UpdateSize (style, subStyle) style = style or self.style subStyle = subStyle or self.subStyle --qprint('|cFF00FF88'..self:GetName()..'|r:UpdateSize()', style, subStyle) self.currentWidth = subStyle.PinSize self.borderSize = subStyle.Border self.trackingBorderSize = subStyle.TrackingBorder self.tagSize = subStyle.TagSize self.TimeleftStage = subStyle.TimeleftStage self.NoIcon = subStyle.NoIcon self:SetSize(self.currentWidth, self.currentWidth) local icon = self.icon local iconBorder = self.iconBorder local trackingBorder = self.supertrackBorder local tag = self.tagIcon local pinMask = style.pinMask local rewardMask = style.rewardMask if self.NoIcon then self.icon:Hide() else self.icon:Show() icon:SetMask(nil) icon:SetMask(rewardMask) icon:SetTexture(self.icon:GetTexture()) end iconBorder:SetMask(nil) trackingBorder:SetMask(nil) local borderWidth = self.borderSize local trackingWidth = self.trackingBorderSize iconBorder:ClearAllPoints() iconBorder:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', -borderWidth + (style.x or 0), -borderWidth + (style.y or 0)) iconBorder:SetPoint('TOPRIGHT', self, 'TOPRIGHT', borderWidth + (style.x or 0), borderWidth + (style.y or 0)) trackingBorder:ClearAllPoints() trackingBorder:SetPoint('BOTTOMLEFT', iconBorder, 'BOTTOMLEFT', -trackingWidth, -trackingWidth) trackingBorder:SetPoint('TOPRIGHT', iconBorder, 'TOPRIGHT', trackingWidth, trackingWidth) if self.tagSize then tag:Show() tag:ClearAllPoints() tag:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', borderWidth, -borderWidth) else tag:Hide() end --qprint('using mask:', mask, self.name ) iconBorder:SetMask(pinMask) trackingBorder:SetMask(pinMask) end --%debug% local SetTimedCallbackForAllPins = function(seconds, callback) C_Timer.After(seconds, function() for id, pin in pairs(WorldPlanQuests.QuestsByID) do callback(pin) 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%