comparison ObjectiveTracker/Quests.lua @ 37:e84d645c8ab8

- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used - also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times - schema handling polish
author Nenue
date Mon, 18 Apr 2016 07:56:23 -0400
parents 69d03f8e293e
children 1f8f9cc3d956
comparison
equal deleted inserted replaced
36:a487841050be 37:e84d645c8ab8
7 local GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches = GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches 7 local GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches = GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches
8 local GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup = GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup 8 local GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup = GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup
9 local QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY = QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY 9 local QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY = QUEST_TAG_ACCOUNT, LE_QUEST_FACTION_HORDE, LE_QUEST_FREQUENCY_DAILY, LE_QUEST_FREQUENCY_WEEKLY
10 local QUEST_TAG_TCOORDS, IsQuestSequenced = QUEST_TAG_TCOORDS, IsQuestSequenced 10 local QUEST_TAG_TCOORDS, IsQuestSequenced = QUEST_TAG_TCOORDS, IsQuestSequenced
11 local Default, Quest = T.DefaultHandler, T.Quest 11 local Default, Quest = T.DefaultHandler, T.Quest
12 local format = format 12 local format, wipe, select = format, table.wipe, select
13 local print = B.print('Tracker') 13 local wipeall = B.wipeall
14 local lprint = B.print('Line') 14 local lprint, iprint, tprint = B.print('Line'), B.print('Info'), B.print('Tracker')
15 local iprint = B.print('Info') 15 local print = tprint
16 local colors = T.colors
17 local tprint = B.print('Tracker')
18 16
19 local superTrackQuestID, playerMoney, inScenario, showPOIs 17 local superTrackQuestID, playerMoney, inScenario, showPOIs
20 Quest.Update = function(self, reason, ...) 18 Quest.Update = function(self, reason, ...)
21 local print = tprint 19 local print = tprint
22 print('QuestTracker:Update() received') 20 print('QuestTracker:Update() received')
77 return data.text, nil, objectiveType 75 return data.text, nil, objectiveType
78 end 76 end
79 77
80 ----------------------------- 78 -----------------------------
81 --- QUEST 79 --- QUEST
80 local tremove, tinsert = tremove, tinsert
81 local GetQuestLogIndexByID, IsQuestWatched = GetQuestLogIndexByID, IsQuestWatched
82 Quest.QuestBlock = {} 82 Quest.QuestBlock = {}
83 Quest.LogBlock = {} 83 Quest.LogBlock = {}
84 Quest.LogInfo = {} 84 Quest.LogInfo = {}
85 85 function Quest:FreeBlock (block)
86 function Quest:GetNumWatched () 86 local used = Quest.usedBlocks
87 local free = Quest.freeBlocks
88 local reason = ''
89 local doRelease = false
90 local info = block.info
91 local questID = info.questID
92 local logIndex = info.logIndex
93
94 if info.posIndex then
95 if used[info.posIndex] == block then
96 doRelease = true
97 reason = 'posIndex mismatch'
98 end
99 elseif logIndex then
100 if not IsQuestWatched(logIndex) then
101 reason = 'not being watched'
102 elseif not self.LogBlock[logIndex] then
103 doRelease = true
104 reason = 'missing logBlock entry'
105 elseif (self.LogBlock[logIndex] ~= block) then
106 doRelease = true
107 reason = 'different block using index'
108 end
109 elseif info.questID then
110 if not GetQuestLogIndexByID(info.questID) then
111 doRelease = true
112 reason = 'no identifiable quest log entry'
113 end
114 end
115
116
117 if doRelease then
118 print(' |cFF00FF00FreeBlock (' .. block:GetName() .. '):', reason)
119 block:Hide()
120 tremove(used, info.posIndex)
121 tinsert(free, block)
122 end
123
124
125 end
126 local watchesChecked = {}
127 local infosChecked = {}
128 local blocksChecked = {}
129 local GetQuestWatchIndex = GetQuestWatchIndex
130 --- Get a total of things to show, and straighten out the index while we're at it
131 --- Return the number shown, total in log, and the info table to parse
132 Quest.GetNumWatched = function (self, id, added)
87 superTrackQuestID = GetSuperTrackedQuestID() 133 superTrackQuestID = GetSuperTrackedQuestID()
88 playerMoney = GetMoney(); 134 playerMoney = GetMoney();
89 inScenario = C_Scenario.IsInScenario(); 135 inScenario = C_Scenario.IsInScenario();
90 showPOIs = GetCVarBool("questPOI"); 136 showPOIs = GetCVarBool("questPOI");
91 self.numAll = GetNumQuestLogEntries() 137 local numAll = GetNumQuestLogEntries()
92 self.numWatched = GetNumQuestWatches() 138 local numWatched = GetNumQuestWatches()
93 return self.numWatched, self.numAll 139 local bottomIndex = 1
94 end 140 print(' |cFF00FF88GetNumWatched:|r',self.name, numWatched, 'of', numAll)
141 local start, limit = 1, numAll
142
143 --- start a list of blocks affected by this function
144 wipe(blocksChecked)
145 if id and not added then
146 if self.InfoBlock[id] then
147 tinsert(blocksChecked, self.InfoBlock[id])
148 end
149 end
150
151 for logIndex = start, limit do
152 local reason1, reason2 = '', ''
153 local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex)
154 local watchIndex = GetQuestWatchIndex(logIndex)
155
156 if watchIndex and watchIndex >= bottomIndex then
157 local watchInfo = self.WatchInfo[watchIndex]
158 local watchBlock = self.WatchBlock[watchIndex]
159 if watchInfo and watchInfo.questID ~= questID then
160 print(' |cFFBBFF00GetNumWatched: trimming WatchInfo ['..watchIndex..'] =/=', questID)
161 self.WatchInfo[watchIndex] = nil
162 end
163 if watchBlock and watchBlock.info.questID ~= questID then
164 print(' |cFFBBFF00GetNumWatched: trimming WatchBlock ['..watchIndex..'] =/=', watchBlock:GetName())
165 self.WatchBlock[watchIndex] = nil
166 tinsert(blocksChecked, watchBlock)
167 end
168 end
169
170 local logBlock = self.LogBlock[logIndex]
171 if logBlock and logBlock.info.questID ~= questID then
172 --print(' |cFFBBFF00GetNumWatched: trimming LogBlock ['..logIndex..'] =/=', logBlock:GetName())
173 self.LogBlock[logIndex] = nil
174 tinsert(blocksChecked, logBlock)
175 end
176
177 if questID ~= 0 then
178 self.Info[questID] = self:GetInfo(logIndex, watchIndex)
179 --print(' |cFF44BBFFGetNumWatched:|r map', questID, 'to', logIndex, (watchIndex and ('('..watchIndex..')') or ''))
180 end
181 end
182
183 --- remove any orphaned blocks from view and, if possible, free it for re-use
184 for i, block in ipairs(blocksChecked) do
185 if not GetQuestLogIndexByID(block.info.questID, 'player') then
186 print(' |cFFBBFF00GetNumWatched:|r literating a block without an index |cFFBBFF00'.. block:GetName()..'|r')
187 block:Hide()
188 self:FreeBlock(block)
189 end
190 if not IsQuestWatched(block.info.logIndex) then
191 print(' |cFFBBFF00GetNumWatched:|r hiding untracked quest |cFFBBFF00'.. block:GetName()..'|r')
192 block:Hide()
193 end
194 end
195
196 self.numWatched = numWatched
197 self.numAll = numAll
198
199 return numWatched, numAll, self.WatchList
200 end
201
95 202
96 --- Returns an iterable table from which tracker blocks can be filled out. Data includes: 203 --- Returns an iterable table from which tracker blocks can be filled out. Data includes:
97 -- All entry-layer GetXInfo return values 204 -- All entry-layer GetXInfo return values
98 -- Manifest of line data to be displayed in relation to the tracked object 205 -- Manifest of line data to be displayed in relation to the tracked object
99 Quest.GetInfo = function (self, watchIndex) 206 Quest.GetInfo = function (self, logIndex, watchIndex)
100 local print = iprint 207 local print = iprint
101 208 local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex)
102 local questID, title, questLogIndex, numObjectives, requiredMoney, isComplete, startEvent, isAutoComplete,
103 failureTime, timeElapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(watchIndex)
104 if ( not questID ) then 209 if ( not questID ) then
210 tprint(' |cFFFF0088GetInfo:|r', logIndex, watchIndex, '|cFFFF2299no data|r')
105 return 211 return
106 end 212 end
107 213
108 tprint(' |cFFFFBB00GetInfo:|r', watchIndex, '|cFFFF2299'..title..'|r')
109 local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex)
110
111 Quest.Info[questID] = Quest.Info[questID] or {} 214 Quest.Info[questID] = Quest.Info[questID] or {}
112
113
114 local q = Quest.Info[questID] 215 local q = Quest.Info[questID]
216 q.questID = questID
217 q.id = questID
218 q.logIndex = logIndex
219 q.watchIndex = watchIndex
220
221 local numObjectives, requiredMoney, isAutoComplete, failureTime, timeElapsed, questType
222 = 0, 0, nil, false, false, 0
223 if watchIndex then
224 local _
225 _,_,_, numObjectives, requiredMoney, _, _, isAutoComplete,
226 failureTime, timeElapsed, questType = GetQuestWatchInfo(watchIndex)
227 self.WatchList[watchIndex] = q
228 --tprint(' |cFF88FF00GetInfo:|r set watch entry', watchIndex)
229 tprint(' |cFFFFBB00GetInfo:|r', logIndex, watchIndex, '|cFFFF2299'..title..'|r')
230 end
231 self.LogInfo[logIndex] = q
232
233 q.numObjectives = numObjectives
234 q.requiredMoney = requiredMoney
235 q.failureTime = failureTime
236 q.timeElapsed = timeElapsed
237
238
239
115 q.type = 'Quest' 240 q.type = 'Quest'
116 q.title = title 241 q.title = title
117 q.level = level 242 q.level = level
118 q.displayQuestID = displayQuestID 243 q.displayQuestID = displayQuestID
119 q.suggestedGroup = suggestedGroup 244 q.suggestedGroup = suggestedGroup
172 297
173 temp_status = 'PROGRESS_OBJECTIVES' 298 temp_status = 'PROGRESS_OBJECTIVES'
174 -- Case 3: quest in progress 299 -- Case 3: quest in progress
175 -- * Multiple objective lines 300 -- * Multiple objective lines
176 -- * Possible extra lines for money and timer data respectively 301 -- * Possible extra lines for money and timer data respectively
177 objectives = Quest.GetObjectives(questLogIndex, numObjectives, false, isSequenced, isStory) 302 objectives = Quest.GetObjectives(logIndex, numObjectives, false, isSequenced, isStory)
178 q.objectives = objectives 303 q.objectives = objectives
179 304
180 --- anything past here gets appended to existing objectives 305 --- anything past here gets appended to existing objectives
181 306
182 -- money 307 -- money
206 } 331 }
207 tinsert(objectives, timerInfo) 332 tinsert(objectives, timerInfo)
208 end 333 end
209 end 334 end
210 end 335 end
211 q.numObjectives = numObjectives
212 q.objectives = objectives 336 q.objectives = objectives
213 q.requiredMoney = requiredMoney
214 q.moneyInfo = moneyInfo 337 q.moneyInfo = moneyInfo
215 q.timerInfo = timerInfo 338 q.timerInfo = timerInfo
216 q.failureTime = failureTime
217 q.timeElapsed = timeElapsed
218 q.completionText = completionText 339 q.completionText = completionText
219 340
220 -- POI data 341 -- POI data
221 local POI = false 342 local POI = false
222 if ( showPOIs ) then 343 if ( showPOIs ) then
223 POI = { 344 POI = {
224 questID = questID, 345 questID = questID,
225 questLogIndex = questLogIndex, 346 logIndex = logIndex,
347 watchIndex = watchIndex
226 } 348 }
227 local poiButton; 349 local poiButton;
228 if ( hasLocalPOI ) then 350 if ( hasLocalPOI ) then
229 351
230 if ( isComplete ) then 352 if ( isComplete ) then
234 end 356 end
235 elseif ( isComplete ) then 357 elseif ( isComplete ) then
236 POI.type = 'remote' 358 POI.type = 'remote'
237 end 359 end
238 360
239 local distance, onContinent = GetDistanceSqToQuest(questLogIndex) 361 local distance, onContinent = GetDistanceSqToQuest(logIndex)
240 if distance ~= nil and distance > 0 then 362 if distance ~= nil and distance > 0 then
241 POI.distance = distance 363 POI.distance = distance
242 POI.onContinent = onContinent 364 POI.onContinent = onContinent
243 end 365 end
244 end 366 end
246 368
247 --- Block Tags 369 --- Block Tags
248 -- completionTag - in progres, complete, failed, autocomplete 370 -- completionTag - in progres, complete, failed, autocomplete
249 -- typeTag - account, faction, pvp, dungeon, group 371 -- typeTag - account, faction, pvp, dungeon, group
250 -- frequencyTag - daily/weekly 372 -- frequencyTag - daily/weekly
373 local schema = 'default'
251 local questTagID, tagName = GetQuestTagInfo(questID) 374 local questTagID, tagName = GetQuestTagInfo(questID)
252 local tagInfo = {} 375 local tagInfo = {}
253 local tagCoords = {} 376 local tagCoords = {}
254 local factionGroup = GetQuestFactionGroup(questID); 377 local factionGroup = GetQuestFactionGroup(questID);
255 if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then 378 if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then
256 if( factionGroup ) then 379 if( factionGroup ) then
257 tagID = "ALLIANCE" 380 tagID = "ALLIANCE"
381 schema = 'alliance'
258 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then 382 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then
259 tagID = "HORDE" 383 tagID = "HORDE"
384 schema = 'horde'
260 end 385 end
261 isFaction = true 386 isFaction = true
262 else 387 else
263 tagID = QUEST_TAG_ACCOUNT 388 tagID = QUEST_TAG_ACCOUNT
264 isAccount = true 389 isAccount = true
278 if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then 403 if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then
279 tagID = 'DAILY' 404 tagID = 'DAILY'
280 tagInfo['frequencyTag'] = tagID 405 tagInfo['frequencyTag'] = tagID
281 tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] 406 tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID]
282 isDaily = true 407 isDaily = true
408 schema = 'daily'
283 elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then 409 elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then
284 tagID = 'WEEKLY' 410 tagID = 'WEEKLY'
285 tagInfo['frequencyTag'] = tagID 411 tagInfo['frequencyTag'] = tagID
286 tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] 412 tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID]
287 isWeekly = true 413 isWeekly = true
414 schema = 'weekly'
288 elseif( questTagID ) then 415 elseif( questTagID ) then
289 tagID = questTagID 416 tagID = questTagID
290 end 417 end
291 418
292 if( isComplete ) then 419 if( isComplete ) then
301 -- establishes the primary block tag for view compacting 428 -- establishes the primary block tag for view compacting
302 q.tagID = tagID 429 q.tagID = tagID
303 q.tagName = tagName 430 q.tagName = tagName
304 431
305 -- action button information 432 -- action button information
306 local link, icon, charges = GetQuestLogSpecialItemInfo(questLogIndex) 433 local link, icon, charges = GetQuestLogSpecialItemInfo(logIndex)
307 local start, duration, enable = GetQuestLogSpecialItemCooldown(questLogIndex) 434 local start, duration, enable = GetQuestLogSpecialItemCooldown(logIndex)
308 if link or icon or charges then 435 if link or icon or charges then
309 q.specialItem = { 436 q.specialItem = {
310 questID = questID, 437 questID = questID,
311 questLogIndex = questLogIndex, 438 logIndex = questLogIndex,
312 link = link, 439 link = link,
313 charges = charges, 440 charges = charges,
314 icon = icon, 441 icon = icon,
315 start = start, 442 start = start,
316 duration = duration, 443 duration = duration,
339 q.selected = (questID == superTrackQuestID) 466 q.selected = (questID == superTrackQuestID)
340 467
341 T.SetRewards(q, questID) 468 T.SetRewards(q, questID)
342 469
343 q.questID = questID 470 q.questID = questID
344 q.logIndex = questLogIndex 471 q.logIndex = logIndex
345 q.watchIndex = watchIndex 472 q.watchIndex = watchIndex
346 q.id = questID 473 q.id = questID
347 self.WatchInfo[watchIndex] = q 474 q.schema = schema
348 self.LogInfo[questLogIndex] = q
349 475
350 if Devian and Devian.InWorkspace() then 476 if Devian and Devian.InWorkspace() then
351 print('|cFF00DDFFstatus:|r', temp_status, '|cFF00FF00questLogIndex|r:', questLogIndex, title) 477 print('|cFF00DDFFstatus:|r', temp_status, '|cFF00FF00questLogIndex|r:', logIndex, title)
352 local temp ={} 478 local temp ={}
353 local data_txt = '|cFFFF4400values:|r' 479 local data_txt = '|cFFFF4400values:|r'
354 for k,v in pairs(q) do 480 for k,v in pairs(q) do
355 if type(v) =='number' then 481 if type(v) =='number' then
356 data_txt = data_txt .. ' |cFFFFFF00'..k..'|r: ' .. tostring(v) 482 data_txt = data_txt .. ' |cFFFFFF00'..k..'|r: ' .. tostring(v)
369 end 495 end
370 496
371 return q 497 return q
372 end 498 end
373 499
374 Quest.GetObjectives = function(questLogIndex, numObjectives, isComplete, isSequenced, isStory) 500 Quest.GetObjectives = function(logIndex, numObjectives, isComplete, isSequenced, isStory)
375 local objectives = {} 501 local objectives = {}
376 for i = 1, numObjectives do 502 for i = 1, numObjectives do
377 local text, type, finished = GetQuestLogLeaderBoard(i, questLogIndex) 503 local text, type, finished = GetQuestLogLeaderBoard(i, logIndex)
378 print(format(' |cFFFF4400GetObjectives:|r #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished))) 504 print(format(' |cFFFF4400GetObjectives:|r #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)))
379 objectives[i] = { 505 objectives[i] = {
380 index = i, 506 index = i,
381 type = type, 507 type = type,
382 text = text, 508 text = text,