Mercurial > wow > buffalo2
view ObjectiveTracker/QuestData.lua @ 43:9480bd904f4c
- file name organizing
author | Nenue |
---|---|
date | Mon, 25 Apr 2016 13:51:58 -0400 |
parents | ObjectiveTracker/Quests.lua@03ed70f846de |
children | 756e8aeb040b |
line wrap: on
line source
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 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, wipe, select = format, table.wipe, select local wipeall = B.wipeall local lprint, iprint, tprint = B.print('Line'), B.print('Info'), B.print('Tracker') local print = tprint local fprint = B.print('Frame') local superTrackQuestID, playerMoney, inScenario, showPOIs Quest.Update = function(self, reason, ...) local print = self.print print('QuestTracker:Update() received') T.UpdateActionButtons() Default.Update(self, reason, ...) end T.Quest.numButtons = 0 local usedButtons = T.Quest.itemButtons local freeButtons = T.Quest.freeButtons Quest.UpdateObjectives = function(self, block) local print = lprint print('|cFF'..self.internalColor..'UpdateObjectives()') local info = block.info 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) local displayObjectives = true local block_schema = 'default' if info.isAccount then if info.isFaction then print(' faction', info.tagID) block_schema = 'faction_'..info.tagID else print(' account', info.isAccount, info.isFaction) block_schema = 'account' end elseif info.isDaily then print(' daily', info.frequency) block_schema = 'daily' elseif info.isWeekly then print(' weekly', info.frequency) block_schema = 'weekly' end local completionText if info.isComplete then if info.isAutoComplete then local questID, popupType = GetAutoQuestPopUp(info.logIndex) if popupType == 'COMPLETE' then print(' :: auto-complete quest :: set the message') self:AddLine(block, T.strings.CLICK_TO_COMPLETE, nil, 'complete') end else if not completionText or info.completionText then info.completionText = GetQuestLogCompletionText(info.logIndex) end end self:AddLine(block, info.completionText, nil, 'complete') displayObjectives = false print('|cFF'..self.internalColor..' :: complete quest :: show instruction: "'.. tostring(info.completionText) .. '"') end Default.UpdateObjectives(self, block, block_schema, displayObjectives) return 0, block_schema end Quest.UpdateLine = function(handler, block, data) local objectiveType = data.type return data.text, nil, objectiveType end ----------------------------- --- QUEST local tremove, tinsert = tremove, tinsert local GetQuestLogIndexByID, IsQuestWatched = GetQuestLogIndexByID, IsQuestWatched Quest.QuestBlock = {} Quest.LogBlock = {} Quest.LogInfo = {} Quest.OnRemoved = function(block) end Quest.GetBlock = function(self, index) local block = Default.GetBlock(self, index) block:SetScript('OnEvent', Quest.OnRemoved) block:RegisterEvent('QUEST_REMOVED') return block end local GetQuestWatchIndex = GetQuestWatchIndex local numAnimating = 0 local blocksChecked = {} --- Get a total of things to show, and straighten out the index while we're at it --- Return the number shown, total in log, and the info table to parse Quest.GetNumWatched = function (self, id, added) local print = self.print B.print('Block')('########') B.print('Block')('########') superTrackQuestID = GetSuperTrackedQuestID() playerMoney = GetMoney(); inScenario = C_Scenario.IsInScenario(); showPOIs = GetCVarBool("questPOI"); local numAll = GetNumQuestLogEntries() local numWatched = GetNumQuestWatches() local bottomIndex = 1 print('GetNumWatched', self.name, numWatched, 'of', numAll) local start, limit = 1, numAll if id and not added then -- if a particular id is supplied, add to checklist if self.InfoBlock[id] then blocksChecked[self.InfoBlock[id]] = self.InfoBlock[id] end end numAnimating = 0 for logIndex = start, limit do local reason1, reason2 = '', '' local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) local watchIndex = GetQuestWatchIndex(logIndex) --- Start of crazy audit flagging if watchIndex and watchIndex >= bottomIndex then -- do watch data pointers match? local watchInfo = self.WatchInfo[watchIndex] local watchBlock = self.WatchBlock[watchIndex] if watchInfo and watchInfo.questID ~= questID then print('GetNumWatched', 'trimming WatchInfo ['..watchIndex..'] =/=', questID) self.WatchInfo[watchIndex] = nil end if watchBlock and watchBlock.info.questID ~= questID then print('GetNumWatched', 'trimming WatchBlock ['..watchIndex..'] =/=', watchBlock:GetName()) self.WatchBlock[watchIndex] = nil blocksChecked[watchBlock] = watchBlock end end -- check log-block pointer local logBlock = self.LogBlock[logIndex] if logBlock then -- check later that the block isn't for a dropped quest if logBlock.info.questID ~= questID then print('GetQuests', 'replace info', logBlock.info.questID, '->', questID) self.LogBlock[logIndex] = nil blocksChecked[logBlock] = logBlock end end --- end of crazy audit flagging -- add to watch index if: the questID is non-zero if questID ~= 0 then self.Info[questID] = self:GetInfo(logIndex, watchIndex) print('GetQuests', format('request info |cFF00FF00%2d|r |cFFFFFF00%6d|r |cFFFF4400%3s|r', logIndex, questID, tostring(watchIndex or ''))) end end --- After GetInfo pass, look for any non-conformant blocks and deal with them for _, block in pairs(blocksChecked) do local logIndex = GetQuestLogIndexByID(block.info.questID, 'player') -- animating blocks have been evaluated if not block.isAnimating then if not logIndex then self:ClearBlock(block) elseif not IsQuestWatched(block.info.logIndex) then self:ClearBlock(block) end end blocksChecked[block] = nil end self.numWatched = numWatched self.numAll = numAll return numWatched, numAll, self.WatchList 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, logIndex, watchIndex) local print = iprint local title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(logIndex) if ( not questID ) then tprint('GetNumWatched', logIndex, watchIndex, '|cFFFF2299no data|r') return end Quest.Info[questID] = Quest.Info[questID] or {} local q = Quest.Info[questID] q.questID = questID q.id = questID q.logIndex = logIndex q.watchIndex = watchIndex local numObjectives, requiredMoney, isAutoComplete, failureTime, timeElapsed, questType = 0, 0, nil, false, false, 0 if watchIndex then local _ _,_,_, numObjectives, requiredMoney, _, _, isAutoComplete, failureTime, timeElapsed, questType = GetQuestWatchInfo(watchIndex) -- ensure that the entry being populated isn't animating if self.WatchBlock[watchIndex] then local checkIndex = watchIndex while self.WatchBlock[checkIndex + numAnimating] and self.WatchBlock[checkIndex + numAnimating].isAnimating do print(self.WatchBlock[checkIndex + numAnimating]:GetName(), 'is in an animation sequence') numAnimating = numAnimating + 1 end end self.WatchList[watchIndex + numAnimating] = q --tprint(' |cFF88FF00GetInfo:|r set watch entry', watchIndex) print('GetInfo:', logIndex, watchIndex, '|cFFFF2299'..title..'|r') end self.LogInfo[logIndex] = q q.numObjectives = numObjectives q.requiredMoney = requiredMoney q.failureTime = failureTime q.timeElapsed = timeElapsed q.type = 'Quest' q.title = title q.level = level q.displayQuestID = displayQuestID q.suggestedGroup = suggestedGroup -- re-use Blizzard logic for consistency local showQuest = true if isTask then showQuest = false end 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('QuestFlags', (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 self.print(' QuestInfo', title, questType, isAutoComplete) objectives = Quest.GetObjectives(logIndex, 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, } tinsert(objectives, moneyInfo) 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, } tinsert(objectives, timerInfo) end end end q.objectives = objectives q.moneyInfo = moneyInfo q.timerInfo = timerInfo q.completionText = completionText -- POI data local POI = false if ( showPOIs ) then POI = { questID = questID, logIndex = logIndex, watchIndex = watchIndex } 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(logIndex) 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 schema = 'default' 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" schema = 'alliance' if ( factionGroup == LE_QUEST_FACTION_HORDE ) then tagID = "HORDE" schema = '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 schema = 'daily' 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 schema = 'weekly' 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(logIndex) local start, duration, enable = GetQuestLogSpecialItemCooldown(logIndex) if link or icon or charges then q.specialItem = { questID = questID, logIndex = questLogIndex, link = link, charges = charges, icon = icon, start = start, duration = duration, enable = enable, } end if moneyInfo or timerInfo then numObjectives = #objectives end -- raw data q.isComplete = isComplete q.startEvent = startEvent q.isAutoComplete = isAutoComplete q.questType = questType q.isTask = isTask q.isStory = isStory q.isOnMap = isOnMap q.hasLocalPOI = hasLocalPOI q.frequency = frequency q.isComplete = isComplete q.isStory = isStory q.isTask = isTask q.statusKey = temp_status q.selected = (questID == superTrackQuestID) T.SetRewards(q, questID) q.questID = questID q.logIndex = logIndex q.watchIndex = watchIndex q.id = questID q.schema = schema if Devian and Devian.InWorkspace() then print('QuestStatus', temp_status, '|cFF00FF00questLogIndex|r:', logIndex, title) local temp ={} local data_txt = '|cFF'..self.internalColor..'values:|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 end print('DataStatus',data_txt) sort(temp, function(a,b) return a < b end) for i, k in ipairs(temp) do iprint('GetInfo', questID, ''..k..'|r') for kk,v in pairs(q[k]) do iprint('GetInfo', questID, kk, '=', v) end end end return q end Quest.GetObjectives = function(logIndex, numObjectives, isComplete, isSequenced, isStory) local print = Quest.print local objectives = {} if not logIndex then return end for i = 1, numObjectives do local text, type, finished = GetQuestLogLeaderBoard(i, logIndex) local progress = 0 if finished then progress = 1 elseif text then local quantity, maxQuantity = text:match('^(%d+)/(%d+)') if quantity and maxQuantity then progress = quantity / maxQuantity --print('GetObjectives', 'calculated objective progress:', quantity, '/', maxQuantity, '=', progress) end end print('GetObjectives', format('|cFF88FF88#%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)), '('.. tostring(progress)..')') objectives[i] = { index = i, type = type, text = text, finished = finished, progress = progress } end return objectives end local huge, sqrt = math.huge, math.sqrt Quest.GetClosest = function() local minID, minTitle local minDist = huge local numQuests = GetNumQuestLogEntries() for questIndex = 1, numQuests do local distance, onContinent = GetDistanceSqToQuest(questIndex) local title, level, _, _, _, _, _, _, questID = GetQuestLogTitle(questIndex) if onContinent and distance < minDist then minDist = distance minTitle = title minID = questID end end print('nearest quest is', minTitle, 'by', sqrt(minDist)) return minID, minTitle, minDist end Quest.OnTurnIn = function(self, questID, xp, money) end Quest.Select = function (handler, block) if block.info.isAutoComplete and block.info.isComplete then ShowQuestComplete(block.info.logIndex) else SetSuperTrackedQuestID(block.info.questID) end end Quest.Link = function(handler, block) local questLink = GetQuestLink(block.info.logIndex); if ( questLink ) then ChatEdit_InsertLink(questLink); end end Quest.Open = function(handler, block) QuestMapFrame_OpenToQuestDetails(block.info.questID) end Quest.Remove = function(handler, block) print('removing', block.info.logIndex, 'from watcher') RemoveQuestWatch(block.info.logIndex) end