Mercurial > wow > buffalo2
diff ObjectiveTracker/Quests.lua @ 30:7583684becf4
- implement procedural block contents generation
- redo anchor calculations to allow for transitional animation
- attempt to sort out event handling quirks related to autopopup quest completion and turn-in
- revise the data structures created by the different GetInfo's
- start on trimming out redundant variables
author | Nenue |
---|---|
date | Thu, 14 Apr 2016 17:11:13 -0400 |
parents | adcd7c328d07 |
children | 48b3e3959a0a |
line wrap: on
line diff
--- a/ObjectiveTracker/Quests.lua Wed Apr 13 21:53:24 2016 -0400 +++ b/ObjectiveTracker/Quests.lua Thu Apr 14 17:11:13 2016 -0400 @@ -1,7 +1,13 @@ local B = select(2,...).frame local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame') local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band -local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText +local GetQuestWatchInfo, GetQuestLogCompletionText = GetQuestWatchInfo, GetQuestLogCompletionText +local GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle = GetQuestLogLeaderBoard, GetNumQuestLogEntries, GetQuestLogTitle +local GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, GetQuestLogSpecialItemCooldown +local GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches = GetSuperTrackedQuestID, GetMoney, C_Scenario, GetCVarBool, GetNumQuestWatches +local GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup = GetQuestTagInfo, GetMoneyString, GetDistanceSqToQuest, GetQuestFactionGroup +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 +local QUEST_TAG_TCOORDS, IsQuestSequenced = QUEST_TAG_TCOORDS, IsQuestSequenced local Default, Quest = T.DefaultHandler, T.Quest local format = format local print = B.print('Tracker') @@ -10,6 +16,7 @@ local colors = T.colors local tprint = B.print('Tracker') +local superTrackQuestID, playerMoney, inScenario, showPOIs Quest.Update = function(self, reason, ...) local print = tprint print('QuestTracker:Update() received') @@ -91,50 +98,255 @@ line.status:SetTextColor(r, g, b, a) line.displayText = data.text - return line + return data.text, nil end ----------------------------- --- QUEST -Quest.POI = {} Quest.QuestBlock = {} Quest.LogBlock = {} Quest.LogInfo = {} function Quest:GetNumWatched () print(self.name, self) + superTrackQuestID = GetSuperTrackedQuestID() + playerMoney = GetMoney(); + inScenario = C_Scenario.IsInScenario(); + showPOIs = GetCVarBool("questPOI"); self.numAll = GetNumQuestLogEntries() self.numWatched = GetNumQuestWatches() return self.numWatched, self.numAll end + +--- Returns an iterable table from which tracker blocks can be filled out. Data includes: +-- All entry-layer GetXInfo return values +-- Manifest of line data to be displayed in relation to the tracked object Quest.GetInfo = function (self, watchIndex) local print = iprint - print('|cFF00DDFFQuest|r.|cFF0088FFGetInfo(|r'.. tostring(watchIndex)..'|r)') - local questID, title, questIndex, numObjectives, requiredMoney, _, - _, isAutoComplete, failureTime, timeElapsed, questType, _, _, _, _ = GetQuestWatchInfo(watchIndex) + print('') + print('|cFF00DDFFindex: |r'.. tostring(watchIndex)) - if not questIndex then + local questID, title, questLogIndex, numObjectives, requiredMoney, isComplete, startEvent, isAutoComplete, + failureTime, timeElapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(watchIndex) + if ( not questID ) then return end + local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex) - local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questIndex) - - - if not questID then - return - end Quest.Info[questID] = Quest.Info[questID] or {} + local showQuest = true + if isTask then + showQuest = false + end + local q = Quest.Info[questID] + -- re-use Blizzard logic for consistency + local watchMoney = false; + local tagID, typeTag, frequencyTag, completionTag, completionText + local isAccount, isFaction, isWeekly, isDaily = false, false, false, false + local isBreadcrumb = false + local questFailed = false + local watchMoney = false + local timerInfo, moneyInfo = false, false + local objectives = q.objectives or {} + + + -- Case 1: completed quest or "go to thing" breadcrumb + -- * 1 line containing the completion text + if ( isComplete and isComplete < 0 ) then + isComplete = false + questFailed = true + elseif ( numObjectives == 0 and playerMoney >= requiredMoney and not startEvent ) then + isComplete = true; + questFailed = false + if ( requiredMoney == 0 ) then + isBreadcrumb = true; + end + end + print('|cFF0088FFflags:|r', (isComplete and 'isComplete' or ''), (questFailed and 'questFailed' or ''), (isBreadcrumb and 'isBreadcrumb' or '')) + + -- completion message? + local isSequenced = IsQuestSequenced(questID) + local temp_status = '' + if ( isComplete ) then + temp_status = 'COMPLETED_OBJECTIVES' + objectives = Quest.GetObjectives(questLogIndex, numObjectives, true, isSequenced, isStory) + if ( isAutoComplete ) then + temp_status = 'AUTOCOMPLETE_OBJECTIVES' + completionText = _G.QUEST_WATCH_CLICK_TO_COMPLETE + else + if ( isBreadcrumb ) then + temp_status = 'COMPLETE_BREADCRUMB' + completionText = GetQuestLogCompletionText(questLogIndex) + else + temp_status = 'COMPLETE_READY_FOR_TURN_IN' + completionText = _G.QUEST_WATCH_QUEST_READY + end + end + elseif ( questFailed ) then + temp_status = 'FAILED' + -- Case 2: failed quest + -- * 1 status line; hide other info + completionText = _G.FAILED + else + + temp_status = 'PROGRESS_OBJECTIVES' + -- Case 3: quest in progress + -- * Multiple objective lines + -- * Possible extra lines for money and timer data respectively + objectives = Quest.GetObjectives(questLogIndex, numObjectives, false, isSequenced, isStory) + q.objectives = objectives + + --- anything past here gets appended to existing objectives + + -- money + if ( requiredMoney > playerMoney ) then + + temp_status = temp_status .. '_MONEY' + local text = GetMoneyString(playerMoney).." / "..GetMoneyString(requiredMoney); + moneyInfo = { + type = 'money', + text = text, + finished = false, + requiredMoney = requiredMoney, + playerMoney = playerMoney, + } + end + + -- time limit + if ( failureTime ) then + temp_status = temp_status .. '_TIMED' + if ( timeElapsed and timeElapsed <= failureTime ) then + timerInfo = { + type = 'timer', + finished = false, + timeElapsed = timeElapsed, + failureTime = failureTime, + } + end + end + end + q.numObjectives = numObjectives + q.objectives = objectives + q.moneyInfo = moneyInfo + q.timerInfo = timerInfo + q.completionText = completionText + + -- POI data + local POI = false + if ( showPOIs ) then + POI = { + questID = questID, + questLogIndex = questLogIndex, + } + local poiButton; + if ( hasLocalPOI ) then + + if ( isComplete ) then + POI.type = 'normal' + else + POI.type = 'numeric' + end + elseif ( isComplete ) then + POI.type = 'remote' + end + + local distance, onContinent = GetDistanceSqToQuest(questLogIndex) + if distance ~= nil and distance > 0 then + POI.distance = distance + POI.onContinent = onContinent + end + end + q.POI = POI + + --- Block Tags + -- completionTag - in progres, complete, failed, autocomplete + -- typeTag - account, faction, pvp, dungeon, group + -- frequencyTag - daily/weekly + local questTagID, tagName = GetQuestTagInfo(questID) + local tagInfo = {} + local tagCoords = {} + local factionGroup = GetQuestFactionGroup(questID); + if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then + if( factionGroup ) then + tagID = "ALLIANCE" + if ( factionGroup == LE_QUEST_FACTION_HORDE ) then + tagID = "HORDE" + end + isFaction = true + else + tagID = QUEST_TAG_ACCOUNT + isAccount = true + end + tagInfo['typeTag'] = tagID + tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] + elseif ( factionGroup) then + tagID = "ALLIANCE" + if ( factionGroup == LE_QUEST_FACTION_HORDE ) then + tagID = "HORDE" + end + isFaction = true + tagInfo['typeTag'] = tagID + tagCoords['typeTag'] = QUEST_TAG_TCOORDS[tagID] + end + + if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then + tagID = 'DAILY' + tagInfo['frequencyTag'] = tagID + tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] + isDaily = true + elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then + tagID = 'WEEKLY' + tagInfo['frequencyTag'] = tagID + tagCoords['frequencyTag'] = QUEST_TAG_TCOORDS[tagID] + isWeekly = true + elseif( questTagID ) then + tagID = questTagID + end + + if( isComplete ) then + tagInfo['completionTag'] = 'COMPLETED' + elseif ( questFailed ) then + tagInfo['completionTag'] = 'FAILED' + end + tagCoords['completionTag'] = QUEST_TAG_TCOORDS[tagInfo['completionTag']] + + q.tagInfo = tagInfo + q.tagCoords = tagCoords + -- establishes the primary block tag for view compacting + q.tagID = tagID + q.tagName = tagName + + -- action button information + local link, icon, charges = GetQuestLogSpecialItemInfo(questLogIndex) + local start, duration, enable = GetQuestLogSpecialItemCooldown(questLogIndex) + if link or icon or charges then + q.specialItem = { + questID = questID, + questLogIndex = questLogIndex, + link = link, + charges = charges, + icon = icon, + start = start, + duration = duration, + enable = enable, + } + end + + -- resolved data + + -- raw data q.watchIndex = watchIndex q.type = 'Quest' + q.id = questID q.questID = questID q.title = title q.level = level q.displayQuestID = displayQuestID q.suggestedGroup = suggestedGroup - q.questLogIndex = questIndex + q.questLogIndex = questLogIndex q.numObjectives = numObjectives q.requiredMoney = requiredMoney q.isComplete = isComplete @@ -152,155 +364,53 @@ q.isStory = isStory q.isTask = isTask - --- resolve icon type and template - local questTagID, tagName = GetQuestTagInfo(questID) - local tagID + q.selected = (questID == superTrackQuestID) -- call directly so artifact data doesn't become an issue + self.WatchInfo[watchIndex] = q + self.LogInfo[questLogIndex] = q - local factionGroup = GetQuestFactionGroup(questID); - if( questTagID and questTagID == QUEST_TAG_ACCOUNT ) then - if( factionGroup ) then - tagID = "ALLIANCE"; - if ( factionGroup == LE_QUEST_FACTION_HORDE ) then - tagID = "HORDE"; + if Devian and Devian.InWorkspace() then + print('|cFF00DDFFstatus:|r', temp_status, '|cFF00FF00questLogIndex|r:', title) + local temp ={} + local data_txt = '|cFFFF4400values:|r' + for k,v in pairs(q) do + if type(v) =='number' then + data_txt = data_txt .. ' |cFFFFFF00'..k..'|r: ' .. tostring(v) + elseif type(v) == 'table' then + tinsert(temp, k) end - q.isFaction = true - else - tagID = QUEST_TAG_ACCOUNT; - q.isAccount = true end - q.typeTag = QUEST_TAG_TCOORDS[tagID] - elseif ( factionGroup) then - tagID = "ALLIANCE"; - if ( factionGroup == LE_QUEST_FACTION_HORDE ) then - tagID = "HORDE"; + print(data_txt) + sort(temp, function(a,b) return a < b end) + for i, k in ipairs(temp) do + print('|cFF00FF00'..k..'|r') + for kk,v in pairs(q[k]) do + print(' ', kk, '=', v) + end end - q.isFaction = true end - if( frequency == LE_QUEST_FREQUENCY_DAILY and (not isComplete or isComplete == 0) ) then - tagID = "DAILY"; - q.frequencyTag = QUEST_TAG_TCOORDS["DAILY"] - q.isDaily = true - elseif( frequency == LE_QUEST_FREQUENCY_WEEKLY and (not isComplete or isComplete == 0) )then - tagID = "WEEKLY"; - q.frequencyTag = QUEST_TAG_TCOORDS["WEEKLY"] - q.isWeekly = true - elseif( questTagID ) then - tagID = questTagID; - end + return q +end - if ( isComplete and isComplete < 0 ) then - q.completionTag = QUEST_TAG_TCOORDS["FAILED"] - q.isFailed = true - elseif isComplete then - q.completionTag = QUEST_TAG_TCOORDS["COMPLETED"] - end - - - q.tagID = questTagID - q.tagName = tagName - --q.isBreadCrumb = isBreadCrumb - q.completionText= GetQuestLogCompletionText(questIndex) - q.numObjectives = GetNumQuestLeaderBoards(questIndex) - q.objectives = {} - for i = 1, q.numObjectives do - local text, type, finished = GetQuestLogLeaderBoard(i, questIndex) +Quest.GetObjectives = function(questLogIndex, numObjectives, isComplete, isSequenced, isStory) + local objectives = {} + for i = 1, numObjectives do + local text, type, finished = GetQuestLogLeaderBoard(i, questLogIndex) print(format(' #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished))) - q.objectives[i] = { + objectives[i] = { index = i, type = type, text = text, finished = finished } - if type == 'event' then - elseif type == 'monster' then - elseif type == 'object' then - elseif type == 'reputation' then - elseif type == 'item' then - end end - - if requiredMoney >= 1 then - local money = GetMoney() - local moneyText = money - local requiredSilver, requiredCopper - local requiredGold = (requiredMoney > 10000) and (floor(requiredMoney/10000)) or nil - if mod(requiredMoney, 10000) ~= 0 then - requiredSilver = (requiredMoney > 100) and (mod(requiredMoney, 10000) / 100) or nil - if mod(requiredMoney, 100) ~= 0 then - requiredCopper = mod(requiredMoney, 100) - end - end - - -- round the money value down - if requiredMoney > 9999 and not (requiredSilver or requiredCopper) then - moneyText = floor(money/10000) - elseif requiredMoney < 10000 and mod(requiredMoney,100) == 0 then - moneyText = floor(money/100) - end - - local text = moneyText - local index = #q.objectives + 1 - local finished = (GetMoney() >= requiredMoney) - - if not finished then - text = text .. ' / ' .. GetCoinTextureString(requiredMoney, 12) - else - text = '' .. GetCoinTextureString(requiredMoney, 12) - end - q.objectives[index] = { - index = index, - type = 'progressbar', - quantity = money, - requiredQuantity = requiredMoney, - text = text, - finished = finished - } - print(format(' #%d %s %s %s', index, 'money', text, tostring(finished))) - end - - - local link, icon, charges = GetQuestLogSpecialItemInfo(questIndex) - local start, duration, enable = GetQuestLogSpecialItemCooldown(questIndex) - if link or icon or charges then - q.specialItem = { - questID = questID, - questIndex = questIndex, - link = link, - charges = charges, - icon = icon, - start = start, - duration = duration, - enable = enable, - } - end - - if QuestHasPOIInfo(questID) then - local distance, onContinent = GetDistanceSqToQuest(questIndex) - if distance ~= nil and distance > 0 then - self.POI[questIndex] = { - questIndex = questIndex, - questID = questID, - distance = distance, - onContinent = onContinent - } - end - end - - - q.selected = (questID == GetSuperTrackedQuestID()) -- call directly so artifact data doesn't become an issue - self.WatchInfo[watchIndex] = q - self.LogInfo[questIndex] = q - print('- logIndex =', questIndex, 'title =', title) - for k,v in pairs(q) do - print('|cFFFFFF00'..k..'|r:', v) - end - return q + return objectives end +local huge, sqrt = math.huge, math.sqrt Quest.GetClosest = function() local minID, minTitle - local minDist = math.huge + local minDist = huge local numQuests = GetNumQuestLogEntries() for questIndex = 1, numQuests do local distance, onContinent = GetDistanceSqToQuest(questIndex) @@ -312,7 +422,7 @@ end end - print('nearest quest is', minTitle, 'by', math.sqrt(minDist)) + print('nearest quest is', minTitle, 'by', sqrt(minDist)) return minID, minTitle, minDist end