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 @@ </OnLoad> </Scripts> </CheckButton> + <Frame name="$parentUseEffectUptimeRatio" parentKey = "useEffectUptimeRatio" inherits="ww_labeledElement"> + <Anchors> + <Anchor point="TOPLEFT" relativePoint="BOTTOMLEFT" relativeTo="$parentNormalizeWeights"/> + </Anchors> + <Size> + <AbsDimension y="25"/> + </Size> + <Frames> + <EditBox letters="16" name="$parentRatio" parentKey="ratio" autoFocus="false"> + <Anchors> + <Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parentLabel"/> + </Anchors> + <Size> + <AbsDimension x="50" y="22"/> + </Size> + <Backdrop edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true"> + <EdgeSize> + <AbsValue val="10"/> + </EdgeSize> + <TileSize> + <AbsValue val="10"/> + </TileSize> + <BackgroundInsets> + <AbsInset left="0" right="0" top="5" bottom="5"/> + </BackgroundInsets> + </Backdrop> + <FontString inherits="GameFontNormal"> + <Anchors> + <Anchor point="LEFT"/> + </Anchors> + </FontString> + <Scripts> + <OnLoad> + self:SetTextInsets(5, 5, 0, 0) + </OnLoad> + <OnShow> + self:SetText(ww_vars.options.useEffects.uptimeRatio * 100) + </OnShow> + <OnTextChanged> + 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 + </OnTextChanged> + <OnChar> + 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 + </OnChar> + <OnEscapePressed> + self:ClearFocus() + </OnEscapePressed> + </Scripts> + </EditBox> + </Frames> + <Scripts> + <OnLoad> + self.label:SetText("Percent of ideal use effect uptime:") + </OnLoad> + </Scripts> + </Frame> </Frames> </Frame> <Frame name="$parentDisplayOptions" parentKey="displayOptions" inherits="ww_borderedFrame"> 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, + } }, }