A World of Warcraft Experience Bar addon
worldofwarcraft wow addon midnight
at main 199 lines 6.2 kB view raw
1local _, F = ... 2 3F.State = { 4 level = 0, 5 isMaxLevel = false, 6 7 -- XP Values 8 currentXP = 0, 9 maxXP = 0, 10 restedXP = 0, 11 questXP = 0, 12 completeXP = 0, 13 incompleteXP = 0, 14 15 -- Session Data 16 session = { 17 gainedXP = 0, 18 lastXP = 0, 19 startTime = 0, 20 realTotalTime = 0, 21 realLevelTime = 0, 22 lastTimePlayedRequest = 0 23 } 24} 25 26local function GetQuestRewardXP(index, questID) 27 local rewardXP = 0 28 29 if questID and C_QuestLog.GetQuestLogRewardXP then 30 rewardXP = C_QuestLog.GetQuestLogRewardXP(questID) or 0 31 end 32 33 if questID and C_QuestLog.SetSelectedQuest and C_QuestLog.GetSelectedQuest and GetQuestLogRewardXP then 34 local previous = C_QuestLog.GetSelectedQuest() 35 if previous ~= questID then 36 C_QuestLog.SetSelectedQuest(questID) 37 end 38 39 local selectedXP = GetQuestLogRewardXP() or 0 40 41 if previous and previous ~= questID then 42 C_QuestLog.SetSelectedQuest(previous) 43 end 44 45 if selectedXP > 0 then 46 rewardXP = selectedXP 47 end 48 elseif rewardXP == 0 and GetQuestLogRewardXP then 49 rewardXP = GetQuestLogRewardXP(index) or 0 50 end 51 52 return rewardXP 53end 54 55function F.State:UpdatePlayerXP() 56 self.level = UnitLevel("player") 57 self.currentXP = UnitXP("player") 58 self.maxXP = UnitXPMax("player") 59 self.restedXP = GetXPExhaustion() or 0 60 61 -- Max Level Logic 62 local expansionLevel = GetExpansionLevel() 63 local maxLevel = math.min(GetMaxPlayerLevel(), GetMaxLevelForExpansionLevel(expansionLevel)) 64 self.isMaxLevel = self.level >= maxLevel 65end 66 67function F.State:UpdateQuestXP() 68 if F.DB and F.DB.questTrackingEnabled == false then 69 self.questXP = 0 70 self.completeXP = 0 71 self.incompleteXP = 0 72 return 73 end 74 75 local numEntries = C_QuestLog.GetNumQuestLogEntries() 76 local qXP, cXP, iXP = 0, 0, 0 77 78 for i = 1, numEntries do 79 local info = C_QuestLog.GetInfo(i) 80 -- this skips the XP header for a category / campaign as they should not be respected 81 if info and not info.isHeader and not info.isHidden and info.questID > 0 then 82 local isTracked = true 83 if F.DB and F.DB.trackedOnly and C_QuestLog.GetQuestWatchType then 84 local watchType = C_QuestLog.GetQuestWatchType(info.questID) 85 isTracked = (watchType == 1) 86 end 87 88 if isTracked then 89 -- Use the quest log index when querying the reward XP 90 local rewardXP = GetQuestRewardXP(i, info.questID) 91 if rewardXP > 0 then 92 qXP = qXP + rewardXP 93 94 local completeState = info.isComplete 95 if completeState == nil then 96 completeState = C_QuestLog.IsComplete(info.questID) 97 end 98 99 local isComplete = completeState == 1 or completeState == true 100 if not isComplete then 101 isComplete = C_QuestLog.ReadyForTurnIn(info.questID) 102 end 103 104 if isComplete then 105 cXP = cXP + rewardXP 106 else 107 iXP = iXP + rewardXP 108 end 109 end 110 end 111 end 112 end 113 114 self.questXP = qXP 115 self.completeXP = cXP 116 self.incompleteXP = iXP 117end 118 119function F.State:DebugDumpQuests() 120 local numEntries = C_QuestLog.GetNumQuestLogEntries() 121 print("NixxnuxXPBar: DebugDumpQuests - numEntries =", numEntries) 122 123 local qXP, cXP, iXP = 0, 0, 0 124 125 for i = 1, numEntries do 126 local info = C_QuestLog.GetInfo(i) 127 if info then 128 local reward = GetQuestRewardXP(i, info.questID) 129 130 local status = "UNKNOWN" 131 if info.isHeader then 132 status = "HEADER" 133 elseif info.isHidden then 134 status = "HIDDEN" 135 else 136 local completeState = info.isComplete 137 if completeState == nil and info.questID then 138 completeState = C_QuestLog.IsComplete(info.questID) 139 end 140 141 local isComplete = completeState == 1 or completeState == true 142 if not isComplete and info.questID then 143 isComplete = C_QuestLog.ReadyForTurnIn(info.questID) 144 end 145 146 status = isComplete and "COMPLETE" or "INCOMPLETE" 147 end 148 149 print(string.format(" [%d] id=%s title=\"%s\" reward=%d status=%s isHeader=%s isHidden=%s", 150 i, 151 tostring(info.questID), 152 tostring(info.title), 153 reward, 154 status, 155 tostring(info.isHeader), 156 tostring(info.isHidden) 157 )) 158 159 if reward > 0 then 160 qXP = qXP + reward 161 if status == "COMPLETE" then 162 cXP = cXP + reward 163 else 164 iXP = iXP + reward 165 end 166 end 167 end 168 end 169 170 print(string.format("Computed totals -> questXP=%d, completeXP=%d, incompleteXP=%d", qXP, cXP, iXP)) 171 print(string.format("State totals -> questXP=%d, completeXP=%d, incompleteXP=%d", self.questXP or 0, self.completeXP or 0, self.incompleteXP or 0)) 172end 173 174-- Convenience slash command to quickly invoke the debug dump 175SLASH_NIXXNUXXPBARDEBUG1 = SLASH_NIXXNUXXPBARDEBUG1 or "/nxpdebug" 176SlashCmdList = SlashCmdList or {} 177SlashCmdList["NIXXNUXXPBARDEBUG"] = function() 178 F.State:DebugDumpQuests() 179end 180 181function F.State:GetSessionStats() 182 local currentTime = GetTime() 183 local now = time() 184 185 local sessionTime = now - self.session.startTime 186 local hourlyXP, timeToLevel = 0, 0 187 188 local coeff = sessionTime / 3600 189 local remainingXP = self.maxXP - self.currentXP 190 191 if coeff > 0 and self.session.gainedXP > 0 then 192 hourlyXP = math.ceil(self.session.gainedXP / coeff) 193 if hourlyXP > 0 then 194 timeToLevel = math.ceil(remainingXP / hourlyXP * 3600) 195 end 196 end 197 198 return hourlyXP, timeToLevel, sessionTime 199end