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>