Nenue@7: -- WorldPlan Nenue@7: -- QuestPOI.lua Nenue@7: -- Created: 10/1/2016 7:21 PM Nenue@7: -- %file-revision% Nenue@7: -- Nenue@40: local _, db = ... Nick@64: local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID Nenue@7: local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation Nenue@7: local TQ_GetQuestTimeLeftMinutes = C_TaskQuest.GetQuestTimeLeftMinutes Nenue@9: local TQ_IsActive = C_TaskQuest.IsActive Nenue@29: local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData Nenue@7: local QuestPOIGetIconInfo, WorldMapPOIFrame = QuestPOIGetIconInfo, WorldMapPOIFrame Nenue@33: local WorldMap_DoesWorldQuestInfoPassFilters = WorldMap_DoesWorldQuestInfoPassFilters Nenue@33: local QuestMapFrame_IsQuestWorldQuest = QuestMapFrame_IsQuestWorldQuest Nenue@40: local GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo = GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo Nick@64: Nick@64: local IsQuestFlaggedCompleted = IsQuestFlaggedCompleted Nick@64: local GetFactionInfoByID, GetQuestObjectiveInfo = GetFactionInfoByID, GetQuestObjectiveInfo Nick@64: local GetQuestTagInfo, GetProfessionInfo = GetQuestTagInfo, GetProfessionInfo Nick@64: local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData Nick@64: local GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString Nick@64: local SpellCanTargetQuest, GetCVarBool = SpellCanTargetQuest, GetCVarBool Nick@64: local SetSuperTrackedQuestID = SetSuperTrackedQuestID Nick@64: Nenue@40: local pairs, ipairs, tinsert, unpack, select = pairs, ipairs, tinsert, unpack, select Nenue@40: local floor, mod, tostring, tonumber, GetSuperTrackedQuestID = floor, mod, tostring, tonumber, GetSuperTrackedQuestID Nenue@33: local GameTooltip = GameTooltip Nenue@33: local GetItemIcon = GetItemIcon Nenue@7: Nenue@33: local print = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end Nenue@7: local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or function() end Nenue@33: local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or function() end Nenue@30: local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or function() end Nenue@7: local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or function() end Nenue@40: local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or function() end Nenue@49: local dprint = DEVIAN_WORKSPACE and function(...) _G.print('WQData', ...) end or function() end Nenue@7: local QuestPOI = WorldPlanPOIMixin Nenue@7: Nenue@56: local pinBaseIndex = 1300 Nenue@56: local overlayBaseIndex = 1350 Nenue@56: local previousHighlight Nenue@40: Nenue@40: local PIN_REFRESH_DELAY = .5 Nenue@54: local PIN_REQUEST_DELAY = .1 Nenue@9: local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" Nenue@9: local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" Nenue@9: Nenue@40: local WORLD_QUEST_BORDER = "Interface\\UNITPOWERBARALT\\Generic1Target_Circular_Frame" Nenue@47: local PENDING_BORDER = "Interface\\BUTTONS\\YELLOWORANGE64" Nenue@40: local PENDING_ICON = "Interface\\BUTTONS\\YELLOWORANGE64" Nenue@9: Nenue@29: local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD Nenue@29: local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER Nenue@29: local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT Nenue@29: local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES Nenue@29: local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS Nenue@29: Nenue@29: local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP Nenue@29: local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE Nenue@29: local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON Nenue@29: local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION Nenue@29: local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL Nenue@29: Nenue@29: local LE_QUEST_TAG_TYPE_PVP = LE_QUEST_TAG_TYPE_PVP Nenue@29: local LE_QUEST_TAG_TYPE_PET_BATTLE = LE_QUEST_TAG_TYPE_PET_BATTLE Nenue@29: local LE_QUEST_TAG_TYPE_DUNGEON = LE_QUEST_TAG_TYPE_DUNGEON Nenue@29: local LE_QUEST_TAG_TYPE_PROFESSION = LE_QUEST_TAG_TYPE_PROFESSION Nenue@29: local LE_QUEST_TAG_TYPE_NORMAL = LE_QUEST_TAG_TYPE_NORMAL Nenue@29: Nenue@40: local STYLE_TYPE_PENDING = 768 Nenue@40: Nenue@31: Nenue@29: -- Pin color/display variables Nenue@40: db.TooltipExtras = db.TooltipExtras or {} -- idiot-proofing Nenue@49: db.PinAlpha = 1 Nenue@29: Nenue@33: local familiars = { Nenue@40: [42159] = 'Nightwatcher Merayl', Nenue@40: [40277] = 'Tiffany Nelson', Nenue@40: [40298] = 'Sir Galveston', Nenue@40: [40282] = 'Grixis Tinypop', Nenue@40: [40278] = 'Robert Craig', Nenue@40: [48195] = 'Aulier', Nenue@40: [41990] = 'Varenne', Nenue@40: [41860] = 'Xorvasc', Nenue@40: [40299] = 'Bodhi Sunwayver', Nenue@40: [42442] = 'Amalia', Nenue@40: [40280] = 'Bredda Tenderhide', Nenue@40: [41687] = 'Odrogg', Nenue@40: [41944] = 'Trapper Jarrun', Nenue@40: [40337] = 'Master Tamer Flummox', Nenue@40: [40279] = 'Durian Strongfruit' Nenue@40: } Nenue@40: local falcosaurs = { Nenue@40: [44895] = {44881, 'Sharptalon Hatchling', 115786}, Nenue@40: [44894] = {44882, 'Bloodgazer Hatchling', 115787}, Nenue@40: [44893] = {44880, 'Direbeak Hatchling', 115785}, Nenue@40: [44892] = {44879, 'Snowfeather Hatchling', 115784}, Nenue@33: } Nenue@33: local familiars_id = 9696 Nenue@40: for questID, name in pairs(familiars) do Nenue@40: db.TooltipExtras[questID] = {{ Nenue@40: achievementID = familiars_id, Nenue@40: name = name Nenue@40: }} Nenue@40: end Nenue@40: for questID, info in pairs(falcosaurs) do Nenue@40: local trackingQuestID, petName, petID = unpack(info) Nenue@33: Nenue@40: db.TooltipExtras[questID] = {{ Nenue@40: questID = trackingQuestID, Nenue@40: pet = petName, Nenue@40: petID = petID Nenue@40: }} Nenue@9: end Nenue@7: Nenue@40: local GetAchievementTooltipExtras = function(info) Nenue@29: Nenue@40: local hasInfo Nenue@40: local achievementID = info.achievementID Nenue@40: local _, name, _, completed, _, _, _, _, _, icon = GetAchievementInfo(achievementID) Nenue@40: if not completed then Nenue@40: Nenue@40: local numItems = GetAchievementNumCriteria(achievementID) Nenue@40: local numNeeded = 0 Nenue@40: local tooltipLines = {} Nenue@40: for i =1, numItems do Nenue@40: local criteriaName, criteriaType, completed, _, _, _, _, subAchievementID = GetAchievementCriteriaInfo(achievementID, i) Nenue@49: --print(GetAchievementCriteriaInfo(achievementID, i)) Nenue@40: Nenue@40: if not completed then Nenue@49: --print('::', criteriaName, completed, subAchievementID) Nenue@40: if criteriaType == 8 then Nenue@40: local _, _, _, completed, _, _, _, _, _, subIcon = GetAchievementInfo(subAchievementID) Nenue@49: --print(' -', criteriaName, completed, subIcon) Nenue@40: if not completed then Nenue@40: local numCompleted = 0 Nenue@40: local numSubItems = GetAchievementNumCriteria(subAchievementID) Nenue@40: local subCriteriaLine Nenue@40: for j = 1, numSubItems do Nenue@40: local subName, _, completed = GetAchievementCriteriaInfo(subAchievementID, j) Nenue@40: Nenue@49: --print(' -',subName, completed) Nenue@40: if completed then Nenue@40: numCompleted = numCompleted + 1 Nenue@40: else Nenue@40: numNeeded = numNeeded + 1 Nenue@40: if subName:match(info.name) then Nenue@40: hasInfo = true Nenue@40: subCriteriaLine = ' |T'..subIcon..':16:16|t ' .. criteriaName Nenue@40: end Nenue@40: end Nenue@40: Nenue@40: end Nenue@40: if subCriteriaLine then Nenue@40: tinsert(tooltipLines, subCriteriaLine .. ' ('..numCompleted..'/'..numSubItems..')') Nenue@40: end Nenue@40: end Nenue@40: elseif criteriaName:match(info.name) and (not completed) then Nenue@40: numNeeded = numNeeded + 1 Nenue@40: tinsert(tooltipLines, criteriaName) Nenue@40: end Nenue@40: end Nenue@40: end Nenue@49: if hasInfo then Nenue@49: WorldMapTooltip:AddLine(" ") Nenue@49: WorldMapTooltip:AddLine("Achievements:") Nenue@49: WorldMapTooltip:AddLine(' |T'..icon..':20:20|t '..name) Nenue@40: for i, line in ipairs(tooltipLines) do Nenue@40: WorldMapTooltip:AddLine(line) Nenue@40: end Nenue@40: end Nenue@40: end Nenue@40: return hasInfo Nenue@40: end Nenue@40: Nenue@40: local GetQuestTooltipExtras = function(info) Nenue@40: local questID = info.questID Nenue@40: local hasInfo Nenue@40: Nenue@40: if info.pet then Nenue@40: local index, guid = C_PetJournal.FindPetIDByName(info.pet) Nenue@40: if not index then Nenue@40: hasInfo = true Nenue@40: WorldMapTooltip:AddLine('Pets:') Nenue@40: WorldMapTooltip:AddLine(' - ' .. info.petName) Nenue@40: Nenue@40: if not IsQuestFlaggedCompleted(questID) then Nenue@40: WorldMapTooltip:AddLine(' Required Quest Flags', 1, 1, 0) Nenue@40: else Nenue@40: WorldMapTooltip:AddLine(' Quest Flags Complete!', 0, 1, 0) Nenue@40: end Nenue@40: Nenue@40: end Nenue@29: end Nenue@29: Nenue@29: end Nenue@29: Nenue@40: Nenue@40: function QuestPOI:OnEnter() Nenue@57: if self.filtered and (self.questID ~= GetSuperTrackedQuestID()) then Nenue@49: return Nenue@7: end Nenue@57: WorldMap_HijackTooltip(self.owningFrame); Nenue@56: self:SetFrameLevel(pinBaseIndex+100) Nenue@56: self.Overlay:SetFrameLevel(pinBaseIndex+101) Nenue@56: Nenue@56: if previousHighlight then Nenue@56: previousHighlight:SetFrameLevel(pinBaseIndex+previousHighlight:GetID()) Nenue@56: previousHighlight.Overlay:SetFrameLevel(overlayBaseIndex+previousHighlight:GetID()) Nenue@56: end Nenue@56: Nenue@56: previousHighlight = self Nenue@56: Nenue@56: Nenue@40: WorldMapTooltip:SetOwner(self, "ANCHOR_RIGHT"); Nenue@49: --print('doing tooltip stuff') Nenue@40: Nenue@40: -- Can't add stuff after, so most of the blizzard tooltip hook is simply copied over Nenue@40: local questID = self.questID Nenue@40: local color = WORLD_QUEST_QUALITY_COLORS[self.rarity] or NORMAL_FONT_COLOR; Nenue@40: Nenue@40: Nenue@40: WorldMapTooltip:SetText(self.title, color.r, color.g, color.b); Nenue@40: QuestUtils_AddQuestTypeToTooltip(WorldMapTooltip, questID, NORMAL_FONT_COLOR); Nenue@40: Nenue@40: if ( self.factionID ) then Nenue@40: local factionName = GetFactionInfoByID(self.factionID); Nenue@40: if ( factionName ) then Nenue@40: if (self.capped) then Nenue@40: WorldMapTooltip:AddLine(factionName, GRAY_FONT_COLOR:GetRGB()); Nenue@40: else Nenue@40: WorldMapTooltip:AddLine(factionName); Nenue@40: end Nenue@40: end Nenue@40: end Nenue@40: Nenue@40: if self.worldQuest then Nenue@40: WorldMap_AddQuestTimeToTooltip(questID); Nenue@40: end Nenue@40: Nenue@40: Nenue@40: for objectiveIndex = 1, self.numObjectives do Nenue@40: local objectiveText, objectiveType, finished = GetQuestObjectiveInfo(questID, objectiveIndex, false); Nenue@40: if ( objectiveText and #objectiveText > 0 ) then Nenue@40: local color = finished and GRAY_FONT_COLOR or HIGHLIGHT_FONT_COLOR; Nenue@40: WorldMapTooltip:AddLine(QUEST_DASH .. objectiveText, color.r, color.g, color.b, true); Nenue@40: end Nenue@40: end Nenue@40: Nenue@40: local percent = C_TaskQuest.GetQuestProgressBarInfo(self.questID); Nenue@40: if ( percent ) then Nenue@40: GameTooltip_InsertFrame(WorldMapTooltip, WorldMapTaskTooltipStatusBar); Nenue@40: WorldMapTaskTooltipStatusBar.Bar:SetValue(percent); Nenue@40: WorldMapTaskTooltipStatusBar.Bar.Label:SetFormattedText(PERCENTAGE_STRING, percent); Nenue@40: end Nenue@40: Nenue@40: if db.TooltipExtras[self.questID] then Nenue@40: for index, info in pairs(db.TooltipExtras[questID]) do Nenue@40: if info.achievementID then Nenue@40: GetAchievementTooltipExtras(info) Nenue@40: end Nenue@40: if info.questID then Nenue@40: GetQuestTooltipExtras(info) Nenue@40: end Nenue@40: end Nenue@40: end Nenue@40: WorldMap_AddQuestRewardsToTooltip(questID) Nenue@40: Nenue@40: WorldMapTooltip:Show() Nenue@40: --WorldMapTooltip.recalculatePadding = true; Nenue@40: --print(WorldMapTooltip:GetParent()) Nenue@40: --print(WorldMapTooltip:IsVisible()) Nenue@7: end Nenue@40: function QuestPOI:OnLeave() Nenue@57: if self.filtered and (self.questID ~= GetSuperTrackedQuestID()) then Nenue@57: return Nenue@57: end Nenue@35: WorldMap_RestoreTooltip() Nenue@40: WorldMapTooltip:Hide(); Nenue@7: end Nenue@7: Nenue@40: -- attempt to pull pin data Nenue@40: function QuestPOI:GetData () Nenue@49: dprint('|cFF00FF88'..self:GetID()..':GetData()|r') Nenue@40: local questID = self.questID Nenue@40: if not questID then Nenue@49: dprint('|cFFFF4400bad pin|r', self:GetName()) Nenue@40: return nil Nenue@29: end Nenue@29: Nenue@40: local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) Nenue@40: -- if the title is nil, then wait and try later Nenue@40: if not questTitle then Nenue@54: if not self.isPending then Nenue@54: C_TaskQuest.RequestPreloadRewardData(questID) Nenue@54: self.isPending = true Nenue@54: end Nenue@49: dprint('|cFFBB8844isPending=true|r|cFF00FFFF', self.questId) Nenue@40: else Nenue@40: self.title, self.factionID, self.capped = questTitle, factionID, capped Nenue@49: dprint('|cFFBB8844 data|r|cFF00FFFF', (self.isPending and '|cFFFF4400delayed|r' or '|cFF00FF00success|r'), self.title, '|r', self.factionID) Nenue@49: if self.dataLoaded then Nenue@49: dprint(' |cFFFF4400overwriting data|r') Nenue@49: end Nenue@49: Nenue@40: -- set tag details Nenue@40: local worldQuestType Nenue@40: self.tagID, self.tagName, worldQuestType, self.rarity, self.isElite, self.tradeskillLineIndex = GetQuestTagInfo(questID); Nenue@40: local tagAtlas Nenue@40: if worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE then Nenue@40: tagAtlas = "worldquest-icon-petbattle" Nenue@40: elseif worldQuestType == LE_QUEST_TAG_TYPE_PVP then Nenue@40: tagAtlas = "worldquest-icon-pvp-ffa" Nenue@40: elseif worldQuestType == LE_QUEST_TAG_TYPE_PROFESSION then Nenue@40: self.isKnownProfession = nil Nenue@40: local id = self.tradeskillLineIndex and select(7, GetProfessionInfo(self.tradeskillLineIndex)) Nenue@40: if id then Nenue@40: self.isKnownProfession = true Nenue@40: qprint('profession' , self.title, id) Nenue@40: tagAtlas = WORLD_QUEST_ICONS_BY_PROFESSION[id] Nenue@40: end Nenue@40: elseif worldQuestType == LE_QUEST_TAG_TYPE_DUNGEON then Nenue@40: tagAtlas = "worldquest-icon-dungeon" Nenue@40: end Nenue@40: self.worldQuestType = worldQuestType Nenue@40: self.tagAtlas = tagAtlas Nenue@29: Nenue@40: self:SetRewardInfo() Nenue@40: Nenue@40: -- force throttle on success Nenue@40: --qprint(' |cFF00FFFF'..questID..'|r hasUpdate:', hasUpdate, 'isPending:', isPending, 'isShown', self:IsShown()) Nenue@40: --qprint(' ', 'rewardType:', self.rewardType, 'tag:', self.tagID) Nenue@40: qprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) Nenue@40: Nenue@40: if self.itemTexture and self.itemName and self.title then Nenue@49: self.dataLoaded = true Nenue@40: self.isPending = nil Nenue@40: self.throttle = 1 Nenue@40: self.updateRate = PIN_REFRESH_DELAY Nenue@48: self.isStale = true Nenue@40: end Nenue@40: end Nenue@40: Nenue@40: self.isCriteria = WorldMapFrame.UIElementsFrame.BountyBoard:IsWorldQuestCriteriaForSelectedBounty(questID) Nenue@40: Nenue@40: return self.isStale, self.isPending Nenue@40: end Nenue@40: Nenue@40: function QuestPOI:SetRewardInfo() Nenue@40: local questID = self.questID Nenue@29: if not HaveQuestData(questID) then Nenue@40: self.isPending = true Nenue@29: else Nenue@29: Nenue@40: local rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality Nenue@29: -- set reward category Nenue@29: local numRewards = GetNumQuestLogRewards(questID) Nenue@29: local numCurrency = GetNumQuestLogRewardCurrencies(questID) Nenue@29: local money = GetQuestLogRewardMoney(questID) Nenue@29: if numRewards >= 1 then Nenue@40: rewardType, rewardIcon, rewardCount, rewardName, itemID, quality = WorldPlanQuests:GetRewardHeader(questID) Nenue@29: elseif numCurrency >= 1 then Nenue@29: rewardName, rewardIcon, rewardCount = GetQuestLogRewardCurrencyInfo(1, questID) Nenue@29: rewardType = REWARD_CURRENCY Nenue@29: elseif money >= 1 then Nenue@29: rewardIcon = ICON_MONEY Nenue@29: rewardName = GetMoneyString(money) Nenue@29: rewardType = REWARD_CASH Nenue@29: end Nenue@29: Nenue@49: qprint(' '..self.questID..':|cFFFFFF00SetRewardInfo():', numRewards, rewardType) Nenue@40: self.itemNumber = tonumber(rewardCount or self.itemNumber) Nenue@49: self.rewardType = rewardType Nenue@31: self.quality = quality Nenue@29: Nenue@40: self.itemTexture = rewardIcon or self.itemTexture Nenue@40: self.itemName = rewardName or self.itemName Nenue@29: Nenue@29: -- flag unresolved info Nenue@29: if not (rewardIcon and rewardName) then Nenue@40: self.isPending = true Nenue@48: self.isStale = nil Nenue@29: --WorldPlan:print('|cFFFFFF00'..tostring(self.title)..'|r waiting on texture info') Nenue@29: else Nenue@40: if (rewardIcon and rewardName) and self.isPending then Nenue@29: --WorldPlan:print('|cFF00FF00'..tostring(self.title)..'|r has info', rewardIcon, rewardName) Nenue@40: self.isStale = true Nenue@29: end Nenue@40: self.isPending = nil Nenue@29: end Nenue@29: Nenue@40: end Nenue@7: end Nenue@7: Nenue@34: -- run from OnShow if .isNew is set Nenue@34: Nenue@49: function QuestPOI:StartFade() Nenue@34: if not self.isAnimating then Nenue@35: --qprint('|cFFFFFF00'.. self.title .. ' added to quest log.') Nenue@35: self:SetAlpha(0) Nenue@49: self.FadeIn.FadeIn:SetToAlpha(db.PinAlpha) Nenue@49: self.PendingFade.FadeIn:SetToAlpha(db.PinAlpha) Nenue@49: self.PendingFade.FadeOut:SetFromAlpha(db.PinAlpha) Nenue@49: Nenue@34: self.isAnimating = true Nenue@35: self.isNew = nil Nenue@40: self.isStale = true Nenue@35: self.FadeIn:Play() Nenue@34: end Nenue@7: end Nenue@7: Nenue@49: function QuestPOI:EndFade() Nenue@49: self.isAnimating = nil Nenue@49: self:SetAlpha(db.PinAlpha) Nenue@49: end Nenue@49: Nenue@40: function QuestPOI:OnShow () Nenue@27: Nenue@49: if self.isStale then Nenue@49: qprint('|cFF0088FFflagged for refresh') Nenue@48: self:Refresh() Nenue@48: end Nenue@34: Nenue@54: if self.isNew or (not self.Overlay:IsShown()) then Nenue@54: --qprint('|cFFFFFF00popping new pin handler') Nenue@49: self:StartFade() Nenue@49: end Nenue@49: Nenue@54: if not self.isAnimating then Nenue@57: self:SetAlpha(db.PinAlpha) -- fix stuck alpha Nenue@54: end Nenue@59: Nick@62: self:ShowFrames() Nenue@27: end Nick@62: Nenue@40: function QuestPOI:OnHide() Nick@60: --DEFAULT_CHAT_FRAME:AddMessage('|cFFFFFF00'..self:GetName()..'|r:OnHide()') Nick@62: self:HideFrames() Nenue@59: -- reset flags Nenue@59: self:SetAlpha(db.PinAlpha) Nenue@49: self.isAnimating = nil Nenue@27: end Nenue@27: Nenue@57: -- different from owningFrame Nenue@52: function QuestPOI:SetAnchor(owner, dX, dY, mapWidth, mapHeight) Nick@62: wqprint(self:GetName()..':SetAnchor()', owner, dX, dY, self.filtered, self.used) Nick@62: if not self.used then Nick@62: self:HideFrames() Nick@62: return Nick@62: end Nick@62: Nick@62: Nenue@52: self:SetParent(owner) Nenue@49: self:ClearAllPoints() Nenue@56: self:SetFrameLevel(pinBaseIndex + self:GetID()) Nenue@53: self.Overlay:SetParent(owner) Nenue@53: self.Overlay:SetFrameLevel(overlayBaseIndex + self:GetID()) Nenue@53: if (dX and dY) then Nenue@53: if not (mapHeight and mapWidth) then Nenue@53: mapWidth, mapHeight = owner:GetSize() Nenue@53: end Nenue@53: local pX = (dX * mapWidth) Nenue@53: local pY = (-dY * mapHeight) Nenue@53: self.x = dX Nenue@53: self.y = dY Nenue@53: self:SetPoint('CENTER', owner, 'TOPLEFT', pX, pY) Nenue@53: else Nenue@53: self:SetPoint('CENTER') Nenue@53: end Nick@62: Nick@62: self:ShowFrames() Nick@62: end Nick@62: Nick@64: -- Show/Hide the text overlays associated with the quest pin; they aren't hierarchically linked Nick@62: function QuestPOI:ShowFrames() Nick@62: if not self:IsShown() then Nick@62: print('|cFFFFFF00' ..self:GetName()..':ShowFrames()') Nick@64: -- do not SetShown() here Nick@64: end Nick@62: Nick@62: self.count:SetShown(true) Nick@62: self.Overlay:SetShown(true) Nick@62: self.count:SetShown(true) Nick@62: self.timeLabel:SetShown(true) Nick@62: end Nick@62: Nick@62: function QuestPOI:HideFrames() Nick@62: if self:IsShown() then Nick@62: print(self:GetName()..':HideFrames()') Nick@62: self:SetShown(false) Nick@62: end Nick@62: self.count:SetShown(false) Nick@62: self.Overlay:SetShown(false) Nick@62: self.count:SetShown(false) Nick@62: self.timeLabel:SetShown(false) Nick@62: self.used = nil Nenue@7: end Nenue@7: Nenue@40: function QuestPOI:OnLoad() Nenue@40: qprint('|cFF00FF88'..self:GetName()..':OnLoad()|r',db.Config) Nenue@7: self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') Nenue@36: Nenue@40: self.title = '|cFF0088FF' .. RETRIEVING_DATA..'|r' Nenue@40: self.isPending = true Nenue@36: self.count = self.Overlay.count Nick@62: self.timeLabel = self.Overlay.timeLabel Nenue@54: self.Description = self.Overlay.Description Nenue@40: self.updateRate = PIN_REQUEST_DELAY Nenue@40: self.itemName = '|cFF0088FF' .. RETRIEVING_DATA..'|r' Nenue@41: Nenue@53: self.Overlay:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 4) Nenue@53: self.Overlay:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, -4) Nenue@7: end Nick@64: Nenue@57: function QuestPOI:OnMouseDown(button) Nenue@57: if button == 'RightButton' then Nenue@57: SetSuperTrackedQuestID(nil) Nenue@57: else Nenue@57: TaskPOI_OnClick(self, button) Nenue@57: end Nenue@57: end Nenue@57: Nenue@7: Nenue@40: function QuestPOI:OnEvent(event, ...) Nenue@7: if event == 'SUPER_TRACKED_QUEST_CHANGED' then Nenue@33: self.isStale = true Nenue@7: end Nenue@7: end Nenue@7: Nenue@40: function QuestPOI:OnUpdate (sinceLast) Nenue@40: -- control update check intervals Nenue@40: self.throttle = (self.throttle or self.updateRate) + sinceLast Nenue@40: if self.throttle >= self.updateRate then Nenue@40: -- factor overtime into the throttle timer Nenue@40: self.throttle = self.throttle - self.updateRate Nenue@40: else Nenue@40: return Nenue@40: end Nenue@35: if self.isNew then Nenue@59: --print('|cFFFFFF00push new poi stuff') Nenue@35: self:OnNew() Nenue@40: elseif (self.isStale or (not self.title)) and not self.isAnimating then Nenue@59: --wprint('|cFFFFFF00push poi update') Nenue@35: self:Refresh() Nenue@35: return Nenue@35: end Nenue@7: Nenue@7: -- query for reward data if it wasn't found in the original scan Nenue@7: local questID = self.questID Nenue@7: if self.isPending then Nenue@59: --print('|cFFFF4400'..self:GetID()..':|r polling reward info') Nenue@49: if not (self.isAnimating) then Nenue@7: self.PendingFade:Play() Nenue@7: end Nenue@49: self:GetData() Nenue@7: return Nenue@7: else Nenue@7: if self.PendingFade:IsPlaying() then Nenue@7: self.PendingFade:Stop() Nenue@7: end Nenue@7: end Nenue@7: Nenue@55: self:UpdateStatus() Nenue@55: end Nenue@7: Nenue@55: -- Called at static intervals and with Refresh Nenue@55: function QuestPOI:UpdateStatus() Nenue@7: -- update time elements Nick@64: self.isActive = TQ_IsActive(self.questID) Nick@64: Nick@64: if self.isActive then Nenue@40: local tl = self.alertLevel Nenue@55: local timeLeft = TQ_GetQuestTimeLeftMinutes(self.questID) Nenue@40: if timeLeft > 0 then Nenue@40: Nenue@40: local text, timeState = WorldPlan:GetTimeInfo(timeLeft, self.maxAlertLevel) Nenue@40: if tl ~= timeState then Nenue@40: tl = timeState Nenue@40: self.timeLabel:SetText(text) Nenue@40: end Nenue@40: else Nenue@9: if self.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION then Nick@62: self:HideFrames() Nenue@9: end Nenue@7: end Nenue@55: Nenue@57: if tl and (timeLeft < 120) then Nenue@55: self.HighlightBorder:SetVertexColor(1,0,0,0.7) Nenue@55: elseif self.isBounty then Nenue@55: self.HighlightBorder:SetVertexColor(.25,.5,1,1) Nenue@55: else Nenue@55: self.HighlightBorder:SetVertexColor(0,0,0,0.7) Nenue@55: end Nenue@40: self.alertLevel = tl Nick@60: self.timeLabel:SetShown(self.worldQuest and (self.maxAlertLevel >= 1)) Nenue@59: else Nick@60: if not self.completed then Nick@60: self.completed = true Nick@62: self:HideFrames() Nick@60: end Nenue@7: end Nenue@8: end Nenue@8: Nick@60: function QuestPOI:Refresh () Nenue@49: Nick@60: rprint('|cFF00FF88'..self:GetID()..'|r:Refresh() type =', self.rewardType, 'title =', self.title) Nenue@49: Nenue@49: Nenue@9: Nenue@40: local styleType = (self.isPending and STYLE_TYPE_PENDING) or self.rewardType Nenue@40: local style,subStyle = self:GetTypeInfo(self.rewardType) Nenue@52: if (self.filtered or (not self.dataLoaded)) and (self.questID ~= GetSuperTrackedQuestID()) then Nenue@40: subStyle = style.minimized Nenue@40: end Nenue@40: self.style = style Nenue@40: self.subStyle = subStyle Nenue@40: --print(style, subStyle) Nenue@40: self.currentWidth = subStyle.iconWidth Nenue@40: self.borderWidth = subStyle.borderWidth Nenue@40: self.highlightWidth = subStyle.highlightWidth Nenue@40: self.tagSize = subStyle.TagSize Nenue@40: self.maxAlertLevel = subStyle.maxAlertLevel Nenue@40: self.NoIcon = subStyle.NoIcon Nenue@9: Nenue@57: local questID = self.questID Nenue@36: local iconBorder = self.RewardBorder Nenue@36: local trackingBorder = self.HighlightBorder Nenue@9: local icon = self.icon Nenue@9: local count = self.count Nenue@55: self.isBounty = WorldMapFrame.UIElementsFrame.BountyBoard:IsWorldQuestCriteriaForSelectedBounty(self.questID) Nenue@36: Nenue@9: if self.itemName then Nenue@45: Nenue@54: if self.itemNumber then Nenue@54: local numberString = self.itemNumber Nenue@54: if self.itemNumber >= 1000 then Nenue@54: local numeral = floor(self.itemNumber/1000) Nenue@54: local decimal = mod(self.itemNumber, 1000) Nenue@54: numberString = numeral Nenue@54: if decimal > 100 then Nenue@54: numberString = numberString .. '.' .. tostring(floor(decimal/100)) Nenue@54: end Nenue@54: numberString = numberString .. 'k' Nenue@40: end Nenue@45: self.count:SetText(numberString) Nenue@45: else Nenue@54: self.count:SetText(nil) Nenue@45: end Nenue@54: end Nenue@30: Nenue@55: if db.Config.ShowVerboseInfo then Nenue@55: self.Description:SetText(self.title .. "\n" .. floor(self.x*100+.5) .. "," .. floor(self.y*100+.5)) Nenue@55: end Nenue@55: Nenue@40: Nenue@40: icon:SetMask("Interface\\Minimap\\UI-Minimap-Background") Nenue@36: if self.itemTexture then Nenue@47: --iconBorder:SetTexture(WORLD_QUEST_BORDER) Nenue@40: Nenue@40: if self.NoIcon then Nenue@40: icon:SetTexture(PENDING_ICON) Nenue@40: icon:SetDesaturated(true) Nenue@47: icon:SetVertexColor(style.r, style.g, style.b) Nenue@40: else Nenue@40: Nenue@40: icon:SetTexture(self.itemTexture) Nenue@40: icon:SetDesaturated(false) Nenue@40: icon:SetVertexColor(1, 1, 1) Nenue@40: end Nenue@40: else Nenue@47: -- Nenue@40: icon:SetTexture(PENDING_ICON) Nenue@40: icon:SetDesaturated(true) Nenue@47: icon:SetVertexColor(style.r, style.g, style.b) Nenue@9: end Nenue@9: Nenue@47: iconBorder:SetMask("Interface\\Minimap\\UI-Minimap-Background") Nenue@47: iconBorder:SetTexture(PENDING_BORDER) Nenue@54: iconBorder:SetVertexColor(style.r, style.g, style.b, 1) Nenue@52: Nenue@9: iconBorder:SetDesaturated(true) Nenue@40: iconBorder:SetAlpha(subStyle.alpha or 1) Nenue@9: Nenue@47: trackingBorder:SetMask("Interface\\Minimap\\UI-Minimap-Background") Nenue@47: trackingBorder:SetTexture(PENDING_BORDER) Nenue@9: Nenue@49: self.tagIcon:SetShown((not self.filtered) and true or false) Nenue@9: self.tagIcon:SetAtlas(self.tagAtlas) Nenue@49: Nenue@47: self.EliteBorder:SetShown(self.isElite and not self.filtered) Nenue@36: Nenue@9: self:UpdateSize() Nenue@55: self:UpdateStatus() Nenue@33: self.isStale = nil Nenue@57: Nenue@57: -- signal filter info update Nenue@57: WorldPlanSummary.isStale = true Nenue@9: end Nenue@9: Nenue@35: local cvar_check = { Nenue@35: [REWARD_CASH] = 'worldQuestFilterGold', Nenue@35: [REWARD_ARTIFACT_POWER] = 'worldQuestFilterArtifactPower', Nenue@35: [REWARD_CURRENCY] = 'worldQuestFilterOrderResources', Nenue@35: [REWARD_REAGENT]= 'worldQuestFilterProfessionMaterials', Nenue@35: [REWARD_GEAR] = 'worldQuestFilterEquipment', Nenue@35: } Nenue@8: Nick@64: Nick@64: Nenue@57: function QuestPOI:CheckFilterRules () Nenue@36: local print = qprint Nenue@33: local qType = self.worldQuestType Nenue@57: local filtered Nenue@57: local canShow = TQ_IsActive(self.questID) Nenue@52: if SpellCanTargetQuest() then Nenue@52: -- hiding so player can click a valid target Nenue@52: self.used = nil Nenue@52: elseif qType == LE_QUEST_TAG_TYPE_PROFESSION then Nenue@57: if not(self.isKnownProfession or db.Config.ShowAllProfessionQuests) then Nenue@57: canShow = nil Nenue@36: end Nenue@36: end Nenue@57: if canShow then Nenue@57: for filterKey, value in pairs(db.UsedFilters) do Nenue@57: if self[filterKey] ~= value then Nenue@57: if not self.filtered then Nenue@57: print('|cFFFF4400filtering', filterKey, value, '~=', self[filterKey], self.title) Nenue@57: end Nenue@57: Nenue@57: filtered = true Nenue@57: end Nenue@57: end Nenue@57: if self.rewardType and cvar_check[self.rewardType] then Nenue@57: if not GetCVarBool(cvar_check[self.rewardType]) then Nenue@57: filtered = true Nenue@57: end Nenue@57: end Nenue@57: if canShow and self.filtered ~= filtered then Nenue@57: self.isStale = true Nenue@57: print(' '..self.questID..':|cFFFFFF00CheckFilterRules()|r ', canShow, filtered, self.title) Nenue@57: end Nenue@57: Nenue@57: self.filtered = filtered Nenue@57: end Nenue@57: Nenue@57: self.used = canShow Nenue@57: Nenue@57: Nenue@33: end Nenue@33: Nenue@33: --- Fixes icons upon size update Nenue@36: function QuestPOI:UpdateSize () Nenue@33: Nenue@49: --qprint('|cFF00BB88'..self:GetID()..'|r:UpdateSize()', self.style, self.subStyle) Nenue@33: Nenue@40: local style = self.style Nenue@40: local subStyle = self.subStyle Nenue@36: local icon = self.icon Nenue@36: local iconBorder = self.RewardBorder Nenue@36: local trackingBorder = self.HighlightBorder Nenue@36: local tag = self.tagIcon Nenue@33: Nenue@36: local iconWidth = subStyle.iconWidth Nenue@36: local borderWidth = iconWidth + (subStyle.borderWidth * 2) Nenue@36: local highlightWidth = borderWidth + (subStyle.highlightWidth * 2) Nenue@36: local iconTexture = self.itemTexture Nenue@33: Nenue@47: Nenue@56: self:SetSize(highlightWidth, highlightWidth) Nenue@47: if self.questID == GetSuperTrackedQuestID() then Nenue@47: highlightWidth = highlightWidth + 2 Nenue@57: if self.filtered then Nenue@57: self:SetAlpha(db.PinAlpha * 0.5) Nenue@57: else Nenue@57: self:SetAlpha(db.PinAlpha) Nenue@57: end Nenue@57: Nenue@47: end Nenue@47: Nenue@47: if self.rarity and WORLD_QUEST_QUALITY_COLORS[self.rarity] then Nenue@47: highlightWidth = highlightWidth + self.rarity Nenue@47: end Nenue@40: self.tagIcon:SetSize(self.tagSize, self.tagSize) Nenue@36: icon:SetSize(iconWidth, iconWidth) Nenue@36: iconBorder:SetSize(borderWidth, borderWidth) Nenue@36: trackingBorder:SetSize(highlightWidth, highlightWidth) Nenue@33: Nenue@36: Nenue@36: iconBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) Nenue@36: trackingBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) Nenue@36: Nenue@36: Nick@62: if (subStyle.showNumber and self.itemNumber) and style.hasNumeric then Nenue@36: self.count:SetTextColor(unpack(style.numberRGB)) Nenue@36: if subStyle.numberFontObject then Nenue@36: --wqprint('change font', _G[subStyle.numberFontObject]:GetName()) Nenue@36: self.count:SetFontObject(_G[subStyle.numberFontObject]) Nenue@36: end Nick@62: else Nick@62: self.count:SetText(nil) Nenue@33: end Nenue@7: end