Mercurial > wow > worldplan
comparison WorldQuests.lua @ 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 | 77013bd72adb |
children | b29b35cb8539 |
comparison
equal
deleted
inserted
replaced
92:df725cba1a6a | 93:98b5e08b75ed |
---|---|
24 local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget | 24 local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget |
25 local tonumber, abs = tonumber, math.abs | 25 local tonumber, abs = tonumber, math.abs |
26 local GetQuestLogRewardInfo = GetQuestLogRewardInfo | 26 local GetQuestLogRewardInfo = GetQuestLogRewardInfo |
27 local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID | 27 local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID |
28 local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete | 28 local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete |
29 local IsQuestCriteriaForBounty = IsQuestCriteriaForBounty | 29 local HaveQuestRewardData = HaveQuestRewardData |
30 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation | |
30 | 31 |
31 local ToggleButton = {} | 32 local ToggleButton = {} |
32 local callbacks = {} | |
33 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 | 33 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 |
34 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah", | 34 local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70', [AZSUNA_ID] = 'Azsuna', [VALSHARAH_ID] = "Val'sharah", |
35 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } | 35 [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim', [SURAMAR_ID] = 'Suramar', [EOA_ID] = 'EyeOfAszhara', } |
36 | 36 |
37 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD | 37 local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD |
41 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS | 41 local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS |
42 local SCALE_FACTORS = { 0.25, 0.7, 1 } | 42 local SCALE_FACTORS = { 0.25, 0.7, 1 } |
43 | 43 |
44 local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard | 44 local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard |
45 local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton | 45 local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton |
46 | 46 local defaults = {} |
47 | |
48 local continentScanned | |
49 local layoutDirty = true | |
50 local bountiesDirty = true | |
51 local artifactPowerDirty = true | |
52 local currentScale = WorldMapDetailFrame:GetScale() | |
53 local canTargetQuests | |
54 local isDataLoaded = true | |
55 local artifactKnowledgeLevel | |
56 local superTrackedQuestID | |
57 local lastRefresh | |
58 local refreshReason | |
59 | |
60 local bountyQuests = {} | |
61 local bountyInfo = {} | |
62 local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID | |
63 | |
64 local totalPins = 0 | |
65 local numShown = 0 | |
66 local numLoaded = 0 | |
67 local numOverlays = 1 | |
68 local scaleConstant = 1 | |
47 local pinBaseIndex = 1500 | 69 local pinBaseIndex = 1500 |
48 local overlayBaseIndex = 1580 | 70 local overlayBaseIndex = 1580 |
49 local layoutDirty = true | 71 |
50 local bountiesDirty = true | 72 local artifactKnowldegeSpells = { |
51 local currentScale = WorldMapDetailFrame:GetScale() | 73 [207856] = true, |
52 local canTargetQuests | 74 [209203] = true, |
53 local numShown = 0 | 75 [209204] = true, |
54 local numLoaded = 0 | 76 [209205] = true, |
55 local isDataLoaded = true | 77 [209206] = true, |
56 local numOverlays = 1 | 78 [209207] = true, |
57 local scaleConstant = 1 | 79 [209208] = true, |
58 Module.TasksByID = {} | 80 [209209] = true, |
81 [209210] = true, | |
82 [209211] = true, | |
83 [209212] = true, | |
84 [219978] = true, | |
85 [227852] = true, | |
86 [236477] = true, | |
87 [236489] = true, | |
88 [236302] = true, | |
89 [236488] = true, | |
90 [236490] = true, | |
91 [240475] = true, | |
92 [243176] = true, | |
93 [243177] = true, | |
94 [243178] = true, | |
95 [243182] = true, | |
96 [243183] = true, | |
97 [243187] = true, | |
98 [245133] = true, | |
99 } | |
59 | 100 |
60 --%debug% | 101 --%debug% |
61 local SetTimedCallbackForAllPins = function(seconds, callback) | 102 local SetTimedCallbackForAllPins = function(seconds, callback) |
62 C_Timer.After(seconds, function() | 103 C_Timer.After(seconds, function() |
63 for id, pin in pairs(WorldPlanQuests.QuestsByID) do | 104 for id, pin in pairs(WorldPlanQuests.QuestsByID) do |
64 callback(pin) | 105 callback(pin) |
65 end | 106 end |
66 end) | 107 end) |
67 end | 108 end |
68 | 109 |
110 function Module:OnLoad() | |
111 --print('|cFFFF4400'..self:GetName()..':OnLoad()') | |
112 | |
113 self:SetParent(WorldMapFrame.UIElementsFrame) | |
114 WorldPlan:AddHandler(self, defaults) | |
115 | |
116 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do | |
117 db.QuestsByZone[areaID] = {} | |
118 end | |
119 | |
120 -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level | |
121 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') | |
122 self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') | |
123 self:RegisterEvent('SKILL_LINES_CHANGED') | |
124 self:RegisterEvent('ARTIFACT_UPDATE') | |
125 self:RegisterEvent('QUEST_LOG_UPDATE') | |
126 self:RegisterEvent('UNIT_SPELLCAST_STOP') | |
127 end | |
128 | |
129 function Module:OnEvent (event, ...) | |
130 print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...) | |
131 if (event == 'QUEST_LOG_UPDATE') then | |
132 self:UpdateBounties(event) | |
133 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then | |
134 local questID = ... | |
135 if questID and db.QuestsByID[questID] then | |
136 db.QuestsByID[questID]:Release() | |
137 end | |
138 self:Refresh(event) | |
139 elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then | |
140 self:Refresh(event) | |
141 elseif event == 'ARTIFACT_UPDATE' then | |
142 self:UpdateArtifactPower() | |
143 elseif event == 'MODIFIER_STATE_CHANGED' then | |
144 self:UpdateModifierState() | |
145 elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then | |
146 if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then | |
147 db.QuestsByID[superTrackedQuestID].isStale = true | |
148 end | |
149 local newID = GetSuperTrackedQuestID() | |
150 if newID and db.QuestsByID[newID] then | |
151 db.QuestsByID[newID].isStale = true | |
152 end | |
153 elseif event == 'UNIT_SPELLCAST_STOP' then | |
154 local name, _, _, _, spellID = ... | |
155 if artifactKnowldegeSpells[spellID] then | |
156 db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')') | |
157 self:UpdateArtifactPower() | |
158 end | |
159 end | |
160 end | |
161 | |
162 function Module:OnUpdate(sinceLast) | |
163 if WorldPlanData.DebugEnabled then | |
164 if self.refreshBenchMarkTicker then | |
165 --print(self.refreshBenchMarkTicker) | |
166 self.refreshBenchMarkTicker = self.refreshBenchMarkTicker - 1 | |
167 | |
168 if self.refreshBenchMarkTicker == 0 then | |
169 | |
170 self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000) | |
171 self.debugMessage:SetText(self.refreshTime) | |
172 self.refreshBenchMarkTicker = nil | |
173 end | |
174 else | |
175 self.refreshBenchMark = GetTime() | |
176 end | |
177 end | |
178 | |
179 if self.filtersDirty or self.isStale then | |
180 self:Refresh() | |
181 end | |
182 | |
183 if #db.UpdatedPins >= 1 then | |
184 --print('|cFF00FF88pending update', #db.UpdatedPins) | |
185 self:UpdateNext() | |
186 end | |
187 end | |
188 | |
189 local callbacks = {} | |
190 callbacks.ClickWorldMapActionButton = function(WorldQuests) | |
191 WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON') | |
192 end | |
193 callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests) | |
194 WorldQuests:UpdateTaskPOIs() | |
195 end | |
196 callbacks.WorldMapFrame_UpdateMap = function(WorldQuests) | |
197 WorldQuests:RefreshIfChanged('WMF_UPDATE') | |
198 end | |
199 callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests) | |
200 WorldQuests:RefreshIfChanged('WMF_REANCHOR') | |
201 end | |
202 | |
203 callbacks[BountyBoard] = {} | |
204 callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests) | |
205 WorldQuests:UpdateBounties('BOUNTY_SELECTED') | |
206 WorldQuests:Refresh('BOUNTY_SELECTED') | |
207 end | |
208 | |
209 callbacks[ActionButton] = {} | |
210 callbacks[ActionButton].UpdateCastingState = function(WorldQuests) | |
211 WorldQuests:Refresh('CASTING_STATE_CHANGED') | |
212 end | |
69 | 213 |
70 function Module:Setup() | 214 function Module:Setup() |
71 --print('|cFFFF4400'..self:GetName()..':Setup()') | 215 --print('|cFFFF4400'..self:GetName()..':Setup()') |
72 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do | 216 for mapID, mapName in pairs(WORLD_QUEST_MAPS) do |
73 db.QuestsByZone[mapID] = {} | 217 db.QuestsByZone[mapID] = {} |
87 self:OnSecureHook(target, arg, ...) | 231 self:OnSecureHook(target, arg, ...) |
88 end) | 232 end) |
89 end | 233 end |
90 end | 234 end |
91 | 235 |
92 self.Status = CreateFrame('Frame', nil, self) | |
93 self.Status:SetPoint('TOPLEFT', WorldMapFrame.UIElementsFrame, 'TOPLEFT', 0, 0) | |
94 self.Status:SetPoint('BOTTOMRIGHT', WorldMapFrame.UIElementsFrame, 'TOPRIGHT', 0, -4) | |
95 self.Status.t = self.Status:CreateTexture(nil, 'OVERLAY') | |
96 self.Status.b = self.Status:CreateTexture(nil, 'BACKGROUND') | |
97 self.Status.b:SetColorTexture(0,0,0,.25) | |
98 self.Status.b:SetAllPoints(self.Status) | |
99 self.Status.t:SetColorTexture(1,1,1,.5) | |
100 self.Status.t:SetPoint('TOP') | |
101 self.Status.t:SetPoint('BOTTOM') | |
102 self.Status.t:SetPoint('LEFT') | |
103 local translationEnd, translationStart | |
104 self.Status:SetScript('OnUpdate', function(status) | |
105 local translateTo | |
106 if numLoaded < numShown then | |
107 translateTo = (numLoaded/numShown) * status:GetWidth() | |
108 status.t:SetWidth(translateTo) | |
109 else | |
110 translateTo = status:GetWidth() | |
111 status.t:SetWidth(translateTo) | |
112 end | |
113 end) | |
114 | 236 |
115 self:SetAllPoints(WorldMapFrame.UIElementsFrame) | 237 self:SetAllPoints(WorldMapFrame.UIElementsFrame) |
116 for k,v in pairs( ToggleButton) do | 238 self:UpdateArtifactPower() |
117 self.Toggle:SetScript(k,v) | |
118 end | |
119 | |
120 self:UpdateBounties('SETUP') | 239 self:UpdateBounties('SETUP') |
121 | |
122 self:Show() | 240 self:Show() |
123 end | 241 end |
124 callbacks.ClickWorldMapActionButton = function(WorldQuests) | 242 |
125 WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON') | 243 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen) |
126 end | 244 if isNewMap or self.isStale then |
127 callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests) | 245 print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) |
128 WorldQuests:UpdateTaskPOIs() | 246 layoutDirty = true |
129 end | 247 self:Refresh('WORLD_MAP_CHANGED') |
130 callbacks.WorldMapFrame_UpdateMap = function(WorldQuests) | 248 end |
131 WorldQuests:RefreshIfChanged('WMF_UPDATE') | |
132 end | |
133 callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests) | |
134 WorldQuests:RefreshIfChanged('WMF_REANCHOR') | |
135 end | |
136 | |
137 callbacks[BountyBoard] = {} | |
138 callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests) | |
139 WorldQuests:UpdateBounties('BOUNTY_SELECTED') | |
140 WorldQuests:Refresh('BOUNTY_SELECTED') | |
141 end | |
142 | |
143 callbacks[ActionButton] = {} | |
144 callbacks[ActionButton].UpdateCastingState = function(WorldQuests) | |
145 WorldQuests:Refresh('CASTING_STATE_CHANGED') | |
146 end | 249 end |
147 | 250 |
148 function Module:OnConfigUpdate() | 251 function Module:OnConfigUpdate() |
149 --print('|cFFFFFF00OnConfigUpdate()|r') | 252 --print('|cFFFFFF00OnConfigUpdate()|r') |
150 if db.Config.FadeWhileGrouped then | 253 if db.Config.FadeWhileGrouped then |
156 if not db.Config.EnablePins then | 259 if not db.Config.EnablePins then |
157 for _, pin in pairs(db.QuestsByID) do | 260 for _, pin in pairs(db.QuestsByID) do |
158 pin:SetShown(false) | 261 pin:SetShown(false) |
159 end | 262 end |
160 end | 263 end |
161 | |
162 ToggleButton.OnShow(self.Toggle) | |
163 end | |
164 | |
165 local InternalHideButton = function(button, index) | |
166 button:Hide() | |
167 end | |
168 local InternalShowButton = function(button, index) | |
169 button:Show() | |
170 end | 264 end |
171 | 265 |
172 function Module:OnSecureHook(callbackName, func, ...) | 266 function Module:OnSecureHook(callbackName, func, ...) |
173 --rprint('|cFFFF4400'..callbackName..'|r', ...) | 267 --rprint('|cFFFF4400'..callbackName..'|r', ...) |
174 func(self, ...) | 268 func(self, ...) |
175 end | 269 end |
176 | 270 |
177 local defaults = {} | 271 function Module:UpdateModifierState() |
178 local REWARD_UNKNOWN = 768 | 272 |
179 function Module:OnLoad() | 273 end |
180 --print('|cFFFF4400'..self:GetName()..':OnLoad()') | |
181 | |
182 self:SetParent(WorldMapFrame.UIElementsFrame) | |
183 WorldPlan:AddHandler(self, defaults) | |
184 | |
185 for areaID, fileName in pairs(WORLD_QUEST_MAPS) do | |
186 db.QuestsByZone[areaID] = {} | |
187 end | |
188 | |
189 -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level | |
190 self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL') | |
191 self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED') | |
192 self:RegisterEvent('SKILL_LINES_CHANGED') | |
193 --self:RegisterEvent('CURRENT_SPELL_CAST_CHANGED') | |
194 self:RegisterEvent('ARTIFACT_UPDATE') | |
195 self:RegisterEvent('QUEST_LOG_UPDATE') | |
196 end | |
197 | |
198 local artifactKnowledgeMultiplier | |
199 local superTrackedQuestID | |
200 function Module:OnEvent (event, ...) | |
201 | |
202 print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...) | |
203 if (event == 'QUEST_LOG_UPDATE') then | |
204 self:UpdateBounties(event) | |
205 elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then | |
206 local questID = ... | |
207 if questID and db.QuestsByID[questID] then | |
208 db.QuestsByID[questID].complete = true | |
209 self:ReleasePin(db.QuestsByID[questID]) | |
210 end | |
211 self:Refresh(event) | |
212 elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then | |
213 self:Refresh(event) | |
214 elseif event == 'ARTIFACT_UPDATE' then | |
215 local akCheck = C_ArtifactUI.GetArtifactKnowledgeMultiplier() | |
216 if akCheck and (akCheck ~= artifactKnowledgeMultiplier) then | |
217 if artifactKnowledgeMultiplier then | |
218 --print('push artifact knowledge update', artifactKnowledgeMultiplier, 'to', akCheck) | |
219 for index, pin in pairs( db.QuestsByID) do | |
220 if pin.rewardType == REWARD_ARTIFACT_POWER then | |
221 db.log(pin.questID .. ' ' .. tostring(pin.title) .. ' Flagged for artifact power.') | |
222 pin.itemNumber = 0 | |
223 pin.dataLoaded = nil | |
224 end | |
225 end | |
226 else | |
227 | |
228 print('artifact knowledge multiplier is known', akCheck) | |
229 end | |
230 artifactKnowledgeMultiplier = akCheck | |
231 end | |
232 elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then | |
233 if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then | |
234 db.QuestsByID[superTrackedQuestID].isStale = true | |
235 end | |
236 local newID = GetSuperTrackedQuestID() | |
237 if newID and db.QuestsByID[newID] then | |
238 db.QuestsByID[newID].isStale = true | |
239 end | |
240 end | |
241 end | |
242 | |
243 | |
244 function Module:OnUpdate(sinceLast) | |
245 | |
246 if self.refreshBenchMarkTicker then | |
247 --print(self.refreshBenchMarkTicker) | |
248 self.refreshBenchMarkTicker = self.refreshBenchMarkTicker - 1 | |
249 | |
250 if self.refreshBenchMarkTicker == 0 then | |
251 | |
252 self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000) | |
253 self.debugMessage:SetText(self.refreshTime) | |
254 self.refreshBenchMarkTicker = nil | |
255 end | |
256 else | |
257 self.refreshBenchMark = GetTime() | |
258 end | |
259 | |
260 if self.filtersDirty or self.isStale then | |
261 self:Refresh() | |
262 end | |
263 if #db.UpdatedPins >= 1 then | |
264 --print('|cFF00FF88pending update', #db.UpdatedPins) | |
265 self:UpdateNext() | |
266 end | |
267 | |
268 end | |
269 | |
270 function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen) | |
271 if isNewMap or self.isStale then | |
272 print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) | |
273 layoutDirty = true | |
274 self:Refresh('WORLD_MAP_CHANGED') | |
275 else | |
276 | |
277 --print('|cFFFFFF00'..self:GetName()..':OnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap) | |
278 end | |
279 end | |
280 | |
281 | 274 |
282 function Module:UpdateTaskPOIs() | 275 function Module:UpdateTaskPOIs() |
283 canTargetQuests = SpellCanTargetQuest() | 276 canTargetQuests = SpellCanTargetQuest() |
284 local func = canTargetQuests and 'Show' or 'Hide' | |
285 for i = 1, NUM_WORLDMAP_TASK_POIS do | 277 for i = 1, NUM_WORLDMAP_TASK_POIS do |
286 local button = _G['WorldMapFrameTaskPOI'..i] | 278 local poiFrame = _G['WorldMapFrameTaskPOI'..i] |
287 if button and button.worldQuest then | 279 if poiFrame and poiFrame.worldQuest then |
288 button[func](button) | 280 local pin = db.QuestsByID[poiFrame.questID] |
289 end | 281 if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then |
290 end | 282 poiFrame:Show() |
291 end | 283 else |
292 | 284 poiFrame:Hide() |
293 local bountyQuests = {} | 285 end |
294 local bountyInfo = {} | 286 end |
295 | 287 end |
296 local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID | 288 end |
289 -- re-anchors and scales pins that have had either of these changed due to data loading delays | |
290 function Module:UpdateNext() | |
291 --print('|cFF00FF88UpdateNext()') | |
292 local pin = tremove(db.UpdatedPins) | |
293 | |
294 -- criteria state is asserted independently | |
295 pin:CheckFilterRules() | |
296 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] | |
297 --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor) | |
298 if pin.used then | |
299 pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor) | |
300 if pin:IsVisible() then | |
301 pin:Refresh() | |
302 else | |
303 pin.isStale = true | |
304 end | |
305 end | |
306 end | |
307 | |
297 function Module:UpdateBounties(...) | 308 function Module:UpdateBounties(...) |
298 print('|cFF00FF88BountyInfo()|r', ...) | 309 print('|cFF00FF88BountyInfo()|r', ...) |
299 wipe(db.BountiesByFactionID) | 310 wipe(db.BountiesByFactionID) |
300 wipe(db.BountiesByQuestID) | 311 wipe(db.BountiesByQuestID) |
301 | 312 |
318 end | 329 end |
319 end | 330 end |
320 bountiesDirty = nil | 331 bountiesDirty = nil |
321 end | 332 end |
322 | 333 |
323 | 334 -- check current artifact knowledge and update pins accordingly |
324 local totalPins = 0 | 335 function Module:UpdateArtifactPower(overrideLevel) |
325 local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation | 336 if InCombatLockdown() then |
326 function Module:AcquirePin (info) | 337 artifactPowerDirty = true |
327 local questID = info.questId | 338 return |
328 if not questID then | 339 end |
329 return nil | 340 |
330 end | 341 print('|cFF00FF88UpdateArtifactPower()|r') |
331 | 342 local _, akLevel = GetCurrencyInfo(1171) |
332 if not QuestUtils_IsQuestWorldQuest(questID) then | 343 if overrideLevel then |
333 return nil | 344 akLevel = overrideLevel |
334 end | 345 end |
335 | 346 |
336 -- if we're grabbing a pin, the filters need to be checked | 347 --db.print('current AK', akLevel) |
337 local pin = db.QuestsByID[questID] | 348 if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then |
338 if not pin then | 349 --print('new ak level', akLevel) |
339 local numFree = #db.FreePins | 350 db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel)) |
340 if numFree >= 1 then | 351 for _, pin in pairs(db.QuestsByID) do |
341 pin = tremove(db.FreePins, numFree) | 352 if (pin.rewardType == REWARD_ARTIFACT_POWER) then |
342 --print('|cFF00FF00Re-using', pin:GetName()) | 353 print(pin.title, pin.itemNumber) |
343 else | 354 local newAP = pin:UpdateArtifactPower() |
344 totalPins = totalPins + 1 | 355 if newAP then |
345 local name = 'WorldPlanQuestMarker' .. numOverlays | 356 pin.itemNumber = newAP |
346 --print('|cFF00FF00Creating', name) | 357 print(newAP) |
347 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') | 358 else |
348 | 359 pin.dataLoaded = nil |
349 pin:SetID(totalPins) | 360 end |
350 numOverlays = numOverlays + 1 | |
351 --pin.iconBorder:SetVertexColor(0,0,0,1) | |
352 end | |
353 pin.questID = questID | |
354 pin.worldQuest = true | |
355 pin.throttle = pin.updateRate | |
356 pin.isNew = true | |
357 pin.currentWidth = nil | |
358 db.QuestsByID[questID] = pin | |
359 tinsert(db.UsedPins, pin) | |
360 | |
361 end | |
362 | |
363 if pin and info then | |
364 pin.inProgress = info.inProgress | |
365 pin.floor = info.floor | |
366 pin.numObjectives = info.numObjectives or 0 | |
367 if info.x and info.y then | |
368 if (info.x ~= pin.x) or (info.y ~= pin.y) then | |
369 pin.isStale = true | 361 pin.isStale = true |
370 --rprint('|cFFFF4400SetCoords|r', info.x, info.y) | 362 end |
371 end | 363 end |
372 | 364 artifactKnowledgeLevel = akLevel |
373 end | 365 end |
374 end | 366 artifactPowerDirty = nil |
375 | |
376 pin.x = info.x or pin.x | |
377 pin.y = info.y or pin.y | |
378 | |
379 if not HaveQuestData(questID) then | |
380 TQ_RequestPreloadRewardData(questID); | |
381 end | |
382 | |
383 | |
384 if (not pin.dataLoaded) then | |
385 local dataLoaded = pin:GetData() | |
386 if dataLoaded then | |
387 WorldPlan.dataFlush = true | |
388 else | |
389 isDataLoaded = false | |
390 end | |
391 end | |
392 | |
393 | |
394 pin.isActive = TQ_IsActive(questID) | |
395 pin:GetCriteriaState() | |
396 pin:CheckFilterRules() | |
397 --rprint(pin:GetID(), pin.filtered, pin.used) | |
398 | |
399 return pin | |
400 end | |
401 | |
402 -- remove from index and add it to the recycling heap | |
403 function Module:ReleasePin (pin) | |
404 | |
405 local id = pin.questID | |
406 if id then | |
407 db.QuestsByID[id] = nil | |
408 | |
409 for i, zone in pairs(db.QuestsByZone) do | |
410 --print('-', i, zone[i]) | |
411 zone[id] = nil | |
412 end | |
413 db.TasksByID[id] = nil | |
414 end | |
415 pin:Reset() | |
416 tinsert(db.FreePins, pin) | |
417 | |
418 WorldPlan.dataFlush = true | |
419 --print('|cFF00FF00-'.. (pin.mapID and GetMapNameByID(pin.mapID) or '???') ..'|r', id, pin.title) | |
420 end | |
421 | |
422 -- re-anchors and scales pins that have had either of these changed due to data loading delays | |
423 function Module:UpdateNext() | |
424 --print('|cFF00FF88UpdateNext()') | |
425 local pin = tremove(db.UpdatedPins) | |
426 pin:CheckFilterRules() | |
427 | |
428 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] | |
429 --print(pin.title, pin.dataLoaded and not pin.filtered, scaleFactor) | |
430 if pin.used then | |
431 pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor) | |
432 pin:OnShow() | |
433 end | |
434 | |
435 | |
436 end | |
437 | |
438 function Module:Debug(...) | |
439 print(...) | |
440 end | 367 end |
441 | 368 |
442 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF' | 369 local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF' |
443 local lastRefresh | |
444 function Module:Refresh(...) | 370 function Module:Refresh(...) |
445 -- | |
446 | |
447 if not self:IsVisible() then | 371 if not self:IsVisible() then |
448 print('|cFFFF4400Refresh()|r', ...) | 372 print('|cFFFF4400Refresh()|r', ...) |
449 --layoutDirty = true | 373 --layoutDirty = true |
450 return | 374 return |
451 else | 375 else |
480 --print(' bounties dirty, pushing that') | 404 --print(' bounties dirty, pushing that') |
481 self:UpdateBounties() | 405 self:UpdateBounties() |
482 end | 406 end |
483 --]] | 407 --]] |
484 | 408 |
485 | 409 if artifactPowerDirty and not InCombatLockdown() then |
410 self:UpdateArtifactPower() | |
411 end | |
486 -- calculate quests shown | 412 -- calculate quests shown |
487 numShown = 0 | 413 numShown = 0 |
488 numLoaded = 0 | 414 numLoaded = 0 |
489 for questID, pin in pairs(db.QuestsByID) do | 415 for questID, pin in pairs(db.QuestsByID) do |
490 local oV = pin:IsShown() | 416 local oV = pin:IsShown() |
508 end | 434 end |
509 --]] | 435 --]] |
510 pin.hideReason = "Not used in map area " .. (db.currentMapID) | 436 pin.hideReason = "Not used in map area " .. (db.currentMapID) |
511 pin:SetShown(false) | 437 pin:SetShown(false) |
512 end | 438 end |
513 end | 439 |
514 | 440 end |
515 | |
516 --print('flags ', layoutDirty, self.isStale) | 441 --print('flags ', layoutDirty, self.isStale) |
517 --print(' ', numShown, 'shown,', numLoaded, 'with data') | 442 --print(' ', numShown, 'shown,', numLoaded, 'with data') |
518 if numShown > numLoaded then | 443 |
519 self.Status:Show() | |
520 end | |
521 | 444 |
522 -- | 445 -- |
523 self.refreshBenchMark = GetTime() | 446 self.refreshBenchMark = GetTime() |
524 self.refreshBenchMarkTicker = 2 | 447 self.refreshBenchMarkTicker = 2 |
525 print('starting bench', self.refreshBenchMark) | 448 print('starting bench', self.refreshBenchMark) |
526 | 449 |
527 -- | 450 -- |
528 | 451 |
529 layoutDirty = nil | 452 layoutDirty = nil |
530 self.isStale = nil | 453 self.isStale = nil |
531 self.sizesDirty = nil | 454 self.sizesDirty = nil |
532 self.isZoomDirty = nil | 455 self.isZoomDirty = nil |
533 | 456 |
534 end | 457 if WorldPlanSummary then |
535 | 458 WorldPlanSummary.isStale = true |
536 local refreshReason | 459 end |
460 | |
461 WorldPlan.dataFlush = true | |
462 end | |
463 | |
537 function Module:RefreshIfChanged(event) | 464 function Module:RefreshIfChanged(event) |
538 local scaleCheck = WorldMapDetailFrame:GetScale() | 465 local scaleCheck = WorldMapDetailFrame:GetScale() |
539 refreshReason = nil | 466 refreshReason = nil |
540 if scaleCheck ~= currentScale then | 467 if scaleCheck ~= currentScale then |
541 refreshReason = 'map scale updated' | 468 refreshReason = 'map scale updated' |
546 end | 473 end |
547 if not refreshReason then | 474 if not refreshReason then |
548 return | 475 return |
549 end | 476 end |
550 | 477 |
551 | |
552 if self:IsVisible() then | 478 if self:IsVisible() then |
553 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason) | 479 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason) |
554 self:Refresh(event) | 480 self:Refresh(event) |
555 else | 481 else |
556 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason) | 482 print('|cFF00FFFFRefreshIfChanged()|r', refreshReason) |
557 self.isStale = true | 483 self.isStale = true |
558 end | 484 end |
559 end | 485 end |
560 | 486 |
561 -- update visibility states of all pins | 487 -- marks a pin set for passive update |
562 function Module:MarkAllPins(pins) | 488 function Module:MarkAllPins(pins) |
563 --print(' |cFFFFFF00'..self:GetName()..':MarkAllPins()|r', pins) | 489 --print(' |cFFFFFF00'..self:GetName()..':MarkAllPins()|r', pins) |
564 pins = pins or db.QuestsByID | 490 pins = pins or db.QuestsByID |
565 for questID, pin in pairs(pins) do | 491 for questID, pin in pairs(pins) do |
566 pin.isStale = true | 492 pin.isStale = true |
567 --rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used) | 493 --rprint('|cFF00FF00filter', pin.questID, pin.filtered, 'used:', pin.used) |
568 end | 494 end |
569 end | 495 end |
570 | 496 |
571 -- Updates quest markers in taskInfo while associating them with the given map | 497 -- Walks the current map tree and fires updates as needed |
498 function Module:UpdateAnchors () | |
499 wipe(self.UsedPositions) | |
500 print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()') | |
501 local hostWidth, hostHeight = WorldMapPOIFrame:GetSize() | |
502 | |
503 if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then | |
504 self.hostWidth, self.hostHeight = hostWidth, hostHeight | |
505 layoutDirty = true | |
506 end | |
507 | |
508 --rprint('|cFF00FF00'..self:GetName()..':UpdateAnchors()') | |
509 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() | |
510 if isMicroDungeon then | |
511 return | |
512 end | |
513 | |
514 isDataLoaded = true | |
515 local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID) | |
516 if taskInfo then | |
517 self:UpdateQuestsForMap(taskInfo, db.currentMapID) | |
518 end | |
519 local numZones = MC_GetNumZones(db.currentMapID) | |
520 if numZones then | |
521 for i = 1, numZones do | |
522 local mapAreaID = MC_GetZoneInfo(db.currentMapID, i) | |
523 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID) | |
524 | |
525 db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {} | |
526 | |
527 if taskInfo then | |
528 self:UpdateQuestsForMap(taskInfo, mapAreaID) | |
529 end | |
530 end | |
531 end | |
532 end | |
533 | |
534 -- Applies map association to the pins corresponding with each TaskInfo item | |
572 function Module:UpdateQuestsForMap(taskInfo, mapID) | 535 function Module:UpdateQuestsForMap(taskInfo, mapID) |
573 print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty) | 536 print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty) |
574 if db.QuestsByZone[mapID] then | 537 if db.QuestsByZone[mapID] then |
575 wipe(db.QuestsByZone[mapID]) | 538 wipe(db.QuestsByZone[mapID]) |
576 end | 539 elseif db.isBrokenIsle then |
577 | 540 continentScanned = true |
541 end | |
578 | 542 |
579 for index, info in pairs(taskInfo) do | 543 for index, info in pairs(taskInfo) do |
580 | |
581 local questID, x, y = info.questId, info.x, info.y | 544 local questID, x, y = info.questId, info.x, info.y |
582 local pin = self:AcquirePin(info) | 545 local pin = self:AcquirePin(info) |
583 | 546 |
584 if pin then | 547 if pin then |
585 pin.used = true | 548 pin.used = true |
586 print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame)) | 549 print(pin.title, pin.isStale, layoutDirty, (pin.owningFrame ~= WorldMapFrame)) |
587 if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then | 550 if pin:IsShown() and (layoutDirty or pin.isStale or (pin.owningFrame ~= WorldMapFrame)) then |
588 local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1] | 551 local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1] |
589 pin.owningFrame = WorldMapFrame | 552 pin.owningFrame = WorldMapFrame |
590 pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor) | 553 pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor) |
591 if pin.isStale then | 554 if pin.isStale then |
592 pin:Refresh('WORLDMAP_REFRESH ' .. GetTime()) | 555 pin:Refresh('WORLDMAP_REFRESH ' .. GetTime()) |
593 end | 556 end |
598 end | 561 end |
599 | 562 |
600 if db.QuestsByZone[mapID] and pin.used then | 563 if db.QuestsByZone[mapID] and pin.used then |
601 db.QuestsByZone[mapID][questID] = pin | 564 db.QuestsByZone[mapID][questID] = pin |
602 end | 565 end |
603 | 566 end |
604 end | 567 end |
605 end | 568 end |
606 end | 569 |
607 | 570 -- locates or creates a corresponding pin frame for the provided TaskInfo data |
608 -- Used to refresh the visible quest markers | 571 function Module:AcquirePin (info) |
609 function Module:UpdateAnchors () | 572 local questID = info.questId |
610 wipe(self.UsedPositions) | 573 if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then |
611 print(' |cFF00FF00'..self:GetName()..':UpdateAnchors()') | 574 return nil |
612 local hostWidth, hostHeight = WorldMapPOIFrame:GetSize() | 575 end |
613 | 576 |
614 if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then | 577 local pin = db.QuestsByID[questID] |
615 self.hostWidth, self.hostHeight = hostWidth, hostHeight | 578 if not pin then |
616 layoutDirty = true | 579 local numFree = #db.FreePins |
617 end | 580 if numFree >= 1 then |
618 | 581 pin = tremove(db.FreePins, numFree) |
619 | 582 print('|cFF00FF00Re-using', pin:GetName()) |
620 --rprint('|cFF00FF00'..self:GetName()..':UpdateAnchors()') | 583 else |
621 local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo() | 584 totalPins = totalPins + 1 |
622 if isMicroDungeon then | 585 local name = 'WorldPlanQuestMarker' .. numOverlays |
623 return | 586 print('|cFF00FF00Creating', name) |
624 end | 587 pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin') |
625 | 588 |
626 isDataLoaded = true | 589 pin:SetID(totalPins) |
627 local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID) | 590 numOverlays = numOverlays + 1 |
628 if taskInfo then | 591 --pin.iconBorder:SetVertexColor(0,0,0,1) |
629 self:UpdateQuestsForMap(taskInfo, db.currentMapID) | 592 end |
630 end | 593 pin.questID = questID |
631 local numZones = MC_GetNumZones(db.currentMapID) | 594 pin.worldQuest = true |
632 if numZones then | 595 pin.throttle = pin.updateRate |
633 for i = 1, numZones do | 596 pin.isNew = true |
634 local mapAreaID = MC_GetZoneInfo(db.currentMapID, i) | 597 pin.currentWidth = nil |
635 local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID) | 598 db.QuestsByID[questID] = pin |
636 | 599 tinsert(db.UsedPins, pin) |
637 db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {} | 600 end |
638 | 601 |
639 if taskInfo then | 602 if IsQuestComplete(questID) then |
640 self:UpdateQuestsForMap(taskInfo, mapAreaID) | 603 pin:Release() |
641 end | 604 return nil |
642 end | 605 elseif info then |
643 end | 606 pin.inProgress = info.inProgress |
644 end | 607 pin.floor = info.floor |
645 | 608 pin.numObjectives = info.numObjectives or 0 |
646 function ToggleButton:OnShow() | 609 if info.x and info.y then |
647 self:SetChecked(db.Config.EnablePins and true or false) | 610 if (info.x ~= pin.x) or (info.y ~= pin.y) then |
648 end | 611 pin.isStale = true |
649 function ToggleButton:OnClick() | 612 --rprint('|cFFFF4400SetCoords|r', info.x, info.y) |
650 --print(self:GetChecked()) | 613 end |
651 db.Config.EnablePins = self:GetChecked() | 614 end |
652 _G.WorldPlan:OnConfigUpdate() | 615 end |
653 end | 616 |
617 pin.x = info.x or pin.x | |
618 pin.y = info.y or pin.y | |
619 | |
620 if not HaveQuestRewardData(questID) then | |
621 TQ_RequestPreloadRewardData(questID); | |
622 end | |
623 | |
624 if (not pin.dataLoaded) then | |
625 local dataLoaded = pin:GetData() | |
626 if dataLoaded then | |
627 WorldPlan.dataFlush = true | |
628 else | |
629 isDataLoaded = false | |
630 end | |
631 end | |
632 | |
633 pin.isActive = TQ_IsActive(questID) | |
634 pin:GetCriteriaState() | |
635 pin:CheckFilterRules() | |
636 --rprint(pin:GetID(), pin.filtered, pin.used) | |
637 return pin | |
638 end | |
639 | |
640 function Module:Debug(...) | |
641 print(...) | |
642 end |