Mercurial > wow > worldplan
view QuestPOI.lua @ 106:1197c8825eda
- remove 7.2.5 changes from live
author | Nenue |
---|---|
date | Sun, 28 May 2017 19:58:56 -0400 |
parents | 9f664a0ef8a8 |
children | b67ba1078824 |
line wrap: on
line source
-- WorldPlan -- QuestPOI.lua -- Created: 10/1/2016 7:21 PM -- %file-revision% -- Big TODOs: -- -- generate frames using `WorldMap_GetOrCreateTaskPOI' to remove tainting issues -- local _, db = ... local TQ_GetQuestInfoByQuestID = C_TaskQuest.GetQuestInfoByQuestID 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 GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo = GetAchievementNumCriteria, GetAchievementCriteriaInfo, GetAchievementInfo local IsQuestFlaggedCompleted = IsQuestFlaggedCompleted local GetFactionInfoByID, GetQuestObjectiveInfo = GetFactionInfoByID, GetQuestObjectiveInfo local GetQuestTagInfo, GetProfessionInfo = GetQuestTagInfo, GetProfessionInfo local GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData = GetNumQuestLogRewards, GetNumQuestLogRewardCurrencies, HaveQuestData local GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString = GetQuestLogRewardMoney, GetQuestLogRewardCurrencyInfo, GetMoneyString local SpellCanTargetQuest, GetCVarBool = SpellCanTargetQuest, GetCVarBool local SetSuperTrackedQuestID = SetSuperTrackedQuestID local HaveQuestRewardData = HaveQuestRewardData local GetTime = GetTime local pairs, ipairs, tinsert, tremove, unpack, select = pairs, ipairs, tinsert, tremove, unpack, select local floor, mod, tostring, tonumber, GetSuperTrackedQuestID = floor, mod, tostring, tonumber, GetSuperTrackedQuestID local GameTooltip = GameTooltip local GetItemIcon = GetItemIcon local print = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or nop local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or nop local wqprint = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or nop local iprint = DEVIAN_WORKSPACE and function(...) _G.print('ItemScan', ...) end or nop local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or nop local dprint = DEVIAN_WORKSPACE and function(...) _G.print('WQData', ...) end or nop local QuestPOI = WorldPlanPOIMixin local pinBaseIndex = 1400 local overlayBaseIndex = 1450 local previousHighlight local FADE_TIMING_MULTIPLIER = 3 local DATA_DEBUG = false local PIN_REFRESH_DELAY = 1 local PIN_REQUEST_DELAY = .2 local ICON_UNKNOWN = "Interface\\ICONS\\inv_misc_questionmark" local ICON_MONEY = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" local WORLD_QUEST_BORDER = "Interface\\UNITPOWERBARALT\\Generic1Target_Circular_Frame" local PENDING_BORDER = "Interface\\BUTTONS\\YELLOWORANGE64" local PENDING_ICON = "Interface\\BUTTONS\\YELLOWORANGE64" 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 REWARD_TYPE_NAMES = { [REWARD_CASH] = 'Money', [REWARD_ARTIFACT_POWER] = 'AP', [REWARD_GEAR] = 'Equipment', [REWARD_CURRENCY] = 'Currency', [REWARD_REAGENT] = 'Trade Goods' } 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 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 local DEFAULT_STYLE = { border = {1,1,1}, textColor = {1,1,1,1}, x = 0, y = 0, desaturated = true, iconMask = "Interface\\Minimap\\UI-Minimap-Background", borderMask = "Interface\\Minimap\\UI-Minimap-Background", rewardMark = "Interface\\Minimap\\UI-Minimap-Background", scaleFactors = {0.25, 0.7, 1}, iconWidth = 18, borderWidth = 2, highlightWidth = 2, TagSize = 8, maxAlertLevel = 3, numberFontObject = 'WorldPlanFont' } local MINIMIZED_STYLE = { hideNumber = true, hideIcon = true, iconWidth = 3, } local REWARD_TYPE_STYLES = { [REWARD_CASH] = { hideNumber = true, }, [REWARD_ARTIFACT_POWER] = {}, [REWARD_GEAR] = { hideNumber = true, }, [REWARD_CURRENCY] = { textColor = {1,1,0,.5} }, [REWARD_REAGENT] = { hideNumber = true, }, } local BORDER_SELECTED_BOUNTY = {1, 1, 0, 1 } local BORDER_CRITERIA = {.25, .5, 1, 1} local LE_ITEM_CLASS_WEAPON, LE_ITEM_CLASS_ARMOR, LE_ITEM_CLASS_GEM, LE_ITEM_GEM_ARTIFACTRELIC, LE_ITEM_CLASS_TRADEGOODS = LE_ITEM_CLASS_WEAPON, LE_ITEM_CLASS_ARMOR, LE_ITEM_CLASS_GEM, LE_ITEM_GEM_ARTIFACTRELIC, LE_ITEM_CLASS_TRADEGOODS local STYLE_TYPE_PENDING = 768 -- Pin color/display variables db.TooltipExtras = db.TooltipExtras or {} -- idiot-proofing db.PinAlpha = 1 local familiars = { [42159] = 'Nightwatcher Merayl', [40277] = 'Tiffany Nelson', [40298] = 'Sir Galveston', [40282] = 'Grixis Tinypop', [40278] = 'Robert Craig', [48195] = 'Aulier', [41990] = 'Varenne', [41860] = 'Xorvasc', [40299] = 'Bodhi Sunwayver', [42442] = 'Amalia', [40280] = 'Bredda Tenderhide', [41687] = 'Odrogg', [41944] = 'Trapper Jarrun', [40337] = 'Master Tamer Flummox', [40279] = 'Durian Strongfruit' } local falcosaurs = { [44895] = {44881, 'Sharptalon Hatchling', 115786}, [44894] = {44882, 'Bloodgazer Hatchling', 115787}, [44893] = {44880, 'Direbeak Hatchling', 115785}, [44892] = {44879, 'Snowfeather Hatchling', 115784}, } local familiars_id = 9696 for questID, name in pairs(familiars) do db.TooltipExtras[questID] = {{ achievementID = familiars_id, name = name }} end for questID, info in pairs(falcosaurs) do local trackingQuestID, petName, petID = unpack(info) db.TooltipExtras[questID] = {{ questID = trackingQuestID, pet = petName, petID = petID }} end do local timeStates = { {maxSeconds = 60, r=1, g=0.25, b =0, format = function (minutes) return '|cFFFF4400'.. minutes .. 'm' end, }, {maxSeconds = 240, r=1, g=.5, b=0, format = function(minutes) return '|cFFFF4400'.. floor(minutes/60) .. 'h' end, }, {maxSeconds = 1440, r=1, g=1, b=0, format = function(minutes) return '|cFFFFFF00'.. floor(minutes/60) .. 'h' end, }, {maxSeconds = 10081, r=0, g=1, b=0, }, -- 7 days + 1 minute } -- Generates a timeleft string function QuestPOI:GetTimeInfo(timeLeft, limit) for index = 1, limit do local state = timeStates[index] if timeLeft <= state.maxSeconds then local text if state.format then text = state.format(timeLeft) end return text, index, state end end return end end local GetAchievementTooltipExtras = function(info) local hasInfo local achievementID = info.achievementID local _, name, _, completed, _, _, _, _, _, icon = GetAchievementInfo(achievementID) if not completed then local numItems = GetAchievementNumCriteria(achievementID) local numNeeded = 0 local tooltipLines = {} for i =1, numItems do local criteriaName, criteriaType, completed, _, _, _, _, subAchievementID = GetAchievementCriteriaInfo(achievementID, i) --print(GetAchievementCriteriaInfo(achievementID, i)) if not completed then --print('::', criteriaName, completed, subAchievementID) if criteriaType == 8 then local _, _, _, completed, _, _, _, _, _, subIcon = GetAchievementInfo(subAchievementID) --print(' -', criteriaName, completed, subIcon) if not completed then local numCompleted = 0 local numSubItems = GetAchievementNumCriteria(subAchievementID) local subCriteriaLine for j = 1, numSubItems do local subName, _, completed = GetAchievementCriteriaInfo(subAchievementID, j) --print(' -',subName, completed) if completed then numCompleted = numCompleted + 1 else numNeeded = numNeeded + 1 if subName:match(info.name) then hasInfo = true subCriteriaLine = ' |T'..subIcon..':16:16|t ' .. criteriaName end end end if subCriteriaLine then tinsert(tooltipLines, subCriteriaLine .. ' ('..numCompleted..'/'..numSubItems..')') end end elseif criteriaName:match(info.name) and (not completed) then numNeeded = numNeeded + 1 tinsert(tooltipLines, criteriaName) end end end if hasInfo then WorldMapTooltip:AddLine(" ") WorldMapTooltip:AddLine("Achievements:") WorldMapTooltip:AddLine(' |T'..icon..':20:20|t '..name) for i, line in ipairs(tooltipLines) do WorldMapTooltip:AddLine(line) end end end return hasInfo end local GetQuestTooltipExtras = function(info) local questID = info.questID local hasInfo if info.pet then local index, guid = C_PetJournal.FindPetIDByName(info.pet) if not index then hasInfo = true WorldMapTooltip:AddLine('Pets:') WorldMapTooltip:AddLine(' - ' .. info.petName) if not IsQuestFlaggedCompleted(questID) then WorldMapTooltip:AddLine(' Required Quest Flags', 1, 1, 0) else WorldMapTooltip:AddLine(' Quest Flags Complete!', 0, 1, 0) end end end end function QuestPOI:OnLoad() --print('|cFF00FF88'..self:GetName()..':OnLoad()|r',db.Config) self.debugTimer = 4 self.title = '|cFF0088FF' .. RETRIEVING_DATA..'|r' self.count = self.Overlay.count self.timeLabel = self.Overlay.timeLabel self.Description = self.Overlay.Description self.updateRate = PIN_REQUEST_DELAY self.itemName = '|cFF0088FF' .. RETRIEVING_DATA..'|r' self.checkFilters = true self.checkCriteria = true self.checkCursor = true self.worldQuest = true self.isNew = true self.IconBackdrop:SetVertexColor(0,0,0,1) self.Overlay:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 4) self.Overlay:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, -4) end function QuestPOI:OnShow () if self.isStale then --print('|cFF00FF00refresh on show') self:Refresh('POI_ONSHOW_STALE') end if self.questID and IsQuestComplete(self.questID) then self:Release() return end self:RegisterEvent('QUEST_TURNED_IN') self:RegisterEvent('QUEST_LOG_UPDATE') self:HideOrShowFrames(true) end function QuestPOI:OnEvent(event, questID) if (self.questID == questID) and IsQuestComplete(self.questID) then db.log(event .. ' for ' .. self:GetName().. ' triggered.') self:Release() end end function QuestPOI:OnHide() --DEFAULT_CHAT_FRAME:AddMessage('|cFFFFFF00'..self:GetName()..'|r:OnHide()') self:HideOrShowFrames(false) -- reset flags self:SetAlpha(db.PinAlpha) self.isAnimating = nil --if db.Config.DebugEnabled then -- db.log(tostring(self.questID) .. ' ' .. tostring(self.title) .. "\n" .. tostring(REWARD_TYPE_NAMES[self.rewardType]) .. ' ' .. tostring(self.itemName) .. ' ' .. tostring(self.itemNumber) .. "\n|cFFFF4400" .. (self.hideReason or 'NO_MESSAGE') .. "|r\n|cFF00FFFF" .. debugstack(2,3,0) .. '|r') --end self.hideReason = nil end function QuestPOI:OnEnter() if self.filtered and (self.questID ~= GetSuperTrackedQuestID()) then return end WorldMap_HijackTooltip(self.owningFrame); self:SetFrameLevel(pinBaseIndex+100) self.Overlay:SetFrameLevel(overlayBaseIndex+100) if previousHighlight then previousHighlight:SetFrameLevel(pinBaseIndex+previousHighlight:GetID()) previousHighlight.Overlay:SetFrameLevel(overlayBaseIndex+previousHighlight:GetID()) end previousHighlight = self WorldMapTooltip:SetOwner(self, "ANCHOR_RIGHT"); --print('doing tooltip stuff') -- Can't add stuff after, so most of the blizzard tooltip hook is simply copied over local questID = self.questID local color = WORLD_QUEST_QUALITY_COLORS[self.rarity] or NORMAL_FONT_COLOR; WorldMapTooltip:SetText(self.title, color.r, color.g, color.b); QuestUtils_AddQuestTypeToTooltip(WorldMapTooltip, questID, NORMAL_FONT_COLOR); if ( self.factionID ) then local factionName = GetFactionInfoByID(self.factionID); if ( factionName ) then if (self.capped) then WorldMapTooltip:AddLine(factionName, GRAY_FONT_COLOR:GetRGB()); else WorldMapTooltip:AddLine(factionName); end end end if self.worldQuest then WorldMap_AddQuestTimeToTooltip(questID); end for objectiveIndex = 1, self.numObjectives do local objectiveText, objectiveType, finished = GetQuestObjectiveInfo(questID, objectiveIndex, false); if ( objectiveText and #objectiveText > 0 ) then local color = finished and GRAY_FONT_COLOR or HIGHLIGHT_FONT_COLOR; WorldMapTooltip:AddLine(QUEST_DASH .. objectiveText, color.r, color.g, color.b, true); end end local percent = C_TaskQuest.GetQuestProgressBarInfo(self.questID); if ( percent ) then GameTooltip_InsertFrame(WorldMapTooltip, WorldMapTaskTooltipStatusBar); WorldMapTaskTooltipStatusBar.Bar:SetValue(percent); WorldMapTaskTooltipStatusBar.Bar.Label:SetFormattedText(PERCENTAGE_STRING, percent); end if db.TooltipExtras[self.questID] then for index, info in pairs(db.TooltipExtras[questID]) do if info.achievementID then GetAchievementTooltipExtras(info) end if info.questID then GetQuestTooltipExtras(info) end end end GameTooltip_AddQuestRewardsToTooltip(WorldMapTooltip, questID) WorldMapTooltip:Show() --WorldMapTooltip.recalculatePadding = true; --print(WorldMapTooltip:GetParent()) --print(WorldMapTooltip:IsVisible()) end function QuestPOI:OnMouseDown(button) if button == 'RightButton' then local timers = db.IgnoreTimers if timers[self.questID] then timers[self.questID] = nil else local tl = TQ_GetQuestTimeLeftMinutes(self.questID) if tl and (tl ~= 0) then timers[self.questID] = time() + (tl * 60) else timers[self.questID] = 0 end end self:Refresh() else TaskPOI_OnClick(self, button) end end function QuestPOI:OnLeave() if self.filtered and (self.questID ~= GetSuperTrackedQuestID()) then return end WorldMap_RestoreTooltip() WorldMapTooltip:Hide(); end local updateTime, markTime function QuestPOI:OnUpdate (sinceLast) -- control update check intervals if self.toAlpha then if not self.alphaStart then self.alphaStart = GetTime() end local alpha = self.icon:GetAlpha() local alphaMod = ((GetTime()-self.alphaStart) *FADE_TIMING_MULTIPLIER) if alpha > self.toAlpha then alpha = alpha - (sinceLast*FADE_TIMING_MULTIPLIER) if (alpha <= self.toAlpha) then alpha = self.toAlpha self.toAlpha = nil elseif (alpha <= 0) then alpha = 0 self.toAlpha = nil end elseif alpha < self.toAlpha then alpha = alpha + alphaMod if (alpha >= self.toAlpha) then alpha = self.toAlpha self.toAlpha = nil elseif (alpha >= 1) then alpha = 1 self.toAlpha = nil end else self.toAlpha = nil end if not self.toAlpha then self.alphaStart = nil else self.alphaStart = GetTime() end self.icon:SetAlpha(alpha) self.RewardBorder:SetAlpha(alpha) end self.throttle = (self.throttle or self.updateRate) + sinceLast if self.throttle >= self.updateRate then -- factor overtime into the throttle timer self.throttle = self.throttle - self.updateRate else return end --@debug@ if DATA_DEBUG then self.debugTimer = self.debugTimer - sinceLast if self.debugTimer >= 0 then print(self.debugTimer) return end end --@end-debug@ -- query for reward data if it wasn't found in the original scan if not self.dataLoaded then local dataLoaded = self:GetData() if dataLoaded and not tContains(db.UpdatedPins, self) then -- self.PendingFade:Stop() -- scale info from the parent module is needed, so deal with it there print('|cFF00FF88 queueing for update') self.isNew = true tinsert(db.UpdatedPins, self) else --print('|cFFFF4400OnUpdate(|r'..self:GetID()..'|cFFFF4400)|r poll failed') end return end if self.isStale then self:Refresh() elseif self.maxAlertLevel then self:UpdateStatus() end end function QuestPOI:StartFading() if not self.toAlpha then print('setting toAlpha') self.toAlpha = 1 self.icon:SetAlpha(0) self.RewardBorder:SetAlpha(0) end end -- attempt to pull pin data function QuestPOI:GetData () --dprint('|cFF00FF88'..self:GetID()..':GetData()|r') local questID = self.questID if not questID then --dprint('|cFFFF4400bad pin|r', self:GetName()) return nil end local questTitle, factionID, capped = TQ_GetQuestInfoByQuestID(questID) -- if the title is nil, then wait and try later if not questTitle then --dprint('|cFFBB8844dataLoaded|r = false|cFF00FFFF', self.questId) return false else self.title, self.factionID, self.capped = questTitle, factionID, capped --print(questTitle, factionID, capped) -- set tag details local worldQuestType self.tagID, self.tagName, worldQuestType, self.rarity, self.isElite, self.tradeskillLineIndex = GetQuestTagInfo(questID); local tagAtlas if worldQuestType == LE_QUEST_TAG_TYPE_PET_BATTLE then tagAtlas = "worldquest-icon-petbattle" elseif worldQuestType == LE_QUEST_TAG_TYPE_PVP then tagAtlas = "worldquest-icon-pvp-ffa" elseif worldQuestType == LE_QUEST_TAG_TYPE_PROFESSION then self.isKnownProfession = nil local id = self.tradeskillLineIndex and select(7, GetProfessionInfo(self.tradeskillLineIndex)) if id then self.isKnownProfession = true --print('profession' , self.title, id) tagAtlas = WORLD_QUEST_ICONS_BY_PROFESSION[id] end elseif worldQuestType == LE_QUEST_TAG_TYPE_DUNGEON then tagAtlas = "worldquest-icon-dungeon" end self.worldQuestType = worldQuestType self.tagAtlas = tagAtlas local dataLoaded, rewardType, itemName, itemTexture, itemNumber, quality, xpType, xpName, xpIcon, xpCount = self:UpdateRewards() --dprint('|cFFBB8844 dataLoaded|r =', dataLoaded, rewardType, itemName, itemTexture, itemNumber, quality) if dataLoaded then self.rewardType = rewardType self.itemName = itemName self.itemTexture = itemTexture self.itemNumber = itemNumber self.itemQuality = quality self.dataLoaded = true self.isStale = true self.xpType, self.xpName, self.xpIcon, self.xpCount = xpType, xpName, xpIcon, xpCount WorldPlan.dataFlush = true end end return self.dataLoaded end local ID_RESOURCES = 1220 local ID_LEGIONFALL = 1342 --- Returns true if data has changed (either from loading in or qualifications changed) function QuestPOI:UpdateRewards() local questID = self.questID if not HaveQuestRewardData(questID) then C_TaskQuest.RequestPreloadRewardData(questID); return false; else local rewardMoney, rewardAP, rewardHonor local rewardItems, rewardCurrency = {}, {} local rewardIcon, rewardName, rewardCount, rewardStyle, rewardType, itemID, quantity, quality local xpIcon, xpName, xpCount, xpType local foundPrimary if (GetNumQuestLogRewardCurrencies(questID) > 0 or GetNumQuestLogRewards(questID) > 0 or GetQuestLogRewardMoney(questID) > 0 or GetQuestLogRewardArtifactXP(questID) > 0 or GetQuestLogRewardHonor(questID)) then local money = GetQuestLogRewardMoney(questID) if money > 0 then rewardMoney = money rewardIcon = ICON_MONEY rewardName = GetMoneyString(money) rewardCount = floor(money/10000) rewardType = REWARD_CASH end local artifactXP = GetQuestLogRewardArtifactXP(questID); if artifactXP > 0 then rewardAP = artifactXP rewardIcon = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" rewardCount = artifactXP rewardType = REWARD_ARTIFACT_POWER --dprint(' artifactXP', artifactXP) foundPrimary = true end local numQuestCurrencies = GetNumQuestLogRewardCurrencies(questID); for i = 1, numQuestCurrencies do local name, texture, numItems, currencyID = GetQuestLogRewardCurrencyInfo(i, questID); local text = BONUS_OBJECTIVE_REWARD_WITH_COUNT_FORMAT:format(texture, numItems, name); tinsert(rewardCurrency, { name = name, texture = texture, numItems = numItems, text = text }) --dprint(' currency', i, currencyID, name, " |T"..tostring(texture)..":12:12|t") if currencyID == ID_RESOURCES then rewardIcon = texture rewardCount = numItems rewardName = name rewardType = REWARD_CURRENCY foundPrimary = true elseif currencyID == ID_LEGIONFALL then xpIcon = texture xpCount = numItems xpName = name xpType = REWARD_CURRENCY end end local honorAmount = GetQuestLogRewardHonor(questID); if honorAmount > 0 then xpIcon = "Interface\\ICONS\\Achievement_LegionPVPTier4" xpCount = honorAmount xpName = HONOR xpType = HONOR_CURRENCY -- let items override end local numQuestRewards = GetNumQuestLogRewards(questID); if numQuestRewards > 0 then for i = 1, numQuestRewards do local name, texture, numItems, quality, isUsable, itemID = GetQuestLogRewardInfo(i, questID) if itemID then local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, sellPrice, classID, subclassID = GetItemInfo(itemID); if ( classID == LE_ITEM_CLASS_WEAPON or classID == LE_ITEM_CLASS_ARMOR or (classID == LE_ITEM_CLASS_GEM and subclassID == LE_ITEM_GEM_ARTIFACTRELIC) ) then rewardType = REWARD_GEAR rewardIcon = texture rewardName = name rewardCount = numItems foundPrimary = true elseif IsArtifactPowerItem(itemID) then rewardType = REWARD_ARTIFACT_POWER rewardIcon = texture rewardName = name rewardCount = self:UpdateArtifactPower(itemLink) foundPrimary = true --dprint('is an AP token') elseif classID == LE_ITEM_CLASS_TRADEGOODS then rewardType = REWARD_REAGENT rewardIcon = texture rewardName = name rewardCount = numItems foundPrimary = true end --dprint(' reward', i, name, " |T"..tostring(texture)..":12:12|t", quality, isUsable, itemID) tinsert(rewardItems, { name = name, texture = texture, numItems = numItems, quality = quality, isUsable = isUsable }) if not foundPrimary then --print(' -updating primary') rewardType = REWARD_REAGENT rewardIcon = texture rewardName = name rewardCount = numItems end end end end --dprint(' '..self.questID..':|cFFFFFF00UpdateRewards():', numQuestRewards, rewardType) --dprint(' ', tostring(self.title), " |T"..tostring(self.itemTexture)..":12:12|t", tostring(self.itemName)) if rewardType and ((self.itemNumber ~= rewardCount) or (self.rewardType ~= rewardType) or (self.itemName ~= rewardName) or (self.itemTexture ~= rewardIcon)) then if DATA_DEBUG and (self.debugTimer <= 0) then return false end return true, rewardType, rewardName, rewardIcon, rewardCount, quality, xpType, xpName, xpIcon, xpCount else return false end end end end function QuestPOI:UpdateArtifactPower(rewardLink) if not (rewardLink or self.rewardLink) then return end self.rewardLink = rewardLink or self.rewardLink local rewardCount WorldPlanTooltip:SetOwner(self, 'ANCHOR_NONE') WorldPlanTooltip:SetHyperlink(rewardLink or self.rewardLink) for i = 1, WorldPlanTooltip:NumLines() do local line = _G['WorldPlanTooltipTextLeft' .. i] local text = line and line:GetText() local multiplier = (text:match('million') and 1000000) or 1 if text then text = text:gsub(',', '') local ap = text:match('([%d]+) '..ARTIFACT_POWER) if not ap then ap = text:match('([%d%.]+) million '..ARTIFACT_POWER) if ap then ap = tonumber(ap) * 1000000 end end if ap then rewardCount = tonumber(ap) end end end return rewardCount end -- Applies position and sizing parameters to the pin data function QuestPOI:SetAnchor(owner, dX, dY, mapWidth, mapHeight, scaleFactor) --dprint(self:GetName()..':SetAnchor()', owner, dX, dY, scaleFactor, self.filtered, self.used) if not self.used then self.hideReason = 'SetAnchor() on an unused frame.' self:HideOrShowFrames(false) return end if owner then self:SetParent(owner) self.Overlay:SetParent(owner) self:SetFrameStrata('HIGH') self:SetFrameLevel(pinBaseIndex + self:GetID()) self.Overlay:SetFrameStrata('HIGH') self.Overlay:SetFrameLevel(overlayBaseIndex + self:GetID()) self.isStale = true else owner = self:GetParent() end if scaleFactor then print('scaleFactor') self:SetScale(scaleFactor) self.Overlay:SetScale(scaleFactor) self.scaleFactor = scaleFactor end mapWidth = mapWidth or owner:GetWidth() mapHeight = mapHeight or owner:GetHeight() dX = dX or self.x dY = dY or self.y --print(owner:GetName() or tostring(owner), self:GetName(), owner:GetScale(), scaleFactor) if (self.x ~= dX) or (self.y ~= dY) or scaleFactor then self.x = dX self.y = dY local pX = (dX * mapWidth) * (1 / scaleFactor) local pY = (-dY * mapHeight) * (1 / scaleFactor) --print('to', pX, pY, self:GetScale()) self:ClearAllPoints() self:SetPoint('CENTER', owner, 'TOPLEFT', pX, pY) end end -- Non-hieriarchical display states, checked separately from used/filtered states function QuestPOI:OnCriteria() self.checkCriteria = nil local isCriteria, isBounty, isSpellTarget print('|cFFFFFF00OnCriteria(' ..self:GetID() .. ')' ) for index, bounty in pairs(db.Bounties) do if (not IsQuestComplete(bounty.questID)) and IsQuestCriteriaForBounty(self.questID, bounty.questID) then isCriteria = true if db.selectedBounty == bounty then isBounty = true end --dprint('|cFF00FF88Criteria:|r', self.questID, bounty.questID, isCriteria, isBounty) end end if (self.isBounty ~= isBounty) or (self.isCriteria ~= isCriteria) then --wqprint('|cFF00FF00criteria state changed') self.isBounty = isBounty self.isCriteria = isCriteria self.isSpellTarget = isSpellTarget end end function QuestPOI:OnCursor() self.checkCursor = nil self.isSpellTarget = IsQuestIDValidSpellTarget(self.questID) end local cvar_check = { [REWARD_CASH] = 'worldQuestFilterGold', [REWARD_ARTIFACT_POWER] = 'worldQuestFilterArtifactPower', [REWARD_CURRENCY] = 'worldQuestFilterOrderResources', [REWARD_REAGENT]= 'worldQuestFilterProfessionMaterials', [REWARD_GEAR] = 'worldQuestFilterEquipment', } function QuestPOI:OnFilters () local qType = self.worldQuestType self.canShow = false self.checkFilters = nil if not TQ_IsActive(self.questID) then self.hideReason = 'Filter check ended because quest is inactive.' self.used = nil self:SetShown(false) return end if qType == LE_QUEST_TAG_TYPE_PROFESSION then if not(self.isKnownProfession or db.Config.ShowAllProfessionQuests) then self.hideReason = 'Failed profession check.' self.used = nil self:SetShown(false) return end end local filtered for filterKey, value in pairs(db.UsedFilters) do if self[filterKey] ~= value then if not self.filtered then print('|cFFFF4400filtering', filterKey, value, '~=', self[filterKey], self.title) end filtered = true end end if self.rewardType and cvar_check[self.rewardType] then if not GetCVarBool(cvar_check[self.rewardType]) then filtered = true end end print(' '..self.questID..':|cFFFFFF00OnFilters()|r', filtered, self.title) if self.filtered ~= filtered then wqprint('|cFF00FF00filter changed') self.isStale = true end self.canShow = true self.filtered = filtered end function QuestPOI:Refresh (event) print('|cFF00FF88Refresh(|r'..self:GetID()..'|cFF00FF88)|r', event, self.title) if not self:IsShown() then print('queued for Refresh') self.isStale = true return nil elseif IsQuestComplete(self.questID) then self:Release() return nil end if self.checkCriteria then self:OnCriteria() end if self.checkFilters then self:OnFilters() end if self.checkCursor then self:OnCursor() end local style = DEFAULT_STYLE if self.filtered or db.IgnoreTimers[self.questID] then print('choose minimized') style = MINIMIZED_STYLE elseif self.dataLoaded then print('choose reward type') style = REWARD_TYPE_STYLES[self.rewardType] else print('choose default') end local currentWidth = style.iconWidth or DEFAULT_STYLE.iconWidth local borderWidth = style.borderWidth or DEFAULT_STYLE.borderWidth local highlightWidth = style.highlightWidth or DEFAULT_STYLE.highlightWidth local tagSize = style.TagSize or DEFAULT_STYLE.TagSize local hideIcon = style.hideIcon or DEFAULT_STYLE.hideIcon local borderColor = style.border or DEFAULT_STYLE.border local textColor = style.textColor or DEFAULT_STYLE.textColor local questID = self.questID local iconBorder = self.RewardBorder local trackingBorder = self.HighlightBorder local icon = self.icon local count = self.count local hideNumbers = style.hideNumber or DEFAULT_STYLE.hideNumber local tagIcon = self.tagIcon self.maxAlertLevel = style.maxAlertLevel or DEFAULT_STYLE.maxAlertLevel if self.dataLoaded then if self.isNew then print('new pin, has data, cue fade') self:StartFading() self.isNew = nil end else if not self.toAlpha then icon:SetAlpha(0) iconBorder:SetAlpha(0) end end if self.itemName then if self.itemNumber and (self.itemNumber > 1) and (not hideNumbers) then local numberString = self.itemNumber if self.itemNumber >= 1000000 then numberString = (floor(self.itemNumber/100000)/10) .. 'M' elseif self.itemNumber >= 10000 then numberString = floor(self.itemNumber/1000) .. 'k' elseif self.itemNumber >= 1000 then local numeral = floor(self.itemNumber/1000) local decimal = mod(self.itemNumber, 1000) numberString = numeral if decimal > 100 then numberString = numberString .. '.' .. tostring(floor(decimal/100)) end numberString = numberString .. 'k' end self.count:SetText(numberString) self.count:SetTextColor(unpack(textColor)) self.count:Show() else self.count:SetText(nil) self.count:Hide() end else self.count:Hide() end if db.Config.ShowVerboseInfo then self.Description:SetText(self.title .. "\n" .. floor(self.x*100+.5) .. "," .. floor(self.y*100+.5)) end icon:SetSize(currentWidth, currentWidth) icon:SetMask(style.iconMask or DEFAULT_STYLE.iconMask) if self.itemTexture then --iconBorder:SetTexture(WORLD_QUEST_BORDER) if hideIcon then icon:SetTexture(PENDING_ICON) icon:SetDesaturated(true) icon:SetVertexColor(unpack(borderColor)) else icon:SetTexture(self.itemTexture) icon:SetDesaturated(false) icon:SetVertexColor(1, 1, 1) end else -- --icon:SetTexture(PENDING_ICON) --icon:SetDesaturated(true) --icon:SetVertexColor(unpack(borderColor)) end local borderMask = style.borderMask or DEFAULT_STYLE.borderMask local borderSize = currentWidth + (borderWidth * 2) + (self.isCriteria and 2 or 0) iconBorder:SetSize(borderSize, borderSize) iconBorder:SetMask(borderMask) iconBorder:SetTexture(PENDING_BORDER) iconBorder:SetDesaturated(true) local highlightSize = borderSize + (highlightWidth * 2) trackingBorder:SetSize(highlightSize, highlightSize) trackingBorder:SetMask(borderMask) trackingBorder:SetTexture(PENDING_BORDER) self:SetSize(borderSize, borderSize) self.IconBackdrop:SetSize(currentWidth, currentWidth) iconBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) trackingBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) self.tagIcon:SetShown((not self.filtered) and true or false) self.tagIcon:SetAtlas(self.tagAtlas) self.EliteBorder:SetShown(self.isElite and not self.filtered) if self.isBounty then print('is bounty') iconBorder:SetVertexColor(trackingBorder:GetVertexColor()) trackingBorder:SetVertexColor(unpack(BORDER_SELECTED_BOUNTY)) elseif self.isCriteria then print('is criteria of a bounty') iconBorder:SetVertexColor(trackingBorder:GetVertexColor()) trackingBorder:SetVertexColor(unpack(BORDER_CRITERIA)) else print('is nothing') iconBorder:SetVertexColor(unpack(borderColor)) trackingBorder:SetVertexColor(0,0,0,.5) end self:UpdateStatus() if SpellCanTargetQuest() then if self.isSpellTarget then icon:SetVertexColor(1,1,1) self:EnableMouse(false) else icon:SetVertexColor(0.5,0.5,0.5,1) self:EnableMouse(true) end else icon:SetVertexColor(1,1,1) self:EnableMouse(true) end self.isStale = nil -- signal filter info update WorldPlanSummary.isStale = true return true end -- Called at static intervals and with Refresh function QuestPOI:UpdateStatus() -- update time elements self.isActive = TQ_IsActive(self.questID) --print(self.maxAlertLevel) local border = (self.isBounty or self.isCriteria) and self.RewardBorder or self.HighlightBorder if self.isActive then local tl = self.alertLevel local timeLeft = TQ_GetQuestTimeLeftMinutes(self.questID) if timeLeft > 0 then local text, timeState, style = self:GetTimeInfo(timeLeft, self.maxAlertLevel) if tl ~= timeState then tl = timeState self.timeLabel:SetText(text) end end self.alertLevel = tl self.timeLabel:SetShown(self.worldQuest and (self.maxAlertLevel >= 1)) else self.hideReason = "No longer active." self:HideOrShowFrames(false) end end -- Show/Hide the text overlays associated with the quest pin; they aren't hierarchically linked function QuestPOI:HideOrShowFrames(isShown) if not isShown then -- print('|cFFFFFF00' ..self:GetName()..':HideOrShowFrames()') -- do not SetShown() here if not self.hideReason then self.hideReason = "HideOrShowFrames() called without a reason." end end self.Overlay:SetShown(isShown) self.count:SetShown(isShown) self.timeLabel:SetShown(isShown) end function QuestPOI:Release(msg) print('|cFFFF4400Release('..self:GetID()..')', self.hideReason) self.hideReason = msg or 'Released by script.' self:ClearAllPoints() self:SetShown(false) self:HideOrShowFrames(false) if self.questID then db.QuestsByID[self.questID] = nil for _, map in pairs(db.QuestsByZone) do map[self.questID] = nil end self.questID = nil end self.isActive = nil self.complete = nil self.used = nil self.dataLoaded = nil self.rewardType = nil self.itemTexture = nil self.itemName = nil self.itemNumber = nil self.animating = nil self.icon:SetAlpha(0) self.RewardBorder:SetAlpha(0) self:UnregisterEvent('QUEST_TURNED_IN') self:UnregisterEvent('QUEST_LOG_UPDATE') self.checkCursor = true self.checkFilters = true self.checkCriteria = true for i, pin in ipairs(db.UsedPins) do if pin == self then print('|cFFFF4400cleared from UsedPins|r') tremove(db.UsedPins, i) break end end tinsert(db.FreePins, self) WorldPlan.dataFlush = true WorldPlanSummary.isStale = true return true end