Mercurial > wow > worldplan
diff WorldQuests.lua @ 40:589c444d4837
WowAce/Curseforge migration push
author | Nenue |
---|---|
date | Sun, 25 Dec 2016 13:04:57 -0500 |
parents | 78cf1f19856a |
children | 79e5e96e5f18 |
line wrap: on
line diff
--- a/WorldQuests.lua Fri Nov 04 02:54:32 2016 -0400 +++ b/WorldQuests.lua Sun Dec 25 13:04:57 2016 -0500 @@ -2,21 +2,21 @@ -- WorldQuests.lua -- Created: 11/2/2016 3:40 PM -- %file-revision% - +local _, db = ... 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 print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end +local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) 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 PinBaseIndex = 1200 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', } @@ -29,9 +29,8 @@ local numPins = 0 -local ZoneInfo = {} local NumPinFrames = 1 - +WorldQuests.TasksByID = {} --%debug% local SetTimedCallbackForAllPins = function(seconds, callback) @@ -42,21 +41,35 @@ end) end +function WorldQuests:OnShow() + self:Refresh(true) +end + +function WorldQuests:OnUpdate(sinceLast) + if self.filtersDirty or self.isStale then + self:Refresh() + end +end + function WorldQuests:Setup() - + print('|cFFFF4400'..self:GetName()..':Setup()') for mapID, mapName in pairs(WORLD_QUEST_MAPS) do - self.QuestsByZone[mapID] = {} + db.QuestsByZone[mapID] = {} end -- refresh positions any time blizzard does so (i.e. mousewheel zoom) hooksecurefunc("WorldMapScrollFrame_ReanchorQuestPOIs", function() + print('|cFFFF4400WorldMapScrollFrame_ReanchorQuestPOIs') self:Refresh(true) end) + -- hide the original world quest POIs + hooksecurefunc("WorldMap_UpdateQuestBonusObjectives", function() + print('|cFFFF4400WorldMap_UpdateQuestBonusObjectives') for i = 1, NUM_WORLDMAP_TASK_POIS do local button = _G['WorldMapFrameTaskPOI'..i] if button and button.worldQuest then @@ -65,22 +78,24 @@ end end) end -local WorldMapPOIFrame local defaults = {} +local REWARD_UNKNOWN = 768 function WorldQuests:OnLoad() - print('|cFF00FF88'..self:GetName()..':OnLoad') + print('|cFFFF4400'..self:GetName()..':OnLoad()') + self:SetParent(WorldMapFrame) WorldPlan:AddHandler(self, defaults) - local rgbWhite = {1, 1, 1} + local rgbWhite = {1, 1, 1 } + WorldPlan:AddTypeInfo(self, REWARD_UNKNOWN, { r = 1, g = 1, b = 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 }) + WorldPlan:AddTypeInfo(self, REWARD_CASH, { r = 1, g = 1, b = .32, pinMask = false, rewardMask = false }) for areaID, fileName in pairs(WORLD_QUEST_MAPS) do - self.QuestsByZone[areaID] = {} + db.QuestsByZone[areaID] = {} end self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') @@ -91,40 +106,53 @@ end function WorldQuests:OnEvent (event, ...) - local print = wqprint - print('|cFFFFFF00'..self:GetName()..':OnEvent()'..event..'|r', GetTime(), ...) - if event == 'QUEST_LOG_UPDATE' then + + print('|cFFFFFF00'..self:GetName()..':OnEvent() '..event..'|r', GetTime(), ...) + if event == 'QUEST_LOG_UPDATE' or event == 'PLAYER_LOGIN' then local questID, added = ... if questID and added then local questPOI = self:AcquirePin(questID) - self.isStale, self.isPending = questPOI:RefreshData() + questPOI:GetQuestInfo() + questPOI.isStale = true + self.isStale = true else - self:RefreshData() + self:Refresh(true) 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_MAP_UPDATE' then + self:Refresh(true) elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then local questID = ... - if questID and self.QuestsByID[questID] then - self:ReleasePin(self.QuestsByID[questID]) + if questID and db.QuestsByID[questID] then + self:ReleasePin(db.QuestsByID[questID]) + rprint('|cFFFF4400release|r', questID) end elseif event == 'SKILL_LINES_CHANGED' then - self.isStale = true + self:SetFilteredPins() end end +local totalPins = 0 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation -function WorldQuests:AcquirePin (questID, mapID) - local pin = self.QuestsByID[questID] - local isNew = false +function WorldQuests:AcquirePin (info) + local questID = info.questId + if not questID then + return nil + end + + if not QuestUtils_IsQuestWorldQuest(questID) then + return nil + end + + + local pin = db.QuestsByID[questID] if not pin then - isNew = true - local numFree = #self.freePins + local numFree = #db.FreePins if numFree >= 1 then - pin = tremove(self.freePins, numFree) + pin = tremove(db.FreePins, numFree) --print('|cFF00FF00Re-using', pin:GetName()) else + totalPins = totalPins + 1 local name = 'WorldPlanQuestMarker' .. NumPinFrames --print('|cFF00FF00Creating', name) pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') @@ -133,181 +161,355 @@ pin.GetTypeInfo = function(frame, typeID) return self:GetTypeInfo(typeID) end + pin:SetID(totalPins) NumPinFrames = NumPinFrames + 1 --pin.iconBorder:SetVertexColor(0,0,0,1) end - pin:SetID(questID) + pin.questID = questID + pin.worldQuest = true + pin.throttle = 1 pin.isNew = true pin.currentWidth = nil + db.QuestsByID[questID] = pin + tinsert(db.UsedPins, pin) + end - -- used by TaskPOI_x scripts - pin.questID = questID - pin.worldQuest = true + if pin and info then + pin.inProgress = info.inProgress + pin.floor = info.floor + pin.numObjectives = info.numObjectives or 0 + if info.x and info.y then + pin.x = info.x or pin.x + pin.y = info.y or pin.y + rprint('|cFFFF4400coords|r', info.x, info.y) + end + end - self.QuestsByID[questID] = pin - else - --print('|cFF00FF00Using', pin:GetName()) - end - mapID = mapID or TQ_GetQuestZoneID(questID) - self.QuestsByZone[mapID][questID] = pin - - return pin, isNew + pin:GetData() + C_TaskQuest.RequestPreloadRewardData(info.questId) + return pin end -- remove from index and add it to the recycling heap function WorldQuests:ReleasePin (pin) - local id = pin.questId + local id = pin.questID if id then - self.QuestsByID[id] = nil - for i, zone in pairs(self.QuestsByZone) do + db.QuestsByID[id] = nil + + for i, zone in pairs(db.QuestsByZone) do print('-', i, zone[i]) zone[id] = nil end + db.TasksByID[id] = nil end - pin:Hide() + pin:SetShown(false) pin:ClearAllPoints() - tinsert(self.freePins, pin) - print('|cFFFF4400Clearing out', pin:GetName(),id) + tinsert(db.FreePins, pin) + + print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title) end +function WorldQuests:GetBonusObjectives() + + + local tasksTable = GetTasksTable() + if tasksTable ~= nil then + print('|cFF00FF88'..self:GetName()..':BonusObjectives()|r ') + self.numTasks = #tasksTable + for i, taskID in ipairs(tasksTable) do + if not QuestUtils_IsQuestWorldQuest(taskID) then + local info = db.TasksByID[taskID] + if not info then + local isInArea, isOnMap, numObjectives, taskName, displayAsObjective = GetTaskInfo(taskID) + if isOnMap then + print(' * '..i, taskID, GetTaskInfo(taskID)) + info = { + questID = taskID, + numObjectives = numObjectives, + title = taskName, + isInArea = isInArea, + isOnMap = isOnMap, + displayAsObjective = displayAsObjective, + worldQuest = false, + isPending = false, + isNew = true, + } + + + db.TasksByID[taskID] = info + + local pin = self:AcquirePin(taskID) + for k,v in pairs(info) do + pin[k] = v + end + pin:GetBonusObjectiveInfo(info) + end + end + end + + + end + end +end + + + + +-- use tooltip object to extract item details +function WorldQuests:GetRewardHeader(questID) + local name, icon, quantity, quality, _, itemID = GetQuestLogRewardInfo(1, questID) + local scanner = _G.WorldPlanTooltip + local print = qprint + if not itemID then + return + end + --print('GetRewardHeader', questID) + + scanner:SetOwner(WorldPlan, "ANCHOR_NONE") + scanner:SetItemByID(itemID) + scanner:Show() + local ttl1 = _G['WorldPlanTooltipTextLeft1'] + local ttl2 = _G['WorldPlanTooltipTextLeft2'] + local ttl3 = _G['WorldPlanTooltipTextLeft3'] + local ttl4 = _G['WorldPlanTooltipTextLeft4'] + --print(ttl2, ttl3, ttl4) + if ttl2 then + local text = ttl2:GetText() + -- Artifact Power + --print(text) + if text then + if text:match("|cFFE6CC80") then + --print('AP token!', text) + local power + if ttl4 then + local text = ttl4:GetText() + --print('tip line 4', text) + if text then + power = text:gsub("%p", ""):match("%d+") + power = tonumber(power) + end + + end + return REWARD_ARTIFACT_POWER, "Interface\\ICONS\\inv_7xp_inscription_talenttome01", power, name, itemID, quality + elseif text:match("Item Level") then + --print('equipment!', text) + quantity = text:match("Item Level ([%d\+]+)") + return REWARD_GEAR, icon, quantity, name, itemID, quality + elseif text:match("Crafting Reagent") then + --print('|cFFFF4400it is a reagent', text) + return REWARD_REAGENT, icon, quantity, name, itemID, quality + end + end + end + + if ttl3 then + local text = ttl3:GetText() + if text and text:match("Crafting Reagent") then + --print('|cFFFF4400it is a reagent', text) + return REWARD_REAGENT, icon, quantity, name, itemID, quality + end + end + return 128, icon, quantity, name, itemID, quality +end + +local GetCurrentMapAreaID, GetMapNameByID= GetCurrentMapAreaID, GetMapNameByID +local wipe, pairs = wipe, pairs -- create of update quest pins for a map and its underlying zones -function WorldQuests:RefreshData (mapID) - local print = wqprint - mapID = mapID or WorldPlan.currentMapID +function WorldQuests:UpdateWorldQuests (mapID) + + mapID = mapID or db.currentMapID if not mapID then -- info not available yet return end - print('|cFF00FF88'..self:GetName()..':RefreshData()|r', 'map:', mapID, 'realMap:', GetCurrentMapAreaID()) + print('|cFF00FF88'..self:GetName()..':UpdateWorldQuests()|r', 'map:', mapID, 'realMap:', db.currentMapID) - 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 + + self.isStale = nil + print('|cFF00FFFFContinent:|r', BROKEN_ISLES_ID, GetMapNameByID(BROKEN_ISLES_ID)) + self.isRecursed = true + for i = 1, MC_GetNumZones(BROKEN_ISLES_ID) do + local submapID, name, depth = MC_GetZoneInfo(BROKEN_ISLES_ID, i) + local taskInfo = TQ_GetQuestsForPlayerByMapID(submapID, BROKEN_ISLES_ID) + if taskInfo then + local zoneName = GetMapNameByID(submapID) + print('|cFF00FFFF Zone:|r', submapID, zoneName, #taskInfo) + db.QuestsByZone[submapID] = db.QuestsByZone[submapID] or {} + for i, info in ipairs(taskInfo) do + if HaveQuestData(info.questId) then + rprint('|cFF44FF44update|r', info.questId, zoneName) + local questID = info.questId + local pin = self:AcquirePin(questID) + local pin = db.QuestsByID[questID] + if pin then + pin.isStale = true + if pin.isPending then + self.isPending = true + end + end + else + rprint('|cFFFF4400no data|r', info.questId, zoneName) + end 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) + self:GetBonusObjectives() + + print(' hasUpdate:', self.isStale, 'isPending:', self.isPending, 'timer:', (self.OnNext and 'waiting' or '')) + --WorldPlan.isStale = (self.isStale or WorldPlan.isStale) + if self.isStale and self:IsVisible() then + self:Refresh() + end +end + +function WorldQuests:Report() + for i, pin in ipairs(db.UsedPins) do + db:print(i, pin.questID, pin.title) end + for id, pin in pairs(db.QuestsByID) do + db:print(id, pin.worldQuestType, pin.rewardType, pin.title) + end end -function WorldQuests:Refresh(forced) - local print = wqprint - print('|cFF00FF88'..self:GetName()..':Refresh()|r') +function WorldQuests:Refresh(fromUser) + self.currentMapID = GetCurrentMapAreaID() + print('|cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') if not self:IsVisible() then + print(' not visible, flag for later') self.isStale = true - print('frame closed, do it later') + return + end + wprint(' |cFF00FF88'..self:GetName()..':Refresh()|r', fromUser or '|cFFFFFF00internal') + + for index, pin in pairs(db.QuestsByID) do + pin.used = nil + pin:SetShown(false) + end + + self:SetFilteredPins(db.QuestsByID) + self:UpdateAnchors(nil, fromUser) + self:Cleanup (fromUser) + self.isStale = nil +end + +-- update visibility states of all pins +function WorldQuests:SetFilteredPins(pins) + print(' |cFFFFFF00'..self:GetName()..':SetFilteredPins()|r', pins) + pins = pins or db.QuestsByID + for questID, pin in pairs(pins) do + pin.filtered = pin:IsFiltered() + pin.isStale = true + rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used) + end +end + +local abs = math.abs +function WorldQuests:UpdateQuestButton(info, mapID) + local questID, x, y = info.questId, info.x, info.y + local pin = self:AcquirePin(info) + if not pin then 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 + print('~ ', pin.mapID, pin.questID, pin.title) + rprint('|cFF00FF00update|r', x, y, pin.title) + pin:IsShowable() + + if x and y then + + pin.x = x + pin.y = y + pin:SetFrameLevel(PinBaseIndex+numPins) + pin:SetPoint('CENTER', self.hostFrame, 'TOPLEFT', self.hostWidth * pin.x, -self.hostHeight * pin.y) + pin.throttle = 1 + pin:SetShown(pin.used) + tinsert(self.UsedPositions, pin) + end + pin.owningFrame = self.hostFrame + pin:SetParent(self.hostFrame) + + if mapID then + if not db.QuestsByZone[mapID] then + db.QuestsByZone[mapID] = {} + end + db.QuestsByZone[mapID][questID] = pin end end --- update visibility states of all pins -function WorldQuests:UpdateAnchors (submapID) +function WorldQuests:UpdateMap(taskInfo, mapID) + print('Map', GetMapNameByID(mapID), GetMapNameByID(self.currentMapID)) + for index, info in pairs(taskInfo) do + self:UpdateQuestButton(info, mapID) + end +end - local print = wqprint - local db = WorldPlan.db +function WorldQuests:UpdateAnchors (fromUser) + + + wipe(self.UsedPositions) + print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser) + self.hostFrame = WorldMapPOIFrame + self.hostWidth, self.hostHeight = self.hostFrame:GetSize() + self.nudgeThrescholdX = 16/self.hostWidth + self.nudgeThrescholdY = 16/self.hostHeight + local print = rprint + print('|cFF00FF00'..self:GetName()..':UpdateAnchors()', fromUser) 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 + numPins = 0 + local taskInfo = TQ_GetQuestsForPlayerByMapID(self.currentMapID) + if taskInfo then + self:UpdateMap(taskInfo, self.currentMapID) end - print('|cFF88FF00'..self:GetName()..':UpdateAnchors|r', submapID, GetMapNameByID(submapID), 'pin count:', numPins) - local numZones = MC_GetNumZones(submapID) + local numZones = MC_GetNumZones(self.currentMapID) if numZones then for i = 1, numZones do - local subMapID = MC_GetZoneInfo(submapID, i) - self:UpdateAnchors(subMapID) + local mapAreaID = MC_GetZoneInfo(self.currentMapID, i) + local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, self.currentMapID) + if taskInfo then + self:UpdateMap(taskInfo, mapAreaID) + end 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 + if self.filtersDirty then + self:SetFilteredPins(db.QuestsByID) 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 +function WorldQuests:Cleanup (fromUser) + print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') - -- continent or zone sizing + local print = rprint + print('|cFFFFFF00'..self:GetName()..':Cleanup()|r') + --local showQuestPOI = db.Config.EnablePins + for questID, pin in pairs(db.QuestsByID) do + local oV = pin:IsShown() + if pin.used then + pin:SetShown(true) + pin.throttle = 1 + if oV == false then + print('|cFF00FF00cleanup +|r', questID, pin.title) + end + else + if oV == true then + print('|cFFFF4400 -|r', questID, pin.title) + end + end - - numPins = 0 - for questID, pin in pairs(self.QuestsByID) do - pin:SetShown((showQuestPOI and pin.used)) + if pin.worldQuest and (not C_TaskQuest.IsActive(pin.questID)) then + self:ReleasePin(pin) + end + pin.isStale = true end - self.isStale = nil end -function WorldQuests:FilterCheckByID(questID) - local pin = WorldQuests:GetPinByQuestID(questID) - return pin:IsShowable() -end - -