Skip to content
Closed
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
3 changes: 3 additions & 0 deletions src/Data/Skills/act_str.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4929,6 +4929,9 @@ skills["PetrifiedBlood"] = {
["skill_grants_life_cost_%_mana_cost_while_not_on_low_life"] = {
mod("ManaCostAsLifeCost", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }, { type="Condition", var="LowLife", neg = true }),
},
["petrified_blood_%_life_loss_below_half_from_hit_to_prevent"] = {
mod("LifeLossBelowHalfPrevented", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff" }),
},
},
baseFlags = {
},
Expand Down
3 changes: 3 additions & 0 deletions src/Export/Skills/act_str.txt
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,9 @@ local skills, mod, flag, skill = ...
["skill_grants_life_cost_%_mana_cost_while_not_on_low_life"] = {
mod("ManaCostAsLifeCost", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }, { type="Condition", var="LowLife", neg = true }),
},
["petrified_blood_%_life_loss_below_half_from_hit_to_prevent"] = {
mod("LifeLossBelowHalfPrevented", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff" }),
},
},
#mods

Expand Down
51 changes: 44 additions & 7 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -825,18 +825,52 @@ function calcs.defence(env, actor)
output[damageType.."EnergyShieldBypass"] = m_max(m_min(output[damageType.."EnergyShieldBypass"], 100), 0)
end


-- Prevented life loss (Petrified Blood)
output.AnyPreventedLifeLoss = false
for _, damageType in ipairs(dmgTypeList) do
preventedLifeLoss = modDB:Sum("BASE", nil, "LifeLossBelowHalfPrevented")

if not modDB:Flag(nil, "Condition:LowLife") then
preventedLifeLoss = preventedLifeLoss / 2
end

output[damageType.."PreventedLifeLoss"] = preventedLifeLoss
if output[damageType.."PreventedLifeLoss"] > 0 then
output.AnyPreventedLifeLoss = true
local sourcePool = m_max(output.LifeUnreserved or 0, 0)
local poolProtected = sourcePool / (output[damageType.."PreventedLifeLoss"] / 100) * (1 - output[damageType.."PreventedLifeLoss"] / 100)
output[damageType.."PreventedEffectiveLife"] = m_max(sourcePool - poolProtected, 0) + m_min(sourcePool, poolProtected) / (1 - output[damageType.."PreventedLifeLoss"] / 100)
if breakdown then
if output[damageType.."PreventedLifeLoss"] then
breakdown[damageType.."PreventedLifeLoss"] = {
s_format("Total life protected:"),
s_format("%d ^8(%s)", sourcePool, "unreserved life"),
s_format("/ %.2f ^8(portion of damage prevented)", output[damageType.."PreventedLifeLoss"] / 100),
s_format("x %.2f ^8(portion taken from life)", 1 - output[damageType.."PreventedLifeLoss"] / 100),
s_format("= %d", poolProtected),
s_format("Effective life: %d", output[damageType.."PreventedEffectiveLife"])
}
end
end
else
output[damageType.."PreventedEffectiveLife"] = output.LifeUnreserved
end
end

-- Guard
output.AnyGuard = false
for _, damageType in ipairs(dmgTypeList) do
output[damageType.."GuardAbsorbRate"] = m_min(modDB:Sum("BASE", nil, "GuardAbsorbRate") + modDB:Sum("BASE", nil, damageType.."GuardAbsorbRate"), 100)
if output[damageType.."GuardAbsorbRate"] > 0 then
output.AnyGuard = true
local sourcePool = m_max(output[damageType.."PreventedEffectiveLife"] or 0, 0)
output[damageType.."GuardAbsorb"] = calcLib.val(modDB, "GuardAbsorbLimit") + calcLib.val(modDB, damageType.."GuardAbsorbLimit")
local lifeProtected = output[damageType.."GuardAbsorb"] / (output[damageType.."GuardAbsorbRate"] / 100) * (1 - output[damageType.."GuardAbsorbRate"] / 100)
if output[damageType.."GuardAbsorbRate"] >= 100 then
output[damageType.."GuardEffectiveLife"] = output.LifeUnreserved + output[damageType.."GuardAbsorb"]
output[damageType.."GuardEffectiveLife"] = sourcePool + output[damageType.."GuardAbsorb"]
else
output[damageType.."GuardEffectiveLife"] = m_max(output.LifeUnreserved - lifeProtected, 0) + m_min(output.LifeUnreserved, lifeProtected) / (1 - output[damageType.."GuardAbsorbRate"] / 100)
output[damageType.."GuardEffectiveLife"] = m_max(sourcePool - lifeProtected, 0) + m_min(sourcePool, lifeProtected) / (1 - output[damageType.."GuardAbsorbRate"] / 100)
end
if breakdown then
breakdown[damageType.."GuardAbsorb"] = {
Expand All @@ -845,11 +879,11 @@ function calcs.defence(env, actor)
s_format("/ %.2f ^8(portion taken from guard)", output[damageType.."GuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output[damageType.."GuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected),
s_format("Guard life protection: %d", output[damageType.."GuardEffectiveLife"] - output.LifeUnreserved)
s_format("Guard life protection: %d", output[damageType.."GuardEffectiveLife"] - sourcePool)
}
end
else
output[damageType.."GuardEffectiveLife"] = output.LifeUnreserved
output[damageType.."GuardEffectiveLife"] = output[damageType.."PreventedEffectiveLife"]
end
end

Expand Down Expand Up @@ -921,7 +955,7 @@ function calcs.defence(env, actor)
output[damageType.."TotalPool"] = output[damageType.."TotalPool"] + (output.EnergyShieldRecoveryCap or output.EnergyShield)
end
if output[damageType.."GuardAbsorbRate"] > 0 then
local guardRemain = output[damageType.."GuardAbsorb"] - (output[damageType.."GuardEffectiveLife"] - output.LifeUnreserved)
local guardRemain = output[damageType.."GuardAbsorb"] - (output[damageType.."GuardEffectiveLife"] - output[damageType.."PreventedEffectiveLife"])
local espool = output[damageType.."TotalPool"] - output[damageType.."ManaEffectiveLife"]
if guardRemain > 0 then
local poolProtected = guardRemain / (output[damageType.."GuardAbsorbRate"] / 100) * (1 - output[damageType.."GuardAbsorbRate"] / 100)
Expand All @@ -942,8 +976,11 @@ function calcs.defence(env, actor)
breakdown[damageType.."TotalPool"] = {
s_format("Life: %d", output.LifeUnreserved)
}
if output[damageType.."GuardEffectiveLife"] ~= output.LifeUnreserved then
t_insert(breakdown[damageType.."TotalPool"], s_format("Guard skill: %d", output[damageType.."GuardEffectiveLife"] - output.LifeUnreserved + output[damageType.."GuardEffectivePool"]))
if output[damageType.."PreventedEffectiveLife"] ~= output.LifeUnreserved then
t_insert(breakdown[damageType.."TotalPool"], s_format("Damage prevented: %d", output[damageType.."PreventedEffectiveLife"] - output.LifeUnreserved))
end
if output[damageType.."GuardEffectiveLife"] ~= output[damageType.."PreventedEffectiveLife"] then
t_insert(breakdown[damageType.."TotalPool"], s_format("Guard skill: %d", output[damageType.."GuardEffectiveLife"] - output[damageType.."PreventedEffectiveLife"] + output[damageType.."GuardEffectivePool"]))
end
if output[damageType.."ManaEffectiveLife"] ~= output[damageType.."GuardEffectiveLife"] then
t_insert(breakdown[damageType.."TotalPool"], s_format("%s through MoM: %d", manatext, output[damageType.."ManaEffectiveLife"] - output[damageType.."GuardEffectiveLife"]))
Expand Down
22 changes: 22 additions & 0 deletions src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,28 @@ return {
{ modName = {"ChaosEnergyShieldBypass", "ChaosNotBypassEnergyShield", "BlockedDamageDoesntBypassES", "UnblockedDamageDoesBypassES"} },
},
},
{ label = "Prevented Life Loss", haveOutput = "AnyPreventedLifeLoss",
{ format = "{0:output:PhysicalPreventedLifeLoss}",
{ breakdown = "PhysicalPreventedLifeLoss" },
{ modName = "LifeLossBelowHalfPrevented" },
},
{ format = "{0:output:LightningPreventedLifeLoss}",
{ breakdown = "LightningPreventedLifeLoss" },
{ modName = "LifeLossBelowHalfPrevented" },
},
{ format = "{0:output:ColdPreventedLifeLoss}",
{ breakdown = "ColdPreventedLifeLoss" },
{ modName = "LifeLossBelowHalfPrevented" },
},
{ format = "{0:output:FirePreventedLifeLoss}",
{ breakdown = "FirePreventedLifeLoss" },
{ modName = "LifeLossBelowHalfPrevented" },
},
{ format = "{0:output:ChaosPreventedLifeLoss}",
{ breakdown = "ChaosPreventedLifeLoss" },
{ modName = "LifeLossBelowHalfPrevented" },
},
},
{ label = "Guard", haveOutput = "AnyGuard",
{ format = "{0:output:PhysicalGuardAbsorb}",
{ breakdown = "PhysicalGuardAbsorb" },
Expand Down