Quantcast

Add table WeightsWatcher.player to track player level, skills, and reputations

Kevin Lyles [02-26-11 - 18:47]
Add table WeightsWatcher.player to track player level, skills, and reputations
Filename
EnchantIDs.lua
Upgrade.lua
WeightsWatcher.lua
weights.lua
weights.xml
diff --git a/EnchantIDs.lua b/EnchantIDs.lua
index 9639e2d..966fd4a 100644
--- a/EnchantIDs.lua
+++ b/EnchantIDs.lua
@@ -10921,6 +10921,7 @@ ww_slotsToCheck = {
 }

 ww_factionsToTrack = {}
+ww_professionsToTrack = {}

 for item, info in pairs(EnchantItems) do
 	if info.enchID and info.source ~= "Unavailable" then
@@ -10972,6 +10973,7 @@ for item, info in pairs(EnchantItems) do
 					end
 					local skills = info.skill or { ["none"] = 0 }
 					for skill, level in pairs(skills) do
+						ww_professionsToTrack[skill] = true
 						if not repInterval[skill] then
 							repInterval[skill] = IntervalTree.create()
 						end
@@ -11051,6 +11053,7 @@ for item, info in pairs(EnchantSpells) do
 					end
 					local skills = info.skill or { ["none"] = 0 }
 					for skill, level in pairs(skills) do
+						ww_professionsToTrack[skill] = true
 						if not repInterval[skill] then
 							repInterval[skill] = IntervalTree.create()
 						end
@@ -11084,31 +11087,33 @@ local enchantItemMetatable = {
 	__index = function(tbl, key)
 		local bestScore, bestEnchants = 0, {}
 		local bareStats = ww_bareItemCache[key]
-		for _, choices in ipairs(tbl.enchants) do
-			for _, slot in ipairs(ww_slotsToCheck[bareStats.nonStats.slot]) do
-				if choices[slot] then
-					local subslots = { "all" }
-					table.insert(subslots, bareStats.nonStats.subslot)
-					for _, subslot in ipairs(subslots) do
-						for source, enchants in pairs(choices[slot][subslot] or {}) do
-							for boa, enchants in pairs(enchants) do
-								for faction, enchantIntervals in pairs(enchants) do
-									for _, enchants in ipairs(enchantIntervals.find(ww_vars.options.useBoa and boa and #(ww_reputations) or getRep(faction))) do
-										for profession, intervals in pairs(enchants) do
-											for _, intervals in ipairs(intervals.find(getSkill(profession))) do
-												for _, intervals in ipairs(intervals.find(bareStats.normalStats["item level"] or 1)) do
-													for _, interval in ipairs(intervals.find(WeightsWatcher.playerLevel or 85)) do
-														for name, ids in pairs(interval) do
-															for id in pairs(ids) do
-																local score = WeightsWatcher.calculateWeight({}, { enchantStats = WeightsWatcher.enchantStats(id).stats }, tbl.weight)
-																if score > bestScore then
-																	bestScore = score
-																	bestEnchants = { [name] = { id } }
-																elseif score == bestScore then
-																	if not bestEnchants[name] then
-																		bestEnchants[name] = {}
+		if bareStats.nonStats.slot then
+			for _, choices in ipairs(tbl.enchants) do
+				for _, slot in ipairs(ww_slotsToCheck[bareStats.nonStats.slot]) do
+					if choices[slot] then
+						local subslots = { "all" }
+						table.insert(subslots, bareStats.nonStats.subslot)
+						for _, subslot in ipairs(subslots) do
+							for source, enchants in pairs(choices[slot][subslot] or {}) do
+								for boa, enchants in pairs(enchants) do
+									for faction, enchantIntervals in pairs(enchants) do
+										for _, enchants in ipairs(enchantIntervals.find(ww_vars.options.useBoa and boa and #(ww_reputations) or WeightsWatcher.getRepLevel(faction))) do
+											for profession, intervals in pairs(enchants) do
+												for _, intervals in ipairs(intervals.find(WeightsWatcher.getSkillLevel(profession))) do
+													for _, intervals in ipairs(intervals.find(bareStats.normalStats["item level"] or 1)) do
+														for _, interval in ipairs(intervals.find(WeightsWatcher.player.level)) do
+															for name, ids in pairs(interval) do
+																for id in pairs(ids) do
+																	local score = WeightsWatcher.calculateWeight({}, { enchantStats = WeightsWatcher.enchantStats(id) }, tbl.weight)
+																	if score > bestScore then
+																		bestScore = score
+																		bestEnchants = { [name] = { id } }
+																	elseif score == bestScore then
+																		if not bestEnchants[name] then
+																			bestEnchants[name] = {}
+																		end
+																		table.insert(bestEnchants[name], id)
 																	end
-																	table.insert(bestEnchants[name], id)
 																end
 															end
 														end
diff --git a/Upgrade.lua b/Upgrade.lua
index 3c9868d..d48f75d 100644
--- a/Upgrade.lua
+++ b/Upgrade.lua
@@ -996,7 +996,7 @@ local function ww_copyDefaultCharVars()
 	local charVars

 	charVars = ww_deepTableCopy(ww_defaultCharVars)
-	charVars.activeWeights = createActiveWeights(WeightsWatcher.playerClass)
+	charVars.activeWeights = createActiveWeights(WeightsWatcher.player.class)
 	return charVars
 end

diff --git a/WeightsWatcher.lua b/WeightsWatcher.lua
index f83daa9..7635648 100644
--- a/WeightsWatcher.lua
+++ b/WeightsWatcher.lua
@@ -198,7 +198,8 @@ ww_weightNormalizationCache = setmetatable({}, ww_weightNormalizationCacheMetata

 local function loadGeneralInfo()
 	local _, class = UnitClass("player")
-	WeightsWatcher.playerClass = class
+	WeightsWatcher.player = {}
+	WeightsWatcher.player.class = class

 	local slotList = {
 		"AmmoSlot",
@@ -267,6 +268,120 @@ local function hookTooltip(objectName, funcName)
 	hooksecurefunc(object, funcName, function(self, ...) WeightsWatcher.displayItemStats(self, objectName, ...) end)
 end

+local function populateProfessions()
+	local professions = {}
+	for _, idx in ipairs({ GetProfessions() }) do
+		local name, _, rank = GetProfessionInfo(idx)
+		if ww_professionsToTrack[name] then
+			professions[name] = rank
+		end
+	end
+	WeightsWatcher.player.professions = professions
+	WeightsWatcher.ResetEnchantCache()
+end
+
+local function populateReputations()
+	local rep = {}
+	ExpandAllFactionHeaders()
+	for i = 1, GetNumFactions() do
+		local name, _, standingID, barMin, barMax, barValue, _, _, isHeader, _, hasRep = GetFactionInfo(i)
+		if not isHeader or hasRep then
+			if ww_factionsToTrack[name] then
+				rep[name] = {
+					level = standingID,
+					min = barMin,
+					max = barMax,
+					value = barValue,
+				}
+			end
+		end
+	end
+	WeightsWatcher.player.reputation = rep
+	WeightsWatcher.ResetEnchantCache()
+end
+
+function WeightsWatcher:eventHandler(event, message, ...)
+	if event == "PLAYER_LEVEL_UP" then
+		WeightsWatcher.player.level = tonumber(message)
+	elseif event == "CHAT_MSG_SKILL" then
+		-- "Your skill in x has increased to y."
+		local skill, level = message:match("^Your skill in ([A-Z][A-Za-z '-]+) has increased to (%d+)%.$")
+		if skill then
+			if WeightsWatcher.player.professions[skill] then
+				WeightsWatcher.player.professions[skill] = tonumber(level)
+				WeightsWatcher.ResetEnchantCache()
+			end
+		else
+			print("WeightsWatcher: warning: unhandled profession event \"" .. message .. "\"")
+			populateProfessions()
+		end
+	elseif event == "CHAT_MSG_COMBAT_FACTION_CHANGE" then
+		-- "Reputation with X (in|de)creased by y."
+		local faction, direction, reputation = message:match("^Reputation with ([A-Z][A-Za-z '-]+) ([di][en]creased) by (%d+)%.$")
+		if faction then
+			if not WeightsWatcher.player.reputation then
+				populateReputations()
+				return
+			end
+			local rep = WeightsWatcher.player.reputation[faction]
+			if not rep then
+				return
+			end
+			reputation = tonumber(reputation)
+			if direction == "increased" then
+				rep.value = rep.value + reputation
+				if rep.value > rep.max then
+					while rep.level < #(ww_reputations) and ww_reputations[rep.level] <= rep.value do
+						rep.level = rep.level + 1
+					end
+					rep.min = ww_reputations[rep.level - 1]
+					rep.max = ww_reputations[rep.level]
+					if rep.value >= rep.max then
+						rep.value = rep.max - 1
+					end
+					WeightsWatcher.ResetEnchantCache()
+				end
+			else
+				rep.value = rep.value - reputation
+				if rep.value < rep.min then
+					while rep.level > 0 and ww_reputations[rep.level - 1] > rep.value do
+						rep.level = rep.level - 1
+					end
+					rep.min = ww_reputations[rep.level - 1]
+					rep.max = ww_reputations[rep.level]
+					if rep.value < rep.min then
+						rep.value = rep.min
+					end
+					WeightsWatcher.ResetEnchantCache()
+				end
+			end
+		else
+			print("WeightsWatcher: warning: unhandled reputation event \"" .. message .. "\"")
+			populateReputations()
+		end
+	elseif event == "SKILL_LINES_CHANGED" then
+		populateProfessions()
+	else
+		print("WeightsWatcher: warning: unhandled event \"" .. tostring(event) .. "\"")
+	end
+end
+
+function WeightsWatcher.getRepLevel(faction)
+	if not WeightsWatcher.player.reputation then
+		populateReputations()
+	end
+
+	if not WeightsWatcher.player.reputation[faction] then
+		return 0
+	end
+
+	return WeightsWatcher.player.reputation[faction].level
+end
+
+function WeightsWatcher.getSkillLevel(profession)
+	return WeightsWatcher.player.professions[profession] or 0
+end
+
 local function initializeAfterDataUpgrade()
 	ww_initializeParser()

@@ -312,6 +427,16 @@ local function initializeAfterDataUpgrade()
 	if AtlasLootTooltip then
 		hookTooltip("AtlasLootTooltip", "SetHyperlink")
 	end
+
+	populateProfessions()
+	WeightsWatcher.player.level = UnitLevel("player")
+
+	WeightsWatcher:SetScript("OnEvent", WeightsWatcher.eventHandler)
+
+	WeightsWatcher:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
+	WeightsWatcher:RegisterEvent("CHAT_MSG_SKILL")
+	WeightsWatcher:RegisterEvent("SKILL_LINES_CHANGED")
+	WeightsWatcher:RegisterEvent("PLAYER_LEVEL_UP")
 end

 function WeightsWatcher.OnInitialize()
@@ -380,7 +505,7 @@ function WeightsWatcher.Broken(dataType)
 end

 local function checkForTitansGrip()
-	if WeightsWatcher.playerClass ~= "WARRIOR" then
+	if WeightsWatcher.player.class ~= "WARRIOR" then
 		return false
 	end
 	local name, _, _, _, rank = GetTalentInfo(2, 20, false, false)
@@ -407,7 +532,7 @@ local function checkForTitansGrip()
 end

 local function checkForDualWield()
-	local class = WeightsWatcher.playerClass
+	local class = WeightsWatcher.player.class
 	if class == "ROGUE" or class == "DEATHKNIGHT" then
 		return true
 	elseif class == "HUNTER" and UnitLevel("player") >= 20 then
@@ -746,7 +871,7 @@ function WeightsWatcher.displayItemStats(tooltip, ttname)
 							if ww_vars.options.tooltip.showZeroScores or currentScore > 0 then
 								local compareScore, compareScore2, compareBareScore, compareBareScore2
 								local str = weight
-								if ww_vars.options.tooltip.showClassNames == "Always" or (ww_vars.options.tooltip.showClassNames == "Others" and class ~= WeightsWatcher.playerClass) then
+								if ww_vars.options.tooltip.showClassNames == "Always" or (ww_vars.options.tooltip.showClassNames == "Others" and class ~= WeightsWatcher.player.class) then
 									str = string.format(L["WEIGHT_CLASS_FORMAT"], str, ww_classDisplayNames[class])
 								end
 								if compareLink then
diff --git a/weights.lua b/weights.lua
index 4255d3e..883747d 100644
--- a/weights.lua
+++ b/weights.lua
@@ -497,7 +497,7 @@ local function loadClassButtons()

 	for _, classFrame in ipairs(ww_weights.leftPanel.scrollContainer.elements) do
 		classFrame.class = revClassLookup[classFrame.text:GetText()]
-		local used = (classFrame.class == WeightsWatcher.playerClass)
+		local used = (classFrame.class == WeightsWatcher.player.class)
 		for i, weightFrame in ipairs({classFrame:GetChildren()}) do
 			if weightFrame.name then
 				weightFrame.category = classFrame
diff --git a/weights.xml b/weights.xml
index 5731997..c0ce9c7 100644
--- a/weights.xml
+++ b/weights.xml
@@ -849,7 +849,7 @@
 				<Scripts>
 					<OnShow>
 						UIDropDownMenu_Initialize(self, ww_ClassDropDownInitialize)
-						UIDropDownMenu_SetSelectedValue(self, WeightsWatcher.playerClass)
+						UIDropDownMenu_SetSelectedValue(self, WeightsWatcher.player.class)
 					</OnShow>
 				</Scripts>
 			</Button>