annotate ObjectiveTracker/QuestTracker.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 4b3da1b221de
children
rev   line source
Nenue@23 1 local B = select(2,...).frame
Nenue@23 2 local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
Nenue@23 3 local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band
Nenue@23 4 local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText
Nenue@23 5 local Default, Quest = T.DefaultHandler, T.Quest
Nenue@23 6 local format = format
Nenue@23 7 local print = B.print('Tracker')
Nenue@23 8 local lprint = B.print('Line')
Nenue@24 9 local iprint = B.print('Info')
Nenue@23 10
Nenue@23 11 local colors = T.colors
Nenue@24 12
Nenue@24 13 local tprint = B.print('Tracker')
Nenue@24 14 Quest.Update = function(self, reason, ...)
Nenue@24 15 local print = tprint
Nenue@24 16 print('QuestTracker:Update() received')
Nenue@24 17 T.UpdateActionButtons()
Nenue@24 18 Default.Update(self, reason, ...)
Nenue@24 19 end
Nenue@24 20
Nenue@23 21 Quest.UpdateObjectives = function(handler, block)
Nenue@23 22 local print = lprint
Nenue@23 23 print('|cFF00FFFFUpdateObjectives()')
Nenue@23 24 local info = block.info
Nenue@23 25
Nenue@23 26 local titlebg, textbg = colors.default.titlebg, colors.default.textbg
Nenue@23 27 print((info.isAccount and 'isAccount' or ''), (info.isFaction and 'isFaction' or ''), (info.isDaily and 'isDaily' or ''), (info.isWeekly and 'isWeekly' or ''), info.tagID, info.tagName)
Nenue@23 28
Nenue@23 29 if info.isAccount then
Nenue@23 30 if info.isFaction then
Nenue@23 31 print(' faction', info.tagID)
Nenue@23 32 titlebg, textbg = colors['faction_'..info.tagID].titlebg, colors.default.textbg
Nenue@23 33 else
Nenue@23 34 print(' account', info.isAccount, info.isFaction)
Nenue@23 35 titlebg, textbg = colors.account.titlebg, colors.account.textbg
Nenue@23 36 end
Nenue@23 37 elseif info.isDaily then
Nenue@23 38 print(' daily', info.frequency)
Nenue@23 39 titlebg, textbg = colors.daily.titlebg, colors.daily.textbg
Nenue@23 40 elseif info.isWeekly then
Nenue@23 41 print(' weekly', info.frequency)
Nenue@23 42 titlebg, textbg = colors.weekly.titlebg, colors.weekly.textbg
Nenue@23 43 end
Nenue@23 44
Nenue@23 45 block.titlebg:SetGradientAlpha(unpack(titlebg))
Nenue@23 46 block.statusbg:SetGradientAlpha(unpack(textbg))
Nenue@23 47
Nenue@23 48 local completionText
Nenue@23 49 if info.isComplete then
Nenue@25 50 if info.isAutoComplete then
Nenue@25 51 local questID, popupType = GetAutoQuestPopUp(info.questLogIndex)
Nenue@25 52 if popupType == 'COMPLETE' then
Nenue@25 53 print(' :: auto-complete quest :: set the message')
Nenue@25 54 info.completionText = T.strings.CLICK_TO_COMPLETE
Nenue@25 55 end
Nenue@25 56 else
Nenue@25 57 if not completionText or info.completionText then
Nenue@25 58 info.completionText = GetQuestLogCompletionText(info.questLogIndex)
Nenue@25 59 end
Nenue@23 60 end
Nenue@23 61 print(' :: complete quest :: show instruction: "'.. tostring(info.completionText) .. '"')
Nenue@23 62 end
Nenue@23 63
Nenue@23 64 Default.UpdateObjectives(handler, block)
Nenue@23 65 end
Nenue@23 66
Nenue@23 67 Quest.UpdateLine = function(handler, block, line, data)
Nenue@23 68 local print = lprint
Nenue@23 69 local objectiveType = data.type
Nenue@23 70 local r, g, b, a = 0, 1, 1, 1
Nenue@23 71
Nenue@23 72 line.progress = 0
Nenue@23 73 if data.finished then
Nenue@23 74 line.progress = 2
Nenue@23 75 r, g, b, a = 0, 1, 0, 1
Nenue@23 76 elseif objectiveType == 'monster' then
Nenue@23 77 r, g, b, a = 1, .55, .2, 1
Nenue@23 78 elseif objectiveType == 'item' then
Nenue@23 79 r, g, b, a = .8, .8, .8, 1
Nenue@23 80 elseif objectiveType == 'object' then
Nenue@23 81 r, g, b, a = 1, 1, 1, 1
Nenue@23 82 elseif objectiveType == 'player' then
Nenue@23 83 r, g, b, a = 0, 0.8, 1, 1
Nenue@23 84 end
Nenue@23 85 print(format(' |cFF%02X%02X%02X%0.1f, %0.1f, %0.1f|r', (r * 255), g * 255, b * 255, r, g, b))
Nenue@23 86
Nenue@23 87 line.displayColor = {r, g, b, a}
Nenue@23 88 line.status:SetTextColor(r, g, b, a)
Nenue@23 89 line.displayText = data.text
Nenue@23 90
Nenue@23 91 return line
Nenue@23 92 end
Nenue@23 93
Nenue@23 94 -----------------------------
Nenue@23 95 --- QUEST
Nenue@23 96 Quest.POI = {}
Nenue@23 97 Quest.QuestBlock = {}
Nenue@23 98 Quest.LogBlock = {}
Nenue@23 99 Quest.LogInfo = {}
Nenue@23 100
Nenue@23 101 function Quest:GetNumWatched ()
Nenue@23 102 print(self.name, self)
Nenue@23 103 self.numAll = GetNumQuestLogEntries()
Nenue@23 104 self.numWatched = GetNumQuestWatches()
Nenue@23 105 return self.numWatched, self.numAll
Nenue@23 106 end
Nenue@23 107 Quest.GetInfo = function (self, watchIndex)
Nenue@24 108 local print = iprint
Nenue@23 109 print('|cFF00DDFFQuest|r.|cFF0088FFGetInfo(|r'.. tostring(watchIndex)..'|r)')
Nenue@24 110 local questID, title, questIndex, numObjectives, requiredMoney, _,
Nenue@24 111 _, isAutoComplete, failureTime, timeElapsed, questType, _, _, _, _ = GetQuestWatchInfo(watchIndex)
Nenue@23 112
Nenue@23 113 if not questIndex then
Nenue@23 114 return
Nenue@23 115 end
Nenue@23 116
Nenue@25 117
Nenue@23 118 local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questIndex)
Nenue@23 119
Nenue@23 120
Nenue@23 121 if not questID then
Nenue@23 122 return
Nenue@23 123 end
Nenue@23 124 Quest.Info[questID] = Quest.Info[questID] or {}
Nenue@23 125
Nenue@23 126 local q = Quest.Info[questID]
Nenue@23 127 q.watchIndex = watchIndex
Nenue@23 128 q.type = 'Quest'
Nenue@23 129 q.questID = questID
Nenue@23 130 q.title = title
Nenue@23 131 q.level = level
Nenue@23 132 q.displayQuestID = displayQuestID
Nenue@23 133 q.suggestedGroup = suggestedGroup
Nenue@23 134 q.questLogIndex = questIndex
Nenue@23 135 q.numObjectives = numObjectives
Nenue@23 136 q.requiredMoney = requiredMoney
Nenue@23 137 q.isComplete = isComplete
Nenue@23 138 q.startEvent = startEvent
Nenue@23 139 q.isAutoComplete = isAutoComplete
Nenue@23 140 q.failureTime = failureTime
Nenue@23 141 q.timeElapsed = timeElapsed
Nenue@23 142 q.questType = questType
Nenue@23 143 q.isTask = isTask
Nenue@23 144 q.isStory = isStory
Nenue@23 145 q.isOnMap = isOnMap
Nenue@23 146 q.hasLocalPOI = hasLocalPOI
Nenue@23 147 q.frequency = frequency
Nenue@23 148 q.isComplete = isComplete
Nenue@23 149 q.isStory = isStory
Nenue@23 150 q.isTask = isTask
Nenue@23 151
Nenue@23 152 --- resolve icon type and template
Nenue@23 153 local questTagID, tagName = GetQuestTagInfo(questID)
Nenue@23 154 local tagID
Nenue@23 155
Nenue@23 156 local factionGroup = GetQuestFactionGroup(questID);
Nenue@23 157 if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then
Nenue@23 158 if( factionGroup ) then
Nenue@23 159 tagID = "ALLIANCE";
Nenue@23 160 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then
Nenue@23 161 tagID = "HORDE";
Nenue@23 162 end
Nenue@23 163 q.isFaction = true
Nenue@23 164 else
Nenue@23 165 tagID = QUEST_TAG_ACCOUNT;
Nenue@23 166 q.isAccount = true
Nenue@23 167 end
Nenue@23 168 q.typeTag = QUEST_TAG_TCOORDS[tagID]
Nenue@23 169 elseif ( factionGroup) then
Nenue@23 170 tagID = "ALLIANCE";
Nenue@23 171 if ( factionGroup == LE_QUEST_FACTION_HORDE ) then
Nenue@23 172 tagID = "HORDE";
Nenue@23 173 end
Nenue@23 174 q.isFaction = true
Nenue@23 175 end
Nenue@23 176
Nenue@23 177 if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then
Nenue@23 178 tagID = "DAILY";
Nenue@23 179 q.frequencyTag = QUEST_TAG_TCOORDS["DAILY"]
Nenue@23 180 q.isDaily = true
Nenue@23 181 elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then
Nenue@23 182 tagID = "WEEKLY";
Nenue@23 183 q.frequencyTag = QUEST_TAG_TCOORDS["WEEKLY"]
Nenue@23 184 q.isWeekly = true
Nenue@23 185 elseif( questTagID ) then
Nenue@23 186 tagID = questTagID;
Nenue@23 187 end
Nenue@23 188
Nenue@23 189 if ( isComplete and isComplete < 0 ) then
Nenue@23 190 q.completionTag = QUEST_TAG_TCOORDS["FAILED"]
Nenue@23 191 q.isFailed = true
Nenue@23 192 elseif isComplete then
Nenue@23 193 q.completionTag = QUEST_TAG_TCOORDS["COMPLETED"]
Nenue@23 194 end
Nenue@23 195
Nenue@23 196
Nenue@23 197 q.tagID = questTagID
Nenue@23 198 q.tagName = tagName
Nenue@23 199 --q.isBreadCrumb = isBreadCrumb
Nenue@23 200 q.completionText= GetQuestLogCompletionText(questIndex)
Nenue@23 201 q.numObjectives = GetNumQuestLeaderBoards(questIndex)
Nenue@23 202 q.objectives = {}
Nenue@23 203 for i = 1, q.numObjectives do
Nenue@23 204 local text, type, finished = GetQuestLogLeaderBoard(i, questIndex)
Nenue@23 205 print(format(' #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)))
Nenue@23 206 q.objectives[i] = {
Nenue@23 207 index = i,
Nenue@23 208 type = type,
Nenue@23 209 text = text,
Nenue@23 210 finished = finished
Nenue@23 211 }
Nenue@23 212 if type == 'event' then
Nenue@23 213 elseif type == 'monster' then
Nenue@23 214 elseif type == 'object' then
Nenue@23 215 elseif type == 'reputation' then
Nenue@23 216 elseif type == 'item' then
Nenue@23 217 end
Nenue@23 218 end
Nenue@23 219
Nenue@23 220 if requiredMoney >= 1 then
Nenue@23 221 local money = GetMoney()
Nenue@23 222 local moneyText = money
Nenue@23 223 local requiredSilver, requiredCopper
Nenue@23 224 local requiredGold = (requiredMoney > 10000) and (floor(requiredMoney/10000)) or nil
Nenue@23 225 if mod(requiredMoney, 10000) ~= 0 then
Nenue@23 226 requiredSilver = (requiredMoney > 100) and (mod(requiredMoney, 10000) / 100) or nil
Nenue@23 227 if mod(requiredMoney, 100) ~= 0 then
Nenue@23 228 requiredCopper = mod(requiredMoney, 100)
Nenue@23 229 end
Nenue@23 230 end
Nenue@23 231
Nenue@23 232 -- round the money value down
Nenue@23 233 if requiredMoney > 9999 and not (requiredSilver or requiredCopper) then
Nenue@23 234 moneyText = floor(money/10000)
Nenue@23 235 elseif requiredMoney < 10000 and mod(requiredMoney,100) == 0 then
Nenue@23 236 moneyText = floor(money/100)
Nenue@23 237 end
Nenue@23 238
Nenue@23 239 local text = moneyText
Nenue@23 240 local index = #q.objectives + 1
Nenue@23 241 local finished = (GetMoney() >= requiredMoney)
Nenue@23 242
Nenue@23 243 if not finished then
Nenue@23 244 text = text .. ' / ' .. GetCoinTextureString(requiredMoney, 12)
Nenue@23 245 else
Nenue@23 246 text = '' .. GetCoinTextureString(requiredMoney, 12)
Nenue@23 247 end
Nenue@23 248 q.objectives[index] = {
Nenue@23 249 index = index,
Nenue@23 250 type = 'progressbar',
Nenue@23 251 quantity = money,
Nenue@23 252 requiredQuantity = requiredMoney,
Nenue@23 253 text = text,
Nenue@23 254 finished = finished
Nenue@23 255 }
Nenue@23 256 print(format(' #%d %s %s %s', index, 'money', text, tostring(finished)))
Nenue@23 257 end
Nenue@23 258
Nenue@23 259
Nenue@23 260 local link, icon, charges = GetQuestLogSpecialItemInfo(questIndex)
Nenue@23 261 local start, duration, enable = GetQuestLogSpecialItemCooldown(questIndex)
Nenue@23 262 if link or icon or charges then
Nenue@23 263 q.specialItem = {
Nenue@23 264 questID = questID,
Nenue@23 265 questIndex = questIndex,
Nenue@23 266 link = link,
Nenue@23 267 charges = charges,
Nenue@23 268 icon = icon,
Nenue@23 269 start = start,
Nenue@23 270 duration = duration,
Nenue@23 271 enable = enable,
Nenue@23 272 }
Nenue@23 273 end
Nenue@23 274
Nenue@23 275 if QuestHasPOIInfo(questID) then
Nenue@23 276 local distance, onContinent = GetDistanceSqToQuest(questIndex)
Nenue@23 277 if distance ~= nil and distance > 0 then
Nenue@23 278 self.POI[questIndex] = {
Nenue@23 279 questIndex = questIndex,
Nenue@23 280 questID = questID,
Nenue@23 281 distance = distance,
Nenue@23 282 onContinent = onContinent
Nenue@23 283 }
Nenue@23 284 end
Nenue@23 285 end
Nenue@23 286
Nenue@23 287
Nenue@23 288 q.selected = (questID == GetSuperTrackedQuestID()) -- call directly so artifact data doesn't become an issue
Nenue@23 289 self.WatchInfo[watchIndex] = q
Nenue@23 290 self.LogInfo[questIndex] = q
Nenue@23 291 print('- logIndex =', questIndex, 'title =', title)
Nenue@25 292 for k,v in pairs(q) do
Nenue@25 293 print('|cFFFFFF00'..k..'|r:', v)
Nenue@25 294 end
Nenue@23 295 return q
Nenue@23 296 end
Nenue@23 297
Nenue@23 298 Quest.GetClosest = function()
Nenue@23 299 local minID, minTitle
Nenue@23 300 local minDist = math.huge
Nenue@23 301 local numQuests = GetNumQuestLogEntries()
Nenue@23 302 for questIndex = 1, numQuests do
Nenue@23 303 local distance, onContinent = GetDistanceSqToQuest(questIndex)
Nenue@23 304 local title, level, _, _, _, _, _, _, questID = GetQuestLogTitle(questIndex)
Nenue@23 305 if onContinent and distance < minDist then
Nenue@23 306 minDist = distance
Nenue@23 307 minTitle = title
Nenue@23 308 minID = questID
Nenue@23 309 end
Nenue@23 310 end
Nenue@23 311
Nenue@23 312 print('nearest quest is', minTitle, 'by', math.sqrt(minDist))
Nenue@23 313 return minID, minTitle, minDist
Nenue@23 314 end
Nenue@23 315
Nenue@23 316 Quest.OnTurnIn = function(self, questID, xp, money)
Nenue@23 317
Nenue@23 318 end