Mercurial > wow > worldplan
view WorldQuests.lua @ 38:a93cae445d3f v1.0-rc9
WorldPlan:
- Quest pins are now placed on the flight map. Their visibility rules will mirror the filter options from the world map.
- Filter controls polish:
- First click negates other reward type filters. Subsequent clicks will then toggle individual reward types until the filters are reset via Right-click.
- Adheres to the Blizzard CVars added in patch 7.1
- Numerous optimizations to how data and visual updates are handled; should see an even better load time, and snappier world map interaction.
ClassPlan:
- The 'Available Missions' list is now recorded. It can be reviewed by clicking on the mission list heading.
- Information filtering by character and realm.
author | Nenue |
---|---|
date | Fri, 04 Nov 2016 02:53:57 -0400 |
parents | 78cf1f19856a |
children | 589c444d4837 |
line wrap: on
line source
-- WorldPlan -- WorldQuests.lua -- Created: 11/2/2016 3:40 PM -- %file-revision% 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 mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or function() end local PinBaseIndex = 1000 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 = .7, g = .6, b = .32, pinMask = false, rewardMask = false }) 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' or event == 'PLAYER_ENTERING_WORLD' 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 WorldPlan.currentMapID 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, WorldPlan.currentMapID) 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) -- WorldPlan:print('|cFF0088FF'..questPOI.title..'|r', hasUpdate) 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(forced) local print = wqprint print('|cFF00FF88'..self:GetName()..':Refresh()|r') if not self:IsVisible() then self.isStale = true print('frame closed, do it later') return end 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.isStale = true pin:SetFrameLevel(PinBaseIndex+ numPins) print('level', PinBaseIndex+ numPins) pin:SetAnchor(_G.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 = WorldPlan.db.EnablePins print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') -- continent or zone sizing numPins = 0 for questID, pin in pairs(self.QuestsByID) do pin:SetShown((showQuestPOI and pin.used)) end self.isStale = nil end function WorldQuests:FilterCheckByID(questID) local pin = WorldQuests:GetPinByQuestID(questID) return pin:IsShowable() end