annotate ObjectiveTracker/QuestTracker.lua @ 25:4b3da1b221de v1.0-beta

- distinction between all possible types of values for the 'isComplete' field - style polish applied to title headers - clickable regions altered to somewhat match those of the blizzard objectives tracker, for more world frame space and quicker user familiarity
author Nenue
date Wed, 13 Apr 2016 11:20:09 -0400
parents 66b927b46776
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