From a933e0f19a0ceb901cbba8101df9af67b1090952 Mon Sep 17 00:00:00 2001 From: Kevin Lyles Date: Thu, 18 Feb 2010 21:21:35 -0600 Subject: [PATCH] Added initial support for use effects with cooldowns Handles "increases stat by x for y seconds"-type cooldowns --- Regexps.lua | 62 +++++++++++++++++++++++++++++++++++++++++++++ Upgrade.lua | 14 +++++++++++ WeightsWatcher.lua | 21 +++++++++++----- config.xml | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ defaults.lua | 5 +++- 5 files changed, 166 insertions(+), 7 deletions(-) diff --git a/Regexps.lua b/Regexps.lua index eabd600..37101a2 100644 --- a/Regexps.lua +++ b/Regexps.lua @@ -405,6 +405,31 @@ local ElixirAffixes = { "%.$", } +local CooldownUseMatchLines = { + "^use: grants? .* cooldown%)$", + "^use: increases? .* cooldown%)$", +} + +local CooldownUsePreprocessLines = { + {" (arcane spell) power ", " %1 damage "}, + {" (fire spell) power ", " %1 damage "}, + {" (frost spell) power ", " %1 damage "}, + {" (holy spell) power ", " %1 damage "}, + {" (nature spell) power ", " %1 damage "}, + {" (shadow spell) power ", " %1 damage "}, + {" your stats ", " all stats "}, + {" dodge by ", " dodge rating by "}, +} + +local CooldownUseAffixes = { + "^use: +", + "^grants? +", + "^increases? +", + "^your +", + "^the target's +", + "^maximum +", +} + local function parseStats(text, section) for _, regex in ipairs(ww_regexes[section].MultipleStat) do local pattern, func = unpack(regex) @@ -433,6 +458,7 @@ EffectHandlers = { {ElixirMatchLines, {}, ElixirUnweightedLines, ElixirPreprocessLines, ElixirAffixes, parseStats, "elixir"}, {FishingMatchLines, {}, {}, {}, FishingAffixes, parseStats, "fishing"}, {UseEffectMatchLines, UseEffectIgnoreLines, UseEffectUnweightedLines, UseEffectPreprocessLines, UseEffectAffixes, parseStats, "useEffect"}, + {CooldownUseMatchLines, {}, {}, CooldownUsePreprocessLines, CooldownUseAffixes, function(text) local stat = WeightsWatcher.useEffect(text) if stat then return {useEffect = stat} end end, "cooldownUseEffect"}, } function WeightsWatcher.twoStats(text, pattern, section) @@ -532,6 +558,42 @@ function WeightsWatcher.newStatTable(tbl) return setmetatable(tbl or {}, ww_normalStatsMetatable) end +function WeightsWatcher.convertToSeconds(duration) + local start, _, hours = string.find(duration, "^(%d+) ho?u?rs?$") + if start then + return hours * 3600 + end + local start, _, minutes, seconds = string.find(duration, "^(%d+) minu?t?e?s? (%d+) seco?n?d?s?$") + if start then + return minutes * 60 + seconds + end + local start, _, minutes = string.find(duration, "^(%d+) minu?t?e?s?$") + if start then + return minutes * 60 + end + local start, _, seconds = string.find(duration, "^(%d+) seco?n?d?s?$") + if start then + return tonumber(seconds) + end +end + +function WeightsWatcher.useEffect(text) + local start, _, stat, value, duration, cooldown = string.find(text, "^(%a+ ?%a+ ?%a+ ?%a+) by ([+-]?%d+) for (%d+ %a+ ?%d* ?%a*)%. +%((%d+ %a+ ?%d* ?%a*) cooldown%)$") + if not start then + start, _, value, stat, duration, cooldown = string.find(text, "^([+-]?%d+) (%a+ ?%a+ ?%a+ ?%a+) for (%d+ %a+ ?%d* ?%a*)%. +%((%d+ %a+ ?%d* ?%a*) cooldown%)$") + end + if start then + cooldown = WeightsWatcher.convertToSeconds(cooldown) + duration = WeightsWatcher.convertToSeconds(duration) + return { + stat = stat, + value = value, + duration = duration, + cooldown = cooldown, + } + end +end + Preprocess = { {"|c[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]([^|]+)|r", "%1"}, {" +$", ""}, diff --git a/Upgrade.lua b/Upgrade.lua index 0ddf0f2..057e209 100644 --- a/Upgrade.lua +++ b/Upgrade.lua @@ -135,6 +135,18 @@ function noop_major_up(vars) return vars end +function upgradeAccountToUseEffectRatio(vars) + if not vars.options.useEffects then + vars.options.useEffects = {} + end + if not vars.options.useEffects.uptimeRatio then + vars.options.useEffects.uptimeRatio = 0.8 + end + + vars.dataMinorVersion = 11 + return vars +end + function upgradeAccountToWorkingMeleeDamage(vars) for _, class in ipairs(vars.weightsList) do for _, weight in ipairs(vars.weightsList[class]) do @@ -792,6 +804,7 @@ upgradeAccountFunctions = { [7] = upgradeAccountToShowAlternateGemsTypoFix, [8] = upgradeAccountToWorkingResistances, [9] = upgradeAccountToWorkingMeleeDamage, + [10] = upgradeAccountToUseEffectRatio, }, } @@ -819,6 +832,7 @@ downgradeAccountFunctions = { [8] = noop_down, [9] = noop_down, [10] = noop_down, + [11] = noop_down, }, } diff --git a/WeightsWatcher.lua b/WeightsWatcher.lua index 544f0f5..575dd1b 100644 --- a/WeightsWatcher.lua +++ b/WeightsWatcher.lua @@ -72,11 +72,12 @@ ww_weightCacheWeightMetatable = { local itemStats = ww_bareItemCache[splitItemLink(key)] local normalStats = itemStats.normalStats local socketBonusStat = itemStats.socketBonusStat + local useEffects = itemStats.useEffects itemStats = ww_itemCache[key] local socketBonusActive = itemStats.socketBonusActive local gemStats = itemStats.gemStats - tbl[key] = WeightsWatcher.calculateWeight(normalStats, socketBonusActive, socketBonusStat, gemStats, tbl.weight) + tbl[key] = WeightsWatcher.calculateWeight(normalStats, socketBonusActive, socketBonusStat, gemStats, useEffects, tbl.weight) return tbl[key] end, } @@ -125,6 +126,7 @@ ww_weightIdealCacheWeightMetatable = { local normalStats = itemStats.normalStats local sockets = itemStats.sockets local socketBonusStat = itemStats.socketBonusStat + local useEffects = itemStats.useEffects local socketBonusWeight = 0 if socketBonusStat then for stat, value in pairs(socketBonusStat) do @@ -151,10 +153,10 @@ ww_weightIdealCacheWeightMetatable = { end end gemStats = WeightsWatcher.getGemStats(bestGems) - weightVal = WeightsWatcher.calculateWeight(normalStats, true, socketBonusStat, gemStats, tbl.weight) + weightVal = WeightsWatcher.calculateWeight(normalStats, true, socketBonusStat, gemStats, useEffects, tbl.weight) if breakSocketColors then gemStatsIgnoreSockets = WeightsWatcher.getGemStats(bestGemsIgnoreSocket) - weightValIgnoreSockets = WeightsWatcher.calculateWeight(normalStats, false, socketBonusStat, gemStatsIgnoreSockets, tbl.weight) + weightValIgnoreSockets = WeightsWatcher.calculateWeight(normalStats, false, socketBonusStat, gemStatsIgnoreSockets, useEffects, tbl.weight) if weightVal < weightValIgnoreSockets then weightVal = weightValIgnoreSockets @@ -780,7 +782,7 @@ function WeightsWatcher.bestGemForSocket(socketColor, weightScale, qualityLimit) if gems[quality] then for gemId, gemStats in pairs(gems[quality]) do if WeightsWatcher.matchesSocket(gemStats[1], socketColor) then - weight = WeightsWatcher.calculateWeight({}, true, nil, {{gemStats}}, weightScale) + weight = WeightsWatcher.calculateWeight({}, true, nil, {{gemStats}}, {}, weightScale) if #(bestGem) == 0 or weight > bestWeight then bestGem = {gemId} bestWeight = weight @@ -845,7 +847,7 @@ function WeightsWatcher.matchesSocket(gemId, socketColor) return false end -function WeightsWatcher.calculateWeight(normalStats, socketBonusActive, socketBonusStat, gemStats, weightsScale) +function WeightsWatcher.calculateWeight(normalStats, socketBonusActive, socketBonusStat, gemStats, useEffects, weightsScale) local weight = 0 for stat, value in pairs(normalStats) do @@ -889,6 +891,9 @@ function WeightsWatcher.calculateWeight(normalStats, socketBonusActive, socketBo end weight = weight + maxWeight end + for _, useEffect in pairs(useEffects) do + weight = weight + WeightsWatcher.getWeight(useEffect.stat, useEffect.value * useEffect.duration / useEffect.cooldown * ww_vars.options.useEffects.uptimeRatio, weightsScale) + end if ww_vars.options.tooltip.normalizeWeights == true then local total = 0 @@ -1001,7 +1006,7 @@ end function WeightsWatcher.getItemStats(link) local textL, textR, pattern, func, start - local normalStats, nonStats, socketList, socketBonusStat = WeightsWatcher.newStatTable(), {}, {}, WeightsWatcher.newStatTable() + local normalStats, nonStats, socketList, socketBonusStat, useEffects = WeightsWatcher.newStatTable(), {}, {}, WeightsWatcher.newStatTable(), {} local ranged = false -- Populate hidden tooltip @@ -1038,6 +1043,9 @@ function WeightsWatcher.getItemStats(link) if stats.socketBonusStat then socketBonusStat = socketBonusStat + stats.socketBonusStat end + if stats.useEffect then + table.insert(useEffects, stats.useEffect) + end end end @@ -1051,6 +1059,7 @@ function WeightsWatcher.getItemStats(link) nonStats = nonStats, sockets = socketList, socketBonusStat = socketBonusStat, + useEffects = useEffects, } end diff --git a/config.xml b/config.xml index e4df82d..3e09300 100644 --- a/config.xml +++ b/config.xml @@ -413,6 +413,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self:SetTextInsets(5, 5, 0, 0) + + + self:SetText(ww_vars.options.useEffects.uptimeRatio * 100) + + + local text = self:GetText() + if self:GetNumber() ~= 0 or text:match("^[0.]+$") or text == "" then + self.number = text + ww_vars.options.useEffects.uptimeRatio = self:GetNumber() / 100 + ww_weightCache = setmetatable({}, ww_weightCacheMetatable) + ww_weightIdealCache = setmetatable({}, ww_weightIdealCacheMetatable) + end + + + if validateNumber(text, self:GetText()) then + self.number = self:GetText() + ww_vars.options.useEffects.uptimeRatio = self:GetNumber() / 100 + ww_weightCache = setmetatable({}, ww_weightCacheMetatable) + ww_weightIdealCache = setmetatable({}, ww_weightIdealCacheMetatable) + else + local cursorPosition = self:GetCursorPosition() - 1 + self:SetText(self.number) + self:SetCursorPosition(cursorPosition) + end + + + self:ClearFocus() + + + + + + + self.label:SetText("Percent of ideal use effect uptime:") + + + diff --git a/defaults.lua b/defaults.lua index be52734..8805e00 100644 --- a/defaults.lua +++ b/defaults.lua @@ -208,7 +208,7 @@ classNameOptions = { defaultVars = { dataMajorVersion = 1, - dataMinorVersion = 10, + dataMinorVersion = 11, weightsList = { [1] = "DEATHKNIGHT", [2] = "DRUID", @@ -633,6 +633,9 @@ defaultVars = { showIdealWeights = "Shift", showWeights = "Always", }, + useEffects = { + uptimeRatio = 0.8, + } }, } -- 1.7.9.5