diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 143fc09c96..0bac7c89e6 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -534,7 +534,7 @@ c["+350 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type= c["+36 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=36}},nil} c["+37% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=37}},nil} c["+39 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=39}},nil} -c["+4 to Ailment Threshold per Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=4}}," Ailment Threshold per "} +c["+4 to Ailment Threshold per Dexterity"]={{[1]={[1]={stat="Dex",type="PerStat"},flags=0,keywordFlags=0,name="AilmentThreshold",type="BASE",value=4}},nil} c["+4 to Level of all Chaos Spell Skills"]={{[1]={flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyOfScaledMod="value",keywordList={[1]="chaos",[2]="spell"},value=4}}},nil} c["+4 to Level of all Elemental Skills"]={{[1]={flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyOfScaledMod="value",keyword="elemental",value=4}}},nil} c["+4 to Level of all Fire Skills"]={{[1]={flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyOfScaledMod="value",keyword="fire",value=4}}},nil} @@ -553,6 +553,7 @@ c["+4% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="Elemen c["+4% to all Elemental Resistances per socketed Grand Spectrum"]={{[1]={[1]={type="Multiplier",var="GrandSpectrum"},flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=4}},nil} c["+4% to maximum Block chance"]={{[1]={flags=0,keywordFlags=0,name="BlockChanceMax",type="BASE",value=4}},nil} c["+40 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=40}},nil} +c["+40 to Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="BASE",value=40}},nil} c["+40 to Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="BASE",value=40}},nil} c["+40 to Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=40}},nil} c["+40 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=40}},nil} @@ -598,8 +599,7 @@ c["+5% to all Maximum Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name c["+5% to maximum Block chance"]={{[1]={flags=0,keywordFlags=0,name="BlockChanceMax",type="BASE",value=5}},nil} c["+5% to maximum Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="ChaosResistMax",type="BASE",value=5}},nil} c["+50 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=50}},nil} -c["+50 to Ailment Threshold"]={{}," Ailment Threshold "} -c["+50 to Ailment Threshold Iron Reflexes"]={{}," Ailment Threshold Iron Reflexes "} +c["+50 to Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="BASE",value=50}},nil} c["+50 to Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="BASE",value=50}},nil} c["+50 to Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=50}},nil} c["+50 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=50}},nil} @@ -1096,7 +1096,7 @@ c["15% increased Duration of Damaging Ailments on Enemies"]={{[1]={flags=0,keywo c["15% increased Duration of Ignite, Shock and Chill on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockDuration",type="INC",value=15},[2]={flags=0,keywordFlags=0,name="EnemyChillDuration",type="INC",value=15},[3]={flags=0,keywordFlags=0,name="EnemyIgniteDuration",type="INC",value=15}},nil} c["15% increased Effect of your Mark Skills"]={{[1]={[1]={skillType=109,type="SkillType"},flags=0,keywordFlags=0,name="LocalEffect",type="INC",value=15}},nil} c["15% increased Electrocute Buildup"]={{}," Electrocute Buildup "} -c["15% increased Elemental Ailment Threshold"]={{}," Elemental Ailment Threshold "} +c["15% increased Elemental Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=15}}," Elemental "} c["15% increased Energy Shield Recharge Rate"]={{[1]={flags=0,keywordFlags=0,name="EnergyShieldRecharge",type="INC",value=15}},nil} c["15% increased Energy Shield Recovery rate"]={{[1]={flags=0,keywordFlags=0,name="EnergyShieldRecoveryRate",type="INC",value=15}},nil} c["15% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=15}},nil} @@ -1518,7 +1518,7 @@ c["25% increased Daze Buildup 25% increased Daze Duration"]={{[1]={flags=0,keywo c["25% increased Daze Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=25}}," Daze "} c["25% increased Defences from Equipped Shield"]={{[1]={[1]={slotName="Weapon 2",type="SlotName"},[2]={type="Condition",var="UsingShield"},flags=0,keywordFlags=0,name="Defences",type="INC",value=25}},nil} c["25% increased Electrocute Buildup"]={{}," Electrocute Buildup "} -c["25% increased Elemental Ailment Threshold"]={{}," Elemental Ailment Threshold "} +c["25% increased Elemental Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=25}}," Elemental "} c["25% increased Energy Shield Recharge Rate"]={{[1]={flags=0,keywordFlags=0,name="EnergyShieldRecharge",type="INC",value=25}},nil} c["25% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=25}},nil} c["25% increased Evasion Rating if you've Dodge Rolled Recently"]={{[1]={[1]={type="Condition",var="DodgeRolledRecently"},flags=0,keywordFlags=0,name="Evasion",type="INC",value=25}},nil} @@ -1702,7 +1702,7 @@ c["30% increased Daze Buildup with Quarterstaves 30% increased Freeze Buildup wi c["30% increased Defences from Equipped Shield"]={{[1]={[1]={slotName="Weapon 2",type="SlotName"},[2]={type="Condition",var="UsingShield"},flags=0,keywordFlags=0,name="Defences",type="INC",value=30}},nil} c["30% increased Defences while wielding a Staff"]={{[1]={[1]={type="Condition",var="UsingStaff"},flags=0,keywordFlags=0,name="Defences",type="INC",value=30}},nil} c["30% increased Electrocute Buildup"]={{}," Electrocute Buildup "} -c["30% increased Elemental Ailment Threshold"]={{}," Elemental Ailment Threshold "} +c["30% increased Elemental Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=30}}," Elemental "} c["30% increased Elemental Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=30}},nil} c["30% increased Elemental Damage if you've Chilled an Enemy Recently"]={{[1]={[1]={type="Condition",var="ChilledEnemyRecently"},flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=30}},nil} c["30% increased Elemental Damage if you've Ignited an Enemy Recently"]={{[1]={[1]={type="Condition",var="IgnitedEnemyRecently"},flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=30}},nil} @@ -1890,8 +1890,8 @@ c["40% increased Damage with Warcries"]={{[1]={flags=0,keywordFlags=4,name="Dama c["40% increased Defences from Equipped Shield"]={{[1]={[1]={slotName="Weapon 2",type="SlotName"},[2]={type="Condition",var="UsingShield"},flags=0,keywordFlags=0,name="Defences",type="INC",value=40}},nil} c["40% increased Electrocute Buildup"]={{}," Electrocute Buildup "} c["40% increased Electrocute Buildup 30% increased Shock Chance against Electrocuted Enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Electrocuted"},flags=0,keywordFlags=0,name="EnemyShockChance",type="INC",value=40}}," Electrocute Buildup 30% increased "} -c["40% increased Elemental Ailment Threshold"]={{}," Elemental Ailment Threshold "} -c["40% increased Elemental Ailment Threshold 10% reduced Duration of Ailments on You"]={{[1]={flags=0,keywordFlags=0,name="SelfAilmentDuration",type="INC",value=40}}," Elemental Ailment Threshold 10% reduced "} +c["40% increased Elemental Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=40}}," Elemental "} +c["40% increased Elemental Ailment Threshold 10% reduced Duration of Ailments on You"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=40}}," Elemental 10% reduced Duration of Ailments on You "} c["40% increased Elemental Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=40}},nil} c["40% increased Elemental Damage if you've dealt a Critical Hit Recently"]={{[1]={[1]={type="Condition",var="CritRecently"},flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=40}},nil} c["40% increased Elemental Damage with Attack Skills during any Flask Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=65536,name="ElementalDamage",type="INC",value=40}},nil} @@ -2506,7 +2506,6 @@ c["Allocates Breath of Lightning"]={{[1]={flags=0,keywordFlags=0,name="GrantedPa c["Allocates Bringer of Order"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="bringer of order"}},nil} c["Allocates Briny Carapace"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="briny carapace"}},nil} c["Allocates Brutal"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="brutal"}},nil} -c["Allocates Brute Strength"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="brute strength"}},nil} c["Allocates Building Toxins"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="building toxins"}},nil} c["Allocates Burn Away"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="burn away"}},nil} c["Allocates Burning Nature"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="burning nature"}},nil} @@ -2645,7 +2644,6 @@ c["Allocates Feel the Earth"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive c["Allocates Feral Force"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="feral force"}},nil} c["Allocates Fervour"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="fervour"}},nil} c["Allocates Final Barrage"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="final barrage"}},nil} -c["Allocates Finality"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="finality"}},nil} c["Allocates Finesse"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="finesse"}},nil} c["Allocates Finishing Blows"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="finishing blows"}},nil} c["Allocates Fireproof"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="fireproof"}},nil} @@ -3011,7 +3009,6 @@ c["Allocates Unbreaking"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",ty c["Allocates Unerring Impact"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unerring impact"}},nil} c["Allocates Unexpected Finesse"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unexpected finesse"}},nil} c["Allocates Unforgiving"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unforgiving"}},nil} -c["Allocates Unhindered"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unhindered"}},nil} c["Allocates Unimpeded"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unimpeded"}},nil} c["Allocates Unnatural Resilience"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unnatural resilience"}},nil} c["Allocates Unsight"]={{[1]={flags=0,keywordFlags=0,name="GrantedPassive",type="LIST",value="unsight"}},nil} @@ -3911,12 +3908,11 @@ c["Thorns damage is triggered by all Hits"]={nil,"Thorns damage is triggered by c["Totems Regenerate 3% of Life per second"]={nil,"Totems Regenerate 3% of Life per second "} c["Totems gain +12% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="TotemElementalResist",type="BASE",value=12}},nil} c["Totems gain +20% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="TotemElementalResist",type="BASE",value=20}},nil} -c["Totems have 12% additional Physical Damage Reduction"]={nil,"Totems have 12% additional Physical Damage Reduction "} -c["Totems have 2% increased Attack Speed per Summoned Totem"]={nil,"Totems have 2% increased Attack Speed per Summoned Totem "} -c["Totems have 2% increased Cast Speed per Summoned Totem"]={nil,"Totems have 2% increased Cast Speed per Summoned Totem "} -c["Totems have 2% increased Cast Speed per Summoned Totem Totems have 2% increased Attack Speed per Summoned Totem"]={nil,"Totems have 2% increased Cast Speed per Summoned Totem Totems have 2% increased Attack Speed per Summoned Totem "} -c["Totems have 20% additional Physical Damage Reduction"]={nil,"Totems have 20% additional Physical Damage Reduction "} -c["Totems have 4% increased Attack Speed per Summoned Totem"]={nil,"Totems have 4% increased Attack Speed per Summoned Totem "} +c["Totems have 12% additional Physical Damage Reduction"]={{[1]={flags=0,keywordFlags=16384,name="PhysicalDamageReduction",type="BASE",value=12}},nil} +c["Totems have 2% increased Attack Speed per Summoned Totem"]={{[1]={[1]={stat="TotemsSummoned",type="PerStat"},flags=1,keywordFlags=16384,name="Speed",type="INC",value=2}},nil} +c["Totems have 2% increased Cast Speed per Summoned Totem"]={{[1]={[1]={stat="TotemsSummoned",type="PerStat"},flags=16,keywordFlags=16384,name="Speed",type="INC",value=2}},nil} +c["Totems have 20% additional Physical Damage Reduction"]={{[1]={flags=0,keywordFlags=16384,name="PhysicalDamageReduction",type="BASE",value=20}},nil} +c["Totems have 4% increased Attack Speed per Summoned Totem"]={{[1]={[1]={stat="TotemsSummoned",type="PerStat"},flags=1,keywordFlags=16384,name="Speed",type="INC",value=4}},nil} c["Totems reserve 100 Spirit each"]={nil,"Totems reserve 100 Spirit each "} c["Trigger Ancestral Spirits when you Summon a Totem"]={nil,"Trigger Ancestral Spirits when you Summon a Totem "} c["Trigger Ancestral Spirits when you Summon a Totem Grants Skill: Ancestral Spirits"]={nil,"Trigger Ancestral Spirits when you Summon a Totem Grants Skill: Ancestral Spirits "} diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 2b0acc4d28..b59f70ca58 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -349,9 +349,9 @@ function calcs.applyDmgTakenConversion(activeSkill, output, breakdown, sourceTyp local effArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense) -- effArmour needs to consider the "EvasionAddsToPdr" flag mod, and add the evasion to armour armourReduct = round(effArmour ~= 0 and damage ~= 0 and calcs.armourReductionF(effArmour, damage) or 0) - armourReduct = m_min(output.DamageReductionMax, armourReduct) + armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct) end - reductMult = (1 - m_max(m_min(output.DamageReductionMax, armourReduct + reduction), 0) / 100) * damageTakenMods + reductMult = (1 - m_max(m_min(output[damageType.."DamageReductionMax"], armourReduct + reduction), 0) / 100) * damageTakenMods local combinedMult = resMult * reductMult local finalDamage = damage * combinedMult totalDamageTaken = totalDamageTaken + finalDamage @@ -384,9 +384,9 @@ function calcs.takenHitFromDamage(rawDamage, damageType, actor) local effectiveAppliedArmour = output[type .."EffectiveAppliedArmour"] local armourDRPercent = calcs.armourReductionF(effectiveAppliedArmour, damage) local flatDRPercent = modDB:Flag(nil, "SelfIgnore".."Base".. type .."DamageReduction") and 0 or output["Base".. type .."DamageReductionWhenHit"] or output["Base".. type .."DamageReduction"] - local totalDRPercent = m_min(output.DamageReductionMax, armourDRPercent + flatDRPercent) + local totalDRPercent = m_min(output[damageType.."DamageReductionMax"], armourDRPercent + flatDRPercent) local enemyOverwhelmPercent = modDB:Flag(nil, "SelfIgnore".. type .."DamageReduction") and 0 or output[type .."EnemyOverwhelm"] - local totalDRMulti = 1 - m_max(m_min(output.DamageReductionMax, totalDRPercent - enemyOverwhelmPercent), 0) / 100 + local totalDRMulti = 1 - m_max(m_min(output[damageType.."DamageReductionMax"], totalDRPercent - enemyOverwhelmPercent), 0) / 100 local totalResistMult = output[type .."ResistTakenHitMulti"] return totalResistMult * totalDRMulti end @@ -1250,6 +1250,7 @@ function calcs.defence(env, actor) output.EvadeChance = output.MeleeEvadeChance output.noSplitEvade = true end + output.EvadeChance = m_min(output.EvadeChance, modDB:Max(nil, "EvadeChanceMax") or 100) if breakdown then breakdown.EvadeChance = { s_format("Enemy level: %d ^8(%s the Configuration tab)", env.enemyLevel, env.configInput.enemyLevel and "overridden from" or "can be overridden in"), @@ -1634,11 +1635,20 @@ function calcs.defence(env, actor) end -- Damage Reduction - output.DamageReductionMax = modDB:Override(nil, "DamageReductionMax") or data.misc.DamageReductionCap + output.DamageReductionMax = modDB:Max(nil, "DamageReductionMax") or data.misc.DamageReductionCap modDB:NewMod("ArmourAppliesToPhysicalDamageTaken", "BASE", 100) for _, damageType in ipairs(dmgTypeList) do - output["Base"..damageType.."DamageReduction"] = m_min(m_max(0, modDB:Sum("BASE", nil, damageType.."DamageReduction", isElemental[damageType] and "ElementalDamageReduction")), output.DamageReductionMax) - output["Base"..damageType.."DamageReductionWhenHit"] = m_min(m_max(0, output["Base"..damageType.."DamageReduction"] + modDB:Sum("BASE", nil, damageType.."DamageReductionWhenHit")), output.DamageReductionMax) + output[damageType.."DamageReductionMax"] = m_min(modDB:Max(nil, damageType.."DamageReductionMax") or data.misc.DamageReductionCap, output.DamageReductionMax) + + local base = m_max(0, modDB:Sum("BASE", nil, damageType.."DamageReduction", isElemental[damageType] and "ElementalDamageReduction")) + local typeMax = m_min(base, output[damageType.."DamageReductionMax"]) + local globalMax = m_min(typeMax, output[damageType.."DamageReductionMax"]) + output["Base"..damageType.."DamageReduction"] = globalMax + + local baseWhenHit = globalMax + modDB:Sum("BASE", nil, damageType.."DamageReductionWhenHit") + local typeMaxWhenHit = m_min(baseWhenHit, output[damageType.."DamageReductionMax"]) + local globalMaxWhenHit = m_min(typeMaxWhenHit, output[damageType.."DamageReductionMax"]) + output["Base"..damageType.."DamageReductionWhenHit"] = globalMaxWhenHit end -- Miscellaneous: move speed, avoidance, weapon swap speed @@ -1712,6 +1722,8 @@ function calcs.defence(env, actor) end end + -- TODO: Calculate elemental ailment threshold by refactoring calcLib.val to allow for multiple mods, similar to calcLib.mod + output.AilmentThreshold = calcLib.val(modDB, "AilmentThreshold") for _, ailment in ipairs(data.nonElementalAilmentTypeList) do output[ailment.."AvoidChance"] = modDB:Flag(nil, ailment.."Immune") and 100 or m_floor(m_min(modDB:Sum("BASE", nil, "Avoid"..ailment, "AvoidAilments"), 100)) end @@ -2120,16 +2132,16 @@ function calcs.buildDefenceEstimations(env, actor) output[damageType.."takenFlat"] = takenFlat if percentOfArmourApplies > 0 then armourReduct = calcs.armourReduction(effectiveAppliedArmour, damage) - armourReduct = m_min(output.DamageReductionMax, armourReduct) + armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct) if impaleDamage > 0 then - impaleArmourReduct = m_min(output.DamageReductionMax, calcs.armourReduction(effectiveAppliedArmour, impaleDamage)) + impaleArmourReduct = m_min(output[damageType.."DamageReductionMax"], calcs.armourReduction(effectiveAppliedArmour, impaleDamage)) end end - local totalReduct = m_min(output.DamageReductionMax, armourReduct + reduction) - reductMult = 1 - m_max(m_min(output.DamageReductionMax, totalReduct - enemyOverwhelm), 0) / 100 + local totalReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct + reduction) + reductMult = 1 - m_max(m_min(output[damageType.."DamageReductionMax"], totalReduct - enemyOverwhelm), 0) / 100 output[damageType.."DamageReduction"] = 100 - reductMult * 100 if impaleDamage > 0 then - impaleDamage = impaleDamage * resMult * (1 - m_max(m_min(output.DamageReductionMax, m_min(output.DamageReductionMax, impaleArmourReduct + reduction) - enemyOverwhelm), 0) / 100) + impaleDamage = impaleDamage * resMult * (1 - m_max(m_min(output[damageType.."DamageReductionMax"], m_min(output[damageType.."DamageReductionMax"], impaleArmourReduct + reduction) - enemyOverwhelm), 0) / 100) impaleDamage = impaleDamage * enemyImpaleChance / 100 * 5 * output[damageType.."TakenReflect"] end if breakdown then @@ -3372,7 +3384,7 @@ function calcs.buildDefenceEstimations(env, actor) -- tack on some caps local noDRMaxHit = totalHitPool / damageConvertedMulti / totalResistMult / totalTakenMulti * (1 - takenFlat * totalTakenMulti / totalHitPool) - local maxDRMaxHit = noDRMaxHit / (1 - (output.DamageReductionMax - enemyOverwhelmPercent) / 100) + local maxDRMaxHit = noDRMaxHit / (1 - (output[damageType.."DamageReductionMax"] - enemyOverwhelmPercent) / 100) hitTaken = m_floor(m_max(m_min(RAW, maxDRMaxHit), noDRMaxHit)) useConversionSmoothing = useConversionSmoothing or convertPercent ~= 100 end diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index 7bd0652b0b..f7e372c04f 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -1578,7 +1578,7 @@ return { { label = "Armour Defense", haveOutput = "RawArmourDefense", { format = "{0:output:RawArmourDefense}%", { modName = "ArmourDefense" }, }, }, { label = "Phys. Dmg. Reduct", { format = "{0:output:PhysicalDamageReduction}%", { breakdown = "PhysicalDamageReduction" }, - { modName = { "PhysicalDamageReduction", "PhysicalDamageReductionWhenHit", "ArmourDoesNotApplyToPhysicalDamageTaken", "DamageReductionMax" } }, + { modName = { "PhysicalDamageReduction", "PhysicalDamageReductionWhenHit", "ArmourDoesNotApplyToPhysicalDamageTaken", "DamageReductionMax", "PhysicalDamageReductionMax" } }, }, }, { label = "Fire Dmg. Reduct", haveOutput = "FireDamageReduction", { format = "{0:output:FireDamageReduction}%", { breakdown = "FireDamageReduction" }, @@ -1801,6 +1801,7 @@ return { { label = "Knockback Immune", haveOutput = "KnockbackImmunity", { format = "True", { modName = "KnockbackImmune" }, }, }, { label = "Blind Duration", haveOutput = "SelfBlindDuration", { format = "{0:output:SelfBlindDuration}%", { modName = "SelfBlindDuration" }, }, }, } }, { defaultCollapsed = true, label = "Other Ailment Defences", data = { + { label = "Ailment Threshold", { format = "{2:output:AilmentThreshold}", { modName = { "AilmentThreshold" }, }, }, }, { label = "Freeze Duration", { format = "{1:output:SelfFreezeDuration}%", { modName = { "SelfFreezeDuration", "SelfDebuffExpirationRate", "SelfFreezeDebuffExpirationRate", "SelfAilmentDuration", "SelfElementalAilmentDuration", "SelfIgniteDurationToElementalAilments" }, }, }, }, { label = "Chill Duration", { format = "{1:output:SelfChillDuration}%", { modName = { "SelfChillDuration", "SelfDebuffExpirationRate", "SelfChillDebuffExpirationRate", "SelfAilmentDuration", "SelfElementalAilmentDuration", "SelfIgniteDurationToElementalAilments" }, }, }, }, { label = "Shock Duration", { format = "{1:output:SelfShockDuration}%", { modName = { "SelfShockDuration", "SelfDebuffExpirationRate", "SelfShockDebuffExpirationRate", "SelfAilmentDuration", "SelfElementalAilmentDuration", "SelfIgniteDurationToElementalAilments" }, }, }, }, diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 13b9e31d9a..c24b48f3bf 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -1677,6 +1677,14 @@ Huge sets the radius to 11. { var = "conditionEnemyCoveredInFrost", type = "check", label = "Is the enemy covered in Frost?", tooltip = "Covered in Frost applies the following to the enemy:\n\t20% increased ^x3F6DB3Cold ^7Damage taken\n\t50% less Critical Strike Chance", apply = function(val, modList, enemyModList) modList:NewMod("CoveredInFrostEffect", "BASE", 20, "Covered in Frost") end }, + { var = "conditionEnemyHasOpenWeakness", type = "check", label = "Does enemy have Open Weakness?", ifCond = "EnemyHasOpenWeakness", apply = function(val, modList, enemyModList) + -- This one means the enemy you're targeting has open weakness + modList:NewMod("Condition:EnemyHasOpenWeakness", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) + end }, + { var = "conditionOpenWeaknessEnemyPresence", type = "check", label = "Enemy Open Weakness Presence?", ifCond = "OpenWeaknessEnemyPresence", apply = function(val, modList, enemyModList) + -- This one means there's an enemy that has open weakness "nearby" + modList:NewMod("Condition:OpenWeaknessEnemyPresence", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) + end }, { var = "conditionEnemyOnConsecratedGround", type = "check", label = "Is the enemy on Consecrated Ground?", ifEnemyCond = "OnConsecratedGround", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:OnConsecratedGround", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) end }, diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 8d93855722..9f5e30bc69 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -381,6 +381,7 @@ local modNameList = { ["elemental damage taken recouped as energy shield"] = { "LightningEnergyShieldRecoup", "ColdEnergyShieldRecoup", "FireEnergyShieldRecoup" }, ["damage taken recouped as mana"] = "ManaRecoup", ["damage taken recouped as life, mana and energy shield"] = { "LifeRecoup", "EnergyShieldRecoup", "ManaRecoup" }, + ["ailment threshold"] = "AilmentThreshold", -- Stun/knockback modifiers ["stun recovery"] = "StunRecovery", ["stun and block recovery"] = "StunRecovery", @@ -1170,6 +1171,7 @@ local preFlagList = { ["^non%-vaal skills deal "] = { tag = { type = "SkillType", skillType = SkillType.Vaal, neg = true } }, ["^skills [hgdf][aei][vari][eln] "] = { }, ["^triggered spells [hd][ae][va][el] "] = { keywordFlags = KeywordFlag.Spell, tag = { type = "SkillType", skillType = SkillType.Triggered } }, + ["^totems have "] = { keywordFlags = KeywordFlag.Totem }, ["^persistent buffs have "] = { tagList = { { type = "SkillType", skillType = SkillType.Persistent }, { type = "SkillType", skillType = SkillType.Buff } } }, -- Slot specific ["^left ring slot: "] = { tag = { type = "SlotNumber", num = 1 } }, @@ -1386,6 +1388,8 @@ local modTagList = { -- Per stat ["per (%d+)%% of maximum mana they reserve"] = function(num) return { tag = { type = "PerStat", stat = "ManaReservedPercent", div = num } } end, ["per strength"] = { tag = { type = "PerStat", stat = "Str"} }, + ["per dexterity"] = { tag = { type = "PerStat", stat = "Dex"} }, + ["per intelligence"] = { tag = { type = "PerStat", stat = "Int"} }, ["per (%d+) strength"] = function(num) return { tag = { type = "PerStat", stat = "Str", div = num } } end, ["per (%d+) dexterity"] = function(num) return { tag = { type = "PerStat", stat = "Dex", div = num } } end, ["per (%d+) intelligence"] = function(num) return { tag = { type = "PerStat", stat = "Int", div = num } } end, @@ -1479,6 +1483,8 @@ local modTagList = { ["while affected by a rare abyss jewel"] = { tag = { type = "MultiplierThreshold", var = "RareAbyssJewels", threshold = 1 } }, ["while affected by a magic abyss jewel"] = { tag = { type = "MultiplierThreshold", var = "MagicAbyssJewels", threshold = 1 } }, ["while affected by a normal abyss jewel"] = { tag = { type = "MultiplierThreshold", var = "NormalAbyssJewels", threshold = 1 } }, + ["while an enemy with an open weakness is in your presence"] = { tag = { type = "Condition", var = "OpenWeaknessEnemyPresence" } }, -- This one means there's an enemy that has open weakness "nearby" + ["against enemies with an open weakness"] = { tag = { type = "Condition", var = "EnemyHasOpenWeakness" } }, -- This one means the enemy you're targeting has open weakness -- Slot conditions ["when in main hand"] = { tag = { type = "SlotNumber", num = 1 } }, ["when in off hand"] = { tag = { type = "SlotNumber", num = 2 } }, @@ -1564,6 +1570,7 @@ local modTagList = { ["wh[ie][ln]e? you have energy shield"] = { tag = { type = "Condition", var = "HaveEnergyShield" } }, ["wh[ie][ln]e? you have no energy shield"] = { tag = { type = "Condition", var = "HaveEnergyShield", neg = true } }, ["if you have energy shield"] = { tag = { type = "Condition", var = "HaveEnergyShield" } }, + ["if you have no energy shield"] = { tag = { type = "Condition", var = "HaveEnergyShield", neg = true } }, ["while stationary"] = { tag = { type = "Condition", var = "Stationary" } }, ["while you are stationary"] = { tag = { type = "ActorCondition", actor = "player", var = "Stationary" }}, ["while moving"] = { tag = { type = "Condition", var = "Moving" } }, @@ -2271,7 +2278,8 @@ local specialModList = { } end, ["armour also applies to (%a+) damage taken from hits"] = function(dmgType) return { mod("ArmourAppliesTo"..firstToUpper(dmgType).."DamageTaken", "BASE", 100) } end, ["(%d+)%% of armour also applies to (%a+) damage taken from hits"] = function(num, _, dmgType) return { mod("ArmourAppliesTo"..firstToUpper(dmgType).."DamageTaken", "BASE", num) } end, - ["maximum damage reduction for any damage type is (%d+)%%"] = function(num) return { mod("DamageReductionMax", "OVERRIDE", num) } end, + ["maximum damage reduction for any damage type is (%d+)%%"] = function(num) return { mod("DamageReductionMax", "MAX", num) } end, + ["maximum (%a+) damage reduction is (%d+)%%"] = function(_, dmgType, numStr) return { mod(firstToUpper(dmgType) .. "DamageReductionMax", "MAX", tonumber(numStr)) } end, ["gain additional elemental damage reduction equal to half your chaos resistance"] = { mod("ElementalDamageReduction", "BASE", 1, { type = "PerStat", stat = "ChaosResist", div = 2 }) }, @@ -2329,6 +2337,9 @@ local specialModList = { mod("ArmourDefense", "MAX", math.min(numChance / 100, 1.0) * (tonumber(numArmourMultiplier) - 100), "Armour Mastery: Average Calc", { type = "Condition", var = "ArmourAvg" }), mod("ArmourDefense", "MAX", math.min(math.floor(numChance / 100), 1.0) * (tonumber(numArmourMultiplier) - 100), "Armour Mastery: Min Calc", { type = "Condition", var = "ArmourMax", neg = true }, { type = "Condition", var = "ArmourAvg", neg = true }), } end, + ["defend with (%d+)%% of armour"] = function(num) return { + mod("ArmourDefense", "MAX", num - 100), + } end, ["defend with (%d+)%% of armour while not on low energy shield"] = function(num) return { mod("ArmourDefense", "MAX", num - 100, "Armour and Energy Shield Mastery", { type = "Condition", var = "LowEnergyShield", neg = true }), } end, @@ -3125,11 +3136,11 @@ local specialModList = { ["increases and reductions to cast speed also apply to trap throwing speed"] = { flag("CastSpeedAppliesToTrapThrowingSpeed") }, ["increases and reductions to armour also apply to energy shield recharge rate at (%d+)%% of their value"] = function(num) return { flag("ArmourAppliesToEnergyShieldRecharge"), mod("ImprovedArmourAppliesToEnergyShieldRecharge", "MAX", num) } end, ["increases and reductions to projectile speed also apply to damage with bows"] = { flag("ProjectileSpeedAppliesToBowDamage") }, - ["modifiers to maximum (%a+) resistance also apply to maximum (%a+) and (%a+) resistances"] = function(_, resFrom, resTo1, resTo2) return { + ["modifiers to maximum (%a+) resistance also [ga][rp][ap][nl][ty] ?t?o? maximum (%a+) and (%a+) resistances?"] = function(_, resFrom, resTo1, resTo2) return { mod((resFrom:gsub("^%l", string.upper)).."MaxResConvertTo"..(resTo1:gsub("^%l", string.upper)), "BASE", 100), mod((resFrom:gsub("^%l", string.upper)).."MaxResConvertTo"..(resTo2:gsub("^%l", string.upper)), "BASE", 100), } end, - ["modifiers to (%a+) resistance also apply to (%a+) and (%a+) resistances at (%d+)%% of their value"] = function(_, resFrom, resTo1, resTo2, rate) return { + ["modifiers to (%a+) resistance also [ga][rp][ap][nl][ty] ?t?o? (%a+) and (%a+) resistances? at (%d+)%% of their value"] = function(_, resFrom, resTo1, resTo2, rate) return { mod((resFrom:gsub("^%l", string.upper)).."ResConvertTo"..(resTo1:gsub("^%l", string.upper)), "BASE", tonumber(rate)), mod((resFrom:gsub("^%l", string.upper)).."ResConvertTo"..(resTo2:gsub("^%l", string.upper)), "BASE", tonumber(rate)), } end, @@ -4301,6 +4312,7 @@ local specialModList = { ["cannot evade enemy attacks"] = { flag("CannotEvade") }, ["attacks cannot hit you"] = { flag("AlwaysEvade") }, ["attacks against you always hit"] = { flag("CannotEvade") }, + ["maximum evade chance is (%d+)%%"] = function(num) return { mod("EvadeChanceMax", "MAX", num) } end, ["modifiers to maximum block chance instead apply to maximum resistances"] = { flag("MaxBlockChanceModsApplyMaxResist") }, ["you cannot block"] = { flag("CannotBlockAttacks")}, ["cannot block"] = { flag("CannotBlockAttacks"), flag("CannotBlockSpells") }, @@ -4506,6 +4518,9 @@ local specialModList = { ["gain stun threshold equal to the lowest of evasion and armour on your helmet"] = { mod("StunThreshold", "BASE", 1, { type = "PerStat", stat = "LowestOfArmourAndEvasionOnHelmet" }), }, + ["gain (%d+)%% of (%a+) ?r?a?t?i?n?g? as extra (%a+) threshold"] = function(num, _, stat, thresholdType) return { + mod(firstToUpper(thresholdType) .. "Threshold", "BASE", 1, { type = "PercentStat", stat = stat:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", ""), percent = num }) + } end, ["your stun threshold is doubled"] = { mod("StunThreshold", "MORE", 100), },