diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index bab988d5c..5fbbee35f 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -926,8 +926,7 @@ c["1% increased Evasion Rating per 2 Intelligence"]={{[1]={[1]={div=2,stat="Int" c["1% increased Life and Mana Recovery from Flasks per 10 Tribute"]={{[1]={[1]={actor="parent",div=10,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="FlaskLifeRecovery",type="INC",value=1},[2]={[1]={actor="parent",div=10,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="FlaskManaRecovery",type="INC",value=1}},nil} c["1% increased Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} c["1% increased Movement Speed for each time you've Blocked in the past 10 seconds"]={{[1]={[1]={type="Multiplier",var="BlockedPast10Sec"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} -c["1% increased Spirit Reservation Efficiency of Buff Skills per 100 Maximum Life"]={{[1]={[1]={div=100,stat="Life",type="PerStat"},flags=0,keywordFlags=0,name="Spirit",type="INC",value=1}}," Reservation Efficiency of Buff Skills "} -c["1% increased Spirit Reservation Efficiency of Buff Skills per 100 Maximum Life +1 to Maximum Spirit per 50 Maximum Life"]={{[1]={[1]={div=100,stat="Life",type="PerStat"},[2]={div=50,stat="Life",type="PerStat"},flags=0,keywordFlags=0,name="Spirit",type="INC",value=1}}," Reservation Efficiency of Buff Skills +1 to Maximum Spirit "} +c["1% increased Spirit Reservation Efficiency of Buff Skills per 100 Maximum Life"]={{[1]={[1]={skillType=5,type="SkillType"},[2]={div=100,stat="Life",type="PerStat"},flags=0,keywordFlags=0,name="SpiritReservationEfficiency",type="INC",value=1}},nil} c["1% increased Spirit Reservation Efficiency of Skills per 20 Tribute"]={{[1]={[1]={actor="parent",div=20,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="SpiritReservationEfficiency",type="INC",value=1}},nil} c["1% increased damage taken per 10 Tribute"]={{[1]={[1]={actor="parent",div=10,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=1}},nil} c["1% increased maximum Darkness per 1% Chaos Resistance"]={{[1]={[1]={div=1,stat="ChaosResist",type="PerStat"},flags=0,keywordFlags=0,name="Darkness",type="INC",value=1}},nil} @@ -1206,7 +1205,7 @@ c["100% increased Chance to be afflicted by Ailments when Hit"]={{}," Chance to c["100% increased Chance to be afflicted by Ailments when Hit 20% increased Movement Speed while affected by an Ailment"]={{[1]={[1]={type="Condition",varList={[1]="Bleeding",[2]="Poisoned",[3]="Ignited",[4]="Chilled",[5]="Frozen",[6]="Shocked",[7]="Electrocuted"}},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=100}}," Chance to be afflicted by Ailments when Hit 20% increased "} c["100% increased Critical Damage Bonus against Enemies that are on Full Life"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="FullLife"},flags=0,keywordFlags=0,name="CritMultiplier",type="INC",value=100}},nil} c["100% increased Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=100}},nil} -c["100% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} +c["100% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullPercent",type="INC",value=100}},nil} c["100% 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=100}},nil} c["100% increased Effect of Jewel Socket Passive Skills"]={{[1]={flags=0,keywordFlags=0,name="LocalEffect",type="INC",value=100}}," of Jewel Socket Passive Skills "} c["100% increased Effect of Jewel Socket Passive Skills containing Corrupted Magic Jewels"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="corruptedMagicJewelIncEffect",value=100}}},nil} @@ -1816,8 +1815,7 @@ c["20% increased Critical Hit Chance against Marked Enemies"]={{[1]={[1]={actor= c["20% increased Critical Hit Chance for Attacks"]={{[1]={flags=1,keywordFlags=0,name="CritChance",type="INC",value=20}},nil} c["20% increased Critical Hit Chance for Spells"]={{[1]={flags=2,keywordFlags=0,name="CritChance",type="INC",value=20}},nil} c["20% increased Critical Hit Chance while Shapeshifted"]={{[1]={[1]={type="Condition",var="Shapeshifted"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=20}},nil} -c["20% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} -c["20% increased Culling Strike Threshold Culling Strike against Beasts while your Companion is in your Presence"]={{}," Culling Strike Threshold Culling Strike against Beasts "} +c["20% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullPercent",type="INC",value=20}},nil} c["20% increased Curse Duration"]={{[1]={flags=0,keywordFlags=2,name="Duration",type="INC",value=20}},nil} c["20% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=20}},nil} c["20% increased Damage against Enemies with Fully Broken Armour"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="ArmourFullyBroken"},flags=0,keywordFlags=0,name="Damage",type="INC",value=20}},nil} @@ -2110,8 +2108,7 @@ c["25% increased Critical Hit Chance for Attacks"]={{[1]={flags=1,keywordFlags=0 c["25% increased Critical Hit Chance for Spells"]={{[1]={flags=2,keywordFlags=0,name="CritChance",type="INC",value=25}},nil} c["25% increased Critical Hit Chance if you've Triggered a Skill Recently"]={{[1]={[1]={type="Condition",var="TriggeredSkillRecently"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=25}},nil} c["25% increased Critical Hit Chance with Traps"]={{[1]={flags=0,keywordFlags=4096,name="CritChance",type="INC",value=25}},nil} -c["25% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} -c["25% increased Culling Strike Threshold Gain 13% of Damage as Extra Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=25}}," Culling Strike Threshold Gain 13% of as Extra Chaos Damage "} +c["25% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullPercent",type="INC",value=25}},nil} c["25% increased Damage during any Flask Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="Damage",type="INC",value=25}},nil} c["25% increased Damage if you've dealt a Critical Hit in the past 8 seconds"]={{[1]={[1]={type="Condition",var="CritInPast8Sec"},flags=0,keywordFlags=0,name="Damage",type="INC",value=25}},nil} c["25% increased Damage while you have a Totem"]={{[1]={[1]={type="Condition",var="HaveTotem"},flags=0,keywordFlags=0,name="Damage",type="INC",value=25}},nil} @@ -2795,7 +2792,7 @@ c["5% increased Cast Speed"]={{[1]={flags=16,keywordFlags=0,name="Speed",type="I c["5% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ChaosDamage",type="INC",value=5}},nil} c["5% increased Cooldown Recovery Rate"]={{[1]={flags=0,keywordFlags=0,name="CooldownRecovery",type="INC",value=5}},nil} c["5% increased Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=5}},nil} -c["5% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} +c["5% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullPercent",type="INC",value=5}},nil} c["5% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=5}},nil} c["5% increased Damage taken while on Low Life"]={{[1]={[1]={type="Condition",var="LowLife"},flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=5}},nil} c["5% increased Defences from Equipped Shield per 25 Tribute"]={{[1]={[1]={slotName="Weapon 2",type="SlotName"},[2]={type="Condition",var="UsingShield"},[3]={actor="parent",div=25,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="Defences",type="INC",value=5}},nil} @@ -4515,8 +4512,7 @@ c["Can have 3 additional Instilled Modifiers"]={nil,"Can have 3 additional Insti c["Can instead consume 25% of maximum Mana to trigger Charms with insufficient charges"]={nil,"Can instead consume 25% of maximum Mana to trigger Charms with insufficient charges "} c["Can only use a Normal Body Armour"]={nil,"Can only use a Normal Body Armour "} c["Can only use a Normal Body Armour +200 to Armour for each Connected Notable Passive Skill Allocated"]={nil,"Can only use a Normal Body Armour +200 to Armour for each Connected Notable Passive Skill Allocated "} -c["Can't use Body Armour"]={nil,"Can't use Body Armour "} -c["Can't use Body Armour You can wield Two-Handed Axes, Maces and Swords in one hand"]={nil,"Can't use Body Armour You can wield Two-Handed Axes, Maces and Swords in one hand "} +c["Can't use Body Armour"]={{[1]={[1]={slotName="Body Armour",type="DisablesItem"},flags=0,keywordFlags=0,name="CanNotUseBody",type="Flag",value=1}},nil} c["Can't use Helmets"]={nil,"Can't use Helmets "} c["Can't use Helmets Your Critical Hit Chance is Lucky"]={nil,"Can't use Helmets Your Critical Hit Chance is Lucky "} c["Can't use Helmets Your Critical Hit Chance is Lucky Your Damage with Critical Hits is Lucky"]={nil,"Can't use Helmets Your Critical Hit Chance is Lucky Your Damage with Critical Hits is Lucky "} @@ -4754,8 +4750,7 @@ c["Effect is not removed when Unreserved Life is Filled"]={nil,"Effect is not re c["Effect is not removed when Unreserved Life is Filled 30% of Damage taken during effect Recouped as Life"]={nil,"Effect is not removed when Unreserved Life is Filled 30% of Damage taken during effect Recouped as Life "} c["Effect is not removed when Unreserved Mana is Filled"]={{[1]={flags=0,keywordFlags=0,name="ManaFlaskEffectNotRemoved",type="FLAG",value=true}},nil} c["Eldritch Battery"]={{[1]={flags=0,keywordFlags=0,name="Keystone",type="LIST",value="Eldritch Battery"}},nil} -c["Elemental Ailment Threshold is increased by Uncapped Chaos Resistance"]={nil,"Elemental Ailment Threshold is increased by Uncapped Chaos Resistance "} -c["Elemental Ailment Threshold is increased by Uncapped Chaos Resistance Armour is increased by Uncapped Fire Resistance"]={nil,"Elemental Ailment Threshold is increased by Uncapped Chaos Resistance Armour is increased by Uncapped Fire Resistance "} +c["Elemental Ailment Threshold is increased by Uncapped Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="AilmentThresholdIncreasedByUncappedChaosRes",type="FLAG",value=true}},nil} c["Elemental Archon does not expire while on High Infernal Flame"]={nil,"Elemental Archon does not expire while on High Infernal Flame "} c["Elemental Archon does not expire while on High Infernal Flame Lose Elemental Archon on reaching maximum Infernal Flame"]={nil,"Elemental Archon does not expire while on High Infernal Flame Lose Elemental Archon on reaching maximum Infernal Flame "} c["Elemental Damage also Contributes to Bleeding Magnitude"]={{[1]={flags=0,keywordFlags=0,name="FireCanBleed",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ColdCanBleed",type="FLAG",value=true},[3]={flags=0,keywordFlags=0,name="LightningCanBleed",type="FLAG",value=true}},nil} @@ -4772,8 +4767,7 @@ c["Empowered Attacks have 50% increased Stun Buildup"]={{[1]={[1]={type="Conditi c["Enemies Blinded by you have 15% reduced Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Blinded"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=-15}}}},nil} c["Enemies Blinded by you have 50% reduced Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Blinded"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=-50}}}},nil} c["Enemies Chilled by your Hits can be Shattered as though Frozen"]={nil,"your Hits can be Shattered as though Frozen "} -c["Enemies Chilled by your Hits increase damage taken by Chill Magnitude"]={nil,"your Hits increase damage taken by Chill Magnitude "} -c["Enemies Chilled by your Hits increase damage taken by Chill Magnitude Attacks Gain 10% of Damage as Extra Cold Damage"]={nil,"your Hits increase damage taken by Chill Magnitude Attacks Gain 10% of Damage as Extra Cold Damage "} +c["Enemies Chilled by your Hits increase damage taken by Chill Magnitude"]={{[1]={flags=0,keywordFlags=0,name="ChillEffectIncDamageTaken",type="FLAG",value=true}},nil} c["Enemies Frozen by you have -8% to Cold Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Frozen"},flags=0,keywordFlags=0,name="ColdResist",type="BASE",value=-8}}}},nil} c["Enemies Frozen by you take 100% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Frozen"},flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=100}}}},nil} c["Enemies Frozen by you take 20% increased Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Frozen"},flags=0,keywordFlags=0,name="ColdDamageTaken",type="INC",value=20}}}},nil} @@ -4846,8 +4840,7 @@ c["Energy Shield Recharge is not interrupted by Damage if Recharge began Recentl c["Energy Shield Recharge starts on use"]={nil,"Energy Shield Recharge starts on use "} c["Energy Shield Recharge starts when you use a Mana Flask"]={nil,"Energy Shield Recharge starts when you use a Mana Flask "} c["Energy Shield does not Recharge"]={{[1]={flags=0,keywordFlags=0,name="NoEnergyShieldRecharge",type="FLAG",value=true}},nil} -c["Energy Shield is increased by Uncapped Cold Resistance"]={nil,"Energy Shield is increased by Uncapped Cold Resistance "} -c["Energy Shield is increased by Uncapped Cold Resistance Evasion Rating is increased by Uncapped Lightning Resistance"]={nil,"Energy Shield is increased by Uncapped Cold Resistance Evasion Rating is increased by Uncapped Lightning Resistance "} +c["Energy Shield is increased by Uncapped Cold Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnergyShieldIncreasedByUncappedColdRes",type="FLAG",value=true}},nil} c["Energy Shield starts at zero"]={nil,"Energy Shield starts at zero "} c["Energy Shield starts at zero Cannot Recharge or Regenerate Energy Shield"]={nil,"Energy Shield starts at zero Cannot Recharge or Regenerate Energy Shield "} c["Energy Shield starts at zero Cannot Recharge or Regenerate Energy Shield Lose 5% of Energy Shield per second"]={nil,"Energy Shield starts at zero Cannot Recharge or Regenerate Energy Shield Lose 5% of Energy Shield per second "} @@ -4861,7 +4854,7 @@ c["Equipment has no Attribute Requirements Skill Gems have no Attribute Requirem c["Evasion Rating from Equipped Body Armour is halved"]={{[1]={[1]={slotName="Body Armour",type="SlotName"},flags=0,keywordFlags=0,name="Evasion",type="MORE",value=-50}},nil} c["Evasion Rating from Equipped Helmet, Gloves and Boots is doubled"]={{[1]={[1]={slotNameList={[1]="Helmet",[2]="Boots",[3]="Gloves"},type="SlotName"},flags=0,keywordFlags=0,name="Evasion",type="MORE",value=100}},nil} c["Evasion Rating is doubled if you have not been Hit Recently"]={{[1]={[1]={neg=true,type="Condition",var="BeenHitRecently"},[2]={globalLimit=100,globalLimitKey="EvasionDoubledLimit",type="Multiplier",var="EvasionDoubled"},flags=0,keywordFlags=0,name="Evasion",type="MORE",value=100},[2]={[1]={neg=true,type="Condition",var="BeenHitRecently"},flags=0,keywordFlags=0,name="Multiplier:EvasionDoubled",type="OVERRIDE",value=1}},nil} -c["Evasion Rating is increased by Uncapped Lightning Resistance"]={nil,"Evasion Rating is increased by Uncapped Lightning Resistance "} +c["Evasion Rating is increased by Uncapped Lightning Resistance"]={{[1]={flags=0,keywordFlags=0,name="EvasionRatingIncreasedByUncappedLightningRes",type="FLAG",value=true}},nil} c["Everlasting Sacrifice"]={{[1]={flags=0,keywordFlags=0,name="Condition:EverlastingSacrifice",type="FLAG",value=true}},nil} c["Every 10 Rage also grants 12% increased Physical Damage"]={{[1]={[1]={div=10,type="Multiplier",var="RageEffect"},flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=12}},nil} c["Every 10 seconds, gain a random non-damaging Shrine buff for 20 seconds"]={nil,"Every 10 seconds, gain a random non-damaging Shrine buff for 20 seconds "} @@ -4899,7 +4892,7 @@ c["Fire Resistance is unaffected by Area Penalties"]={nil,"Fire Resistance is un c["Fire Resistance is unaffected by Area Penalties Lightning Resistance is unaffected by Area Penalties"]={nil,"Fire Resistance is unaffected by Area Penalties Lightning Resistance is unaffected by Area Penalties "} c["Fire Spells Convert 100% of Fire Damage to Chaos Damage"]={{[1]={[1]={skillType=2,type="SkillType"},[2]={skillType=28,type="SkillType"},flags=0,keywordFlags=0,name="FireDamageConvertToChaos",type="BASE",value="100"}},nil} c["Fissure Skills have +1 to Limit"]={nil,"Fissure Skills have +1 to Limit "} -c["Flammability Magnitude is doubled"]={{},"Magnitude "} +c["Flammability Magnitude is doubled"]={{[1]={[1]={globalLimit=100,globalLimitKey="EnemyIgniteChanceDoubledLimit",type="Multiplier",var="EnemyIgniteChanceDoubled"},flags=0,keywordFlags=0,name="EnemyIgniteChance",type="MORE",value=100},[2]={flags=0,keywordFlags=0,name="Multiplier:EnemyIgniteChanceDoubled",type="OVERRIDE",value=1}},nil} c["Flasks gain 0.17 charges per Second"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargesGenerated",type="BASE",value=0.17}},nil} c["For each colour of Socketed Support Gem that is most numerous, gain:"]={{},nil} c["Fork an additional time"]={nil,"Fork an additional time "} @@ -5380,9 +5373,9 @@ c["Inflict Cold Exposure on Igniting an Enemy"]={nil,"Inflict Cold Exposure on I c["Inflict Cold Exposure on Igniting an Enemy Inflict Fire Exposure on Shocking an Enemy"]={nil,"Inflict Cold Exposure on Igniting an Enemy Inflict Fire Exposure on Shocking an Enemy "} c["Inflict Corrupted Blood for 5 seconds on Block, dealing 50% of"]={nil,"Inflict Corrupted Blood for 5 seconds on Block, dealing 50% of "} c["Inflict Corrupted Blood for 5 seconds on Block, dealing 50% of your maximum Life as Physical damage per second"]={nil,"Inflict Corrupted Blood for 5 seconds on Block, dealing 50% of your maximum Life as Physical damage per second "} -c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 30%"]={nil,"Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 30% "} -c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 30% Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60%"]={nil,"Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 30% Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60% "} -c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60%"]={nil,"Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60% "} +c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 30%"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FireExposure",type="BASE",value=-30}}},[2]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdExposure",type="BASE",value=-30}}},[3]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="LightningExposure",type="BASE",value=-30}}}},nil} +c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 55%"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FireExposure",type="BASE",value=-55}}},[2]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdExposure",type="BASE",value=-55}}},[3]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="LightningExposure",type="BASE",value=-55}}}},nil} +c["Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60%"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FireExposure",type="BASE",value=-60}}},[2]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdExposure",type="BASE",value=-60}}},[3]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="LightningExposure",type="BASE",value=-60}}}},nil} c["Inflict Elemental Exposure to Enemies 3 metres in front of you"]={nil,"Inflict Elemental Exposure to Enemies 3 metres in front of you "} c["Inflict Elemental Exposure to Enemies 3 metres in front of you for 4 seconds, every 0.25 seconds while raised"]={nil,"Inflict Elemental Exposure to Enemies 3 metres in front of you for 4 seconds, every 0.25 seconds while raised "} c["Inflict Fire Exposure on Shocking an Enemy"]={nil,"Inflict Fire Exposure on Shocking an Enemy "} @@ -5654,7 +5647,7 @@ c["No Inherent loss of Rage Regenerate 6% of your maximum Rage per second Increa c["No Inherent loss of Rage Regenerate 6% of your maximum Rage per second Increases and Reductions to Mana Regeneration Rate also apply to Rage Regeneration Rate Skills have +5 to Rage cost +7 to Maximum Rage"]={{[1]={flags=0,keywordFlags=0,name="RageCost",type="BASE",value=7}},"No Inherent loss of Regenerate 6% of your per second Increases and Reductions to Mana Regeneration Rate also apply to Rage Regeneration Rate Skills have +5 to Rage to Maximum Rage "} c["No Inherent loss of Rage during effect"]={nil,"No Inherent loss of Rage during effect "} c["No Inherent loss of Rage during effect 50% increased Duration"]={nil,"No Inherent loss of Rage during effect 50% increased Duration "} -c["No Movement Speed Penalty while Shield is Raised"]={nil,"No Movement Speed Penalty while Shield is Raised "} +c["No Movement Speed Penalty while Shield is Raised"]={{[1]={[1]={skillName="Raise Shield",type="SkillName"},flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="MORE",value=-100}},nil} c["No Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="WeaponData",type="LIST",value={key="PhysicalMin"}},[2]={flags=0,keywordFlags=0,name="WeaponData",type="LIST",value={key="PhysicalMax"}},[3]={flags=0,keywordFlags=0,name="WeaponData",type="LIST",value={key="PhysicalDPS"}}},nil} c["No Rage effect"]={{[1]={flags=0,keywordFlags=0,name="RageEffect",type="OVERRIDE",value=0}},nil} c["No inherent Mana Regeneration"]={{[1]={flags=0,keywordFlags=0,name="Condition:NoInherentManaRegen",type="FLAG",value=true}},nil} @@ -5954,11 +5947,11 @@ c["Skills gain a Base Life Cost equal to 10% of Base Mana Cost"]={{[1]={flags=0, c["Skills gain a Base Life Cost equal to 100% of Base Mana Cost"]={{[1]={flags=0,keywordFlags=0,name="BaseManaCostAsLifeCost",type="BASE",value=100}},nil} c["Skills gain a Base Life Cost equal to 50% of Base Mana Cost"]={{[1]={flags=0,keywordFlags=0,name="BaseManaCostAsLifeCost",type="BASE",value=50}},nil} c["Skills gain a Base Life Cost equal to Base Mana Cost"]={{[1]={flags=0,keywordFlags=0,name="BaseManaCostAsLifeCost",type="BASE",value=100}},nil} -c["Skills have +1 to Limit"]={{}," Limit "} +c["Skills have +1 to Limit"]={{[1]={flags=0,keywordFlags=0,name="AdditionalCooldownUses",type="BASE",value=1}},nil} c["Skills have +5 to Rage cost"]={{[1]={flags=0,keywordFlags=0,name="RageCostBase",type="BASE",value=5},[2]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} -c["Skills have -1 seconds to Cooldown"]={{}," seconds to Cooldown "} -c["Skills have -2 seconds to Cooldown"]={{}," seconds to Cooldown "} -c["Skills have -2 seconds to Cooldown Skills have -1 seconds to Cooldown"]={{}," seconds to Cooldown Skills have -1 seconds to Cooldown "} +c["Skills have -1 seconds to Cooldown"]={{[1]={flags=0,keywordFlags=0,name="CooldownRecovery",type="BASE",value=-1}},nil} +c["Skills have -1.5 seconds to Cooldown"]={{[1]={flags=0,keywordFlags=0,name="CooldownRecovery",type="BASE",value=-1.5}},nil} +c["Skills have -2 seconds to Cooldown"]={{[1]={flags=0,keywordFlags=0,name="CooldownRecovery",type="BASE",value=-2}},nil} c["Skills have 10% chance to not remove Charges but still count as consuming them"]={{[1]={flags=0,keywordFlags=0,name="FlaskCharges",type="BASE",value=10}}," to not remove but still count as consuming them "} c["Skills have 10% chance to not remove Elemental Infusions but still count as consuming them"]={{}," to not remove Elemental Infusions but still count as consuming them "} c["Skills have 20% increased Critical Hit Chance per Connected Blue Support Gem"]={{[1]={flags=0,keywordFlags=0,name="SkillCritChanceIncreasedPerBlueSupport",type="FLAG",value=20}},nil} diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 47c2f0b53..7abadc8d9 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -388,7 +388,7 @@ function calcs.applyDmgTakenConversion(activeSkill, output, breakdown, sourceTyp local effArmourFromEvasion = (output.Evasion * percentOfEvasionApplies / 100) local effArmourFromEnergyShield = (output.EnergyShield * percentOfEnergyShieldApplies / 100) local effArmour = effArmourFromArmour + effArmourFromEvasion + effArmourFromEnergyShield - + armourReduct = round(effArmour ~= 0 and damage ~= 0 and calcs.armourReductionF(effArmour, damage) or 0) armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct) end @@ -461,7 +461,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) local output = actor.output local modDB = actor.modDB local poolTbl = poolTable or { } - + local alliesTakenBeforeYou = poolTbl.AlliesTakenBeforeYou if not alliesTakenBeforeYou then alliesTakenBeforeYou = {} @@ -484,7 +484,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) alliesTakenBeforeYou["soulLink"] = { remaining = output.AlliedEnergyShield, percent = output.SoulLinkMitigation / 100 } end end - + local damageTakenThatCanBeRecouped = poolTbl.damageTakenThatCanBeRecouped or { } local aegis = poolTbl.Aegis if not aegis then @@ -503,10 +503,10 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) guard[damageType] = output[damageType.."GuardAbsorb"] or 0 end end - + local ward = poolTbl.Ward or output.Ward or 0 local restoreWard = modDB:Flag(nil, "WardNotBreak") and ward or 0 - + local energyShield = poolTbl.EnergyShield or output.EnergyShieldRecoveryCap local mana = poolTbl.Mana or output.ManaUnreserved or 0 local life = poolTbl.Life or output.LifeRecoverable or 0 @@ -517,7 +517,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) local resourcesLostToTypeDamage = { Physical = { }, Lightning = { }, Cold = { }, Fire = { }, Chaos = { } } local MoMPoolRemaining = m_huge local esPoolRemaining = m_huge - + local damageRemaindersBeforeES = {} for _, damageType in ipairs(dmgTypeList) do local damageRemainder = damageTable[damageType] @@ -573,7 +573,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) damageRemaindersBeforeES[damageType] = damageRemainder > 0 and damageRemainder or nil end end - + for i=#dmgTypeList, 1, -1 do local damageType = dmgTypeList[i] local damageRemainder = damageRemaindersBeforeES[damageType] @@ -756,7 +756,7 @@ function calcs.defence(env, actor) -- Action Speed output.ActionSpeedMod = calcs.actionSpeedMod(actor) - + -- Armour defence types for conditionals for _, slot in pairs({"Helmet","Gloves","Boots","Body Armour","Weapon 2","Weapon 3"}) do local armourData = actor.itemList[slot] and actor.itemList[slot].armourData @@ -783,7 +783,7 @@ function calcs.defence(env, actor) local armourBase = armourData.Armour or 0 if armourBase > 0 then output["ArmourOnAllArmourItems"] = (output["ArmourOnAllArmourItems"] or 0) + armourBase - if slot == "Body Armour" then + if slot == "Body Armour" then if modDB:Flag(nil, "DoubleBodyArmourDefence") then armourBase = armourBase * 2 end @@ -813,7 +813,7 @@ function calcs.defence(env, actor) -- Resistances output["PhysicalResist"] = 0 - + -- Process Resistance conversion mods for _, resFrom in ipairs(resistTypeList) do local maxRes @@ -834,7 +834,7 @@ function calcs.defence(env, actor) end end end - + for _, resFrom in ipairs(resistTypeList) do local res for _, resTo in ipairs(resistTypeList) do @@ -860,7 +860,7 @@ function calcs.defence(env, actor) end end end - + -- Highest Maximum Elemental Resistance for Melding of the Flesh if modDB:Flag(nil, "ElementalResistMaxIsHighestResistMax") then local highestResistMax = 0; @@ -878,7 +878,7 @@ function calcs.defence(env, actor) end end end - + for _, elem in ipairs(resistTypeList) do local min, max, total, dotTotal, totemTotal, totemMax min = data.misc.ResistFloor @@ -896,7 +896,7 @@ function calcs.defence(env, actor) local base = modDB:Sum("BASE", nil, "Totem"..elem.."Resist", isElemental[elem] and "TotemElementalResist") totemTotal = base * m_max(calcLib.mod(modDB, nil, "Totem"..elem.."Resist", isElemental[elem] and "TotemElementalResist"), 0) end - + -- Fractional resistances are truncated total = m_modf(total) -- Unnatural Resilience needs FireResistTotal before we calc FireResistMax @@ -906,14 +906,14 @@ function calcs.defence(env, actor) max = modDB:Override(nil, elem.."ResistMax") or m_min(data.misc.MaxResistCap, modDB:Sum("BASE", nil, elem.."ResistMax", isElemental[elem] and "ElementalResistMax") + blockMaxBonus) else max = modDB:Override(nil, elem.."ResistMax") or m_min(data.misc.MaxResistCap, modDB:Sum("BASE", nil, elem.."ResistMax", isElemental[elem] and "ElementalResistMax")) - end - + end + dotTotal = dotTotal and m_modf(dotTotal) or total totemTotal = m_modf(totemTotal) min = m_modf(min) max = m_modf(max) totemMax = m_modf(totemMax) - + local final = m_max(m_min(total, max), min) local dotFinal = m_max(m_min(dotTotal, max), min) local totemFinal = m_max(m_min(totemTotal, totemMax), min) @@ -994,7 +994,7 @@ function calcs.defence(env, actor) else output.SpellBlockChanceMax = m_min(modDB:Override(nil, "BlockChanceMax") or (modDB:Sum("BASE", nil, "BaseSpellBlockChanceMax") + modDB:Sum("BASE", nil, "SpellBlockChanceMax")), data.misc.BlockChanceCap) end - if modDB:Flag(nil, "MaxSpellBlockIfNotBlockedRecently") then + if modDB:Flag(nil, "MaxSpellBlockIfNotBlockedRecently") then output.SpellBlockChance = output.SpellBlockChanceMax output.SpellProjectileBlockChance = output.SpellBlockChanceMax elseif modDB:Flag(nil, "SpellBlockChanceIsBlockChance") then @@ -1047,7 +1047,7 @@ function calcs.defence(env, actor) end end output.EffectiveAverageBlockChance = (output.EffectiveBlockChance + output.EffectiveProjectileBlockChance + output.EffectiveSpellBlockChance + output.EffectiveSpellProjectileBlockChance) / 4 - output.BlockEffect = 100 - modDB:Sum("BASE", nil, "BlockEffect") + output.BlockEffect = 100 - modDB:Sum("BASE", nil, "BlockEffect") if output.BlockEffect ~= 0 then output.ShowBlockEffect = true output.DamageTakenOnBlock = 100 - output.BlockEffect @@ -1062,7 +1062,7 @@ function calcs.defence(env, actor) modDB:NewMod("EnergyShieldRecharge", "INC", m_floor(mod.value * multiplier), mod.source, mod.flags, mod.keywordFlags, unpack(modifiers)) end end - + if modDB:Flag(nil, "ManaRegenAppliesToEnergyShieldRecharge") then -- Mana Regen conversion from Waveshaper for i, value in ipairs(modDB:Tabulate("INC", { }, "ManaRegen")) do @@ -1073,43 +1073,64 @@ function calcs.defence(env, actor) if modDB:Flag(nil, "EnergyShieldIncreasedByOvercappedColdRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EnergyShieldIncreasedByOvercappedColdRes")) do - local mod = value.mod - modDB:NewMod("EnergyShield", "INC", output.ColdResistOverCap, mod.source) + local mod = value.mod + modDB:NewMod("EnergyShield", "INC", output.ColdResistOverCap, mod.source) + break + end + end + if modDB:Flag(nil, "EnergyShieldIncreasedByUncappedColdRes") then + for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EnergyShieldIncreasedByUncappedColdRes")) do + local mod = value.mod + modDB:NewMod("EnergyShield", "INC", output.ColdResistTotal, mod.source) break end end if modDB:Flag(nil, "ArmourIncreasedByUncappedFireRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "ArmourIncreasedByUncappedFireRes")) do - local mod = value.mod - modDB:NewMod("Armour", "INC", output.FireResistTotal, mod.source) + local mod = value.mod + modDB:NewMod("Armour", "INC", output.FireResistTotal, mod.source) break end end if modDB:Flag(nil, "ArmourIncreasedByOvercappedFireRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "ArmourIncreasedByOvercappedFireRes")) do local mod = value.mod - modDB:NewMod("Armour", "INC", output.FireResistOverCap, mod.source) + modDB:NewMod("Armour", "INC", output.FireResistOverCap, mod.source) break end end if modDB:Flag(nil, "EvasionRatingIncreasedByUncappedColdRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EvasionRatingIncreasedByUncappedColdRes")) do local mod = value.mod - modDB:NewMod("Evasion", "INC", output.ColdResistTotal, mod.source) + modDB:NewMod("Evasion", "INC", output.ColdResistTotal, mod.source) + break + end + end + if modDB:Flag(nil, "EvasionRatingIncreasedByUncappedLightningRes") then + for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EvasionRatingIncreasedByUncappedLightningRes")) do + local mod = value.mod + modDB:NewMod("Evasion", "INC", output.LightningResistTotal, mod.source) break end end if modDB:Flag(nil, "EvasionRatingIncreasedByOvercappedColdRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EvasionRatingIncreasedByOvercappedColdRes")) do local mod = value.mod - modDB:NewMod("Evasion", "INC", output.ColdResistOverCap, mod.source) + modDB:NewMod("Evasion", "INC", output.ColdResistOverCap, mod.source) break end end if modDB:Flag(nil, "EvasionRatingIncreasedByOvercappedLightningRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EvasionRatingIncreasedByOvercappedLightningRes")) do local mod = value.mod - modDB:NewMod("Evasion", "INC", output.LightningResistOverCap, mod.source) + modDB:NewMod("Evasion", "INC", output.LightningResistOverCap, mod.source) + break + end + end + if modDB:Flag(nil, "AilmentThresholdIncreasedByUncappedChaosRes") then + for i, value in ipairs(modDB:Tabulate("FLAG", nil, "AilmentThresholdIncreasedByUncappedChaosRes")) do + local mod = value.mod + modDB:NewMod("AilmentThreshold", "INC", output.ChaosResistTotal, mod.source) break end end @@ -1189,7 +1210,7 @@ function calcs.defence(env, actor) if modDB:Flag(nil, "DoubleBodyArmourDefence") then armourBase = armourBase * 2 end - if modDB:Flag(nil, "Unbreakable") then + if modDB:Flag(nil, "Unbreakable") then armourBase = armourBase * 2 end if modDB:Flag(nil, "ConvertBodyArmourArmourEvasionToWard") then @@ -1391,7 +1412,7 @@ function calcs.defence(env, actor) local accuracyPenalty = 1 - ((enemyDistance - 20) / 100) * (1 - 0.1) enemyAccuracy = m_floor(enemyAccuracy * accuracyPenalty) end - + if modDB:Flag(nil, "CannotEvade") or enemyDB:Flag(nil, "CannotBeEvaded") then output.EvadeChance = 0 output.MeleeEvadeChance = 0 @@ -1460,7 +1481,7 @@ function calcs.defence(env, actor) } end end - + output.DeflectionRating = (output.Evasion * modDB:Sum("BASE", nil, "EvasionGainAsDeflection") / 100 + output.Armour * modDB:Sum("BASE", nil, "ArmourGainAsDeflection") / 100) * calcLib.mod(modDB, nil, "DeflectionRating") output.DeflectChance = calcs.deflectChance(output.DeflectionRating, enemyAccuracy) if modDB:Flag(nil, "DeflectIsLucky") then @@ -1485,10 +1506,10 @@ function calcs.defence(env, actor) if modDB:Flag(nil, "ConvertSpellSuppressionToSpellDodge") then modDB:NewMod("SpellDodgeChance", "BASE", spellSuppressionChance / 2, "Acrobatics") end - + output.SpellSuppressionChance = m_min(totalSpellSuppressionChance, data.misc.SuppressionChanceCap) output.SpellSuppressionEffect = m_max(data.misc.SuppressionEffect + modDB:Sum("BASE", nil, "SpellSuppressionEffect"), 0) - + do output.EffectiveSpellSuppressionChance = enemyDB:Flag(nil, "CannotBeSuppressed") and 0 or output.SpellSuppressionChance local luck = 1 @@ -1507,7 +1528,7 @@ function calcs.defence(env, actor) end end end - + output.SpellSuppressionChanceOverCap = m_max(0, totalSpellSuppressionChance - data.misc.SuppressionChanceCap) -- Dodge @@ -1686,11 +1707,11 @@ function calcs.defence(env, actor) end end end - + -- Energy Shield Recharge - output.EnergyShieldRechargeAppliesToLife = modDB:Flag(nil, "EnergyShieldRechargeAppliesToLife") and not modDB:Flag(nil, "CannotRecoverLifeOutsideLeech") + output.EnergyShieldRechargeAppliesToLife = modDB:Flag(nil, "EnergyShieldRechargeAppliesToLife") and not modDB:Flag(nil, "CannotRecoverLifeOutsideLeech") output.EnergyShieldRechargeAppliesToEnergyShield = not (modDB:Flag(nil, "NoEnergyShieldRecharge") or modDB:Flag(nil, "CannotGainEnergyShield") or output.EnergyShieldRechargeAppliesToLife) - + if output.EnergyShieldRechargeAppliesToLife or output.EnergyShieldRechargeAppliesToEnergyShield then local inc = modDB:Sum("INC", nil, "EnergyShieldRecharge") local more = modDB:More(nil, "EnergyShieldRecharge") @@ -1711,7 +1732,7 @@ function calcs.defence(env, actor) base = { "%.1f", recharge }, { "%.2f ^8(recovery rate modifier)", output.LifeRecoveryRateMod }, total = s_format("= %.1f ^8per second", output.LifeRecharge), - }) + }) end else local recharge = output.EnergyShield * data.misc.EnergyShieldRechargeBase * (1 + inc/100) * more @@ -1747,7 +1768,7 @@ function calcs.defence(env, actor) else output.EnergyShieldRecharge = 0 end - + -- recoup do output["anyRecoup"] = 0 @@ -1783,7 +1804,7 @@ function calcs.defence(env, actor) breakdown.ElementalEnergyShieldRecoup = { s_format("%d%% over %d seconds", output.ElementalEnergyShieldRecoup, (modDB:Flag(nil, "4SecondEnergyShieldRecoup") or modDB:Flag(nil, "4SecondRecoup")) and 4 or 8) } end end - + for _, damageType in ipairs(dmgTypeList) do local LifeRecoup = modDB:Sum("BASE", nil, damageType.."LifeRecoup") output[damageType.."LifeRecoup"] = LifeRecoup * output.LifeRecoveryRateMod @@ -1800,7 +1821,7 @@ function calcs.defence(env, actor) end end end - + -- pseudo recoup (eg %physical damage prevented from hits regenerated) for _, resource in ipairs(recoupTypeList) do if not modDB:Flag(nil, "No"..resource.."Regen") and not modDB:Flag(nil, "CannotGain"..resource) then @@ -1883,7 +1904,7 @@ function calcs.defence(env, actor) output.WeaponSwapSpeed = modDB:Sum("BASE", nil, "WeaponSwapSpeed") output.WeaponSwapSpeedMod = calcLib.mod(modDB, nil, "WeaponSwapSpeed") output.WeaponSwapSpeed = output.WeaponSwapSpeed / output.WeaponSwapSpeedMod - + -- recovery on block, needs to be after primary defences output.LifeOnBlock = 0 output.LifeOnSuppress = 0 @@ -1897,7 +1918,7 @@ function calcs.defence(env, actor) output.EnergyShieldOnBlock = modDB:Sum("BASE", nil, "EnergyShieldOnBlock") output.EnergyShieldOnSpellBlock = modDB:Sum("BASE", nil, "EnergyShieldOnSpellBlock") output.EnergyShieldOnSuppress = modDB:Sum("BASE", nil, "EnergyShieldOnSuppress") - + -- damage avoidances output.specificTypeAvoidance = false for _, damageType in ipairs(dmgTypeList) do @@ -1997,7 +2018,7 @@ function calcs.buildDefenceEstimations(env, actor) local condList = modDB.conditions local damageCategoryConfig = env.configInput.enemyDamageType or "Average" - + -- chance to not be hit calculations if damageCategoryConfig ~= "DamageOverTime" then local worstOf = env.configInput.EHPUnluckyWorstOf or 1 @@ -2033,7 +2054,7 @@ function calcs.buildDefenceEstimations(env, actor) end else if breakdown then - breakdown["totalEnemyDamage"] = { + breakdown["totalEnemyDamage"] = { label = "Total damage from the enemy", rowList = { }, colList = { @@ -2072,10 +2093,10 @@ function calcs.buildDefenceEstimations(env, actor) if enemyOverwhelm == nil then enemyOverwhelm = tonumber(env.configPlaceholder["enemy"..damageType.."enemyOverwhelm"]) or 0 end - + -- Add min-max enemy damage from mods enemyDamage = enemyDamage + (enemyDB:Sum("BASE", enemyCfg, (damageType.."Min")) + enemyDB:Sum("BASE", enemyCfg, (damageType.."Max"))) / 2 - + -- Conversion and Gain As Mods local conversionTotal = 0 if damageType == "Physical" then @@ -2112,7 +2133,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + enemyOverwhelm = enemyOverwhelm + enemyDB:Sum("BASE", nil, "PhysicalOverwhelm") + modDB:Sum("BASE", nil, "EnemyPhysicalOverwhelm") output[damageType.."EnemyPen"] = enemyPen @@ -2151,7 +2172,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + --Damage Taken as do actor.damageShiftTable = wipeTable(actor.damageShiftTable) @@ -2174,11 +2195,11 @@ function calcs.buildDefenceEstimations(env, actor) actor.damageOverTimeShiftTable[damageType] = dotShiftTable shiftTable[damageType] = m_max(100 - destTotal, 0) actor.damageShiftTable[damageType] = shiftTable - + --add same type damage output[damageType.."TakenDamage"] = output[damageType.."EnemyDamage"] * actor.damageShiftTable[damageType][damageType] / 100 if breakdown then - breakdown[damageType.."TakenDamage"] = { + breakdown[damageType.."TakenDamage"] = { label = "Taken", rowList = { }, colList = { @@ -2210,7 +2231,7 @@ function calcs.buildDefenceEstimations(env, actor) --total output["totalTakenDamage"] = 0 if breakdown then - breakdown["totalTakenDamage"] = { + breakdown["totalTakenDamage"] = { label = "Total damage taken from the enemy after taken as", rowList = { }, colList = { @@ -2247,7 +2268,7 @@ function calcs.buildDefenceEstimations(env, actor) takenMore = takenMore * modDB:More(nil, "ElementalDamageTakenWhenHit") end output[damageType.."TakenHitMult"] = m_max((1 + takenInc / 100) * takenMore, 0) - + for _, hitType in ipairs(hitSourceList) do local baseTakenIncType = takenInc + modDB:Sum("INC", nil, hitType.."DamageTaken") local baseTakenMoreType = takenMore * modDB:More(nil, hitType.."DamageTaken") @@ -2295,7 +2316,7 @@ function calcs.buildDefenceEstimations(env, actor) -- Incoming hit damage multipliers output["totalTakenHit"] = 0 if breakdown then - breakdown["totalTakenHit"] = { + breakdown["totalTakenHit"] = { label = "Total damage taken after mitigation", rowList = { }, colList = { @@ -2315,7 +2336,7 @@ function calcs.buildDefenceEstimations(env, actor) local enemyOverwhelm = modDB:Flag(nil, "SelfIgnore"..damageType.."DamageReduction") and 0 or output[damageType.."EnemyOverwhelm"] local damage = output[damageType.."TakenDamage"] local impaleDamage = enemyImpaleChance > 0 and (damageType == "Physical" and (damage * data.misc.ImpaleStoredDamageBase) or 0) or 0 - + --armour/PDR calculations local armourReduct = 0 local impaleArmourReduct = 0 @@ -2339,7 +2360,7 @@ function calcs.buildDefenceEstimations(env, actor) -- should this be done BEFORE percentOfArmourApplies and ArmourDefense is used? Probably needs GGG confirmation effectiveAppliedArmour = effectiveAppliedArmour + amount end - + local resMult = 1 - (resist > 0 and m_max(resist - enemyPen, 0) or resist) / 100 local reductMult = 1 local takenFlat = modDB:Sum("BASE", nil, "DamageTaken", damageType.."DamageTaken", "DamageTakenWhenHit", damageType.."DamageTakenWhenHit") @@ -2374,7 +2395,7 @@ function calcs.buildDefenceEstimations(env, actor) end if effectiveArmourFromArmour == effectiveAppliedArmour then t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from Armour: %d%%", armourReduct)) - else + else for source, amount in pairs(effectiveArmourFromOther) do local label = source:gsub("(%l)(%u)", "%1 %2") t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of %s applies", mapArmourFromOther[source], label)) @@ -2501,7 +2522,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- stun do local stunThresholdBase = 0 @@ -2530,13 +2551,13 @@ function calcs.buildDefenceEstimations(env, actor) local StunThresholdMore = modDB:More("INC", nil, "StunThreshold") local StunThresholdModBase = modDB:Sum("BASE", nil, "StunThreshold") output.StunThreshold = (stunThresholdBase + StunThresholdModBase) * StunThresholdInc * StunThresholdMore - + local notAvoidChance = modDB:Flag(nil, "StunImmune") and 0 or 100 - m_min(modDB:Sum("BASE", nil, "AvoidStun"), 100) if output.EnergyShield > output["totalTakenHit"] and not env.modDB:Flag(nil, "EnergyShieldProtectsMana") then notAvoidChance = notAvoidChance * 0.5 end output.StunAvoidChance = 100 - notAvoidChance - + if breakdown then breakdown.StunThreshold = { s_format("%d ^8(base from %s)", stunThresholdBase, stunThresholdSource) } for _, source in ipairs({"Tree", "Item", "Skill"}) do @@ -2548,10 +2569,10 @@ function calcs.buildDefenceEstimations(env, actor) if StunThresholdInc ~= 1 then t_insert(breakdown.StunThreshold, s_format("* %.2f ^8(increased threshold)", StunThresholdInc)) end - if StunThresholdMore ~= 1 then + if StunThresholdMore ~= 1 then t_insert(breakdown.StunThreshold, s_format("* %.2f ^8(more threshold)", StunThresholdMore)) end - if StunThresholdInc ~= 1 or StunThresholdMore ~= 1 then + if StunThresholdInc ~= 1 or StunThresholdMore ~= 1 then t_insert(breakdown.StunThreshold, s_format("= %d", output.StunThreshold)) end breakdown.StunAvoidChance = { @@ -2588,7 +2609,7 @@ function calcs.buildDefenceEstimations(env, actor) end t_insert(breakdown.StunDuration, s_format("rounded up to nearest server tick")) t_insert(breakdown.StunDuration, s_format("= %.2fs", output.StunDuration)) - + t_insert(breakdown.BlockDuration, s_format("rounded up to nearest server tick")) t_insert(breakdown.BlockDuration, s_format("= %.2fs", output.BlockDuration)) end @@ -2619,7 +2640,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- Life Recoverable output.LifeRecoverable = output.LifeUnreserved if env.configInput["conditionLowLife"] then @@ -2630,12 +2651,12 @@ function calcs.buildDefenceEstimations(env, actor) end -- Dissolution of the flesh life pool change - if modDB:Flag(nil, "DamageInsteadReservesLife") then + if modDB:Flag(nil, "DamageInsteadReservesLife") then output.LifeRecoverable = (output.LifeCancellableReservation / 100) * output.Life end - + output.LifeRecoverable = m_max(output.LifeRecoverable, 1) - + -- Prevented life loss taken over 4 seconds (and Petrified Blood) do local recoverable = output.LifeRecoverable @@ -2652,7 +2673,7 @@ function calcs.buildDefenceEstimations(env, actor) output["preventedLifeLossTotal"] = output["preventedLifeLoss"] + output["preventedLifeLossBelowHalf"] end output.LifeHitPool = calcLifeHitPoolWithLossPrevention(recoverable, output.Life, preventedLifeLoss, initialLifeLossBelowHalfPrevented) - + if breakdown then breakdown["preventedLifeLossTotal"] = { s_format("Total life protected:"), @@ -2834,7 +2855,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + --aegis output.AnyAegis = false output["sharedAegis"] = modDB:Max(nil, "AegisValue") or 0 @@ -2859,13 +2880,13 @@ function calcs.buildDefenceEstimations(env, actor) output[damageType.."AegisDisplay"] = output[damageType.."Aegis"] + output["sharedElementalAegis"] end end - + -- taken from allies before you, eg. frost shield do -- frost shield output["FrostShieldLife"] = modDB:Sum("BASE", nil, "FrostGlobeHealth") output["FrostShieldDamageMitigation"] = modDB:Sum("BASE", nil, "FrostGlobeDamageMitigation") - + local lifeProtected = output["FrostShieldLife"] / (output["FrostShieldDamageMitigation"] / 100) * (1 - output["FrostShieldDamageMitigation"] / 100) if breakdown then breakdown["FrostShieldLife"] = { @@ -2876,31 +2897,31 @@ function calcs.buildDefenceEstimations(env, actor) s_format("= %d", lifeProtected), } end - + -- from spectres output["SpectreAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromSpectresBeforeYou") if output["SpectreAllyDamageMitigation"] ~= 0 then output["TotalSpectreLife"] = modDB:Sum("BASE", nil, "TotalSpectreLife") end - + -- from totems output["TotemAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromTotemsBeforeYou") if output["TotemAllyDamageMitigation"] ~= 0 then output["TotalTotemLife"] = modDB:Sum("BASE", nil, "TotalTotemLife") end - + -- from VaalRejuveTotem output["VaalRejuvenationTotemAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromVaalRejuvenationTotemsBeforeYou") + output["TotemAllyDamageMitigation"] if output["VaalRejuvenationTotemAllyDamageMitigation"] ~= output["TotemAllyDamageMitigation"] then output["TotalVaalRejuvenationTotemLife"] = modDB:Sum("BASE", nil, "TotalVaalRejuvenationTotemLife") end - + -- from Sentinel of Radiance output["RadianceSentinelAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromRadianceSentinelBeforeYou") if output["RadianceSentinelAllyDamageMitigation"] ~= 0 then output["TotalRadianceSentinelLife"] = modDB:Sum("BASE", nil, "TotalRadianceSentinelLife") end - + -- from Allied Energy Shield output["SoulLinkMitigation"] = modDB:Sum("BASE", nil, "TakenFromParentESBeforeYou") if output["SoulLinkMitigation"] ~= 0 then @@ -2912,7 +2933,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- Vaal Arctic Armour do output["VaalArcticArmourLife"] = modDB:Sum("BASE", nil, "VaalArcticArmourMaxHits") @@ -2928,7 +2949,7 @@ function calcs.buildDefenceEstimations(env, actor) if modDB:Flag(nil, "EternalLife") then output[damageType.."TotalPool"] = output[damageType.."TotalPool"] + output.EnergyShieldRecoveryCap / (1 - esBypass) / chaosESMultiplier output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + output.EnergyShieldRecoveryCap / (1 - esBypass) / chaosESMultiplier - elseif esBypass < 1 then + elseif esBypass < 1 then if esBypass > 0 then local poolProtected = output.EnergyShieldRecoveryCap / (1 - esBypass) * esBypass / chaosESMultiplier output[damageType.."TotalPool"] = m_max(output[damageType.."TotalPool"] - poolProtected, 0) + m_min(output[damageType.."TotalPool"], poolProtected) / esBypass @@ -2954,13 +2975,13 @@ function calcs.buildDefenceEstimations(env, actor) t_insert(breakdown[damageType.."TotalPool"], s_format("Total Pool: %d", output[damageType.."TotalPool"])) end end - + -- helper function that iteratively reduces pools until life hits 0 to determine the number of hits it would take with given damage to die local function numberOfHitsToDie(DamageIn) local numHits = 0 DamageIn["cycles"] = DamageIn["cycles"] or 1 DamageIn["iterations"] = DamageIn["iterations"] or 0 - + -- check damage in isn't 0 and that ward doesn't mitigate all damage for _, damageType in ipairs(dmgTypeList) do numHits = numHits + DamageIn[damageType] @@ -3006,7 +3027,7 @@ function calcs.buildDefenceEstimations(env, actor) if output.AlliedEnergyShield then alliesTakenBeforeYou["soulLink"] = { remaining = output.AlliedEnergyShield, percent = output.SoulLinkMitigation / 100 } end - + local poolTable = { AlliesTakenBeforeYou = alliesTakenBeforeYou, Aegis = aegis, @@ -3019,7 +3040,7 @@ function calcs.buildDefenceEstimations(env, actor) LifeBelowHalfLossLostOverTime = output.LifeBelowHalfLossLostOverTime or 0, damageTakenThatCanBeRecouped = { } } - + if DamageIn["cycles"] == 1 then DamageIn["TrackRecoupable"] = DamageIn["TrackRecoupable"] or false DamageIn["TrackLifeLossOverTime"] = DamageIn["TrackLifeLossOverTime"] or false @@ -3028,7 +3049,7 @@ function calcs.buildDefenceEstimations(env, actor) DamageIn["TrackLifeLossOverTime"] = false end DamageIn["WardBypass"] = DamageIn["WardBypass"] or modDB:Sum("BASE", nil, "WardBypass") or 0 - + local VaalArcticArmourHitsLeft = output.VaalArcticArmourLife if DamageIn["cycles"] > 1 then VaalArcticArmourHitsLeft = 0 @@ -3056,7 +3077,7 @@ function calcs.buildDefenceEstimations(env, actor) poolTable.EnergyShield = m_min(poolTable.EnergyShield + DamageIn.EnergyShieldWhenHit * (gainMult - 1), gainMult * output.EnergyShieldRecoveryCap) end poolTable = calcs.reducePoolsByDamage(poolTable, Damage, actor) - + -- If still living and the amount of damage exceeds maximum threshold we survived infinite number of hits. if poolTable.Life > 0 and damageTotal >= maxDamage then return m_huge @@ -3101,7 +3122,7 @@ function calcs.buildDefenceEstimations(env, actor) output.LifeLossLostOverTime = output.LifeLossLostOverTime + poolTable.LifeLossLostOverTime output.LifeBelowHalfLossLostOverTime = output.LifeBelowHalfLossLostOverTime + poolTable.LifeBelowHalfLossLostOverTime end - + if poolTable.Life == 0 and DamageIn["cycles"] == 1 then -- Don't count overkill damage and only on final pass as to not break speedup. numHits = numHits - poolTable.OverkillDamage / damageTotal end @@ -3118,7 +3139,7 @@ function calcs.buildDefenceEstimations(env, actor) end return m_max(numHits, 0) end - + if damageCategoryConfig ~= "DamageOverTime" then -- number of damaging hits needed to be taken to die do @@ -3129,7 +3150,7 @@ function calcs.buildDefenceEstimations(env, actor) output["NumberOfDamagingHits"] = numberOfHitsToDie(DamageIn) end - + do local DamageIn = { } local BlockChance = output.EffectiveBlockChance / 100 @@ -3187,7 +3208,7 @@ function calcs.buildDefenceEstimations(env, actor) for _, damageType in ipairs(dmgTypeList) do -- Emperor's Vigilance (this needs to fail with divine flesh as it can't override it, hence the check for high bypass) if modDB:Flag(nil, "BlockedDamageDoesntBypassES") and (output[damageType.."EnergyShieldBypass"] < 100 and damageType ~= "Chaos") then - DamageIn[damageType.."EnergyShieldBypass"] = output[damageType.."EnergyShieldBypass"] * (1 - BlockChance) + DamageIn[damageType.."EnergyShieldBypass"] = output[damageType.."EnergyShieldBypass"] * (1 - BlockChance) end local AvoidChance = 0 if output.specificTypeAvoidance then @@ -3223,7 +3244,7 @@ function calcs.buildDefenceEstimations(env, actor) if breakdown then breakdown["ConfiguredDamageChance"] = { s_format("%.2f ^8(chance for block to fail)", 1 - BlockChance) - } + } if output.ShowBlockEffect then t_insert(breakdown["ConfiguredDamageChance"], s_format("x %.2f ^8(block effect)", output.BlockEffect / 100)) end @@ -3239,7 +3260,7 @@ function calcs.buildDefenceEstimations(env, actor) t_insert(breakdown["ConfiguredDamageChance"], s_format("= %.1f%% ^8(of damage taken from a%s hit)", output["ConfiguredDamageChance"], (damageCategoryConfig == "Average" and "n " or (damageCategoryConfig == "Untyped" and "n " or " "))..damageCategoryConfig)) end end - + -- chance to not be hit breakdown do output["TotalNumberOfHits"] = output["NumberOfMitigatedDamagingHits"] / (1 - output["ConfiguredNotHitChance"] / 100) @@ -3291,7 +3312,7 @@ function calcs.buildDefenceEstimations(env, actor) } end end - + -- effective hit pool output["TotalEHP"] = output["TotalNumberOfHits"] * output["totalEnemyDamageIn"] if breakdown then @@ -3301,7 +3322,7 @@ function calcs.buildDefenceEstimations(env, actor) s_format("= %d ^8(total damage you can take)", output["TotalEHP"]), } end - + -- survival time do output.enemySkillTime = (env.configInput.enemySpeed or env.configPlaceholder.enemySpeed or 700) / (1 + enemyDB:Sum("INC", nil, "Speed") / 100) @@ -3317,7 +3338,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- recoup if output["anyRecoup"] > 0 and damageCategoryConfig ~= "DamageOverTime" then local totalDamage = 0 @@ -3406,7 +3427,7 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- petrified blood "degen" if output.preventedLifeLossTotal > 0 and (output["LifeLossLostOverTime"] and output["LifeBelowHalfLossLostOverTime"]) then local LifeLossBelowHalfLost = modDB:Sum("BASE", nil, "LifeLossBelowHalfLost") / 100 @@ -3442,7 +3463,7 @@ function calcs.buildDefenceEstimations(env, actor) t_insert(breakdown["LifeLossLostAvg"], s_format("= %.2f per second", output["LifeLossLostAvg"])) end end - + -- net recovery over time from enemy hits if (output["LifeRecoupRecoveryAvg"] or 0) > 0 or output.preventedLifeLossTotal > 0 then output["netLifeRecoupAndLossLostOverTimeMax"] = (output["LifeRecoupRecoveryMax"] or 0) - (output["LifeLossLostMax"] or 0) @@ -3463,12 +3484,12 @@ function calcs.buildDefenceEstimations(env, actor) end end end - + -- pvp if env.configInput.PvpScaling then local PvpTvalue = output.enemySkillTime local PvpMultiplier = (env.configInput.enemyMultiplierPvpDamage or 100) / 100 - + local PvpNonElemental1 = data.misc.PvpNonElemental1 local PvpNonElemental2 = data.misc.PvpNonElemental2 local PvpElemental1 = data.misc.PvpElemental1 @@ -3511,7 +3532,7 @@ function calcs.buildDefenceEstimations(env, actor) t_insert(breakdown.PvPTotalTakenHit, s_format("= %.1f", output.PvPTotalTakenHit)) end end - + -- maximum hit taken do -- fix total pools, as they aren't used anymore @@ -3616,7 +3637,7 @@ function calcs.buildDefenceEstimations(env, actor) local oneMinusFlatPlusOverwhelm = (1 - flatDR + enemyOverwhelmPercent / 100) local HP_tTM_tF_DCM_tRM = (totalHitPool / totalTakenMulti - takenFlat) / (damageConvertedMulti * totalResistMult) - + local a = data.misc.ArmourRatio * damageConvertedMulti * oneMinusFlatPlusOverwhelm local b = (effectiveAppliedArmour * oneMinusFlatPlusOverwhelm - effectiveAppliedArmour - HP_tTM_tF_DCM_tRM * data.misc.ArmourRatio * damageConvertedMulti) local c = -HP_tTM_tF_DCM_tRM * effectiveAppliedArmour @@ -3666,12 +3687,12 @@ function calcs.buildDefenceEstimations(env, actor) break end end - + finalMaxHit = round(passIncomingDamage / enemyDamageMult) else finalMaxHit = round(partMin / enemyDamageMult) end - + local maxHitCurType = damageType.."MaximumHitTaken" output[maxHitCurType] = finalMaxHit @@ -3687,10 +3708,10 @@ function calcs.buildDefenceEstimations(env, actor) { label = "Taken", key = "taken" }, }, } - + local fullTaken, takenDamages = calcs.takenHitFromDamage(finalMaxHit * enemyDamageMult, damageType, actor) fullTaken = fullTaken == fullTaken and fullTaken or 0 - + for takenType, takenAmt in pairs(takenDamages) do local conversion = actor.damageShiftTable[damageType][takenType] local incoming = finalMaxHit * enemyDamageMult * conversion / 100 @@ -3747,7 +3768,7 @@ function calcs.buildDefenceEstimations(env, actor) } end end - + -- degens do output.TotalBuildDegen = 0 @@ -3760,7 +3781,7 @@ function calcs.buildDefenceEstimations(env, actor) output[damageConvertedType.."BuildDegen"] = (output[damageConvertedType.."BuildDegen"] or 0) + total output.TotalBuildDegen = output.TotalBuildDegen + total if breakdown then - breakdown.TotalBuildDegen = breakdown.TotalBuildDegen or { + breakdown.TotalBuildDegen = breakdown.TotalBuildDegen or { rowList = { }, colList = { { label = "Base Type", key = "type" }, @@ -3779,7 +3800,7 @@ function calcs.buildDefenceEstimations(env, actor) mult = s_format("x %.2f", output[damageConvertedType.."TakenDotMult"]), total = s_format("%.1f", total), }) - breakdown[damageConvertedType.."BuildDegen"] = breakdown[damageConvertedType.."BuildDegen"] or { + breakdown[damageConvertedType.."BuildDegen"] = breakdown[damageConvertedType.."BuildDegen"] or { rowList = { }, colList = { { label = "Base Type", key = "type" }, @@ -3811,7 +3832,7 @@ function calcs.buildDefenceEstimations(env, actor) local totalManaDegen = 0 local totalEnergyShieldDegen = 0 if breakdown then - breakdown.NetLifeRegen = { + breakdown.NetLifeRegen = { label = "Total Life Degen", rowList = { }, colList = { @@ -3819,7 +3840,7 @@ function calcs.buildDefenceEstimations(env, actor) { label = "Degen", key = "degen" }, }, } - breakdown.NetManaRegen = { + breakdown.NetManaRegen = { label = "Total Mana Degen", rowList = { }, colList = { @@ -3827,7 +3848,7 @@ function calcs.buildDefenceEstimations(env, actor) { label = "Degen", key = "degen" }, }, } - breakdown.NetEnergyShieldRegen = { + breakdown.NetEnergyShieldRegen = { label = "Total Energy Shield Degen", rowList = { }, colList = { @@ -3837,12 +3858,12 @@ function calcs.buildDefenceEstimations(env, actor) } end for _, damageType in ipairs(dmgTypeList) do - if output[damageType.."BuildDegen"] then + if output[damageType.."BuildDegen"] then local energyShieldDegen = 0 local lifeDegen = 0 local manaDegen = 0 local takenFromMana = output[damageType.."MindOverMatter"] + output["sharedMindOverMatter"] - if output.EnergyShieldRegenRecovery > 0 then + if output.EnergyShieldRegenRecovery > 0 then if modDB:Flag(nil, "EnergyShieldProtectsMana") then lifeDegen = output[damageType.."BuildDegen"] * (1 - takenFromMana / 100) energyShieldDegen = output[damageType.."BuildDegen"] * (1 - output[damageType.."EnergyShieldBypass"] / 100) * (takenFromMana / 100) @@ -3927,7 +3948,7 @@ function calcs.buildDefenceEstimations(env, actor) output[damageConvertedType.."EnemyDegen"] = (output[damageConvertedType.."EnemyDegen"] or 0) + total output.TotalDegen = output.TotalDegen + total if breakdown then - breakdown.TotalDegen = breakdown.TotalDegen or { + breakdown.TotalDegen = breakdown.TotalDegen or { rowList = { }, colList = { { label = "Source", key = "source" }, @@ -3948,7 +3969,7 @@ function calcs.buildDefenceEstimations(env, actor) mult = s_format("x %.2f", output[damageConvertedType.."TakenDotMult"]), total = s_format("%.1f", total), }) - breakdown[damageConvertedType.."EnemyDegen"] = breakdown[damageConvertedType.."EnemyDegen"] or { + breakdown[damageConvertedType.."EnemyDegen"] = breakdown[damageConvertedType.."EnemyDegen"] or { rowList = { }, colList = { { label = "Source", key = "source" }, @@ -3996,7 +4017,7 @@ function calcs.buildDefenceEstimations(env, actor) output[damageConvertedType.."EnemyDegen"] = (output[damageConvertedType.."EnemyDegen"] or 0) + total output.TotalDegen = output.TotalDegen + total if breakdown then - breakdown.TotalDegen = breakdown.TotalDegen or { + breakdown.TotalDegen = breakdown.TotalDegen or { rowList = { }, colList = { { label = "Source", key = "source" }, @@ -4017,7 +4038,7 @@ function calcs.buildDefenceEstimations(env, actor) mult = s_format("x %.2f", output[damageConvertedType.."TakenDotMult"]), total = s_format("%.1f", total), }) - breakdown[damageConvertedType.."EnemyDegen"] = breakdown[damageConvertedType.."EnemyDegen"] or { + breakdown[damageConvertedType.."EnemyDegen"] = breakdown[damageConvertedType.."EnemyDegen"] or { rowList = { }, colList = { { label = "Source", key = "source" }, @@ -4052,7 +4073,7 @@ function calcs.buildDefenceEstimations(env, actor) local totalManaDegen = 0 local totalEnergyShieldDegen = 0 if breakdown then - breakdown.ComprehensiveNetLifeRegen = { + breakdown.ComprehensiveNetLifeRegen = { label = "Total Life Degen", rowList = { }, colList = { @@ -4060,7 +4081,7 @@ function calcs.buildDefenceEstimations(env, actor) { label = "Degen", key = "degen" }, }, } - breakdown.ComprehensiveNetManaRegen = { + breakdown.ComprehensiveNetManaRegen = { label = "Total Mana Degen", rowList = { }, colList = { @@ -4068,7 +4089,7 @@ function calcs.buildDefenceEstimations(env, actor) { label = "Degen", key = "degen" }, }, } - breakdown.ComprehensiveNetEnergyShieldRegen = { + breakdown.ComprehensiveNetEnergyShieldRegen = { label = "Total Energy Shield Degen", rowList = { }, colList = { @@ -4079,12 +4100,12 @@ function calcs.buildDefenceEstimations(env, actor) end for _, damageType in ipairs(dmgTypeList) do local typeDegen = (output[damageType.."BuildDegen"] or 0) + (output[damageType.."EnemyDegen"] or 0) - if typeDegen ~= 0 then + if typeDegen ~= 0 then local energyShieldDegen = 0 local lifeDegen = 0 local manaDegen = 0 local takenFromMana = output[damageType.."MindOverMatter"] + output["sharedMindOverMatter"] - if output.EnergyShieldRegenRecovery > 0 then + if output.EnergyShieldRegenRecovery > 0 then if modDB:Flag(nil, "EnergyShieldProtectsMana") then lifeDegen = typeDegen * (1 - takenFromMana / 100) energyShieldDegen = typeDegen * (1 - output[damageType.."EnergyShieldBypass"] / 100) * (takenFromMana / 100) @@ -4166,7 +4187,7 @@ function calcs.buildDefenceEstimations(env, actor) }) end local poolsRemaining = calcs.reducePoolsByDamage(nil, takenHit, actor) - + t_insert(breakdown["totalTakenHit"], "Such a hit would drain the following resources:") breakdown["totalTakenHit"] = incomingDamageBreakdown(breakdown["totalTakenHit"], poolsRemaining, output) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 3e87cc8ac..dc62af918 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -3576,7 +3576,8 @@ function calcs.offence(env, actor, activeSkill) criticalCull = m_min(criticalCull, criticalCull * (1 - (1 - output.CritChance / 100) ^ hitRate)) end local regularCull = skillModList:Max(cfg, "CullPercent") or 0 - local maxCullPercent = m_max(criticalCull, regularCull) + local incCullPercent = 1 + modDB:Sum("INC", cfg, "CullPercent") / 100 + local maxCullPercent = m_max(criticalCull, regularCull) * incCullPercent globalOutput.CullPercent = maxCullPercent globalOutput.CullMultiplier = 100 / (100 - globalOutput.CullPercent) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index cd5a2bc12..cd2a306ad 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -2955,7 +2955,7 @@ function calcs.perform(env, skipEHP) t_insert(mods, modLib.createMod("ColdDamageTaken", "INC", num, "Bonechill", { type = "Condition", var = "Chilled" })) end if modDB:Flag(nil, "ChillEffectIncDamageTaken") then - t_insert(mods, modLib.createMod("DamageTaken", "INC", num, "Ahuana's Bite", { type = "Condition", var = "Chilled" })) + t_insert(mods, modLib.createMod("DamageTaken", "INC", num, "Asphyxia's Wrath", { type = "Condition", var = "Chilled" })) end return mods end diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index a13144ac8..cb401869e 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -218,6 +218,7 @@ local modNameList = { ["mana reservation efficiency of skills"] = "ManaReservationEfficiency", ["life reservation efficiency of skills"] = "LifeReservationEfficiency", ["spirit reservation efficiency of skills"] = "SpiritReservationEfficiency", + ["spirit reservation efficiency"] = "SpiritReservationEfficiency", ["reservation of skills"] = "Reserved", ["mana reservation if cast as an aura"] = { "ManaReserved", tag = { type = "SkillType", skillType = SkillType.Aura } }, ["reservation if cast as an aura"] = { "Reserved", tag = { type = "SkillType", skillType = SkillType.Aura } }, @@ -1072,6 +1073,7 @@ local modFlagList = { ["totem skills that cast an aura"] = { tag = { type = "SkillType", skillType = SkillType.Aura }, keywordFlags = KeywordFlag.Totem }, ["aura skills that summon totems"] = { tag = { type = "SkillType", skillType = SkillType.Aura }, keywordFlags = KeywordFlag.Totem }, ["of aura skills"] = { tag = { type = "SkillType", skillType = SkillType.Aura } }, + ["of buff skills"] = { tag = { type = "SkillType", skillType = SkillType.Buff } }, ["curse skills"] = { keywordFlags = KeywordFlag.Curse }, ["of curse skills"] = { keywordFlags = KeywordFlag.Curse }, ["with curse skills"] = { keywordFlags = KeywordFlag.Curse }, @@ -3925,6 +3927,7 @@ local specialModList = { flag("SpellSuppressionAppliesToAilmentAvoidance") } end, ["enemies chilled by your hits have damage taken increased by chill effect"] = { flag("ChillEffectIncDamageTaken") }, + ["enemies chilled by your hits increase damage taken by chill magnitude"] = { flag("ChillEffectIncDamageTaken") }, -- Bleed ["melee attacks cause bleeding"] = { mod("BleedChance", "BASE", 100, nil, ModFlag.Melee) }, ["attacks cause bleeding when hitting cursed enemies"] = { mod("BleedChance", "BASE", 100, nil, ModFlag.Attack, { type = "ActorCondition", actor = "enemy", var = "Cursed" }) }, @@ -4367,6 +4370,11 @@ local specialModList = { mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "UsingFlask" }), mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "UsingFlask" }), }, + ["inflict elemental exposure on hit, lowering total elemental resistances by (%d+)%%"] = function(num) return { + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -num) }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -num) }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -num) }), + } end, ["enemies near your linked targets have fire, cold and lightning exposure"] = { mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20, { type = "Condition", var = "NearLinkedTarget" }) }, { type = "Condition", var = "Effective" }), mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20, { type = "Condition", var = "NearLinkedTarget" }) }, { type = "Condition", var = "Effective" }), @@ -4973,9 +4981,12 @@ local specialModList = { ["minion life is increased by t?h?e?i?r? ?overcapped fire resistance"] = { mod("MinionModifier", "LIST", { mod = mod("Life", "INC", 1, { type = "PerStat", stat = "FireResistOverCap", div = 1 }) }) }, ["(%d+)%% to maximum fire resistance for each (%d+)%% uncapped fire resistance"] = function(num, _, percent) return { mod("FireResistMax", "BASE", num, { type = "PerStat", stat = "FireResistTotal", div = tonumber(percent) }) } end, ["evasion rating is increased by uncapped cold resistance"] = { flag( "EvasionRatingIncreasedByUncappedColdRes") }, + ["evasion rating is increased by uncapped lightning resistance"] = { flag( "EvasionRatingIncreasedByUncappedLightningRes") }, ["evasion rating is increased by overcapped cold resistance"] = { flag( "EvasionRatingIncreasedByOvercappedColdRes") }, ["energy shield is increased by overcapped cold resistance"] = { flag( "EnergyShieldIncreasedByOvercappedColdRes") }, + ["energy shield is increased by uncapped cold resistance"] = { flag( "EnergyShieldIncreasedByUncappedColdRes") }, ["evasion rating is increased by overcapped lightning resistance"] = { flag( "EvasionRatingIncreasedByOvercappedLightningRes") }, + ["elemental ailment threshold is increased by uncapped chaos resistance"] = { flag( "AilmentThresholdIncreasedByUncappedChaosRes") }, ["reflects (%d+) physical damage to melee attackers"] = { }, ["ignore all movement penalties from armour"] = { flag("Condition:IgnoreMovementPenalties") }, ["gain armour equal to your reserved mana"] = { mod("Armour", "BASE", 1, { type = "PerStat", stat = "ManaReserved", div = 1 }) }, @@ -5200,6 +5211,7 @@ local specialModList = { ["nearby allies have culling strike"] = { mod("ExtraAura", "LIST", {onlyAllies = true, mod = mod("CullPercent", "MAX", 10) }) }, ["hits that stun enemies have culling strike"] = { mod("CullPercent", "MAX", 10, { type = "Condition", var = "AlwaysStunning" }) }, ["hits that heavy stun enemies have culling strike"] = { mod("CullPercent", "MAX", 10, { type = "Condition", var = "AlwaysHeavyStunning" }) }, + ["(%d+)%% increased culling strike threshold"] = function(num) return { mod("CullPercent", "INC", num)} end, -- Intimidate ["permanently intimidate enemies on block"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Intimidated") }, { type = "Condition", var = "BlockedRecently" }) }, ["with a murderous eye jewel socketed, intimidate enemies for (%d) seconds on hit with attacks"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Intimidated") }, { type = "Condition", var = "HaveMurderousEyeJewelIn{SlotName}" }) }, @@ -5370,7 +5382,7 @@ local specialModList = { -- Misc ["fully broken armour effects also apply to fire damage taken from hits"] = { flag("ArmourBreakFireDamageTaken"), }, ["fully broken armour you inflict also increases fire damage taken from hits"] = { flag("ArmourBreakFireDamageTaken"), }, - ["can't use chest armour"] = { mod("CanNotUseBody", "Flag", 1, { type = "DisablesItem", slotName = "Body Armour" }) }, + ["can't use c?h?e?s?t? ?b?o?d?y? ?armour"] = { mod("CanNotUseBody", "Flag", 1, { type = "DisablesItem", slotName = "Body Armour" }) }, --["can't use helmets"] = { mod("CanNotUseHelmet", "Flag", 1, { type = "DisablesItem", slotName = "Helmet" }) }, -- this one does not work due to being on a passive? ["can't use helmet"] = { mod("CanNotUseHelmet", "Flag", 1, { type = "DisablesItem", slotName = "Helmet" }) }, -- this is to allow for custom mod without saying the other is parsed ["can't use other rings"] = { mod("CanNotUseRightRing", "Flag", 1, { type = "DisablesItem", slotName = "Ring 2" }, { type = "SlotNumber", num = 1 }), mod("CanNotUseLeftRing", "Flag", 1, { type = "DisablesItem", slotName = "Ring 1" }, { type = "SlotNumber", num = 2 }) }, @@ -5619,6 +5631,7 @@ local specialModList = { ["(%d+)%% increased total power counted by warcries"] = function(num) return { mod("WarcryPower", "INC", num) } end, ["warcries have a minimum of (%d+) power"] = function(num) return { mod("MinimumWarcryPower", "BASE", num) } end, ["stance skills have (%+%d+) seconds to cooldown"] = function(num) return { mod("CooldownRecovery", "BASE", num, { type = "SkillType", skillType = SkillType.Stance }) } end, + ["skills have (%-.+) seconds to cooldown"] = function(num) return { mod("CooldownRecovery", "BASE", num) } end, ["using warcries is instant"] = { flag("InstantWarcry") }, ["attacks with axes or swords grant (%d+) rage on hit, no more than once every second"] = { flag("Condition:CanGainRage", { type = "Condition", varList = { "UsingAxe", "UsingSword" } }), @@ -5814,6 +5827,7 @@ local specialModList = { ["(%d+)%% more frozen legion and general's cry cooldown recovery rate"] = function(num) return { mod("CooldownRecovery", "MORE", num, { type = "SkillName", skillNameList = { "Frozen Legion", "General's Cry" }, includeTransfigured = true }) } end, ["flamethrower, seismic and lightning spire trap have (%d+)%% increased cooldown recovery rate"] = function(num) return { mod("CooldownRecovery", "INC", num, { type = "SkillName", skillNameList = { "Flamethrower Trap", "Seismic Trap", "Lightning Spire Trap" }, includeTransfigured = true }) } end, ["flamethrower, seismic and lightning spire trap have %-(%d+) cooldown uses?"] = function(num) return { mod("AdditionalCooldownUses", "BASE", -num, { type = "SkillName", skillNameList = { "Flamethrower Trap", "Seismic Trap", "Lightning Spire Trap" }, includeTransfigured = true }) } end, + ["skills have %+(%d+) to limit"] = function(num) return { mod("AdditionalCooldownUses", "BASE", num) } end, ["flameblast starts with (%d+) additional stages"] = function(num) return { mod("Multiplier:FlameblastMinimumStage", "BASE", num, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }) } end, ["incinerate starts with (%d+) additional stages"] = function(num) return { mod("Multiplier:IncinerateMinimumStage", "BASE", num, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }) } end, ["%+([%d%.]+) seconds to flameblast and incinerate cooldown"] = function(num) return { @@ -5856,6 +5870,9 @@ local specialModList = { } end, ["(%d+)%% reduced movement speed penalty from using skills while moving"] = function(num) return { mod("MovementSpeedPenalty", "INC", -num) } end, ["(%d+)%% less movement speed penalty from using skills while moving"] = function(num) return { mod("MovementSpeedPenalty", "MORE", -num) } end, + ["no movement speed penalty while shield is raised"] = function(num) return { + mod("MovementSpeedPenalty", "MORE", -100, { type = "SkillName", skillName = "Raise Shield"}) + } end, -- Conditional Player Quantity / Rarity ["(%d+)%% increased quantity of items dropped by slain normal enemies"] = function(num) return { mod("LootQuantityNormalEnemies", "INC", num) } end, ["(%d+)%% increased rarity of items dropped by slain magic enemies"] = function(num) return { mod("LootRarityMagicEnemies", "INC", num) } end, @@ -6131,10 +6148,12 @@ local skillNameList = { [" corpse cremation " ] = { tag = { type = "SkillName", skillName = "Cremation", includeTransfigured = true }}, -- Sigh. } local preSkillNameList = { } +-- skills from older versions of the game that cannot be obtained anymore and should be ignored by ModParser's skillNameLists +local deprecatedSkillNames = { ["Flammability"] = true } for gemId, gemData in pairs(data.gems) do local grantedEffect = gemData.grantedEffect - if not grantedEffect.hidden and not grantedEffect.support then - local skillName = grantedEffect.baseTypeName or grantedEffect.name + local skillName = grantedEffect.baseTypeName or grantedEffect.name + if not grantedEffect.hidden and not grantedEffect.support and not deprecatedSkillNames[skillName] then skillNameList[" "..skillName:lower().." "] = { tag = { type = "SkillName", skillName = skillName, includeTransfigured = true } } preSkillNameList["^"..skillName:lower().." "] = { tag = { type = "SkillName", skillName = skillName, includeTransfigured = true } } preSkillNameList["^"..skillName:lower().." has ?a? "] = { tag = { type = "SkillName", skillName = skillName, includeTransfigured = true } }