Mercurial > wow > worldplan
changeset 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 | e8679ecb48d8 |
children | 0100d923d8c3 |
files | FilterBar.lua FilterBar.xml FollowerList.lua FollowerList.xml QuestPOI.lua WorldPlan.lua WorldPlan.toc WorldPlan.xml WorldQuests.lua WorldQuests.xml |
diffstat | 10 files changed, 639 insertions(+), 679 deletions(-) [+] |
line wrap: on
line diff
--- a/FilterBar.lua Tue Nov 01 10:48:50 2016 -0400 +++ b/FilterBar.lua Wed Nov 02 17:25:07 2016 -0400 @@ -5,6 +5,7 @@ -- local print = DEVIAN_WORKSPACE and function(...) _G.print('FilterBar', ...) end or nop +local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local wipe, ipairs, pairs = table.wipe, ipairs, pairs local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD @@ -18,7 +19,26 @@ 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 familiars = { + [42159] = {npc = 106552, name = 'Nightwatcher Merayl'}, + [40277] = {npc = 97804, name = 'Tiffany Nelson'}, + [40298] = {npc = 99182, name = 'Sir Galveston'}, + [40282] = {npc= 99150, name = 'Grixis Tinypop'}, + [40278] = {npc = 98270, name = 'Robert Craig'}, + [48195] = {npc = 105250, name = 'Aulier'}, + [41990] = {npc = 105674, name = 'Varenne'}, + [41860] = {npc = 104970, name = 'Xorvasc'}, + [40299] = {npc = 99210, name = 'Bodhi Sunwayver'}, + [42442] = {npc = 107489, name = 'Amalia'}, + [40280] = {npc = 99077, name = 'Bredda Tenderhide'}, + [41687] = {npc = 104553, name = 'Odrogg'}, + [41944] = {npc = 105455, name = 'Trapper Jarrun'}, + [40337] = {npc = 97709, name = 'Master Tamer Flummox'}, + [40279] = {npc = 99035, name = 'Durian Strongfruit'} +} +local familiars_id = 9696 + local DEFAULT_FILTER_LAYOUT = { PinSize = 22, Border = 3, @@ -51,11 +71,7 @@ WorldPlanFilterPinMixin = {} function WorldPlanSummaryMixin:OnLoad() - self:RegisterEvent('QUEST_LOG_UPDATE') - self:RegisterEvent('WORLD_MAP_UPDATE') - WorldPlan:AddHandler(self, defaults) - for index, info in ipairs(DEFAULT_FILTER_LIST) do info.zone = DEFAULT_FILTER_LAYOUT info.continent = DEFAULT_FILTER_LAYOUT @@ -68,32 +84,36 @@ function WorldPlanSummaryMixin:OnEvent(event) - self:Refresh() + print('|cFF00FF88'..self:GetName()..':OnEvent()', event) + self.isStale = true end local bountyIndex local debug_headers = {} function WorldPlanSummaryMixin:Setup() + print('|cFF00FF88'..self:GetName()..':Setup()') self:GetFilters() end -function WorldPlanSummaryMixin:OnEvent(event,...) - self.isStale = true +function WorldPlanSummaryMixin:OnUpdate() + if self.isStale then + wprint('|cFF00FF00pushing update') + self:Refresh() + end end -function WorldPlanSummaryMixin:OnUpdate() + +function WorldPlanSummaryMixin:OnShow() + print('|cFF00FF88'..self:GetName()..':OnShow()') if self.isStale then self:Refresh() end end -function WorldPlanSummaryMixin:OnShow() - self:Refresh() -end - function WorldPlanSummaryMixin:GetFilters() + print('|cFF00FFFF'..self:GetName()..':GetFilters()') wipe(self.filterList) @@ -127,22 +147,22 @@ self:GetFilters() end -function WorldPlanSummaryMixin:Refresh(forced) - self:Update(forced) +function WorldPlanSummaryMixin:Refresh() + self:Update() end local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64" local filterMask = "Interface\\Minimap\\UI-Minimap-Background" local questResults = {{}} -function WorldPlanSummaryMixin:Update(forced) +function WorldPlanSummaryMixin:Update() local blocks = self.buttons local relativeFrame = WorldMapFrame.UIElementsFrame.TrackingOptionsButton local numHeaders = 0 - print('|cFF00FF88'..tostring(self)..':Refresh()|r', 'currentMap=',self.currentMapID) + print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',WorldPlan.currentMapID) - local quests = WorldPlanQuests.QuestsByZone[self.currentMapID] or WorldPlanQuests.QuestsByID + local quests = WorldPlanQuests.QuestsByZone[WorldPlan.currentMapID] or WorldPlanQuests.QuestsByID local foundQuests = questResults[1] for index, info in ipairs(self.filterList) do local numQuests = 0 @@ -267,7 +287,7 @@ local desaturated = false if self.cVar then self.iconBorder:SetVertexColor(1, 1, 1, 1) - if GetCVarBool(self.cVar) == true then + if GetCVarBool(self.cVar) then self.icon:SetVertexColor(1,1,1,1) self:SetAlpha(1) else @@ -300,6 +320,7 @@ function WorldPlanFilterPinMixin:OnUpdate () end + function WorldPlanFilterPinMixin:OnLeave () if GameTooltip:IsOwned(self) then GameTooltip:Hide() @@ -320,8 +341,22 @@ if not filterKey then wipe(WorldPlan.UsedFilters) + for i, info in ipairs(DEFAULT_FILTER_LIST) do + if info.cVar then + SetCVar(info.cVar, 1) + end + end + elseif self.cVar then - SetCVar(self.cVar, (GetCVarBool(self.cVar) and 0) or 1) + for i, info in ipairs(DEFAULT_FILTER_LIST) do + if info.cVar then + if (info.cVar ~= self.cVar) and (button == 'LeftButton') then + SetCVar(info.cVar, 0) + else + SetCVar(info.cVar, 1) + end + end + end else local setInclude = (button == 'LeftButton') local flushValue @@ -332,5 +367,5 @@ WorldPlan.UsedFilters[filterKey] = filterValue end end - WorldPlan:Refresh() + WorldPlan:Refresh(true) end \ No newline at end of file
--- a/FilterBar.xml Tue Nov 01 10:48:50 2016 -0400 +++ b/FilterBar.xml Wed Nov 02 17:25:07 2016 -0400 @@ -5,6 +5,7 @@ <Scripts> <OnLoad method="OnLoad" /> <OnEvent method="OnEvent" /> + <OnShow method="OnShow" /> </Scripts> </Frame>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FollowerList.lua Wed Nov 02 17:25:07 2016 -0400 @@ -0,0 +1,11 @@ +ClassPlanFollowerMixin = {} +local c = ClassPlanFollowerMixin +function c:OnEvent(event, arg) + +end + +function c:GetPlayerData(event, arg) end + +function c:UpdateItems() end + +function c:Reanchor() end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FollowerList.xml Wed Nov 02 17:25:07 2016 -0400 @@ -0,0 +1,11 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ +..\FrameXML\UI.xsd"> + <Script file="FollowerList.lua" /> + <Frame name="$parentFollowerList" parent="ClassOrderPlan"parentKey="FollowerList" parentArray="Handlers" mixin="ClassPlanFollowerMixin"> + <Scripts> + <OnEvent method="OnEvent" /> + <OnUpdate method="OnUpdate" /> + <OnShow method="OnShow" /> + </Scripts> + </Frame> +</Ui> \ No newline at end of file
--- a/QuestPOI.lua Tue Nov 01 10:48:50 2016 -0400 +++ b/QuestPOI.lua Wed Nov 02 17:25:07 2016 -0400 @@ -4,15 +4,21 @@ -- %file-revision% -- +WorldPlanPOIMixin = {} local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID -- Return the name of a quest with a given ID local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation local TQ_GetQuestTimeLeftMinutes = C_TaskQuest.GetQuestTimeLeftMinutes local TQ_IsActive = C_TaskQuest.IsActive local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData local QuestPOIGetIconInfo, WorldMapPOIFrame = QuestPOIGetIconInfo, WorldMapPOIFrame +local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters +local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest +local GameTooltip = GameTooltip +local GetItemIcon = GetItemIcon -local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end +local print = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end +local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end local QuestPOI = WorldPlanPOIMixin @@ -77,29 +83,32 @@ -- Pin color/display variables - local familiars = { - [42159] = {npc = 106552, name = 'Nightwatcher Merayl'}, - [40277] = {npc = 97804, name = 'Tiffany Nelson'}, - [40298] = {npc = 99182, name = 'Sir Galveston'}, - [40282] = {npc= 99150, name = 'Grixis Tinypop'}, - [40278] = {npc = 98270, name = 'Robert Craig'}, - [48195] = {npc = 105250, name = 'Aulier'}, - [41990] = {npc = 105674, name = 'Varenne'}, - [41860] = {npc = 104970, name = 'Xorvasc'}, - [40299] = {npc = 99210, name = 'Bodhi Sunwayver'}, - [42442] = {npc = 107489, name = 'Amalia'}, - [40280] = {npc = 99077, name = 'Bredda Tenderhide'}, - [41687] = {npc = 104553, name = 'Odrogg'}, - [41944] = {npc = 105455, name = 'Trapper Jarrun'}, - [40337] = {npc = 97709, name = 'Master Tamer Flummox'}, - [40279] = {npc = 99035, name = 'Durian Strongfruit'} - } - local familiars_id = 9696 +local familiars = { + [42159] = {npc = 106552, name = 'Nightwatcher Merayl'}, + [40277] = {npc = 97804, name = 'Tiffany Nelson'}, + [40298] = {npc = 99182, name = 'Sir Galveston'}, + [40282] = {npc= 99150, name = 'Grixis Tinypop'}, + [40278] = {npc = 98270, name = 'Robert Craig'}, + [48195] = {npc = 105250, name = 'Aulier'}, + [41990] = {npc = 105674, name = 'Varenne'}, + [41860] = {npc = 104970, name = 'Xorvasc'}, + [40299] = {npc = 99210, name = 'Bodhi Sunwayver'}, + [42442] = {npc = 107489, name = 'Amalia'}, + [40280] = {npc = 99077, name = 'Bredda Tenderhide'}, + [41687] = {npc = 104553, name = 'Odrogg'}, + [41944] = {npc = 105455, name = 'Trapper Jarrun'}, + [40337] = {npc = 97709, name = 'Master Tamer Flummox'}, + [40279] = {npc = 99035, name = 'Durian Strongfruit'} +} +local familiars_id = 9696 + + +-- update a masked texture without messing up its blending mask -- update a masked texture without messing up its blending mask local SetMaskedTexture = function(region, file, mask) - mask = mask or POI_BORDER_MASK + mask = mask or "Interface\\Minimap\\UI-Minimap-Background" region:SetMask(nil) region:SetTexture(file) region:SetMask(mask) @@ -242,7 +251,7 @@ local questID = self:GetID() local questTitle, rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality, _ - local hasUpdate, isPending = (self.hasUpdate or self.isNew), self.isPending + local hasUpdate, isPending = (self.isStale or self.isNew), self.isPending if not HaveQuestData(questID) then @@ -317,7 +326,7 @@ self.title = questTitle or "|cFFFF0000Retrieving..." self.itemTexture = rewardIcon or self.itemTexture self.itemName = rewardName or self.itemName - self.hasUpdate = hasUpdate + self.isStale = hasUpdate self.isPending = isPending @@ -338,14 +347,14 @@ function WorldPlanPOIMixin:ShowNew() self:SetShown(true) self.isNew = nil - self.hasUpdate = true + self.isStale = true self.FadeIn:Play() end function WorldPlanPOIMixin:OnShow () - qprint('|cFFFFFF00["'..tostring(self.title)..'"]|r:OnShow() update:', self.hasUpdate, 'new:', self.isNew, 'animation:', self.isAnimating) + qprint('|cFFFFFF00["'..tostring(self.title)..'"]|r:OnShow() update:', self.isStale, 'new:', self.isNew, 'animation:', self.isAnimating) -- pop this on principle - if self.hasUpdate then + if self.isStale then self:Refresh() end @@ -355,7 +364,7 @@ end function WorldPlanPOIMixin:SetAnchor(frame, mapID, mapWidth, mapHeight) - qprint(' |cFF00FF00'..self:GetName()..':SetAnchor()|r', self.questID, mapID, mapWidth) + --qprint(' |cFF00FF00'..self:GetName()..':SetAnchor()|r', self.questID, mapID, mapWidth) self:ClearAllPoints() local dX, dY = TQ_GetQuestLocation(self.questID) if not dX or dX == 0 then @@ -388,7 +397,7 @@ function WorldPlanPOIMixin:OnEvent(event, ...) if event == 'SUPER_TRACKED_QUEST_CHANGED' then - self.hasUpdate = true + self.isStale = true end end @@ -397,8 +406,8 @@ local TOP_PIN_ID function WorldPlanPOIMixin:OnUpdate (sinceLast) - if self.hasUpdate then - wqprint('|cFFFFFF00push poi update') + if self.isStale then + print('|cFFFFFF00push poi update') self:Refresh() return end @@ -457,7 +466,6 @@ function WorldPlanPOIMixin:Refresh () local db = WorldPlan.db - local print = wqprint print('|cFF00FF88'..self:GetName()..'|r:Refresh()') @@ -492,10 +500,10 @@ if self.hasNumeric then if subStyle.numberFontObject then - wqprint('change font', _G[subStyle.numberFontObject]:GetName()) + --wqprint('change font', _G[subStyle.numberFontObject]:GetName()) self.count:SetFontObject(_G[subStyle.numberFontObject]) end - wqprint('filtered:', self.filtered, 'showNumber:', self.showNumber) + --wqprint('filtered:', self.filtered, 'showNumber:', self.showNumber) self.count:SetShown(self.showNumber) self.count:SetText(self.itemNumber) @@ -540,36 +548,103 @@ self:UpdateSize() - self.hasUpdate = nil + self.isStale = nil end -function WorldPlanFilterPinMixin:OnEnter () - local filter = WorldPlan.FilterOptions[self:GetID()] - local mapID = GetCurrentMapAreaID() - local quests = (mapID == WorldPlan.BrokenIsleID) and WorldPlan.QuestsByID or WorldPlan.QuestsByZone[mapID] - if quests then - GameTooltip:SetOwner(self, 'ANCHOR_RIGHT') - GameTooltip:AddLine(filter.label) - local filterKey = self.filterKey - local filterValue = self.filterValue - if filterKey then - for questID, pin in pairs(quests) do - if pin.used and not pin.filtered then - if pin[filterKey] == filterValue then - local style = pin.style or WorldPlan.FilterStyle - if familiars[questID] then - GameTooltip:AddLine(pin.title,0,1,0) - else - GameTooltip:AddLine(pin.title,1,1,1) - end - end - end - end - else - GameTooltip:AddLine('Reset all filters') + +function QuestPOI:IsShowable () + local print = wqprint + local db = WorldPlan.db + local qType = self.worldQuestType + local rType = self.rewardType + self.filtered = nil + self.used = true + + + self.questId = self:GetID() + if not (WorldMap_DoesWorldQuestInfoPassFilters(self, false, true)) then + self.filtered = true + end + + for filterKey, value in pairs(WorldPlan.UsedFilters) do + if self[filterKey] ~= value then + self.filtered = true end - GameTooltip:Show() 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 + print(' |cFFFF4400IsShowable()|r', self.used, self.filtered, self.title) + 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 \ No newline at end of file
--- a/WorldPlan.lua Tue Nov 01 10:48:50 2016 -0400 +++ b/WorldPlan.lua Wed Nov 02 17:25:07 2016 -0400 @@ -2,77 +2,33 @@ -- 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 = { + FilterOptions = {}, + UsedFilters = {}, QuestsByZone = {}, QuestsByID = {}, - freePins = {}, + TaskQueue = {}, } -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 WorldPlan = WorldPlanCore -local QuestPOI = WorldPlanPOIMixin -local FilterPin = WorldPlanFilterPinMixin +local print = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end 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 tinsert, pairs, floor = table.insert, pairs, floor 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 BROKEN_ISLES_ID = 1007 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, + pinMask = "Interface\\Minimap\\UI-Minimap-Background", + rewardMask = "Interface\\Minimap\\UI-Minimap-Background", + texture = "Interface\\BUTTONS\\YELLOWORANGE64", continent = { PinSize = 14, Border = 2, @@ -113,71 +69,16 @@ 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 -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 @@ -188,7 +89,7 @@ WorldPlanData[key] = true end end - WorldPlan:Refresh() + _G.WorldPlan:Refresh() end function WorldPlan:print(...) @@ -238,9 +139,6 @@ end WorldPlan = self - scanner = _G.WorldPlanTooltip - wmtt = _G.WorldMapTooltip - WorldMapPOIFrame = _G.WorldMapPOIFrame WorldPlan:print('v'..WP_VERSION) @@ -260,12 +158,11 @@ if self.isStale then self:Refresh() end - end function WorldPlan:OnEvent (event, ...) print() - print(event, self.initialized) + print(event, 'init:', self.initialized) if event == 'ADDON_LOADED' then local addon = ... if addon == "Blizzard_FlightMap" then @@ -276,20 +173,49 @@ 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 + if event == 'WORLD_MAP_UPDATE' then + self.currentMapID = GetCurrentMapAreaID() + self.isContinentMap = (self.currentMapID == BROKEN_ISLES_ID) + print('|cFFFF4400currentMapID =', self.currentMapID) + --self.isStale = true + end + for i, module in ipairs(self.modules) do if module.OnEvent then - print('forwarding to', tostring(module)) + print(' |cFF0088FF'..module:GetName() .. ':OnEvent()|r') module:OnEvent(event, ...) end end end end +function WorldPlanCore:OnNext(func) + tinsert(self.TaskQueue, func) +end + +function WorldPlanCore:OnUpdate() + if #self.TaskQueue >= 1 then + local func = tremove(self.TaskQueue, 1) + if func then + func() + end + + 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 @@ -323,6 +249,16 @@ 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) @@ -398,30 +334,9 @@ end 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() + print('|cFF00FF00external '..module:GetName()..':Refresh()|r') + module:Refresh(forced) end end end @@ -494,345 +409,6 @@ -------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------- -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) - - 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 - -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: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.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() @@ -871,129 +447,10 @@ -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) - - self.questId = self:GetID() - if not (WorldMap_DoesWorldQuestInfoPassFilters(self, false, true)) then - self.filtered = true - end - - for filterKey, value in pairs(WorldPlan.UsedFilters) do - if self[filterKey] ~= value then - self.filtered = true - end - 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()
--- a/WorldPlan.toc Tue Nov 01 10:48:50 2016 -0400 +++ b/WorldPlan.toc Wed Nov 02 17:25:07 2016 -0400 @@ -10,5 +10,6 @@ ## OptionalDeps: Veneer WorldPlan.xml +WorldQuests.xml FilterBar.xml ClassPlan.xml
--- a/WorldPlan.xml Tue Nov 01 10:48:50 2016 -0400 +++ b/WorldPlan.xml Wed Nov 02 17:25:07 2016 -0400 @@ -150,13 +150,6 @@ <Scripts> <OnLoad method="OnLoad" /> <OnEvent method="OnEvent" /> - </Scripts> - </Frame> - - <Frame name="$parentQuests" mixin="WorldPlanQuestsMixin" parent="WorldPlan"> - <Scripts> - <OnLoad method="OnLoad" /> - <OnEvent method="OnEvent" /> <OnUpdate method="OnUpdate" /> <OnShow method="OnShow" /> </Scripts>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WorldQuests.lua Wed Nov 02 17:25:07 2016 -0400 @@ -0,0 +1,354 @@ +-- 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WorldQuests.xml Wed Nov 02 17:25:07 2016 -0400 @@ -0,0 +1,14 @@ +<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ +..\FrameXML\UI.xsd"> + <Script file="WorldQuests.lua" /> + + + <Frame name="$parentQuests" mixin="WorldPlanQuestsMixin" parent="WorldPlan"> + <Scripts> + <OnLoad method="OnLoad" /> + <OnEvent method="OnEvent" /> + <OnShow method="OnShow" /> + </Scripts> + </Frame> + + </Ui> \ No newline at end of file