Skip to content

Commit 59fd6a8

Browse files
Add support for "Sustainable Practices" (Pathfinder Ascendancy Node) (#1250)
* Add Evasion Rating to Elemental DR calculation - This also reworks how "... and protect me from Harm" works, by replacing the boolean `FLAG` "EvasionAddsToPdr" to use a more generic and numerical "EvasionAlsoAppliesToPhysicalDamageTaken" `BASE` mod that works similarly to the Armour mods that apply to Elemental damage * Add Evasion rating calcs to self-damaging hit calc This was previously not done for "EvasionAddsToPdr" * Update `ModCache` for Invoker mod * Fix breakdowns * Remove cap on "x% Armour applies to y Damage" * Spaces --------- Co-authored-by: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com>
1 parent 897f007 commit 59fd6a8

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

src/Data/ModCache.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,7 +2711,7 @@ c["50% of Chaos damage you prevent when Hit Recouped as Life and Mana during eff
27112711
c["50% of Cold and Lightning Damage taken as Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="ColdDamageTakenAsFire",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="LightningDamageTakenAsFire",type="BASE",value=50}},nil}
27122712
c["50% of Damage taken Recouped as Mana"]={{[1]={flags=0,keywordFlags=0,name="ManaRecoup",type="BASE",value=50}},nil}
27132713
c["50% of Elemental Damage taken as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamageTakenAsChaos",type="BASE",value=50}},nil}
2714-
c["50% of Evasion Rating also grants Elemental Damage reduction"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=50}}," also grants Elemental Damage reduction "}
2714+
c["50% of Evasion Rating also grants Elemental Damage reduction"]={{[1]={flags=0,keywordFlags=0,name="EvasionAppliesToFireDamageTaken",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="EvasionAppliesToColdDamageTaken",type="BASE",value=50},[3]={flags=0,keywordFlags=0,name="EvasionAppliesToLightningDamageTaken",type="BASE",value=50}},nil}
27152715
c["50% of Maximum Life Converted to Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="LifeConvertToEnergyShield",type="BASE",value=50}},nil}
27162716
c["50% of Physical Damage prevented Recouped as Life"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="BASE",value=50}}," prevented Recouped as Life "}
27172717
c["50% of Skill Mana costs Converted to Life Costs during any Life Flask Effect"]={{[1]={flags=0,keywordFlags=0,name="ManaCost",type="BASE",value=50}}," Skill s Converted to Life Costs during any Life Flask Effect "}
@@ -5099,7 +5099,7 @@ c["Passives in radius of Whispers of Doom can be Allocated without being connect
50995099
c["Passives in radius of Zealot's Oath can be Allocated without being connected to your tree"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="fromNothingKeystone",value="zealot's oath"}},[2]={flags=0,keywordFlags=0,name="FromNothingKeystones",type="LIST",value={key="zealot's oath",value=true}}},nil}
51005100
c["Permanently Intimidate enemies on Block"]={{[1]={[1]={type="Condition",var="BlockedRecently"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:Intimidated",type="FLAG",value=true}}}},nil}
51015101
c["Persistent Buffs have 50% less Reservation"]={{[1]={[1]={skillType=139,type="SkillType"},[2]={skillType=5,type="SkillType"},flags=0,keywordFlags=0,name="Reserved",type="MORE",value=-50}},nil}
5102-
c["Physical Damage Reduction from Armour is based on your combined Armour and Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="EvasionAddsToPdr",type="FLAG",value=true}},nil}
5102+
c["Physical Damage Reduction from Armour is based on your combined Armour and Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="EvasionAppliesToPhysicalDamageTaken",type="BASE",value=100}},nil}
51035103
c["Physical Damage is Pinning"]={nil,"Physical Damage is Pinning "}
51045104
c["Physical Spell Critical Hits build Pin"]={nil,"Physical Spell Critical Hits build Pin "}
51055105
c["Physical damage based on their Skill Level"]={nil,"Physical damage based on their Skill Level "}

src/Modules/CalcDefence.lua

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,12 @@ function calcs.applyDmgTakenConversion(activeSkill, output, breakdown, sourceTyp
367367
local reductMult = 1
368368

369369
local percentOfArmourApplies = (not activeSkill.skillModList:Flag(nil, "ArmourDoesNotApplyTo"..damageType.."DamageTaken") and activeSkill.skillModList:Sum("BASE", nil, "ArmourAppliesTo"..damageType.."DamageTaken") or 0)
370-
if percentOfArmourApplies > 0 then
371-
local effArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense)
372-
-- effArmour needs to consider the "EvasionAddsToPdr" flag mod, and add the evasion to armour
370+
local percentOfEvasionApplies = (not activeSkill.skillModList:Flag(nil, "EvasionDoesNotApplyTo"..damageType.."DamageTaken") and activeSkill.skillModList:Sum("BASE", nil, "EvasionAppliesTo"..damageType.."DamageTaken") or 0)
371+
if (percentOfArmourApplies > 0) or (percentOfEvasionApplies > 0) then
372+
local effArmourFromArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense)
373+
local effArmourFromEvasion = (output.Evasion * percentOfEvasionApplies / 100)
374+
local effArmour = effArmourFromArmour + effArmourFromEvasion
375+
373376
armourReduct = round(effArmour ~= 0 and damage ~= 0 and calcs.armourReductionF(effArmour, damage) or 0)
374377
armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct)
375378
end
@@ -2259,9 +2262,9 @@ function calcs.buildDefenceEstimations(env, actor)
22592262
local effectiveAppliedArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense)
22602263
local effectiveArmourFromArmour = effectiveAppliedArmour;
22612264
local effectiveArmourFromOther = { }
2262-
local evasionAddsToPdr = modDB:Flag(nil, "EvasionAddsToPdr") and damageType == "Physical"
2263-
if evasionAddsToPdr then
2264-
effectiveArmourFromOther["Evasion"] = output.Evasion
2265+
local percentOfEvasionApplies = (not modDB:Flag(nil, "EvasionDoesNotApplyTo"..damageType.."DamageTaken") and modDB:Sum("BASE", nil, "EvasionAppliesTo"..damageType.."DamageTaken") or 0)
2266+
if percentOfEvasionApplies > 0 then
2267+
effectiveArmourFromOther["Evasion"] = m_max((output.Evasion * percentOfEvasionApplies / 100), 0)
22652268
end
22662269
for source, amount in pairs(effectiveArmourFromOther) do
22672270
-- should this be done BEFORE percentOfArmourApplies and ArmourDefense is used? Probably needs GGG confirmation
@@ -2279,7 +2282,7 @@ function calcs.buildDefenceEstimations(env, actor)
22792282
takenFlat = takenFlat + modDB:Sum("BASE", nil, "DamageTakenFromAttacks", damageType.."DamageTakenFromAttacks") / 2 + modDB:Sum("BASE", nil, damageType.."DamageTakenFromProjectileAttacks") / 4 + modDB:Sum("BASE", nil, "DamageTakenFromSpells", damageType.."DamageTakenFromSpells") / 2 + modDB:Sum("BASE", nil, "DamageTakenFromSpellProjectiles", damageType.."DamageTakenFromSpellProjectiles") / 4
22802283
end
22812284
output[damageType.."takenFlat"] = takenFlat
2282-
if percentOfArmourApplies > 0 then
2285+
if effectiveAppliedArmour > 0 then
22832286
armourReduct = calcs.armourReduction(effectiveAppliedArmour, damage)
22842287
armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct)
22852288
if impaleDamage > 0 then
@@ -2296,18 +2299,19 @@ function calcs.buildDefenceEstimations(env, actor)
22962299
if breakdown then
22972300
breakdown[damageType.."DamageReduction"] = { }
22982301
if armourReduct ~= 0 then
2299-
if percentOfArmourApplies ~= 100 then
2300-
t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of armour applies", percentOfArmourApplies))
2302+
if (percentOfArmourApplies ~= (damageType == "Physical" and 100 or 0)) and (percentOfArmourApplies > 0) then
2303+
t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of Armour applies", percentOfArmourApplies))
23012304
end
23022305
if effectiveArmourFromArmour == effectiveAppliedArmour then
23032306
t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from Armour: %d%%", armourReduct))
23042307
else
23052308
t_insert(breakdown[damageType.."DamageReduction"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour))
23062309
for source, amount in pairs(effectiveArmourFromOther) do
2310+
t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of %s applies", percentOfEvasionApplies, source))
23072311
t_insert(breakdown[damageType.."DamageReduction"], s_format("%s contributing to reduction: %d",source, amount))
23082312
end
2309-
t_insert(breakdown[damageType.."DamageReduction"], s_format("Combined Armour used for reduction: %d", effectiveAppliedArmour))
2310-
t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from combined Armour: %d%%", armourReduct))
2313+
t_insert(breakdown[damageType.."DamageReduction"], s_format("Combined Defence used for reduction: %d", effectiveAppliedArmour))
2314+
t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from combined Defence: %d%%", armourReduct))
23112315
end
23122316
if resMult ~= 1 then
23132317
t_insert(breakdown[damageType.."DamageReduction"], s_format("Enemy Hit Damage After Resistance: %d ^8(total incoming damage)", damage * resMult))
@@ -2356,18 +2360,21 @@ function calcs.buildDefenceEstimations(env, actor)
23562360
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Base %s Damage Taken: %.2f", damageType, 1 - reduction / 100))
23572361
end
23582362
if armourReduct ~= 0 then
2359-
if percentOfArmourApplies ~= 100 then
2360-
t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of armour applies", percentOfArmourApplies))
2363+
if (percentOfArmourApplies ~= (damageType == "Physical" and 100 or 0)) and (percentOfArmourApplies > 0) then
2364+
t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of Armour applies", percentOfArmourApplies))
23612365
end
23622366
if effectiveArmourFromArmour == effectiveAppliedArmour then
23632367
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from Armour: %.2f", 1 - armourReduct / 100))
23642368
else
2365-
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour))
2369+
if effectiveArmourFromArmour > 0 then
2370+
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour))
2371+
end
23662372
for source, amount in pairs(effectiveArmourFromOther) do
2373+
t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of %s applies", percentOfEvasionApplies, source))
23672374
t_insert(breakdown[damageType.."TakenHitMult"], s_format("%s contributing to reduction: %d",source, amount))
23682375
end
2369-
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Combined Armour used for reduction: %d", effectiveAppliedArmour))
2370-
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from combined Armour: %.2f", 1 - armourReduct / 100))
2376+
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Combined Defence used for reduction: %d", effectiveAppliedArmour))
2377+
t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from combined Defence: %.2f", 1 - armourReduct / 100))
23712378
end
23722379
end
23732380
if enemyOverwhelm ~= 0 then

src/Modules/ModParser.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2909,6 +2909,11 @@ local specialModList = {
29092909
} end,
29102910
["double the number of your poisons that targets can be affected by at the same time"] = function(num) return { flag("PoisonCanStack"), mod("PoisonStacks", "MORE", 100) } end,
29112911
["your speed is unaffected by slows"] = { flag("UnaffectedBySlows") },
2912+
["(%d+)%% of evasion rating also grants elemental damage reduction"] = function(num) return {
2913+
mod("EvasionAppliesToFireDamageTaken", "BASE", num),
2914+
mod("EvasionAppliesToColdDamageTaken", "BASE", num),
2915+
mod("EvasionAppliesToLightningDamageTaken", "BASE", num),
2916+
} end,
29122917
-- Raider
29132918
["nearby enemies have (%d+)%% less accuracy rating while you have phasing"] = function(num) return { mod("EnemyModifier", "LIST", { mod = mod("Accuracy", "MORE", -num) }, { type = "Condition", var = "Phasing" }) } end,
29142919
["immun[ei]t?y? to elemental ailments while phasing"] = { flag("ElementalAilmentImmune", { type = "Condition", var = "Phasing" }), },
@@ -3031,6 +3036,7 @@ local specialModList = {
30313036
["critical hits ignore non%-negative enemy monster elemental resistances"] = { flag("IgnoreNonNegativeEleRes", { type = "Condition", var = "CriticalStrike" }) },
30323037
["(%d+)%% chance on shocking enemies to created shocked ground"] = { mod("ShockBase", "BASE", data.nonDamagingAilment["Shock"].default, { type = "ActorCondition", actor = "enemy", var = "OnShockedGround" }) },
30333038
["on freezing enemies create chilled ground"] = { mod("ChillBase", "BASE", data.nonDamagingAilment["Chill"].default, { type = "ActorCondition", actor = "enemy", var = "OnChilledGround" }) },
3039+
["physical damage reduction from armour is based on your combined armour and evasion rating"] = { mod("EvasionAppliesToPhysicalDamageTaken", "BASE", 100) },
30343040
-- Chronomancer
30353041
["skills have (%d+)%% chance to not consume a cooldown when used"] = function(num) return {
30363042
mod("CooldownChanceNotConsume", "BASE", num / 100, { type = "SkillType", skillType = SkillType.Cooldown })
@@ -5585,7 +5591,6 @@ local specialModList = {
55855591
["nearby allies have (%d+)%% chance to block attack damage per (%d+) strength you have"] = function(block, _, str) return {
55865592
mod("ExtraAura", "LIST", { onlyAllies = true, mod = mod("BlockChance", "BASE", block) }, { type = "PerStat", stat = "Str", div = tonumber(str) }),
55875593
} end,
5588-
["physical damage reduction from armour is based on your combined armour and evasion rating"] = { mod("EvasionAddsToPdr", "FLAG", true) }
55895594
}
55905595
for _, name in pairs(data.keystones) do
55915596
specialModList[name:lower()] = { mod("Keystone", "LIST", name) }

0 commit comments

Comments
 (0)