Mercurial > wow > worldplan
changeset 93:98b5e08b75ed v1.4.9
- Fixed quest completion checking and handling
- Changed animation method to hopefully stop weird flickering.
- Pins are now visible before full reward data is loaded
- Filter bar redesigned:
- aligned horizontally along the top of the map display
- filter buttons display a '+' when there are matches in both current and other zones, and '*' when there only matches in other zones
- button tooltips separate local and global quests
- button categories are highlighted and labeled when the cursor is over them
- Fixed invalid POI targets appearing when the spell targeting cursor is active
author | Nenue |
---|---|
date | Sat, 15 Apr 2017 11:04:54 -0400 |
parents | df725cba1a6a |
children | dfd53f7c0fe5 |
files | FilterBar.lua FilterBar.xml FlightMap.lua QuestPOI.lua WorldPlan.lua WorldPlan.xml WorldQuests.lua WorldQuests.xml |
diffstat | 8 files changed, 1186 insertions(+), 960 deletions(-) [+] |
line wrap: on
line diff
--- a/FilterBar.lua Tue Apr 11 00:44:22 2017 -0400 +++ b/FilterBar.lua Sat Apr 15 11:04:54 2017 -0400 @@ -15,11 +15,26 @@ local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS +local filtersUsed +local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64" +local filterMask = "Interface\\Minimap\\UI-Minimap-Background" + +local HEADERS_SPACING = 3 +local BUTTONS_SPACING = 1 +local BUTTONS_HEIGHT = 20 +local TOGGLE_SIZE = 20 +local HEADERS_HEIGHT = 40 + 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 barMouseOver +local filtersDirty = true +local layoutDirty = true +local matchesDirty -- don't flag until first filter loadout + local familiars = { [42159] = {npc = 106552, name = 'Nightwatcher Merayl'}, [40277] = {npc = 97804, name = 'Tiffany Nelson'}, @@ -49,8 +64,15 @@ showNumber = true, numberFontObject = 'WorldPlanNumberFontThin' } + +local headerNames = { + ['rewardType'] = 'Reward Type', + ['worldQuestType'] = 'Quest Type', + ['isElite'] = 'Elite', + ['factionID'] = 'Bounties' +} + db.DefaultFilters = { - { label = 'Filters', texture = "Interface\\WorldMap\\WorldMap-Icon" }, { filterKey= 'rewardType', cVar = 'worldQuestFilterArtifactPower', filterValue = REWARD_ARTIFACT_POWER, label = 'Artifact Power', texture = "Interface\\ICONS\\inv_7xp_inscription_talenttome01" }, { filterKey= 'rewardType', cVar = 'worldQuestFilterOrderResources', filterValue = REWARD_CURRENCY,label = 'Order Resources', texture = "Interface\\Icons\\inv_orderhall_orderresources" }, { filterKey= 'rewardType', cVar = 'worldQuestFilterEquipment', filterValue = REWARD_GEAR, label = 'Equipment', texture = "Interface\\ICONS\\garrison_bluearmorupgrade" }, @@ -58,8 +80,10 @@ { filterKey= 'rewardType', cVar = 'worldQuestFilterGold', filterValue = REWARD_CASH, label = 'Gold', texture = "Interface\\Buttons\\UI-GroupLoot-Coin-Up" }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PVP, label = 'PvP', texture = "Interface\\Icons\\Ability_PVP_GladiatorMedallion", spacing = 10 }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PET_BATTLE, label = 'Pet Battle', texture = "Interface\\Icons\\PetJournalPortrait", }, - { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, + { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_DUNGEON, label = 'Dungeon', texture = "Interface\\LFGFRAME\\BattlenetWorking0", }, { filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\ICONS\\70_professions_scroll_02", }, + --{ filterKey = 'isElite', filterValue = true, label = 'Elite', texture = "", desaturated = false}, + --{ filterKey = 'isElite', filterValue = false, label = 'Not-Elite', texture = "", desaturated = false}, } local defaults = {} @@ -68,15 +92,14 @@ Module.selectedBountyIndex = {} Module.bounties = {} Module.filterList = {} -Module.buttons = {} +Module.Buttons = {} +Module.Headers = {} Module.cvarFiltersDirty = false -WorldPlanFilterPinMixin = {} -local Pin = WorldPlanFilterPinMixin +WorldPlanFilterButtonMixin = {} +local Pin = WorldPlanFilterButtonMixin function Module:OnLoad() - self:SetParent(WorldMapFrame.UIElementsFrame) - self:ClearAllPoints() - self:SetPoint('TOPRIGHT') + --self:SetParent(WorldMapFrame.UIElementsFrame) WorldPlan:AddHandler(self) --[[for index, info in ipairs(db.DefaultFilters) do info.zone = db.DefaultFilterType @@ -85,37 +108,65 @@ WorldPlan:AddTypeInfo(self,index, info) end --]] + + end function Module:OnEvent(event, arg) print('|cFF00FF88'..self:GetName()..':OnEvent()', event) if (event == 'QUEST_LOG_UPDATE') and arg then - if db.QuestsByID[arg] then - if db.QuestsByID[arg].factionID then - - end - end + filtersDirty = true + self:Refresh() end - - self.isStale = true end local bountyIndex local debug_headers = {} - +local ToggleButton = {} function Module:Setup() print('|cFF00FF88'..self:GetName()..':Setup()') self.isStale = true - self:SetShown(true) + self:SetParent(WorldMapFrame.UIElementsFrame) + --self:SetPoint('BOTTOMLEFT') + for k,v in pairs( ToggleButton) do + self.Toggle:SetScript(k,v) + end + self.Toggle:SetSize(TOGGLE_SIZE, TOGGLE_SIZE) + end -function Module:OnUpdate() +function Module:OnUpdate(sinceLast) if self.isStale then - wprint('|cFF00FF00pushing update') + print('|cFF00FF00pushing update') self:Refresh() end + + barMouseOver = self:IsMouseOver() + if barMouseOver or filtersUsed then + + self.toAlpha = 1 + self.Backdrop:Show() + else + self.toAlpha = 0.25 + self.Backdrop:Hide() + end + local cAlpha = self:GetAlpha() + if cAlpha ~= self.toAlpha then + if cAlpha > self.toAlpha then + cAlpha = cAlpha - sinceLast*4 + if cAlpha <= self.toAlpha then + cAlpha = self.toAlpha + end + else + cAlpha = cAlpha + sinceLast*4 + if cAlpha >= self.toAlpha then + cAlpha = self.toAlpha + end + end + end + self:SetAlpha(cAlpha) end function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen) @@ -123,72 +174,142 @@ if not isBrokenIsle then self:SetShown(false) else - if self:IsShown() then + self:SetShown(true) + if isMapOpen then self:Refresh() + else + matchesDirty = true + layoutDirty = true end - self:SetShown(true) end end function Module:OnShow() print('|cFF00FF88'..self:GetName()..':OnShow()') - if self.isStale then - self:Refresh() + self:Refresh() +end + +local IsBountyCriteria = function(poiFrame, questID) + return IsQuestCriteriaForBounty(poiFrame.questID, questID) +end + +local tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID = tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID + +function Module:OnConfigUpdate() + + ToggleButton.OnShow(self.Toggle) +end + +function Module:Reset() + self:UpdateFilters('SUMMARY_RESET') + self:UpdateMatches('SUMMARY_RESET') + self:UpdateLayout('SUMMARY_RESET') +end + +function Module:Refresh() + self:UpdateFilters('SUMMARY_REFRESH') + self:UpdateMatches('SUMMARY_REFRESH') + self:UpdateLayout('SUMMARY_REFRESH') +end + +local questResults = {{} } +db.FilterList = {} + +function Module:UpdateFilters(event) + + print('|cFF00FFFF'..self:GetName()..':GetFilters()', event) + + wipe(db.FilterList) + + for index, info in ipairs(db.DefaultFilters) do + tinsert(db.FilterList, info) + end + self.bounties = db.Bounties + self.BountyFilters = {} + for index, data in ipairs(self.bounties) do + if not IsQuestComplete(data.questID) then + + local info = self.BountyFilters[index] + if not info then + info = {} + self.BountyFilters[index] = info + layoutDirty = true + else + if info.questID ~= data.questID then + layoutDirty = true + end + end + + local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID)) + info.filterKey = 'factionID' + info.filterFunc = IsBountyCriteria + info.filterValue = data.questID + info.label = questTitle + info.texture = data.icon + print('loading emissary', questTitle) + + tinsert(db.FilterList, info) + --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, + end + end end -local tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID = tinsert, GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID -function Module:GetFilters() +function Module:UpdateMatches(event) + print('|cFF00FF00UpdateMatches()', event) + local quests = db.QuestsByID + local questsForMap = db.QuestsByZone[db.currentMapID] or quests - print('|cFF00FFFF'..self:GetName()..':GetFilters()') + for index, info in ipairs(db.FilterList) do + info.GlobalMatches = info.GlobalMatches or {} + info.LocalMatches = info.LocalMatches or {} + wipe(info.GlobalMatches) + wipe(info.LocalMatches) + print(info.filterKey, info.filterValue, info.filterFunc and 'func test' or 'compare') + for questID, pin in pairs(quests) do + print('', questID, pin.dataLoaded, (not IsQuestComplete(questID))) + if pin.dataLoaded and not IsQuestComplete(questID) then - wipe(self.filterList) + local keyName, keyValue = info.filterKey, info.filterValue + local isMatch + if info.filterFunc then - for index, info in ipairs(db.DefaultFilters) do - tinsert(self.filterList, info) - end - self.bounties, self.numBounties = GetQuestBountyInfoForMapID(db.currentMapID) - self.BountyFilters = {} - for index, data in ipairs(self.bounties) do - local info = self.BountyFilters[index] - if not info then - info = {} - self.BountyFilters[index] = info + isMatch = info.filterFunc(pin, keyValue) + print(' running special function, result =', isMatch) + + elseif pin[keyName] and (pin[keyName] == keyValue) then + isMatch = true + print(' rote match') + end + if isMatch then + tinsert(info.GlobalMatches, pin) + if questsForMap[questID] then + print(' local map') + tinsert(info.LocalMatches, pin) + end + + end + end + end - - local questTitle = GetQuestLogTitle(GetQuestLogIndexByID(data.questID)) - - info.filterKey = 'factionID' - info.filterValue = data.factionID - info.label = questTitle - info.texture = data.icon - print('loading emissary', questTitle) - - tinsert(self.filterList, info) - --{ filterKey= 'worldQuestType', filterValue = LE_QUEST_TAG_TYPE_PROFESSION, label = 'Profession', texture = "Interface\\LFGFRAME\\UI-LFR-PORTRAIT", }, + print('global', #info.GlobalMatches, 'local', #info.LocalMatches) end end -function Module:Reset() - self:GetFilters() -end +function Module:UpdateLayout(event) + print('|cFF00FF88UpdateLayout()|r', event, 'currentMap=',db.currentMapID) -function Module:Refresh() - self:GetFilters() - self:Update() -end + self.filtersSelected = nil -local filterFill = "Interface\\BUTTONS\\YELLOWORANGE64" -local filterMask = "Interface\\Minimap\\UI-Minimap-Background" + local currentHeader + local relativeFrame = self + local lastKey -local questResults = {{}} -function Module:Update() - local blocks = self.buttons + local numHeaders = 0 + local numButtons = 0 - local relativeFrame = self - - local numHeaders = 0 - print('|cFF00FF88'..self:GetName()..':Update()|r', 'currentMap=',db.currentMapID) + local layoutWidth = TOGGLE_SIZE + HEADERS_SPACING * 2 + local headerWidth = HEADERS_SPACING local layout = db.DefaultFilterType @@ -201,104 +322,140 @@ end print(n, 'pins to work with') + + filtersUsed = nil local firstCvar, lastCvar - for index, info in ipairs(self.filterList) do - local numQuestsHere = 0 - local numQuestsTotal = 0 - info.questList = info.questList or {} - wipe(info.questList) - print(info.filterKey, info.filterValue) + local isFirst = true + for index, info in ipairs(db.FilterList) do + --print('num here', numQuestsHere, numQuestsTotal) - for questID, pin in pairs(db.QuestsByID) do - --print(pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION, (db.Config.ShowAllProfessionQuests or pin.isKnownProfession)) - if pin.used then - - print(pin.title, mapQuests[questID]) - if (pin.worldQuestType ~= LE_QUEST_TAG_TYPE_PROFESSION) or (db.Config.ShowAllProfessionQuests or pin.isKnownProfession) then - - if not info.filterKey then - if mapQuests[questID] then - numQuestsHere = numQuestsHere + 1 - end - numQuestsTotal = numQuestsTotal + 1 - elseif pin[info.filterKey] == info.filterValue then - if mapQuests[questID] then - numQuestsHere = numQuestsHere + 1 - tinsert(info.questList, pin) - end - numQuestsTotal = numQuestsTotal + 1 - end - end - end - - end - --print('num here', numQuestsHere, numQuestsTotal) - info.totalQuests = numQuestsTotal --print(tostring(index).. ' ("'..tostring(info.label)..'" f('.. tostring(info.filterKey).. '='..tostring(info.filterValue) .. '), '..tostring(numQuests)..')') - if numQuestsTotal >= 1 then - numHeaders = numHeaders + 1 - local button = blocks[numHeaders] - if not blocks[numHeaders] then - button = CreateFrame('Button', 'WorldPlanFilterButton'..numHeaders, self, 'WorldPlanFilterPin') - button:SetSize(32,20) - button.icon:SetTexCoord(0.1,.9,.1,(1 * (20/32))) + if #info.GlobalMatches >= 1 then + if info.filterKey ~= lastKey then + + numHeaders = numHeaders + 1 + local nextHeader = self.Headers[numHeaders] or CreateFrame('Frame', 'FilterHeader' .. numHeaders, self, 'WorldPlanFilterHeader') + if currentHeader then + nextHeader:SetPoint('TOPLEFT', currentHeader, 'TOPRIGHT', 0, 0) + + currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT) + layoutWidth = layoutWidth + headerWidth + headerWidth = HEADERS_SPACING + else + nextHeader:SetPoint('TOPLEFT', TOGGLE_SIZE + HEADERS_SPACING * 2, 0) + + end + + print(' begin header '..numHeaders, 'layout width =', floor(layoutWidth+.5)) + isFirst = true + currentHeader = nextHeader + currentHeader.Backdrop:SetHeight(BUTTONS_HEIGHT *2) + currentHeader.Label:SetText(headerNames[info.filterKey]) + relativeFrame = currentHeader + end + + numButtons = numButtons + 1 + local button = self.Buttons[numButtons] + if not button then + button = CreateFrame('Button', 'FilterButton'..numButtons, self, 'WorldPlanFilterButton') + button:SetSize(32,BUTTONS_HEIGHT) + button.icon:SetTexCoord(0.1,.9,.1,(1 * (BUTTONS_HEIGHT/32))) button.RewardBorder:ClearAllPoints() button.RewardBorder:SetPoint('TOPLEFT', button, 'TOPLEFT') button.RewardBorder:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT') - - - blocks[numHeaders] = button end button.info = info - button.numQuestsTotal = numQuestsTotal - button.numQuestsHere = numQuestsHere - button.questList = info.questList - button.isFirst = (numHeaders == 1) + button.numQuestsTotal = #info.GlobalMatches + button.numQuestsHere = #info.LocalMatches + button.GlobalMatches = info.GlobalMatches + button.LocalMatches = info.LocalMatches + button.isFirst = isFirst button:SetID(index) - button.spacing = ((relativeFrame.cVar and (not info.cVar)) or (relativeFrame.filterKey ~= info.filterKey)) and 5 or 1 + button:SetParent(currentHeader) button.relativeFrame = relativeFrame button:Refresh() button:Show() relativeFrame = button + headerWidth = headerWidth + button:GetWidth() + BUTTONS_SPACING + isFirst = false if info.cVar then firstCvar = firstCvar or button lastCvar = button end - + lastKey = info.filterKey end end self.numHeaders = numHeaders - for i = numHeaders + 1, #blocks do - if blocks[i] then - blocks[i]:Hide() - wipe(blocks[i].questList) + for i = numButtons + 1, #self.Buttons do + if self.Buttons[i] then + self.Buttons[i]:Hide() + wipe(self.Buttons[i].LocalMatches) + wipe(self.Buttons[i].GlobalMatches) + end + end + for i = numHeaders + 1, #self.Headers do + if self.Headers[i] then + self.Headers[i]:Hide() end end + if currentHeader then + currentHeader:SetSize(headerWidth - BUTTONS_SPACING + HEADERS_SPACING, HEADERS_HEIGHT) + layoutWidth = layoutWidth + headerWidth + HEADERS_SPACING + end + self:SetSize(layoutWidth, BUTTONS_HEIGHT + BUTTONS_SPACING * 2) + self:ClearAllPoints() + self:SetPoint('TOP') self.isStale = nil + layoutDirty = nil end function Module:Cleanup() -- hide trailing buttons end -local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF'} +local rgbWhite = {r = 1, g= 1, b= 1, hex = '|cFFFFFFFF' } +local found = {} function Pin:OnEnter() - if #self.questList >= 1 then - GameTooltip:SetOwner(self, 'ANCHOR_LEFT') + if #self.GlobalMatches >= 1 then + GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') GameTooltip:AddLine(self.info.label) - for index, pin in ipairs(self.questList) do - local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite - GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), colorInfo.r, colorInfo.g, colorInfo.b) + wipe(found) + + if self.numQuestsHere >= 1 then + if self.numQuestsHere < self.numQuestsTotal then + GameTooltip:AddLine('This Zone', 1, 1, 0) + end + for index, pin in ipairs(self.LocalMatches) do + local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite + found[pin] = pin + GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 0, 1, 0) + end end + + if self.numQuestsHere < self.numQuestsTotal then + if self.numQuestsHere >= 1 then + GameTooltip:AddLine(' ') + end + GameTooltip:AddLine('Other Maps', 1, 1, 0) + for index, pin in ipairs(self.GlobalMatches) do + if not found[pin] then + local colorInfo = (pin.quality and ITEM_QUALITY_COLORS[pin.quality]) or rgbWhite + found[pin] = pin + GameTooltip:AddLine('|T'.. tostring(pin.itemTexture)..':16:16|t ' .. tostring(pin.title) ..(pin.cheevos and " |cFFFFFF00!|R" or ''), 1, 1, 1) + end + end + end + + GameTooltip:AddLine(self.numQuestsTotal .. ' total') GameTooltip:Show() end @@ -317,46 +474,58 @@ self.tagID = info.tagID self.icon:SetTexture(info.texture) - self.count:SetText(self.numQuestsHere) + + if (self.numQuestsHere == 0) and (self.numQuestsTotal >= 1) then + self.count:SetText('*'..self.numQuestsTotal) + self.count:SetTextColor(0,1,1) + elseif self.numQuestsHere < self.numQuestsTotal then + self.count:SetText(self.numQuestsHere..'+') + self.count:SetTextColor(1,1,0) + else + self.count:SetText(self.numQuestsHere) + self.count:SetTextColor(1,1,1) + end + self.cVar = info.cVar - self.itemTexture = self.texture self:ClearAllPoints() if self.isFirst then - self:SetPoint('TOPRIGHT', self.relativeFrame, 'TOPRIGHT', -5, -42) + self:SetPoint('TOPLEFT', self.relativeFrame, 'TOPLEFT', HEADERS_SPACING, -HEADERS_SPACING) else - self:SetPoint('TOPLEFT', self.relativeFrame, 'BOTTOMLEFT', 0, -(self.spacing or 0)) + self:SetPoint('LEFT', self.relativeFrame, 'RIGHT', BUTTONS_SPACING, 0) end - print('anchor', self.relativeFrame:IsShown(), self:GetPoint(1)) + --print('anchor', self.relativeFrame:IsShown(), self:GetPoint(1)) self.icon:SetDesaturated(self.numQuestsHere == 0) local r, g, b, a = 0,0,0,1 local desaturated = false - if (self.numQuestsHere > 0) then + if (self.numQuestsHere > 0) or db.UsedFilters[self.filterKey] then + if self.cVar then if GetCVarBool(self.cVar) then - self.count:SetTextColor(1,1,1) + --self.count:SetTextColor(1,1,1) r,g,b,a = 0, 0, 0, 1 else - self:GetParent().cvarFiltersDirty = true - self.count:SetTextColor(1,0,0) + filtersUsed = true + --self.count:SetTextColor(1,0,0) self.icon:SetDesaturated(true) r,g,b,a = 1, 0, 0, 0.5 end else if db.UsedFilters[self.filterKey] then + filtersUsed = true if db.UsedFilters[self.filterKey] == self.filterValue then - self.count:SetTextColor(0,1,0) + --self.count:SetTextColor(0,1,0) r, g, b = 0, 1, 0 else - self.count:SetTextColor(1,0,0) + --self.count:SetTextColor(1,0,0) r, g, b = 1, 0, 0 end else - self.count:SetTextColor(1,1,1) + --self.count:SetTextColor(1,1,1) if self.filterKey == 'worldQuestType' then r, g, b = 0, 0, 1 elseif self.filterKey == 'factionID' then @@ -375,12 +544,19 @@ self:RegisterForClicks('AnyUp') self:SetFrameStrata('HIGH') self:SetFrameLevel(151) - self:SetScript('OnUpdate', nil) self.questList = {} -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level end function Pin:OnUpdate () + local group = self:GetParent() + if group:IsMouseOver() and barMouseOver then + group.Backdrop:Show() + group.Label:Show() + else + group.Backdrop:Hide() + group.Label:Hide() + end end -- shift-click: reset filter @@ -436,8 +612,8 @@ -- check the visible filters and consider it clean if they're all lit parent.cvarFiltersDirty = false - for i, info in ipairs(parent.filterList) do - if info.cVar and (#info.questList >= 1) then + for i, info in ipairs(db.FilterList) do + if info.cVar and (#info.GlobalMatches >= 1) then print(info.cVar, GetCVarBool(info.cVar)) if GetCVarBool(info.cVar) == false then parent.cvarFiltersDirty = true @@ -475,4 +651,30 @@ --WorldPlan:print('Setting filter(s):', table.concat(filtered_report, ', ')) end WorldPlan:Refresh(true) +end +function ToggleButton:OnEnter() + + GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT') + GameTooltip:AddLine('Toggle Pins') + GameTooltip:Show() +end +function ToggleButton:OnLeave() + + if GameTooltip:IsOwned(self) then + GameTooltip:Hide() + end +end +function ToggleButton:OnShow() + self:SetChecked(db.Config.EnablePins and true or false) +end +function ToggleButton:OnHide() + if GameTooltip:IsOwned(self) then + GameTooltip:Hide() + end + +end +function ToggleButton:OnClick() + --print(self:GetChecked()) + db.Config.EnablePins = self:GetChecked() + _G.WorldPlan:OnConfigUpdate() end \ No newline at end of file
--- a/FilterBar.xml Tue Apr 11 00:44:22 2017 -0400 +++ b/FilterBar.xml Sat Apr 15 11:04:54 2017 -0400 @@ -1,17 +1,113 @@ <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="FilterBar.lua" /> - <Frame name="$parentSummary" parent="WorldPlan" mixin="WorldPlanSummaryMixin"> + <Frame name="$parentSummary" parent="WorldPlan" mixin="WorldPlanSummaryMixin" hidden="true"> + <Size x="24" y="24" /> + <Anchors> + <Anchor point="BOTTOMLEFT" /> + </Anchors> <Scripts> <OnLoad method="OnLoad" /> <OnEvent method="OnEvent" /> <OnShow method="OnShow" /> + <OnUpdate method="OnUpdate" /> </Scripts> - <Size x="24" y="24" /> + <Layers> + <Layer level="BACKGROUND"> + <Texture parentKey="Backdrop" hidden="true"> + <Size y="40" /> + <Anchors> + <Anchor point="LEFT" /> + <Anchor point="RIGHT" /> + <Anchor point="TOP" /> + </Anchors> + <Gradient orientation="VERTICAL"> + <MinColor r="0" g="0" b="0" a="0" /> + <MaxColor r="0" g="0" b="0" a=".7" /> + </Gradient> + <Color a="1" r="1" g="1" b="1" /> + </Texture> + </Layer> + </Layers> + + <Frames> + <CheckButton name="$parentToggle" parentKey="Toggle" > + <Size x="20" y="20" /> + <Anchors> + <Anchor point="TOPLEFT" x="3" y="-3" /> + </Anchors> + <Layers> + <Layer level="BACKGROUND"> + <Texture setAllPoints="false"> + <Anchors> + <Anchor point="TOPRIGHT" x="-1" y="-1" /> + <Anchor point="BOTTOMLEFT" x="1" y="1" /> + </Anchors> + <Color a="1" r="0" g="0" b="0" /> + </Texture> + </Layer> + </Layers> + <NormalTexture setAllPoints="true"> + <Color a=".25" r="0" g="0" b="0" /> + </NormalTexture> + <CheckedTexture setAllPoints="false" file="Interface\BUTTONS\UI-CheckBox-Check"> + <Anchors> + <Anchor point="TOPRIGHT" x="-1" y="-1" /> + <Anchor point="BOTTOMLEFT" x="1" y="1" /> + </Anchors> + </CheckedTexture> + </CheckButton> + </Frames> </Frame> - <Button name="WorldPlanFilterPin" virtual="true" flattenRenderLayers="true" mixin="WorldPlanFilterPinMixin"> + <Frame name="WorldPlanFilterHeader" parentArray="Headers" virtual="true" enableMouse="true"> + <Size x="24" y="30" /> + <Layers> + <Layer level="BACKGROUND"> + <Texture parentKey="Backdrop" hidden="true"> + <Anchors> + <Anchor point="LEFT" /> + <Anchor point="RIGHT" /> + <Anchor point="TOP" /> + </Anchors> + <Gradient orientation="VERTICAL"> + <MinColor r="0" g="0" b="0" a=".5" /> + <MaxColor r="0" g="0" b="0" a="1" /> + </Gradient> + <Color a="1" r="1" g="1" b="1" /> + </Texture> + <Texture parentKey="Edge1"> + <Size x="1" y="24" /> + <Anchors> + <Anchor point="TOPLEFT" /> + </Anchors> + <Gradient orientation="VERTICAL"> + <MinColor r="1" g="1" b="1" a="0" /> + <MaxColor r="1" g="1" b="1" a=".5" /> + </Gradient> + <Color a="1" r="1" g="1" b="1" /> + </Texture> + <Texture parentKey="Edge2"> + <Size x="1" y="24" /> + <Anchors> + <Anchor point="TOPRIGHT" /> + </Anchors> + <Gradient orientation="VERTICAL"> + <MinColor r="1" g="1" b="1" a="0" /> + <MaxColor r="1" g="1" b="1" a=".5" /> + </Gradient> + <Color a="1" r="1" g="1" b="1" /> + </Texture> + <FontString inherits="GameFontNormal" parentKey="Label" hidden="true"> + <Anchors> + <Anchor point="BOTTOMLEFT" x="2" y="2" /> + </Anchors> + </FontString> + </Layer> + </Layers> + </Frame> + <Button name="WorldPlanFilterButton" parentArray="Buttons" virtual="true" mixin="WorldPlanFilterButtonMixin"> <Scripts> <OnClick method="OnClick" /> <OnLoad method="OnLoad" /> @@ -25,7 +121,7 @@ </Scripts> <Layers> <Layer level="BACKGROUND"> - <Texture parentKey="RewardBorder" setAllPoints="true" /> + <Texture parentKey="RewardBorder" setAllPoints="true" alphaMode="ADD" /> </Layer> <Layer level="ARTWORK"> <Texture parentKey="icon">
--- a/FlightMap.lua Tue Apr 11 00:44:22 2017 -0400 +++ b/FlightMap.lua Sat Apr 15 11:04:54 2017 -0400 @@ -119,6 +119,7 @@ pin.throttle = 1 pin:ClearAllPoints() pin:SetPoint('CENTER', frame, 'CENTER') + frame:SetSize(pin:GetSize()) --print(pin.Overlay:IsShown(), pin.Overlay:GetPoint(1)) end end
--- a/QuestPOI.lua Tue Apr 11 00:44:22 2017 -0400 +++ b/QuestPOI.lua Sat Apr 15 11:04:54 2017 -0400 @@ -26,7 +26,7 @@ local HaveQuestRewardData = HaveQuestRewardData -local pairs, ipairs, tinsert, unpack, select = pairs, ipairs, tinsert, unpack, select +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 @@ -40,8 +40,8 @@ local dprint = DEVIAN_WORKSPACE and function(...) _G.print('WQData', ...) end or nop local QuestPOI = WorldPlanPOIMixin -local pinBaseIndex = 1500 -local overlayBaseIndex = 1580 +local pinBaseIndex = 1320 +local overlayBaseIndex = 1380 local previousHighlight local DATA_DEBUG = false @@ -252,6 +252,50 @@ end +function QuestPOI:OnLoad() + --qprint('|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.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 + 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(self.questID .. " Marked completed.") + 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 @@ -328,6 +372,15 @@ --print(WorldMapTooltip:GetParent()) --print(WorldMapTooltip:IsVisible()) end + +function QuestPOI:OnMouseDown(button) + if button == 'RightButton' then + SetSuperTrackedQuestID(nil) + else + TaskPOI_OnClick(self, button) + end +end + function QuestPOI:OnLeave() if self.filtered and (self.questID ~= GetSuperTrackedQuestID()) then return @@ -336,6 +389,74 @@ WorldMapTooltip:Hide(); end +local updateTime, markTime +function QuestPOI:OnUpdate (sinceLast) + -- control update check intervals + + if self.animating then + local alpha = self.icon:GetAlpha() + sinceLast*3 + + self.animateTime = (self.animateTime or 0) + sinceLast + if alpha >= 1 then + alpha = 1 + print('fade over', self.animateTime) + self.animating = nil + self.animateTime = nil + + 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.maxAlertLevel then + self:UpdateStatus() + end +end + + +function QuestPOI:StartFading() + if not self.animating then + self.animating = true + self.icon:SetAlpha(0) + self.RewardBorder:SetAlpha(0) + end +end + -- attempt to pull pin data function QuestPOI:GetData () --dprint('|cFF00FF88'..self:GetID()..':GetData()|r') @@ -352,7 +473,7 @@ return false else self.title, self.factionID, self.capped = questTitle, factionID, capped - print(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); @@ -397,18 +518,6 @@ local ID_RESOURCES = 1220 local ID_LEGIONFALL = 1342 -function QuestPOI:Reset() - 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:SetShown(false) -end - --- Returns true if data has changed (either from loading in or qualifications changed) function QuestPOI:UpdateRewards() local questID = self.questID @@ -484,8 +593,6 @@ 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 @@ -496,26 +603,8 @@ rewardType = REWARD_ARTIFACT_POWER rewardIcon = texture rewardName = name - rewardCount = 1 + rewardCount = self:UpdateArtifactPower(itemLink) foundPrimary = true - - WorldPlanTooltip:SetOwner(self, 'ANCHOR_NONE') - WorldPlanTooltip:SetHyperlink(itemLink) - for i = 1, WorldPlanTooltip:NumLines() do - local line = _G['WorldPlanTooltipTextLeft' .. i] - local text = line and line:GetText() - local ap = text and text:gsub(',', ''):gsub(' million', '000000'):match('(%d+) '..ARTIFACT_POWER) - if ap then - rewardCount = tonumber(ap) - --dprint(ap) - end - - end - - if WorldPlanTooltipTextLeft2 then - local text = WorldPlanTooltipTextLeft2:GetText() - end - --dprint('is an AP token') elseif classID == LE_ITEM_CLASS_TRADEGOODS then rewardType = REWARD_REAGENT @@ -524,8 +613,6 @@ rewardCount = numItems foundPrimary = true end - - --dprint(' reward', i, name, " |T"..tostring(texture)..":12:12|t", quality, isUsable, itemID) tinsert(rewardItems, { name = name, @@ -582,70 +669,26 @@ end end --- run from OnShow if .isNew is set -function QuestPOI:OnAnimStart() - --qprint('|cFFFFFF00OnAnimStart(|r'..self:GetID()..'|cFFFFFF00)|r', self.fadeEvent) - self:Refresh('FADE_IN_START') - self.isNew = nil -end - -function QuestPOI:TryToFade(event) - if self.FadeIn:IsPlaying() then - --qprint('|cFFFF4400TryToFade('..self:GetID()..'|cFFFF4400)|r stopping because already in progress') +function QuestPOI:UpdateArtifactPower(rewardLink) + if not (rewardLink or self.rewardLink) then return end - self.fadeEvent = event - if self.dataLoaded then - --qprint('|cFFFFFF00TryToFade('..self:GetID()..'|cFFFFFF00)|r', event) - self:SetAlpha(0) - self.FadeIn.FadeIn:SetToAlpha(db.PinAlpha) - self.FadeIn:Play() - else + self.rewardLink = rewardLink or self.rewardLink - --qprint('|cFFFF4400TryToFade('..self:GetID()..'|cFFFF4400)|r stopping because not loaded') - end -end - -function QuestPOI:OnAnimStop() - self:SetAlpha(db.PinAlpha) -end - -function QuestPOI:OnShow () - - if self.isNew then - self:TryToFade('POI_ONSHOW_NEW') - elseif not self.FadeIn:IsPlaying() then - print('|cFF00FF00Alpha correction') - self:SetAlpha(db.PinAlpha) -- fix stuck alpha - if self.isStale then - --print('|cFF00FF00refresh on show') - self:Refresh('POI_ONSHOW_STALE') + 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 ap = text and text:gsub(',', ''):gsub(' million', '000000'):match('([%d%.]+) '..ARTIFACT_POWER) + if ap then + rewardCount = tonumber(ap) end end - self:RegisterEvent('QUEST_LOG_UPDATE') - self:ShowFrames() -end - -function QuestPOI:OnEvent(event) - if not TQ_IsActive(self.questID) then - self:UnregisterEvent('QUEST_LOG_UPDATE') - self.hideReason = 'Hiding self because quest is inactive.' - self:SetShown(false) - end -end - -function QuestPOI:OnHide() - --DEFAULT_CHAT_FRAME:AddMessage('|cFFFFFF00'..self:GetName()..'|r:OnHide()') - self:HideFrames() - -- 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 + return rewardCount end -- Applies position and sizing parameters to the pin data @@ -653,7 +696,7 @@ --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:HideFrames() + self:HideOrShowFrames(false) return end @@ -696,108 +739,19 @@ end --- Show/Hide the text overlays associated with the quest pin; they aren't hierarchically linked -function QuestPOI:ShowFrames() - if not self:IsShown() then - -- print('|cFFFFFF00' ..self:GetName()..':ShowFrames()') - -- do not SetShown() here - end - self.Overlay:SetShown(true) - self.count:SetShown(true) - self.timeLabel:SetShown(true) -end - -function QuestPOI:HideFrames() - if self:IsShown() then - if not self.hideReason then - self.hideReason = "HideFrames() called" - end - end - self.Overlay:SetShown(false) - self.count:SetShown(false) - self.timeLabel:SetShown(false) -end - -function QuestPOI:OnLoad() - --qprint('|cFF00FF88'..self:GetName()..':OnLoad()|r',db.Config) - self.debugTimer = 4 - self.title = '|cFF0088FF' .. RETRIEVING_DATA..'|r' - self.isPending = true - 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.Overlay:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 4) - self.Overlay:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, -4) -end - -function QuestPOI:OnMouseDown(button) - if button == 'RightButton' then - SetSuperTrackedQuestID(nil) - else - TaskPOI_OnClick(self, button) - end -end - -local updateTime, markTime -function QuestPOI:OnUpdate (sinceLast) - -- control update check intervals - - - 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') - tinsert(db.UpdatedPins, self) - else - - --print('|cFFFF4400OnUpdate(|r'..self:GetID()..'|cFFFF4400)|r poll failed') - end - return - end - - if self.maxAlertLevel then - self:UpdateStatus() - end - -end - -- Non-hieriarchical display states, checked separately from used/filtered states function QuestPOI:GetCriteriaState() local isCriteria, isBounty, isSpellTarget - if self.factionID then - for index, bounty in pairs(db.Bounties) do - if 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) + + + + 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 isSpellTarget = IsQuestIDValidSpellTarget(self.questID) @@ -812,184 +766,6 @@ end end --- Called at static intervals and with Refresh -function QuestPOI:UpdateStatus() - -- update time elements - self.isActive = TQ_IsActive(self.questID) - - if self.isActive then - local tl = self.alertLevel - local timeLeft = TQ_GetQuestTimeLeftMinutes(self.questID) - if timeLeft > 0 then - - local text, timeState = WorldPlan:GetTimeInfo(timeLeft, self.maxAlertLevel) - if tl ~= timeState then - tl = timeState - self.timeLabel:SetText(text) - end - end - - local border = (self.isBounty or self.isCriteria) and self.RewardBorder or self.HighlightBorder - - if tl and (timeLeft < 120) then - border:SetVertexColor(1,0,0,0.7) - else - border:SetVertexColor(0,0,0,0.7) - end - self.alertLevel = tl - self.timeLabel:SetShown(self.worldQuest and (self.maxAlertLevel >= 1)) - else - self.hideReason = "No longer active." - self:HideFrames() - - end -end - - -function QuestPOI:Refresh (event) - - print('|cFF00FF88Refresh(|r'..self:GetID()..'|cFF00FF88)|r', event, self.title) - - local style = DEFAULT_STYLE - if self.dataLoaded and not self.filtered then - style = REWARD_TYPE_STYLES[self.rewardType] - else - style = MINIMIZED_STYLE - 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.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) - - - - 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) - - self:UpdateSize() - self:UpdateStatus() - self.isStale = nil - - 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 - - iconBorder:SetVertexColor(unpack(borderColor)) - trackingBorder:SetVertexColor(1,1,1,1) - end - - if SpellCanTargetQuest() then - if IsQuestIDValidSpellTarget(self.questID) then - icon:SetVertexColor(1,1,1) - else - icon:SetVertexColor(1,0,0,1) - end - self:EnableMouse(false) - else - self:EnableMouse(true) - end - - -- signal filter info update - WorldPlanSummary.isStale = true -end - local cvar_check = { [REWARD_CASH] = 'worldQuestFilterGold', [REWARD_ARTIFACT_POWER] = 'worldQuestFilterArtifactPower', @@ -1044,57 +820,250 @@ self:SetShown(true) end ---- Fixes icons upon size update -function QuestPOI:UpdateSize () +function QuestPOI:Refresh (event) + print('|cFF00FF88Refresh(|r'..self:GetID()..'|cFF00FF88)|r', event, self.title) - --qprint('|cFF00BB88'..self:GetID()..'|r:UpdateSize()', self.style, self.subStyle) - return - --[[ - local style = self.style - local subStyle = self.subStyle - local icon = self.icon + + local style = DEFAULT_STYLE + if self.filtered 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 tag = self.tagIcon + local icon = self.icon + local count = self.count + local hideNumbers = style.hideNumber or DEFAULT_STYLE.hideNumber - local iconWidth = subStyle.iconWidth - local borderWidth = iconWidth + (subStyle.borderWidth * 2) - local highlightWidth = borderWidth + (subStyle.highlightWidth * 2) - local iconTexture = self.itemTexture + local tagIcon = self.tagIcon + self.maxAlertLevel = style.maxAlertLevel or DEFAULT_STYLE.maxAlertLevel - self:SetSize(highlightWidth, highlightWidth) - if self.questID == GetSuperTrackedQuestID() then - highlightWidth = highlightWidth + 2 - if self.filtered then - self:SetAlpha(db.PinAlpha * 0.5) + if self.dataLoaded then + print('new pin, has data, cue fade') + if self.isNew then + self:StartFading() + self.isNew = nil + end + else + if not self.animating then + print('new pin, but no data, hide icon') + self.icon:SetAlpha(0) + self.RewardBorder: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:SetAlpha(db.PinAlpha) + 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) + + self:UpdateStatus() + + 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 + + iconBorder:SetVertexColor(unpack(borderColor)) + trackingBorder:SetVertexColor(0,0,0,.5) + end + + if SpellCanTargetQuest() then + if IsQuestIDValidSpellTarget(self.questID) then + icon:SetVertexColor(1,1,1) + else + icon:SetVertexColor(1,0,0,1) + end + self:EnableMouse(false) + else + self:EnableMouse(true) + end + self.isStale = nil + + -- signal filter info update + WorldPlanSummary.isStale = true +end + +-- Called at static intervals and with Refresh +function QuestPOI:UpdateStatus() + -- update time elements + self.isActive = TQ_IsActive(self.questID) + + if self.isActive then + local tl = self.alertLevel + local timeLeft = TQ_GetQuestTimeLeftMinutes(self.questID) + if timeLeft > 0 then + + local text, timeState = WorldPlan:GetTimeInfo(timeLeft, self.maxAlertLevel) + if tl ~= timeState then + tl = timeState + self.timeLabel:SetText(text) + end + end + + local border = (self.isBounty or self.isCriteria) and self.RewardBorder or self.HighlightBorder + + if tl and (timeLeft < 120) then + border:SetVertexColor(1,0,0,0.7) + else + border:SetVertexColor(0,0,0,0.7) + 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" + end + end + self.Overlay:SetShown(isShown) + self.count:SetShown(isShown) + self.timeLabel:SetShown(isShown) +end + +function QuestPOI:Release() + + self.hideReason = 'Released by script.' + self:SetShown(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:SetShown(false) + self.animating = nil + self.icon:SetAlpha(0) + self.RewardBorder:SetAlpha(0) + self:UnregisterEvent('QUEST_TURNED_IN') + self:UnregisterEvent('QUEST_LOG_UPDATE') + + for i, pin in ipairs(db.UsedPins) do + if pin == self then + tremove(db.UsedPins, i) + break end end - if self.rarity and WORLD_QUEST_QUALITY_COLORS[self.rarity] then - highlightWidth = highlightWidth + self.rarity - end - self.tagIcon:SetSize(self.tagSize, self.tagSize) - icon:SetSize(iconWidth, iconWidth) - iconBorder:SetSize(borderWidth, borderWidth) - trackingBorder:SetSize(highlightWidth, highlightWidth) - - - iconBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) - trackingBorder:SetPoint('CENTER', (style.x or 0), (style.y or 0)) - - - if (subStyle.showNumber and self.itemNumber) and style.hasNumeric then - self.count:SetTextColor(unpack(style.numberRGB)) - if subStyle.numberFontObject then - --wqprint('change font', _G[subStyle.numberFontObject]:GetName()) - self.count:SetFontObject(_G[subStyle.numberFontObject]) - end - else - self.count:SetText(nil) - end - --]] + tinsert(db.FreePins, self) + WorldPlan.dataFlush = true end \ No newline at end of file
--- a/WorldPlan.lua Tue Apr 11 00:44:22 2017 -0400 +++ b/WorldPlan.lua Sat Apr 15 11:04:54 2017 -0400 @@ -263,10 +263,6 @@ db.DefaultConfig[frame:GetName()] = frame.defaults end - frame.GetTypeInfo = function(frame, typeID) - return self:GetTypeInfo(frame, typeID) - end - frame.owningFrame = self else @@ -351,26 +347,14 @@ local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() - - if db.isContinentMap ~= isContinent then - for _, pin in pairs(db.QuestsByID) do - pin.isStale = true - end - end local isMapOpen = WorldMapFrame:IsShown() - if not isMapOpen then - return - end - - local isNewMap = (mapAreaID ~= db.currentMapID) or (isMapOpen ~= db.isMapOpen) or (db.isMicroDungeon ~= isMicroDungeon) - + local isNewMap = (mapAreaID ~= db.currentMapID) or (isMapOpen ~= db.isMapOpen) or (db.isMicroDungeon ~= isMicroDungeon) or (db.isContinentMap ~= isContinent) db.isMicroDungeon = isMicroDungeon db.isMapOpen = isMapOpen db.currentMapID = mapAreaID db.isContinentMap = isContinent db.isBrokenIsle = isBrokenIsle - db.useContinentType = (WorldMapDetailFrame:GetScale() < 1) for _, module in ipairs(db.OrderedModules) do if module.OnMapInfo then @@ -394,6 +378,14 @@ else if (event == 'WORLD_MAP_UPDATE') or (event == 'PLAYER_ENTERING_WORLD') or (event == 'PLAYER_LOGIN') then print('|cFFFF4400currentMapID =', db.currentMapID, ...) + if event == 'PLAYER_ENTERING_WORLD' then + -- start from scratch + db.isMicroDungeon = nil + db.isMapOpen = nil + db.currentMapID = nil + db.isContinentMap = nil + db.isBrokenIsle = nil + end self:SetCurrentMap(event .. ' ' .. GetTime())
--- a/WorldPlan.xml Tue Apr 11 00:44:22 2017 -0400 +++ b/WorldPlan.xml Sat Apr 15 11:04:54 2017 -0400 @@ -36,10 +36,11 @@ </Layers> </Button> - <Button name="WorldPlanQuestPin" virtual="true" hidden="true" frameStrata="TOOLTIP" mixin="WorldPlanPOIMixin"> + <Button name="WorldPlanQuestPin" virtual="true" hidden="true" mixin="WorldPlanPOIMixin"> <Animations> <AnimationGroup parentKey="FadeIn" setToFinalAlpha="true" looping="NONE"> - <Alpha parentKey="FadeIn" duration="0.45" fromAlpha="0" toAlpha="1" order="1" /> + <Alpha parentKey="Icon" childKey="icon" duration="0.45" fromAlpha="0" toAlpha="1" order="1" /> + <Alpha parentKey="Border" childKey="RewardBorder" duration="0.45" fromAlpha="0" toAlpha="1" order="1" /> <Scripts> <OnPlay> self:GetParent():OnAnimStart() @@ -52,10 +53,6 @@ </OnFinished> </Scripts> </AnimationGroup> - <AnimationGroup parentKey="PendingFade" setToFinalAlpha="true" looping="REPEAT"> - <Alpha parentKey="FadeOut" duration="0.72" fromAlpha="1" toAlpha="0" order="1" /> - <Alpha parentKey="FadeIn" duration="0.72" fromAlpha="0" toAlpha="1" order="2" /> - </AnimationGroup> </Animations> <Layers> <Layer level="BACKGROUND" textureSubLevel="-2"> @@ -71,20 +68,27 @@ </Anchors> </Texture> </Layer> - <Layer level="BACKGROUND" textureSubLevel="1"> - <Texture parentKey="RewardBorder" file="Interface\UNITPOWERBARALT\Generic1Target_Circular_Frame" desaturated="true"> + <Layer level="BACKGROUND" textureSubLevel="-1"> + <Texture parentKey="RewardBorder" file="Interface\Minimap\UI-Minimap-Background" desaturated="true" alpha="0"> <Anchors> <Anchor point="CENTER" /> </Anchors> </Texture> </Layer> - <Layer level="BORDER"> - <Texture parentKey="icon" setAllPoints="true"> + <Layer textureSubLevel="0"> + + <Texture parentKey="IconBackdrop" file="Interface\Minimap\UI-Minimap-Background"> <Anchors> <Anchor point="CENTER" /> </Anchors> </Texture> - + </Layer> + <Layer level="ARTWORK" textureSubLevel="2"> + <Texture parentKey="icon" setAllPoints="true" alpha="0"> + <Anchors> + <Anchor point="CENTER" /> + </Anchors> + </Texture> </Layer> <Layer level="OVERLAY"> <Texture parentKey="dot" hidden="true" setAllPoints="false">
--- a/WorldQuests.lua Tue Apr 11 00:44:22 2017 -0400 +++ b/WorldQuests.lua Sat Apr 15 11:04:54 2017 -0400 @@ -26,10 +26,10 @@ local GetQuestLogRewardInfo = GetQuestLogRewardInfo local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete -local IsQuestCriteriaForBounty = IsQuestCriteriaForBounty +local HaveQuestRewardData = HaveQuestRewardData +local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation local ToggleButton = {} -local callbacks = {} 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', } @@ -43,19 +43,60 @@ local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton +local defaults = {} +local continentScanned +local layoutDirty = true +local bountiesDirty = true +local artifactPowerDirty = true +local currentScale = WorldMapDetailFrame:GetScale() +local canTargetQuests +local isDataLoaded = true +local artifactKnowledgeLevel +local superTrackedQuestID +local lastRefresh +local refreshReason + +local bountyQuests = {} +local bountyInfo = {} +local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID + +local totalPins = 0 +local numShown = 0 +local numLoaded = 0 +local numOverlays = 1 +local scaleConstant = 1 local pinBaseIndex = 1500 local overlayBaseIndex = 1580 -local layoutDirty = true -local bountiesDirty = true -local currentScale = WorldMapDetailFrame:GetScale() -local canTargetQuests -local numShown = 0 -local numLoaded = 0 -local isDataLoaded = true -local numOverlays = 1 -local scaleConstant = 1 -Module.TasksByID = {} + +local artifactKnowldegeSpells = { + [207856] = true, + [209203] = true, + [209204] = true, + [209205] = true, + [209206] = true, + [209207] = true, + [209208] = true, + [209209] = true, + [209210] = true, + [209211] = true, + [209212] = true, + [219978] = true, + [227852] = true, + [236477] = true, + [236489] = true, + [236302] = true, + [236488] = true, + [236490] = true, + [240475] = true, + [243176] = true, + [243177] = true, + [243178] = true, + [243182] = true, + [243183] = true, + [243187] = true, + [245133] = true, +} --%debug% local SetTimedCallbackForAllPins = function(seconds, callback) @@ -66,61 +107,86 @@ end) end +function Module:OnLoad() + --print('|cFFFF4400'..self:GetName()..':OnLoad()') -function Module:Setup() - --print('|cFFFF4400'..self:GetName()..':Setup()') - for mapID, mapName in pairs(WORLD_QUEST_MAPS) do - db.QuestsByZone[mapID] = {} + self:SetParent(WorldMapFrame.UIElementsFrame) + WorldPlan:AddHandler(self, defaults) + + for areaID, fileName in pairs(WORLD_QUEST_MAPS) do + db.QuestsByZone[areaID] = {} end - for target, arg in pairs(callbacks) do - --print(type(target)) - if type(target) == 'table' then - local callerName = target:GetName() or tostring(target) - for name, method in pairs(arg) do - --print(callerName, arg) - hooksecurefunc(target, name, function(...) - self:OnSecureHook(callerName .. '.' .. name, method, ...) - end) + + -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level + self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') + self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') + self:RegisterEvent('SKILL_LINES_CHANGED') + self:RegisterEvent('ARTIFACT_UPDATE') + self:RegisterEvent('QUEST_LOG_UPDATE') + self:RegisterEvent('UNIT_SPELLCAST_STOP') +end + +function Module:OnEvent (event, ...) + print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...) + if (event == 'QUEST_LOG_UPDATE') then + self:UpdateBounties(event) + elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then + local questID = ... + if questID and db.QuestsByID[questID] then + db.QuestsByID[questID]:Release() + end + self:Refresh(event) + elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then + self:Refresh(event) + elseif event == 'ARTIFACT_UPDATE' then + self:UpdateArtifactPower() + elseif event == 'MODIFIER_STATE_CHANGED' then + self:UpdateModifierState() + elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then + if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then + db.QuestsByID[superTrackedQuestID].isStale = true + end + local newID = GetSuperTrackedQuestID() + if newID and db.QuestsByID[newID] then + db.QuestsByID[newID].isStale = true + end + elseif event == 'UNIT_SPELLCAST_STOP' then + local name, _, _, _, spellID = ... + if artifactKnowldegeSpells[spellID] then + db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')') + self:UpdateArtifactPower() + end + end +end + +function Module:OnUpdate(sinceLast) + if WorldPlanData.DebugEnabled then + if self.refreshBenchMarkTicker then + --print(self.refreshBenchMarkTicker) + self.refreshBenchMarkTicker = self.refreshBenchMarkTicker - 1 + + if self.refreshBenchMarkTicker == 0 then + + self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000) + self.debugMessage:SetText(self.refreshTime) + self.refreshBenchMarkTicker = nil end else - hooksecurefunc(target, function(...) - self:OnSecureHook(target, arg, ...) - end) + self.refreshBenchMark = GetTime() end end - self.Status = CreateFrame('Frame', nil, self) - self.Status:SetPoint('TOPLEFT', WorldMapFrame.UIElementsFrame, 'TOPLEFT', 0, 0) - self.Status:SetPoint('BOTTOMRIGHT', WorldMapFrame.UIElementsFrame, 'TOPRIGHT', 0, -4) - self.Status.t = self.Status:CreateTexture(nil, 'OVERLAY') - self.Status.b = self.Status:CreateTexture(nil, 'BACKGROUND') - self.Status.b:SetColorTexture(0,0,0,.25) - self.Status.b:SetAllPoints(self.Status) - self.Status.t:SetColorTexture(1,1,1,.5) - self.Status.t:SetPoint('TOP') - self.Status.t:SetPoint('BOTTOM') - self.Status.t:SetPoint('LEFT') - local translationEnd, translationStart - self.Status:SetScript('OnUpdate', function(status) - local translateTo - if numLoaded < numShown then - translateTo = (numLoaded/numShown) * status:GetWidth() - status.t:SetWidth(translateTo) - else - translateTo = status:GetWidth() - status.t:SetWidth(translateTo) - end - end) - - self:SetAllPoints(WorldMapFrame.UIElementsFrame) - for k,v in pairs( ToggleButton) do - self.Toggle:SetScript(k,v) + if self.filtersDirty or self.isStale then + self:Refresh() end - self:UpdateBounties('SETUP') + if #db.UpdatedPins >= 1 then + --print('|cFF00FF88pending update', #db.UpdatedPins) + self:UpdateNext() + end +end - self:Show() -end +local callbacks = {} callbacks.ClickWorldMapActionButton = function(WorldQuests) WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON') end @@ -145,6 +211,43 @@ WorldQuests:Refresh('CASTING_STATE_CHANGED') end +function Module:Setup() + --print('|cFFFF4400'..self:GetName()..':Setup()') + for mapID, mapName in pairs(WORLD_QUEST_MAPS) do + db.QuestsByZone[mapID] = {} + end + for target, arg in pairs(callbacks) do + --print(type(target)) + if type(target) == 'table' then + local callerName = target:GetName() or tostring(target) + for name, method in pairs(arg) do + --print(callerName, arg) + hooksecurefunc(target, name, function(...) + self:OnSecureHook(callerName .. '.' .. name, method, ...) + end) + end + else + hooksecurefunc(target, function(...) + self:OnSecureHook(target, arg, ...) + end) + end + end + + + self:SetAllPoints(WorldMapFrame.UIElementsFrame) + self:UpdateArtifactPower() + self:UpdateBounties('SETUP') + self:Show() +end + +function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen) + if isNewMap or self.isStale then + print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) + layoutDirty = true + self:Refresh('WORLD_MAP_CHANGED') + end +end + function Module:OnConfigUpdate() --print('|cFFFFFF00OnConfigUpdate()|r') if db.Config.FadeWhileGrouped then @@ -158,15 +261,6 @@ pin:SetShown(false) end end - - ToggleButton.OnShow(self.Toggle) -end - -local InternalHideButton = function(button, index) - button:Hide() -end -local InternalShowButton = function(button, index) - button:Show() end function Module:OnSecureHook(callbackName, func, ...) @@ -174,126 +268,43 @@ func(self, ...) end -local defaults = {} -local REWARD_UNKNOWN = 768 -function Module:OnLoad() - --print('|cFFFF4400'..self:GetName()..':OnLoad()') +function Module:UpdateModifierState() - self:SetParent(WorldMapFrame.UIElementsFrame) - WorldPlan:AddHandler(self, defaults) - - for areaID, fileName in pairs(WORLD_QUEST_MAPS) do - db.QuestsByZone[areaID] = {} - end - - -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level - self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') - self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') - self:RegisterEvent('SKILL_LINES_CHANGED') - --self:RegisterEvent('CURRENT_SPELL_CAST_CHANGED') - self:RegisterEvent('ARTIFACT_UPDATE') - self:RegisterEvent('QUEST_LOG_UPDATE') end -local artifactKnowledgeMultiplier -local superTrackedQuestID -function Module:OnEvent (event, ...) +function Module:UpdateTaskPOIs() + canTargetQuests = SpellCanTargetQuest() + for i = 1, NUM_WORLDMAP_TASK_POIS do + local poiFrame = _G['WorldMapFrameTaskPOI'..i] + if poiFrame and poiFrame.worldQuest then + local pin = db.QuestsByID[poiFrame.questID] + if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then + poiFrame:Show() + else + poiFrame:Hide() + end + end + end +end +-- re-anchors and scales pins that have had either of these changed due to data loading delays +function Module:UpdateNext() + --print('|cFF00FF88UpdateNext()') + local pin = tremove(db.UpdatedPins) - print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...) - if (event == 'QUEST_LOG_UPDATE') then - self:UpdateBounties(event) - elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then - local questID = ... - if questID and db.QuestsByID[questID] then - db.QuestsByID[questID].complete = true - self:ReleasePin(db.QuestsByID[questID]) - end - self:Refresh(event) - elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then - self:Refresh(event) - elseif event == 'ARTIFACT_UPDATE' then - local akCheck = C_ArtifactUI.GetArtifactKnowledgeMultiplier() - if akCheck and (akCheck ~= artifactKnowledgeMultiplier) then - if artifactKnowledgeMultiplier then - --print('push artifact knowledge update', artifactKnowledgeMultiplier, 'to', akCheck) - for index, pin in pairs( db.QuestsByID) do - if pin.rewardType == REWARD_ARTIFACT_POWER then - db.log(pin.questID .. ' ' .. tostring(pin.title) .. ' Flagged for artifact power.') - pin.itemNumber = 0 - pin.dataLoaded = nil - end - end - else - - print('artifact knowledge multiplier is known', akCheck) - end - artifactKnowledgeMultiplier = akCheck - end - elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then - if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then - db.QuestsByID[superTrackedQuestID].isStale = true - end - local newID = GetSuperTrackedQuestID() - if newID and db.QuestsByID[newID] then - db.QuestsByID[newID].isStale = true + -- criteria state is asserted independently + pin:CheckFilterRules() + local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] + --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor) + if pin.used then + pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor) + if pin:IsVisible() then + pin:Refresh() + else + pin.isStale = true end end end - -function Module:OnUpdate(sinceLast) - - if self.refreshBenchMarkTicker then - --print(self.refreshBenchMarkTicker) - self.refreshBenchMarkTicker = self.refreshBenchMarkTicker - 1 - - if self.refreshBenchMarkTicker == 0 then - - self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000) - self.debugMessage:SetText(self.refreshTime) - self.refreshBenchMarkTicker = nil - end - else - self.refreshBenchMark = GetTime() - end - - if self.filtersDirty or self.isStale then - self:Refresh() - end - if #db.UpdatedPins >= 1 then - --print('|cFF00FF88pending update', #db.UpdatedPins) - self:UpdateNext() - end - -end - -function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen) - if isNewMap or self.isStale then - print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) - layoutDirty = true - self:Refresh('WORLD_MAP_CHANGED') - else - - --print('|cFFFFFF00'..self:GetName()..':OnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) - end -end - - -function Module:UpdateTaskPOIs() - canTargetQuests = SpellCanTargetQuest() - local func = canTargetQuests and 'Show' or 'Hide' - for i = 1, NUM_WORLDMAP_TASK_POIS do - local button = _G['WorldMapFrameTaskPOI'..i] - if button and button.worldQuest then - button[func](button) - end - end -end - -local bountyQuests = {} -local bountyInfo = {} - -local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID function Module:UpdateBounties(...) print('|cFF00FF88BountyInfo()|r', ...) wipe(db.BountiesByFactionID) @@ -320,130 +331,43 @@ bountiesDirty = nil end - -local totalPins = 0 -local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation -function Module:AcquirePin (info) - local questID = info.questId - if not questID then - return nil +-- check current artifact knowledge and update pins accordingly +function Module:UpdateArtifactPower(overrideLevel) + if InCombatLockdown() then + artifactPowerDirty = true + return end - if not QuestUtils_IsQuestWorldQuest(questID) then - return nil + print('|cFF00FF88UpdateArtifactPower()|r') + local _, akLevel = GetCurrencyInfo(1171) + if overrideLevel then + akLevel = overrideLevel end - -- if we're grabbing a pin, the filters need to be checked - local pin = db.QuestsByID[questID] - if not pin then - local numFree = #db.FreePins - if numFree >= 1 then - pin = tremove(db.FreePins, numFree) - --print('|cFF00FF00Re-using', pin:GetName()) - else - totalPins = totalPins + 1 - local name = 'WorldPlanQuestMarker' .. numOverlays - --print('|cFF00FF00Creating', name) - pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') - - pin:SetID(totalPins) - numOverlays = numOverlays + 1 - --pin.iconBorder:SetVertexColor(0,0,0,1) + --db.print('current AK', akLevel) + if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then + --print('new ak level', akLevel) + db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel)) + for _, pin in pairs(db.QuestsByID) do + if (pin.rewardType == REWARD_ARTIFACT_POWER) then + print(pin.title, pin.itemNumber) + local newAP = pin:UpdateArtifactPower() + if newAP then + pin.itemNumber = newAP + print(newAP) + else + pin.dataLoaded = nil + end + pin.isStale = true + end end - pin.questID = questID - pin.worldQuest = true - pin.throttle = pin.updateRate - pin.isNew = true - pin.currentWidth = nil - db.QuestsByID[questID] = pin - tinsert(db.UsedPins, pin) - + artifactKnowledgeLevel = akLevel end - - if pin and info then - pin.inProgress = info.inProgress - pin.floor = info.floor - pin.numObjectives = info.numObjectives or 0 - if info.x and info.y then - if (info.x ~= pin.x) or (info.y ~= pin.y) then - pin.isStale = true - --rprint('|cFFFF4400SetCoords|r', info.x, info.y) - end - - end - end - - pin.x = info.x or pin.x - pin.y = info.y or pin.y - - if not HaveQuestData(questID) then - TQ_RequestPreloadRewardData(questID); - end - - - if (not pin.dataLoaded) then - local dataLoaded = pin:GetData() - if dataLoaded then - WorldPlan.dataFlush = true - else - isDataLoaded = false - end - end - - - pin.isActive = TQ_IsActive(questID) - pin:GetCriteriaState() - pin:CheckFilterRules() - --rprint(pin:GetID(), pin.filtered, pin.used) - - return pin -end - --- remove from index and add it to the recycling heap -function Module:ReleasePin (pin) - - local id = pin.questID - if id then - db.QuestsByID[id] = nil - - for i, zone in pairs(db.QuestsByZone) do - --print('-', i, zone[i]) - zone[id] = nil - end - db.TasksByID[id] = nil - end - pin:Reset() - tinsert(db.FreePins, pin) - - WorldPlan.dataFlush = true - --print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title) -end - --- re-anchors and scales pins that have had either of these changed due to data loading delays -function Module:UpdateNext() - --print('|cFF00FF88UpdateNext()') - local pin = tremove(db.UpdatedPins) - pin:CheckFilterRules() - - local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] - --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor) - if pin.used then - pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor) - pin:OnShow() - end - - -end - -function Module:Debug(...) - print(...) + artifactPowerDirty = nil end local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF' -local lastRefresh function Module:Refresh(...) - -- - if not self:IsVisible() then print('|cFFFF4400Refresh()|r', ...) --layoutDirty = true @@ -482,7 +406,9 @@ end --]] - + if artifactPowerDirty and not InCombatLockdown() then + self:UpdateArtifactPower() + end -- calculate quests shown numShown = 0 numLoaded = 0 @@ -510,19 +436,16 @@ pin.hideReason = "Not used in map area " .. (db.currentMapID) pin:SetShown(false) end + end - - --print('flags ', layoutDirty, self.isStale) --print(' ', numShown, 'shown,', numLoaded, 'with data') - if numShown > numLoaded then - self.Status:Show() - end + -- - self.refreshBenchMark = GetTime() - self.refreshBenchMarkTicker = 2 - print('starting bench', self.refreshBenchMark) + self.refreshBenchMark = GetTime() + self.refreshBenchMarkTicker = 2 + print('starting bench', self.refreshBenchMark) -- @@ -531,9 +454,13 @@ self.sizesDirty = nil self.isZoomDirty = nil + if WorldPlanSummary then + WorldPlanSummary.isStale = true + end + + WorldPlan.dataFlush = true end -local refreshReason function Module:RefreshIfChanged(event) local scaleCheck = WorldMapDetailFrame:GetScale() refreshReason = nil @@ -548,7 +475,6 @@ return end - if self:IsVisible() then print('|cFF00FFFFRefreshIfChanged()|r', refreshReason) self:Refresh(event) @@ -558,7 +484,7 @@ end end --- update visibility states of all pins +-- marks a pin set for passive update function Module:MarkAllPins(pins) --print(' |cFFFFFF00'..self:GetName()..':MarkAllPins()|r', pins) pins = pins or db.QuestsByID @@ -568,44 +494,7 @@ end end --- Updates quest markers in taskInfo while associating them with the given map -function Module:UpdateQuestsForMap(taskInfo, mapID) - print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty) - if db.QuestsByZone[mapID] then - wipe(db.QuestsByZone[mapID]) - end - - - for index, info in pairs(taskInfo) do - - local questID, x, y = info.questId, info.x, info.y - local pin = self:AcquirePin(info) - - if pin then - pin.used = true - print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame)) - if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then - local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] - pin.owningFrame = WorldMapFrame - pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor) - if pin.isStale then - pin:Refresh('WORLDMAP_REFRESH ' .. GetTime()) - end - else - if layoutDirty then - pin.isStale = true - end - end - - if db.QuestsByZone[mapID] and pin.used then - db.QuestsByZone[mapID][questID] = pin - end - - end - end -end - --- Used to refresh the visible quest markers +-- Walks the current map tree and fires updates as needed function Module:UpdateAnchors () wipe(self.UsedPositions) print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()') @@ -616,7 +505,6 @@ layoutDirty = true end - --rprint('|cFF00FF00'..self:GetName()..':UpdateAnchors()') local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() if isMicroDungeon then @@ -643,11 +531,112 @@ end end -function ToggleButton:OnShow() - self:SetChecked(db.Config.EnablePins and true or false) +-- Applies map association to the pins corresponding with each TaskInfo item +function Module:UpdateQuestsForMap(taskInfo, mapID) + print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty) + if db.QuestsByZone[mapID] then + wipe(db.QuestsByZone[mapID]) + elseif db.isBrokenIsle then + continentScanned = true + end + + for index, info in pairs(taskInfo) do + local questID, x, y = info.questId, info.x, info.y + local pin = self:AcquirePin(info) + + if pin then + pin.used = true + print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame)) + if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then + local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1] + pin.owningFrame = WorldMapFrame + pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor) + if pin.isStale then + pin:Refresh('WORLDMAP_REFRESH ' .. GetTime()) + end + else + if layoutDirty then + pin.isStale = true + end + end + + if db.QuestsByZone[mapID] and pin.used then + db.QuestsByZone[mapID][questID] = pin + end + end + end end -function ToggleButton:OnClick() - --print(self:GetChecked()) - db.Config.EnablePins = self:GetChecked() - _G.WorldPlan:OnConfigUpdate() + +-- locates or creates a corresponding pin frame for the provided TaskInfo data +function Module:AcquirePin (info) + local questID = info.questId + if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then + return nil + end + + local pin = db.QuestsByID[questID] + if not pin then + local numFree = #db.FreePins + if numFree >= 1 then + pin = tremove(db.FreePins, numFree) + print('|cFF00FF00Re-using', pin:GetName()) + else + totalPins = totalPins + 1 + local name = 'WorldPlanQuestMarker' .. numOverlays + print('|cFF00FF00Creating', name) + pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') + + pin:SetID(totalPins) + numOverlays = numOverlays + 1 + --pin.iconBorder:SetVertexColor(0,0,0,1) + end + pin.questID = questID + pin.worldQuest = true + pin.throttle = pin.updateRate + pin.isNew = true + pin.currentWidth = nil + db.QuestsByID[questID] = pin + tinsert(db.UsedPins, pin) + end + + if IsQuestComplete(questID) then + pin:Release() + return nil + elseif info then + pin.inProgress = info.inProgress + pin.floor = info.floor + pin.numObjectives = info.numObjectives or 0 + if info.x and info.y then + if (info.x ~= pin.x) or (info.y ~= pin.y) then + pin.isStale = true + --rprint('|cFFFF4400SetCoords|r', info.x, info.y) + end + end + end + + pin.x = info.x or pin.x + pin.y = info.y or pin.y + + if not HaveQuestRewardData(questID) then + TQ_RequestPreloadRewardData(questID); + end + + if (not pin.dataLoaded) then + local dataLoaded = pin:GetData() + if dataLoaded then + WorldPlan.dataFlush = true + else + isDataLoaded = false + end + end + + pin.isActive = TQ_IsActive(questID) + pin:GetCriteriaState() + pin:CheckFilterRules() + --rprint(pin:GetID(), pin.filtered, pin.used) + return pin +end + +function Module:Debug(...) + print(...) end \ No newline at end of file
--- a/WorldQuests.xml Tue Apr 11 00:44:22 2017 -0400 +++ b/WorldQuests.xml Sat Apr 15 11:04:54 2017 -0400 @@ -16,48 +16,13 @@ <Layer level="OVERLAY"> <FontString parentKey="debugMessage" inherits="GameFontNormal"> <Anchors> - <Anchor point="BOTTOMLEFT" /> + <Anchor point="TOP" x="0" y="-8" /> </Anchors> </FontString> </Layer> </Layers> - <Frames> - <CheckButton name="$parentToggle" parentKey="Toggle" > - <Size x="20" y="20" /> - <Anchors> - <Anchor point="TOPLEFT" relativePoint="TOPLEFT" x="2" y="-6" /> - </Anchors> - <Layers> - <Layer level="BACKGROUND"> - <Texture setAllPoints="false"> - <Anchors> - <Anchor point="TOPRIGHT" x="-1" y="-1" /> - <Anchor point="BOTTOMLEFT" x="1" y="1" /> - </Anchors> - <Color a="1" r="0" g="0" b="0" /> - </Texture> - </Layer> - </Layers> - - <ButtonText inherits="GameFontNormal" text="World Quests"> - <Anchors> - <Anchor point="LEFT" relativePoint="RIGHT" x="3" /> - </Anchors> - </ButtonText> - <NormalTexture setAllPoints="true"> - <Color a=".25" r="0" g="0" b="0" /> - </NormalTexture> - <CheckedTexture setAllPoints="false"> - <Anchors> - <Anchor point="TOPRIGHT" x="-1" y="-1" /> - <Anchor point="BOTTOMLEFT" x="1" y="1" /> - </Anchors> - <Color a=".75" r="1" g="1" b="1" /> - </CheckedTexture> - </CheckButton> - </Frames> </Frame> </Ui> \ No newline at end of file