Skip to content

Commit 62c7677

Browse files
Add support for Eternal Life ascendancy notable (#1011)
Defensive calcs and life cost warning
1 parent ecdafa0 commit 62c7677

File tree

4 files changed

+44
-22
lines changed

4 files changed

+44
-22
lines changed

src/Modules/Build.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,9 @@ function buildMode:AddDisplayStatList(statList, actor)
16271627
InsertIfNew(self.controls.warnings.lines, line)
16281628
end
16291629
end
1630+
if actor.output.EternalLifeWarning then
1631+
InsertIfNew(self.controls.warnings.lines, "You cannot pay Life costs of skills while You have Energy Shield and have Eternal Life allocated")
1632+
end
16301633
if actor.output.VixensTooMuchCastSpeedWarn then
16311634
InsertIfNew(self.controls.warnings.lines, "You may have too much cast speed or too little cooldown reduction to effectively use Vixen's Curse replacement")
16321635
end

src/Modules/CalcDefence.lua

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,14 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
542542
local lifeHitPool = calcLifeHitPoolWithLossPrevention(life, output.Life, output.preventedLifeLoss, lifeLossBelowHalfPrevented)
543543
local MoMEffect = m_min(output.sharedMindOverMatter + output[damageType.."MindOverMatter"], 100) / 100
544544
local MoMPool = MoMEffect < 1 and m_min(lifeHitPool / (1 - MoMEffect) - lifeHitPool, mana) or mana
545-
if energyShield > 0 and esBypass < 1 then
545+
if energyShield > 0 and modDB:Flag(nil, "EternalLife") then
546+
local tempDamage = m_min(damageRemainder, energyShield / (1 - esBypass) / esDamageTypeMultiplier)
547+
energyShield = energyShield - tempDamage * (1 - esBypass) * esDamageTypeMultiplier
548+
esPoolRemaining = m_min(esPoolRemaining, energyShield)
549+
damageRemainder = damageRemainder - tempDamage
550+
resourcesLostToTypeDamage[damageType].energyShield = tempDamage >= 1 and tempDamage * (1 - esBypass) * esDamageTypeMultiplier or nil
551+
resourcesLostToTypeDamage[damageType].eternalLifePrevented = tempDamage >= 1 and tempDamage * esBypass * esDamageTypeMultiplier or nil
552+
elseif energyShield > 0 and esBypass < 1 then
546553
local MoMEBPool = esBypass > 0 and m_min((MoMPool + lifeHitPool) / esBypass * esDamageTypeMultiplier - (MoMPool + lifeHitPool), energyShield) or energyShield
547554
local tempDamage = m_min(damageRemainder * (1 - esBypass), MoMEBPool / esDamageTypeMultiplier)
548555
esPoolRemaining = m_min(esPoolRemaining, MoMEBPool - tempDamage * esDamageTypeMultiplier)
@@ -663,7 +670,9 @@ local function incomingDamageBreakdown(breakdownTable, poolsRemaining, output)
663670
if output.sharedAegis and output.sharedAegis > 0 then
664671
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Shared Aegis charge ^7(%d remaining)", output.sharedAegis - poolsRemaining.Aegis.shared, poolsRemaining.Aegis.shared))
665672
end
673+
local eternalLifePrevented = 0
666674
for _, damageType in ipairs(dmgTypeList) do
675+
eternalLifePrevented = eternalLifePrevented + (poolsRemaining.resourcesLostToTypeDamage[damageType].eternalLifePrevented or 0)
667676
if poolsRemaining.resourcesLostToTypeDamage[damageType].guard then
668677
t_insert(breakdownTable, s_format("\n\t%d "..colorCodes.SCOURGE.."%s Guard charge ^7(%d remaining)", poolsRemaining.resourcesLostToTypeDamage[damageType].guard, damageType, poolsRemaining.Guard[damageType]))
669678
end
@@ -677,6 +686,9 @@ local function incomingDamageBreakdown(breakdownTable, poolsRemaining, output)
677686
if output.EnergyShieldRecoveryCap ~= poolsRemaining.EnergyShield and output.EnergyShieldRecoveryCap and output.EnergyShieldRecoveryCap > 0 then
678687
t_insert(breakdownTable, s_format("\t%d "..colorCodes.ES.."Energy Shield ^7(%d remaining)", output.EnergyShieldRecoveryCap - poolsRemaining.EnergyShield, poolsRemaining.EnergyShield))
679688
end
689+
if eternalLifePrevented > 0 then
690+
t_insert(breakdownTable, s_format("\t%d "..colorCodes.POSITIVE.."Life change prevented by Eternal Life", eternalLifePrevented))
691+
end
680692
if output.ManaUnreserved ~= poolsRemaining.Mana and output.ManaUnreserved and output.ManaUnreserved > 0 then
681693
t_insert(breakdownTable, s_format("\t%d "..colorCodes.MANA.."Mana ^7(%d remaining)", output.ManaUnreserved - poolsRemaining.Mana, poolsRemaining.Mana))
682694
end
@@ -2783,33 +2795,35 @@ function calcs.buildDefenceEstimations(env, actor)
27832795
for _, damageType in ipairs(dmgTypeList) do
27842796
output[damageType.."TotalPool"] = output[damageType.."ManaEffectiveLife"]
27852797
output[damageType.."TotalHitPool"] = output[damageType.."MoMHitPool"]
2786-
local manatext = "Mana"
2787-
if output[damageType.."EnergyShieldBypass"] < 100 then
2788-
if modDB:Flag(nil, "EnergyShieldProtectsMana") then
2789-
manatext = manatext.." and non-bypassed Energy Shield"
2798+
local esBypass = output[damageType.."EnergyShieldBypass"] / 100
2799+
local chaosESMultiplier = damageType == "Chaos" and 2 or 1
2800+
if modDB:Flag(nil, "EternalLife") then
2801+
output[damageType.."TotalPool"] = output[damageType.."TotalPool"] + output.EnergyShieldRecoveryCap / (1 - esBypass) / chaosESMultiplier
2802+
output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + output.EnergyShieldRecoveryCap / (1 - esBypass) / chaosESMultiplier
2803+
elseif esBypass < 1 then
2804+
if esBypass > 0 then
2805+
local poolProtected = output.EnergyShieldRecoveryCap / (1 - esBypass) * esBypass / chaosESMultiplier
2806+
output[damageType.."TotalPool"] = m_max(output[damageType.."TotalPool"] - poolProtected, 0) + m_min(output[damageType.."TotalPool"], poolProtected) / esBypass
2807+
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / esBypass
27902808
else
2791-
local chaosESMultiplier = damageType == "Chaos" and 2 or 1
2792-
if output[damageType.."EnergyShieldBypass"] > 0 then
2793-
local poolProtected = output.EnergyShieldRecoveryCap / (1 - output[damageType.."EnergyShieldBypass"] / 100) * (output[damageType.."EnergyShieldBypass"] / 100 / chaosESMultiplier)
2794-
output[damageType.."TotalPool"] = m_max(output[damageType.."TotalPool"] - poolProtected, 0) + m_min(output[damageType.."TotalPool"], poolProtected) / (output[damageType.."EnergyShieldBypass"] / 100)
2795-
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (output[damageType.."EnergyShieldBypass"] / 100)
2796-
else
2797-
output[damageType.."TotalPool"] = output[damageType.."TotalPool"] + output.EnergyShieldRecoveryCap / chaosESMultiplier
2798-
output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + output.EnergyShieldRecoveryCap / chaosESMultiplier
2799-
end
2809+
output[damageType.."TotalPool"] = output[damageType.."TotalPool"] + output.EnergyShieldRecoveryCap / chaosESMultiplier
2810+
output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + output.EnergyShieldRecoveryCap / chaosESMultiplier
28002811
end
28012812
end
28022813
if breakdown then
28032814
breakdown[damageType.."TotalPool"] = {
28042815
s_format("Life: %d", output.LifeRecoverable)
28052816
}
28062817
if output[damageType.."ManaEffectiveLife"] ~= output.LifeRecoverable then
2807-
t_insert(breakdown[damageType.."TotalPool"], s_format("%s through MoM: %d", manatext, output[damageType.."ManaEffectiveLife"] - output.LifeRecoverable))
2818+
t_insert(breakdown[damageType.."TotalPool"], s_format("Mana through MoM: %d", output[damageType.."ManaEffectiveLife"] - output.LifeRecoverable))
28082819
end
2809-
if (not modDB:Flag(nil, "EnergyShieldProtectsMana")) and output[damageType.."EnergyShieldBypass"] < 100 then
2820+
if modDB:Flag(nil, "EternalLife") then
2821+
t_insert(breakdown[damageType.."TotalPool"], s_format("Energy Shield: %d%s", output.EnergyShieldRecoveryCap / chaosESMultiplier, damageType == "Chaos" and "^8 (ES takes double damage from chaos)" or ""))
2822+
t_insert(breakdown[damageType.."TotalPool"], s_format("Life change prevented by Eternal Life: %d", output[damageType.."TotalPool"] - output[damageType.."ManaEffectiveLife"] - output.EnergyShieldRecoveryCap / chaosESMultiplier))
2823+
elseif esBypass < 1 then
28102824
t_insert(breakdown[damageType.."TotalPool"], s_format("Non-bypassed Energy Shield: %d", output[damageType.."TotalPool"] - output[damageType.."ManaEffectiveLife"]))
28112825
end
2812-
t_insert(breakdown[damageType.."TotalPool"], s_format("TotalPool: %d", output[damageType.."TotalPool"]))
2826+
t_insert(breakdown[damageType.."TotalPool"], s_format("Total Pool: %d", output[damageType.."TotalPool"]))
28132827
end
28142828
end
28152829

@@ -4062,6 +4076,9 @@ function calcs.buildDefenceEstimations(env, actor)
40624076
resourcesLostSum = resourcesLostSum + resourcesLost.energyShield
40634077
t_insert(breakdownTable, s_format("\t%d "..colorCodes.ES.."Energy Shield%s", resourcesLost.energyShield, damageType == "Chaos" and "^8 (ES takes double damage from chaos)" or ""))
40644078
end
4079+
if resourcesLost.eternalLifePrevented then
4080+
t_insert(breakdownTable, s_format("\t%d "..colorCodes.POSITIVE.."Life change prevented by Eternal Life", resourcesLost.eternalLifePrevented))
4081+
end
40654082
if resourcesLost.mana then
40664083
resourcesLostSum = resourcesLostSum + resourcesLost.mana
40674084
t_insert(breakdownTable, s_format("\t%d "..colorCodes.MANA.."Mana", resourcesLost.mana))

src/Modules/Calcs.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ function calcs.buildOutput(build, mode)
429429
t_insert(output[costResource.."Warning"], skill.activeEffect.grantedEffect.name)
430430
end
431431
end
432+
output.EternalLifeWarning = output.EternalLifeWarning or env.modDB:Flag(nil, "EternalLife") and costResource == "LifeCost" and cachedCost > 0 and output.EnergyShieldRecoveryCap > 0
432433
end
433434
end
434435
for pool, costResource in pairs({["LifeUnreservedPercent"] = "LifePercentCost", ["ManaUnreservedPercent"] = "ManaPercentCost"}) do

src/Modules/ModParser.lua

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,11 +2282,11 @@ local specialModList = {
22822282
mod("PhysicalEnergyShieldBypass", "BASE", 100),
22832283
},
22842284
["(%d+)%% of damage taken bypasses energy shield"] = function(num) return {
2285-
mod("PhysicalEnergyShieldBypass", "OVERRIDE", num),
2286-
mod("LightningEnergyShieldBypass", "OVERRIDE", num),
2287-
mod("ColdEnergyShieldBypass", "OVERRIDE", num),
2288-
mod("FireEnergyShieldBypass", "OVERRIDE", num),
2289-
mod("ChaosEnergyShieldBypass", "OVERRIDE", num),
2285+
mod("PhysicalEnergyShieldBypass", "BASE", num),
2286+
mod("LightningEnergyShieldBypass", "BASE", num),
2287+
mod("ColdEnergyShieldBypass", "BASE", num),
2288+
mod("FireEnergyShieldBypass", "BASE", num),
2289+
mod("ChaosEnergyShieldBypass", "BASE", num),
22902290
} end,
22912291
["auras from your skills do not affect allies"] = { flag("SelfAuraSkillsCannotAffectAllies") },
22922292
["auras from your skills have (%d+)%% more effect on you"] = function(num) return { mod("SkillAuraEffectOnSelf", "MORE", num) } end,
@@ -2828,6 +2828,7 @@ local specialModList = {
28282828
["gain accuracy rating equal to your strength"] = { mod("Accuracy", "BASE", 1, { type = "PerStat", stat = "Str" }) },
28292829
["gain accuracy rating equal to twice your strength"] = { mod("Accuracy", "BASE", 2, { type = "PerStat", stat = "Str" }) },
28302830
-- Lich
2831+
["your life cannot change while you have energy shield"] = { flag("EternalLife") },
28312832
["while you are not on low mana, you and allies in your presence have unholy might"] = { mod("ExtraAura", "LIST", { mod = flag("Condition:UnholyMight")}, { type = "Condition", var = "LowMana", neg = true }) },
28322833
["(%d+)%% increased magnitude of unholy might buffs you grant per (%d+) maximum mana"] = function(num, _, num2) return { mod("ExtraAura", "LIST", { mod = mod("Multiplier:UnholyMightMagnitude", "BASE", num, { type = "PerStat", stat = "Mana", div = tonumber(num2), actor = "parent"}), { type = "GlobalEffect", effectName = "BlackenedHeart", effectType = "Aura", unscaleable = true}}) } end,
28332834
["non%-channelling spells cost an additional (%d+)%% of maximum energy shield"] = function(num) return { mod("ESCostBase", "BASE", 1, nil, 0, KeywordFlag.Spell, { type = "PercentStat", percent = num, stat = "EnergyShield" }, { type = "SkillType", skillType = SkillType.Channel, neg = true } )} end,

0 commit comments

Comments
 (0)