Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/Modules/Build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -366,24 +366,27 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild)
{ stat = "ManaUnreserved", label = "Unreserved Mana", fmt = "d", color = colorCodes.MANA, condFunc = function(v,o) return v < o.Mana end, compPercent = true, warnFunc = function(v) return v < 0 and "Your unreserved Mana is negative" end },
{ stat = "ManaUnreservedPercent", label = "Unreserved Mana", fmt = "d%%", color = colorCodes.MANA, condFunc = function(v,o) return v < 100 end },
{ stat = "ManaRegenRecovery", label = "Mana Regen", fmt = ".1f", color = colorCodes.MANA },
{ stat = "RageRegen", label = "Rage Regen", fmt = "d", color = colorCodes.RAGE, compPercent = true, condFunc = function(v,o) return v > 0 end },
{ stat = "ManaLeechGainRate", label = "Mana Leech/On Hit Rate", fmt = ".1f", color = colorCodes.MANA, compPercent = true },
{ stat = "ManaLeechGainPerHit", label = "Mana Leech/Gain per Hit", fmt = ".1f", color = colorCodes.MANA, compPercent = true },
{ },
{ stat = "TotalDegen", label = "Total Degen", fmt = ".1f", lowerIsBetter = true },
{ stat = "TotalNetRegen", label = "Total Net Regen", fmt = "+.1f" },
{ stat = "NetLifeRegen", label = "Net Life Regen", fmt = "+.1f", color = colorCodes.LIFE },
{ stat = "NetManaRegen", label = "Net Mana Regen", fmt = "+.1f", color = colorCodes.MANA },
{ stat = "NetEnergyShieldRegen", label = "Net Energy Shield Regen", fmt = "+.1f", color = colorCodes.ES },
{ },
{ stat = "Ward", label = "Ward", fmt = "d", color = colorCodes.WARD, compPercent = true },
{ stat = "EnergyShield", label = "Energy Shield", fmt = "d", color = colorCodes.ES, compPercent = true },
{ stat = "EnergyShieldRecoveryCap", label = "Recoverable ES", color = colorCodes.ES, fmt = "d", condFunc = function(v,o) return o.CappingES end },
{ stat = "Spec:EnergyShieldInc", label = "%Inc ES from Tree", color = colorCodes.ES, fmt = "d%%" },
{ stat = "EnergyShieldRegenRecovery", label = "Energy Shield Regen", color = colorCodes.ES, fmt = ".1f" },
{ stat = "EnergyShieldLeechGainRate", label = "ES Leech/On Hit Rate", color = colorCodes.ES, fmt = ".1f", compPercent = true },
{ stat = "EnergyShieldLeechGainPerHit", label = "ES Leech/Gain per Hit", color = colorCodes.ES, fmt = ".1f", compPercent = true },
{ },
{ stat = "Ward", label = "Ward", fmt = "d", color = colorCodes.WARD, compPercent = true },
{ },
{ stat = "Rage", label = "Rage", fmt = "d", color = colorCodes.RAGE, compPercent = true },
{ stat = "RageRegenRecovery", label = "Rage Regen", fmt = ".1f", color = colorCodes.RAGE, compPercent = true },
{ },
{ stat = "TotalDegen", label = "Total Degen", fmt = ".1f", lowerIsBetter = true },
{ stat = "TotalNetRegen", label = "Total Net Regen", fmt = "+.1f" },
{ stat = "NetLifeRegen", label = "Net Life Regen", fmt = "+.1f", color = colorCodes.LIFE },
{ stat = "NetManaRegen", label = "Net Mana Regen", fmt = "+.1f", color = colorCodes.MANA },
{ stat = "NetEnergyShieldRegen", label = "Net Energy Shield Regen", fmt = "+.1f", color = colorCodes.ES },
{ },
{ stat = "Evasion", label = "Evasion rating", fmt = "d", color = colorCodes.EVASION, compPercent = true },
{ stat = "Spec:EvasionInc", label = "%Inc Evasion from Tree", color = colorCodes.EVASION, fmt = "d%%" },
{ stat = "MeleeEvadeChance", label = "Evade Chance", fmt = "d%%", color = colorCodes.EVASION, condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance == o.ProjectileEvadeChance end },
Expand Down
35 changes: 17 additions & 18 deletions src/Modules/CalcBreakdown.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,28 @@ local s_format = string.format
local breakdown = { }

function breakdown.multiChain(out, chain)
local base = chain.base
local lines = 0
for _, mult in ipairs(chain) do
if mult[2] and mult[2] ~= 1 then
if lines == 0 then
if base then
if chain.label then
t_insert(out, chain.label)
end
t_insert(out, base)
t_insert(out, "x "..s_format(unpack(mult)))
lines = 2
else
base = s_format(unpack(mult))
end
else
local base = (chain.base and chain.base[2]) or nil
local multiplier = 1
local lines = 0 -- lines is the total number of non 1 multipliers.
if chain.label then
t_insert(out, chain.label)
end
if base ~= nil then
t_insert(out, s_format(unpack(chain.base)))
end
if base ~= 0 then
for _, mult in ipairs(chain) do
if mult[2] and mult[2] ~= 1 then
multiplier = multiplier * mult[2]
t_insert(out, "x "..s_format(unpack(mult)))
lines = lines + 1
end
end
end
if lines > 0 then
if chain.total then
t_insert(out, chain.total)
elseif (lines > 0 and base ~= nil) or (lines > 1 and base == nil) then
t_insert(out, s_format("= %.2f", multiplier * (base or 1)))
end
return lines
end
Expand Down Expand Up @@ -149,7 +148,7 @@ end

function breakdown.dot(out, baseVal, inc, more, mult, rate, aura, effMult, total)
breakdown.multiChain(out, {
base = s_format("%.1f ^8(base damage per second)", baseVal),
base = { "%.1f ^8(base damage per second)", baseVal },
{ "%.2f ^8(increased/reduced)", 1 + inc/100 },
{ "%.2f ^8(more/less)", more },
{ "%.2f ^8(multiplier)", 1 + (mult or 0)/100 },
Expand Down
173 changes: 72 additions & 101 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -626,114 +626,85 @@ function calcs.defence(env, actor)
}
end

-- Mana, life, energy shield, and rage regen
if modDB:Flag(nil, "NoManaRegen") then
output.ManaRegen = 0
output.ManaRegenRecovery = - modDB:Sum("BASE", nil, "ManaDegen")
else
local base = modDB:Sum("BASE", nil, "ManaRegen") + output.Mana * modDB:Sum("BASE", nil, "ManaRegenPercent") / 100
output.ManaRegenInc = modDB:Sum("INC", nil, "ManaRegen")
local more = modDB:More(nil, "ManaRegen")
if modDB:Flag(nil, "ManaRegenToRageRegen") then
output.ManaRegenInc = 0
end
local regen = base * (1 + output.ManaRegenInc/100) * more
local regenRate = round(regen * output.ManaRecoveryRateMod, 1)
local degen = modDB:Sum("BASE", nil, "ManaDegen")
output.ManaRegen = regenRate
output.ManaRegenRecovery = (modDB:Flag(nil, "UnaffectedByManaRegen") and 0 or output.ManaRegen) - degen
if breakdown then
breakdown.ManaRegenRecovery = { }
breakdown.multiChain(breakdown.ManaRegenRecovery, {
label = "Mana Regeneration:",
base = s_format("%.1f ^8(base)", base),
{ "%.2f ^8(increased/reduced)", 1 + output.ManaRegenInc/100 },
{ "%.2f ^8(more/less)", more },
total = s_format("= %.1f ^8per second", regen),
})
breakdown.multiChain(breakdown.ManaRegenRecovery, {
label = "Effective Mana Regeneration:",
base = s_format("%.1f", regen),
{ "%.2f ^8(recovery rate modifier)", output.ManaRecoveryRateMod },
total = s_format("= %.1f ^8per second", regenRate),
})
if degen ~= 0 then
t_insert(breakdown.ManaRegenRecovery, s_format("- %d", degen))
t_insert(breakdown.ManaRegenRecovery, s_format("= %.1f ^8per second", output.ManaRegenRecovery))
end
end
end
if modDB:Flag(nil, "NoLifeRegen") then
output.LifeRegen = 0
elseif modDB:Flag(nil, "ZealotsOath") then
output.LifeRegen = 0
local lifeBase = modDB:Sum("BASE", nil, "LifeRegen")
if lifeBase > 0 then
modDB:NewMod("EnergyShieldRegen", "BASE", lifeBase, "Zealot's Oath")
end
local lifePercent = modDB:Sum("BASE", nil, "LifeRegenPercent")
if lifePercent > 0 then
modDB:NewMod("EnergyShieldRegenPercent", "BASE", lifePercent, "Zealot's Oath")
end
else
local lifeBase = modDB:Sum("BASE", nil, "LifeRegen")
local lifePercent = modDB:Sum("BASE", nil, "LifeRegenPercent")
if lifePercent > 0 then
lifeBase = lifeBase + output.Life * lifePercent / 100
end
if lifeBase > 0 then
output.LifeRegen = lifeBase * output.LifeRecoveryRateMod * modDB:More(nil, "LifeRegen") * (1 + modDB:Sum("INC", nil, "LifeRegen") / 100)
else
-- Regeneration
local resources = {"Mana", "Life", "Energy Shield", "Rage"}
for i, resourceName in ipairs(resources) do
local resource = resourceName:gsub(" ", "")
local pool = output[resource] or 0
local baseRegen = 0
local inc = modDB:Sum("INC", nil, resource.."Regen")
local more = modDB:More(nil, resource.."Regen")
local regen = 0
local regenRate = 0
local recoveryRateMod = output[resource.."RecoveryRateMod"] or 1
if modDB:Flag(nil, "No"..resource.."Regen") then
output[resource.."Regen"] = 0
elseif resource == "Life" and modDB:Flag(nil, "ZealotsOath") then
output.LifeRegen = 0
end
-- Don't add life recovery mod for this
if output.LifeRegen and modDB:Flag(nil, "LifeRegenerationRecoversEnergyShield") and output.EnergyShield > 0 then
modDB:NewMod("EnergyShieldRecovery", "BASE",output.LifeRegen / output.LifeRecoveryRateMod, "Life Regeneration Recovers Energy Shield")
end
end
output.LifeRegenRecovery = (modDB:Flag(nil, "UnaffectedByLifeRegen") and 0 or output.LifeRegen) - modDB:Sum("BASE", nil, "LifeDegen") + modDB:Sum("BASE", nil, "LifeRecovery") * output.LifeRecoveryRateMod
output.LifeRegenPercent = round(output.LifeRegenRecovery / output.Life * 100, 1)
if modDB:Flag(nil, "NoEnergyShieldRegen") then
output.EnergyShieldRegenRecovery = 0 - modDB:Sum("BASE", nil, "EnergyShieldDegen")
output.EnergyShieldRegenPercent = round(output.EnergyShieldRegenRecovery / output.EnergyShield * 100, 1)
else
local esBase = modDB:Sum("BASE", nil, "EnergyShieldRegen")
local esPercent = modDB:Sum("BASE", nil, "EnergyShieldRegenPercent")
if esPercent > 0 then
esBase = esBase + output.EnergyShield * esPercent / 100
end
if esBase > 0 then
output.EnergyShieldRegenRecovery = esBase * output.EnergyShieldRecoveryRateMod * calcLib.mod(modDB, nil, "EnergyShieldRegen") - modDB:Sum("BASE", nil, "EnergyShieldDegen")
output.EnergyShieldRegenPercent = round(output.EnergyShieldRegenRecovery / output.EnergyShield * 100, 1)
local lifeBase = modDB:Sum("BASE", nil, "LifeRegen")
if lifeBase > 0 then
modDB:NewMod("EnergyShieldRegen", "BASE", lifeBase, "Zealot's Oath")
end
local lifePercent = modDB:Sum("BASE", nil, "LifeRegenPercent")
if lifePercent > 0 then
modDB:NewMod("EnergyShieldRegenPercent", "BASE", lifePercent, "Zealot's Oath")
end
else
output.EnergyShieldRegenRecovery = 0 - modDB:Sum("BASE", nil, "EnergyShieldDegen")
if inc ~= 0 then -- legacy chain breaker increase/decrease regen rate to different resource.
for j=i+1,#resources do
if modDB:Flag(nil, resource.."RegenTo"..resources[j]:gsub(" ", "").."Regen") then
modDB:NewMod(resources[j]:gsub(" ", "").."Regen", "INC", inc, resourceName.." instead applies to "..resources[j])
inc = 0
end
end
end
baseRegen = modDB:Sum("BASE", nil, resource.."Regen") + pool * modDB:Sum("BASE", nil, resource.."RegenPercent") / 100
regen = baseRegen * (1 + inc/100) * more
if regen ~= 0 then -- Pious Path
for j=i+1,#resources do
if modDB:Flag(nil, resource.."RegenerationRecovers"..resources[j]:gsub(" ", "")) then
modDB:NewMod(resources[j]:gsub(" ", "").."Recovery", "BASE", regen, resourceName.." Regeneration Recovers "..resources[j])
end
end
end
regenRate = round(regen * recoveryRateMod, 1)
output[resource.."Regen"] = regenRate
end
end
output.EnergyShieldRegenRecovery = output.EnergyShieldRegenRecovery + modDB:Sum("BASE", nil, "EnergyShieldRecovery") * output.EnergyShieldRecoveryRateMod
output.EnergyShieldRegenPercent = round(output.EnergyShieldRegenRecovery / output.EnergyShield * 100, 1)
if modDB:Sum("BASE", nil, "RageRegen") > 0 then
modDB:NewMod("Condition:CanGainRage", "FLAG", true, "RageRegen")
local base = modDB:Sum("BASE", nil, "RageRegen")
if modDB:Flag(nil, "ManaRegenToRageRegen") then
local mana = modDB:Sum("INC", nil, "ManaRegen")
modDB:NewMod("RageRegen", "INC", mana, "Mana Regen to Rage Regen")
output[resource.."RegenInc"] = inc
local baseDegen = (modDB:Sum("BASE", nil, resource.."Degen") + pool * modDB:Sum("BASE", nil, resource.."DegenPercent") / 100)
local degenRate = (baseDegen > 0) and baseDegen * calcLib.mod(modDB, nil, resource.."Degen") or 0
output[resource.."Degen"] = degenRate
local recoveryRate = modDB:Sum("BASE", nil, resource.."Recovery") * recoveryRateMod
output[resource.."Recovery"] = recoveryRate
output[resource.."RegenRecovery"] = (modDB:Flag(nil, "UnaffectedBy"..resource.."Regen") and 0 or regenRate) - degenRate + recoveryRate
if output[resource.."RegenRecovery"] > 0 then
modDB:NewMod("Condition:CanGain"..resource, "FLAG", true, resourceName.."Regen")
end
local inc = modDB:Sum("INC", nil, "RageRegen")
local more = modDB:More(nil, "RageRegen")
output.RageRegen = base * (1 + inc /100) * more
output[resource.."RegenPercent"] = round(output[resource.."RegenRecovery"] / pool * 100, 1)
if breakdown then
breakdown.RageRegen = { }
breakdown.multiChain(breakdown.RageRegen, {
base = s_format("%.1f ^8(base)", base),
breakdown[resource.."RegenRecovery"] = { }
breakdown.multiChain(breakdown[resource.."RegenRecovery"], {
label = resourceName.." Regeneration:",
base = { "%.1f ^8(base)", baseRegen },
{ "%.2f ^8(increased/reduced)", 1 + inc/100 },
{ "%.2f ^8(more/less)", more },
total = s_format("= %.1f ^8per second", output.RageRegen),
{ "%.2f ^8(recovery rate modifier)", recoveryRateMod },
total = s_format("= %.1f ^8per second", regenRate)
})
if modDB:Flag(nil, "UnaffectedBy"..resource.."Regen") then
t_insert(breakdown[resource.."RegenRecovery"], "Unaffected by "..resourceName.." Regen")
end
if degenRate ~= 0 then
t_insert(breakdown[resource.."RegenRecovery"], s_format("- %.1f ^8(degen)", degenRate))
t_insert(breakdown[resource.."RegenRecovery"], s_format("= %.1f ^8per second", (modDB:Flag(nil, "UnaffectedBy"..resource.."Regen") and 0 or regenRate) - degenRate))
end
if recoveryRate ~= 0 then
t_insert(breakdown[resource.."RegenRecovery"], s_format("+ %.1f ^8(recovery)", recoveryRate))
t_insert(breakdown[resource.."RegenRecovery"], s_format("= %.1f ^8per second", output[resource.."RegenRecovery"]))
end
end
end



-- Energy Shield Recharge
output.EnergyShieldRechargeAppliesToLife = modDB:Flag(nil, "EnergyShieldRechargeAppliesToLife")
output.EnergyShieldRechargeAppliesToEnergyShield = not (modDB:Flag(nil, "NoEnergyShieldRecharge") or output.EnergyShieldRechargeAppliesToLife)
Expand All @@ -748,14 +719,14 @@ function calcs.defence(env, actor)
breakdown.LifeRecharge = { }
breakdown.multiChain(breakdown.LifeRecharge, {
label = "Recharge rate:",
base = s_format("%.1f ^8(33%% per second)", output.Life * data.misc.EnergyShieldRechargeBase),
base = { "%.1f ^8(33%% per second)", output.Life * data.misc.EnergyShieldRechargeBase },
{ "%.2f ^8(increased/reduced)", 1 + inc/100 },
{ "%.2f ^8(more/less)", more },
total = s_format("= %.1f ^8per second", recharge),
})
breakdown.multiChain(breakdown.LifeRecharge, {
label = "Effective Recharge rate:",
base = s_format("%.1f", recharge),
base = { "%.1f", recharge },
{ "%.2f ^8(recovery rate modifier)", output.LifeRecoveryRateMod },
total = s_format("= %.1f ^8per second", output.LifeRecharge),
})
Expand All @@ -767,14 +738,14 @@ function calcs.defence(env, actor)
breakdown.EnergyShieldRecharge = { }
breakdown.multiChain(breakdown.EnergyShieldRecharge, {
label = "Recharge rate:",
base = s_format("%.1f ^8(33%% per second)", output.EnergyShield * data.misc.EnergyShieldRechargeBase),
base = { "%.1f ^8(33%% per second)", output.EnergyShield * data.misc.EnergyShieldRechargeBase },
{ "%.2f ^8(increased/reduced)", 1 + inc/100 },
{ "%.2f ^8(more/less)", more },
total = s_format("= %.1f ^8per second", recharge),
})
breakdown.multiChain(breakdown.EnergyShieldRecharge, {
label = "Effective Recharge rate:",
base = s_format("%.1f", recharge),
base = { "%.1f", recharge },
{ "%.2f ^8(recovery rate modifier)", output.EnergyShieldRecoveryRateMod },
total = s_format("= %.1f ^8per second", output.EnergyShieldRecharge),
})
Expand Down
Loading