Mercurial > wow > worldplan
view WorldQuests.lua @ 33:be4db60219ca
WorldPlan:
- Toggling a reward filter cancels out other types by default. Use right mouse to clear.
- Fixed filter bar info falling out of sync after player-triggered world map updates.
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 17:25:07 -0400 |
parents | |
children | 0100d923d8c3 |
line wrap: on
line source
-- WorldPlan -- WorldQuests.lua -- Created: 11/2/2016 3:40 PM -- %file-revision% WorldPlanQuestsMixin = { QuestsByZone = {}, QuestsByID = {}, freePins = {}, } local WorldQuests = WorldPlanQuestsMixin local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID local GetMapInfo = GetMapInfo 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 wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() 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 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', } 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 numPins = 0 local ZoneInfo = {} local NumPinFrames = 1 --%debug% local SetTimedCallbackForAllPins = function(seconds, callback) C_Timer.After(seconds, function() for id, pin in pairs(WorldPlanQuests.QuestsByID) do callback(pin) end end) end 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 WorldMapPOIFrame 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('WORLD_QUEST_COMPLETED_BY_SPELL') self:RegisterEvent('SKILL_LINES_CHANGED') WorldMapPOIFrame = _G.WorldMapPOIFrame 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.isStale, self.isPending = questPOI:RefreshData() else self:RefreshData() end print('WorldMapFrame', WorldMapFrame:IsVisible(), 'hasUpdates:', self.isStale) elseif event == 'WORLD_MAP_UPDATE' then self.isStale = true 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.isStale = 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.isStale = 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.isStale = (self.isStale 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.isStale, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) --WorldPlan.isStale = (self.isStale or WorldPlan.isStale) end end function WorldQuests:Refresh() local print = wqprint print('|cFF00FF88'..self:GetName()..':Refresh()|r') self:Reset() self:UpdateAnchors() self:Cleanup () 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:IsShowable() if pin.used then pin.hasUpdate = true 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.isStale = 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 WorldPlan:OnNext(function() pin:ShowNew() 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.isStale = nil end function WorldQuests:FilterCheckByID(questID) local pin = WorldQuests:GetPinByQuestID(questID) return pin:IsShowable() end