diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index ec9a3ac2b..a61fdfb41 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -451,4 +451,99 @@ describe("TestSkills", function() assert.are.equals(30, activeSkill.skillModList:Sum("MORE", activeSkill.skillCfg, "Damage")) assert.True(build.calcsTab.calcsOutput.TotalDPS > noMinionDps) end) + + it("Test conditional exposure supports make exposure configurable", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + New Item + Razor Quarterstaff + Quality: 0 + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + + build.skillsTab:PasteSocketGroup("Killing Palm 20/0 1\nLightning Attunement 1/0 1\nLightning Exposure 1/0 1") + runCallback("OnFrame") + + assert.True(build.calcsTab.mainEnv.player.modDB:GetCondition("CanApplyLightningExposure")) + end) + + it("Test exposure supports on other active skills make exposure configurable", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + New Item + Razor Quarterstaff + Quality: 0 + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + + build.skillsTab:PasteSocketGroup("Spark 20/0 1") + build.skillsTab:PasteSocketGroup("Killing Palm 20/0 1\nLightning Attunement 1/0 1\nLightning Exposure 1/0 1") + runCallback("OnFrame") + + assert.are.equals("Spark", build.calcsTab.mainEnv.player.mainSkill.activeEffect.grantedEffect.name) + assert.True(build.calcsTab.mainEnv.player.modDB:GetCondition("CanApplyLightningExposure")) + + build.configTab.input.conditionEnemyLightningExposure = true + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(20, build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "LightningExposure")) + end) + + it("Test Potent Exposure only scales exposure from supported skills", function() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1\nFire Exposure 1/0 1") + build.configTab.input.conditionEnemyFireExposure = true + build.configTab:BuildModList() + runCallback("OnFrame") + local fireResistWithoutPotentExposure = build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist") + + newBuild() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1\nFire Exposure 1/0 1") + build.skillsTab:PasteSocketGroup("Spark 20/0 1\nPotent Exposure 1/0 1") + build.configTab.input.conditionEnemyFireExposure = true + build.configTab:BuildModList() + runCallback("OnFrame") + assert.are.equals(fireResistWithoutPotentExposure, build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist")) + + newBuild() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1\nFire Exposure 1/0 1\nPotent Exposure 1/0 1") + build.configTab.input.conditionEnemyFireExposure = true + build.configTab:BuildModList() + runCallback("OnFrame") + assert.are.equals(20, build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireExposure")) + assert.True(build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist") < fireResistWithoutPotentExposure) + end) + + it("Test granted skills with exposure stats make exposure configurable", function() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1") + local spec = build.spec + local brewConcoctionNode = spec.nodes[57141] + local shatteringConcoctionNode = spec.nodes[18940] + brewConcoctionNode.alloc = true + shatteringConcoctionNode.alloc = true + spec.allocNodes[brewConcoctionNode.id] = brewConcoctionNode + spec.allocNodes[shatteringConcoctionNode.id] = shatteringConcoctionNode + build.buildFlag = true + runCallback("OnFrame") + build.calcsTab.input.skill_number = 1 + build.buildFlag = true + runCallback("OnFrame") + + assert.are.equals("Fireball", build.calcsTab.mainEnv.player.mainSkill.activeEffect.grantedEffect.name) + assert.True(build.calcsTab.mainEnv.player.modDB:GetCondition("CanApplyFireExposure")) + assert.True(build.configTab.varControls.conditionEnemyFireExposure:shown()) + end) + + it("Test Refraction III exposure scales from player armour", function() + build.configTab.input.customMods = "+30000 to Armour" + build.configTab.input.bannerPlanted = true + build.configTab:BuildModList() + build.skillsTab:PasteSocketGroup("War Banner 20/0 1\nRefraction III 1/0 1") + runCallback("OnFrame") + + assert.are.equals(30000, build.calcsTab.mainEnv.player.output.Armour) + assert.are.equals(60, build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireExposure")) + assert.are.equals(20, build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist")) + assert.True(build.calcsTab.mainEnv.enemyDB:Flag(nil, "Condition:HasExposure")) + end) end) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index fa62f77c9..5a905392d 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -4798,7 +4798,7 @@ c["Enemies in your Presence have -10% to Fire Resistance"]={{[1]={flags=0,keywor c["Enemies in your Presence have -25% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="FireResist",type="BASE",value=-25}}}},nil} c["Enemies in your Presence have 10% reduced Cooldown Recovery Rate"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="CooldownRecovery",type="INC",value=-10}}}},nil} c["Enemies in your Presence have 75% reduced Life Regeneration rate"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="LifeRegen",type="INC",value=-75}}}},nil} -c["Enemies in your Presence have Exposure"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FireExposure",type="BASE",value=-20}}},[2]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdExposure",type="BASE",value=-20}}},[3]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="LightningExposure",type="BASE",value=-20}}}},nil} +c["Enemies in your Presence have Exposure"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FireExposure",type="BASE",value=20}}},[2]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdExposure",type="BASE",value=20}}},[3]={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="LightningExposure",type="BASE",value=20}}}},nil} c["Enemies in your Presence have Lightning Resistance equal to yours"]={{[1]={[1]={type="Condition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyLightningResistEqualToYours",type="FLAG",value=true}},nil} c["Enemies in your Presence have at least 10% of Life Reserved"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="LifeReservationPercent",type="BASE",value=10}}}},nil} c["Enemies in your Presence have no Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="FireResist",type="OVERRIDE",value=0}}},[2]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="ColdResist",type="OVERRIDE",value=0}}},[3]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="LightningResist",type="OVERRIDE",value=0}}}},nil} @@ -4878,7 +4878,7 @@ c["Excess Life Recovery added as Guard for 10 seconds Excess Life Recovery added c["Excess Life Recovery added as Guard for 20 seconds"]={nil,"Excess Life Recovery added as Guard for 20 seconds "} c["Excess Life Recovery from Leech is applied to Energy Shield"]={nil,"Excess Life Recovery from Leech is applied to Energy Shield "} c["Excess Life Recovery from Regeneration is applied to Energy Shield"]={{[1]={[1]={type="Condition",var="FullLife"},flags=0,keywordFlags=0,name="ZealotsOath",type="FLAG",value=true}},nil} -c["Exposure you inflict lowers Resistances by an additional 5%"]={{[1]={flags=0,keywordFlags=0,name="ExtraExposure",type="BASE",value=-5}},nil} +c["Exposure you inflict lowers Resistances by an additional 5%"]={{[1]={flags=0,keywordFlags=0,name="ExtraExposure",type="BASE",value=5}},nil} c["Final Repeat of Spells has 30% increased Area of Effect"]={{[1]={[1]={neg=true,type="Condition",var="CastOnFrostbolt"},[2]={type="Condition",varList={[1]="averageRepeat",[2]="alwaysFinalRepeat"}},flags=2,keywordFlags=0,name="RepeatFinalAreaOfEffect",type="INC",value=30}},nil} c["Fire Damage from Hits Contributes to Shock Chance instead of Flammability and Ignite Magnitudes"]={{[1]={flags=0,keywordFlags=0,name="FireCanShock",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="FireCannotIgnite",type="FLAG",value=true}},nil} c["Fire Resistance is unaffected by Area Penalties"]={nil,"Fire Resistance is unaffected by Area Penalties "} @@ -5365,9 +5365,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%"]={{[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 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 "} diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 704b592d7..fdf133336 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -1649,11 +1649,49 @@ return { ["base_inflict_fire_exposure_on_hit_%_chance"] = { mod("FireExposureChance", "BASE", nil), }, +["inflict_exposure_for_x_ms_on_shock"] = { + mod("ExposureDuration", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "Shocked"}), + flag("InflictExposure", { type = "ActorCondition", actor = "enemy", var = "Shocked"}), +}, +["inflict_exposure_for_x_ms_on_cold_crit"] = { + mod("ExposureDuration", "BASE", nil, 0, 0, { type = "Condition", var = "CritInPast8Sec"}, { type = "Condition", var = "ColdHasDamage"}), + flag("InflictExposure", { type = "Condition", var = "CritInPast8Sec"}, { type = "Condition", var = "ColdHasDamage"}), +}, +["inflict_exposure_for_x_ms_on_ignite"] = { + mod("ExposureDuration", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "Ignited"}), + flag("InflictExposure", { type = "ActorCondition", actor = "enemy", var = "Ignited"}), +}, +["inflict_exposure_on_hit_%_chance"] = { + mod("LightningExposureChance", "BASE", nil), + mod("ColdExposureChance", "BASE", nil), + mod("FireExposureChance", "BASE", nil), +}, +["all_exposure_on_hit_for_duration_ms"] = { + mod("ExposureDuration", "BASE", nil), + flag("InflictExposure"), +}, +["inflict_all_exposure_on_hit"] = { + flag("InflictExposure"), +}, ["all_exposure_on_hit_magnitude"] = { mod("FireExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), mod("LightningExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mult = -1, +}, +['active_skill_all_elemental_exposure_magnitude'] = { + mod("FireExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), + mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), + mod("LightningExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), +}, +["skill_base_oil_exposure_-_to_total_elemental_resistance"] = { + mod("FireExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), + mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), + mod("LightningExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), +}, +["exposure_effect_+%"] = { + mod("FireExposureEffect", "INC", nil), + mod("ColdExposureEffect", "INC", nil), + mod("LightningExposureEffect", "INC", nil), }, ["offering_spells_effect_+%"] = { mod("BuffEffect", "INC", nil), diff --git a/src/Data/Skills/act_int.lua b/src/Data/Skills/act_int.lua index d2df69a20..3c0ec95e3 100644 --- a/src/Data/Skills/act_int.lua +++ b/src/Data/Skills/act_int.lua @@ -8851,12 +8851,6 @@ skills["FrostBombPlayer"] = { incrementalEffectiveness = 0.12999999523163, damageIncrementalEffectiveness = 0.008899999782443, statDescriptionScope = "frost_bomb", - statMap = { - ['skill_cold_exposure_magnitude'] = { - mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mult = -1 - }, - }, baseFlags = { spell = true, area = true, diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 23d10619e..ec0ee2899 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -14407,14 +14407,6 @@ skills["OilGrenadePlayer"] = { baseEffectiveness = 16, incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "oil_grenade_statset_1", - statMap = { - ["skill_base_oil_exposure_-_to_total_elemental_resistance"] = { - mod("FireExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mod("LightningExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mult = -1, - }, - }, baseFlags = { attack = true, area = true, diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index 8f38e21f0..4f043787c 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -3472,12 +3472,6 @@ skills["ExplosiveConcoctionPlayer"] = { baseEffectiveness = 4.5, incrementalEffectiveness = 0.27349999547005, statDescriptionScope = "explosive_concoction", - statMap = { - ["flask_throw_fire_exposure_ms"] = { - mod("FireExposureChance", "BASE", nil), - value = 100, - }, - }, baseFlags = { attack = true, projectile = true, @@ -3840,12 +3834,6 @@ skills["FulminatingConcoctionPlayer"] = { baseEffectiveness = 4.1999998092651, incrementalEffectiveness = 0.27349999547005, statDescriptionScope = "fulminating_concoction", - statMap = { - ["flask_throw_lightning_exposure_ms"] = { - mod("LightningExposureChance", "BASE", nil), - value = 100, - }, - }, baseFlags = { attack = true, projectile = true, @@ -6953,12 +6941,6 @@ skills["ShatteringConcoctionPlayer"] = { baseEffectiveness = 3.9000000953674, incrementalEffectiveness = 0.27349999547005, statDescriptionScope = "shattering_concoction", - statMap = { - ["flask_throw_cold_exposure_ms"] = { - mod("ColdExposureChance", "BASE", nil), - value = 100, - }, - }, baseFlags = { attack = true, projectile = true, diff --git a/src/Data/Skills/sup_int.lua b/src/Data/Skills/sup_int.lua index eef50f101..892ba9104 100644 --- a/src/Data/Skills/sup_int.lua +++ b/src/Data/Skills/sup_int.lua @@ -1906,11 +1906,6 @@ skills["SupportColdExposurePlayer"] = { label = "Cold Exposure", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "gem_stat_descriptions", - statMap = { - ["inflict_cold_exposure_for_x_ms_on_cold_crit"] = { - mod("ColdExposureChance", "BASE", nil), - }, - }, baseFlags = { }, constantStats = { diff --git a/src/Data/Skills/sup_str.lua b/src/Data/Skills/sup_str.lua index 29b4d9390..c1db3600a 100644 --- a/src/Data/Skills/sup_str.lua +++ b/src/Data/Skills/sup_str.lua @@ -3285,11 +3285,6 @@ skills["SupportFireExposurePlayer"] = { label = "Fire Exposure", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "gem_stat_descriptions", - statMap = { - ["inflict_fire_exposure_for_x_ms_on_ignite"] = { - mod("FireExposureChance", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "Ignited"}), - }, - }, baseFlags = { }, constantStats = { @@ -5577,6 +5572,13 @@ skills["SupportRefractionPlayerThree"] = { label = "Refraction III", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "gem_stat_descriptions", + statMap = { + ["support_tempered_valour_banner_applies_%_elemental_exposure_per_1000_armour"] = { + mod("FireExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + mod("ColdExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + mod("LightningExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + }, + }, baseFlags = { }, constantStats = { diff --git a/src/Export/Skills/act_int.txt b/src/Export/Skills/act_int.txt index 16b0575e6..30b6f88f2 100644 --- a/src/Export/Skills/act_int.txt +++ b/src/Export/Skills/act_int.txt @@ -634,12 +634,6 @@ statMap = { #skill FrostBombPlayer #set FrostBombPlayer #flags spell area duration -statMap = { - ['skill_cold_exposure_magnitude'] = { - mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mult = -1 - }, -}, #mods #skillEnd diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index c2c2b7c9a..7350d9542 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -838,14 +838,6 @@ statMap = { #mods #set OilGrenadeOilGroundPlayer #flags attack area projectile duration -statMap = { - ["skill_base_oil_exposure_-_to_total_elemental_resistance"] = { - mod("FireExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mod("ColdExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mod("LightningExposure", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }), - mult = -1, -}, -}, #mods #skillEnd diff --git a/src/Export/Skills/other.txt b/src/Export/Skills/other.txt index 5a8323f34..d23acfaa9 100644 --- a/src/Export/Skills/other.txt +++ b/src/Export/Skills/other.txt @@ -245,12 +245,6 @@ statMap = { #skill ExplosiveConcoctionPlayer #set ExplosiveConcoctionPlayer #flags attack projectile duration unarmed area -statMap = { - ["flask_throw_fire_exposure_ms"] = { - mod("FireExposureChance", "BASE", nil), - value = 100, - }, -}, #mods #skillEnd @@ -272,12 +266,6 @@ statMap = { #skill FulminatingConcoctionPlayer #set FulminatingConcoctionPlayer #flags attack projectile duration unarmed area -statMap = { - ["flask_throw_lightning_exposure_ms"] = { - mod("LightningExposureChance", "BASE", nil), - value = 100, - }, -}, #mods #skillEnd @@ -494,12 +482,6 @@ statMap = { #skill ShatteringConcoctionPlayer #set ShatteringConcoctionPlayer #flags attack projectile duration unarmed area -statMap = { - ["flask_throw_cold_exposure_ms"] = { - mod("ColdExposureChance", "BASE", nil), - value = 100, - }, -}, #mods #skillEnd diff --git a/src/Export/Skills/sup_int.txt b/src/Export/Skills/sup_int.txt index c0cbe8b59..eec7fb43a 100644 --- a/src/Export/Skills/sup_int.txt +++ b/src/Export/Skills/sup_int.txt @@ -329,11 +329,6 @@ statMap = { #skill SupportColdExposurePlayer #set SupportColdExposurePlayer -statMap = { - ["inflict_cold_exposure_for_x_ms_on_cold_crit"] = { - mod("ColdExposureChance", "BASE", nil), - }, -}, #mods #skillEnd diff --git a/src/Export/Skills/sup_str.txt b/src/Export/Skills/sup_str.txt index fd963167b..0d27c9284 100644 --- a/src/Export/Skills/sup_str.txt +++ b/src/Export/Skills/sup_str.txt @@ -723,11 +723,6 @@ statMap = { #skill SupportFireExposurePlayer #set SupportFireExposurePlayer -statMap = { - ["inflict_fire_exposure_for_x_ms_on_ignite"] = { - mod("FireExposureChance", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "Ignited"}), - }, -}, #mods #skillEnd @@ -1295,6 +1290,13 @@ statMap = { #skill SupportRefractionPlayerThree #set SupportRefractionPlayerThree +statMap = { + ["support_tempered_valour_banner_applies_%_elemental_exposure_per_1000_armour"] = { + mod("FireExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + mod("ColdExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + mod("LightningExposure", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "player", var = "BannerPlanted" }, { type = "GlobalEffect", effectType = "AuraDebuff" }, { type = "PerStat", actor = "player", stat = "Armour", div = 1000, limit = 80, limitTotal = true }), + }, +}, #mods #skillEnd diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index e0da4a162..b67830479 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -5139,7 +5139,7 @@ function calcs.offence(env, actor, activeSkill) -- Apply elemental exposure from skill for _, element in ipairs({"Fire", "Cold", "Lightning"}) do - if skillModList:Sum("BASE", cfg, element.."ExposureChance") > 0 then + if (skillModList:Sum("BASE", cfg, element.."ExposureChance") > 0) or skillModList:Flag(cfg, "InflictExposure") then skillFlags["apply"..element.."Exposure"] = true end end diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index f663aad7e..00c23cec6 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -340,14 +340,35 @@ local function doActorAttribsConditions(env, actor) end end if env.mode_effective then - if env.player.mainSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "FireExposureChance") > 0 or modDB:Sum("BASE", nil, "FireExposureChance") > 0 then + local function hasActiveSkillExposureSource(activeSkill, modName) + return activeSkill.skillModList and activeSkill.skillCfg + and (activeSkill.skillModList:HasMod("BASE", activeSkill.skillCfg, modName) or activeSkill.skillModList:HasMod("FLAG", activeSkill.skillCfg, "InflictExposure")) + or activeSkill.baseSkillModList + and (activeSkill.baseSkillModList:HasMod("BASE", nil, modName) or activeSkill.baseSkillModList:HasMod("FLAG", nil, "InflictExposure")) + end + local function hasExposureSource(element) + local modName = element .. "ExposureChance" + if modDB:Sum("BASE", nil, modName) > 0 or modDB:HasMod("FLAG", nil, "InflictExposure") then + return true + end + for _, activeSkill in ipairs(env.player.activeSkillList) do + if hasActiveSkillExposureSource(activeSkill, modName) then + return true + end + end + return false + end + if hasExposureSource("Fire") then condList["CanApplyFireExposure"] = true + modDB:NewMod("Condition:CanApplyFireExposure", "FLAG", true, "Exposure") end - if env.player.mainSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "ColdExposureChance") > 0 or modDB:Sum("BASE", nil, "ColdExposureChance") > 0 then + if hasExposureSource("Cold") then condList["CanApplyColdExposure"] = true + modDB:NewMod("Condition:CanApplyColdExposure", "FLAG", true, "Exposure") end - if env.player.mainSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "LightningExposureChance") > 0 or modDB:Sum("BASE", nil, "LightningExposureChance") > 0 then + if hasExposureSource("Lightning") then condList["CanApplyLightningExposure"] = true + modDB:NewMod("Condition:CanApplyLightningExposure", "FLAG", true, "Exposure") end end @@ -3091,45 +3112,69 @@ function calcs.perform(env, skipEHP) doActorCharges(env, env.enemy) doActorMisc(env, env.enemy) - local major, minor = env.spec.treeVersion:match("(%d+)_(%d+)") + -- Handle consecrated ground effects on enemies + if enemyDB:Flag(nil, "Condition:OnConsecratedGround") then + local effect = 1 + modDB:Sum("INC", nil, "ConsecratedGroundEffect") / 100 + enemyDB:NewMod("DamageTaken", "INC", enemyDB:Sum("INC", nil, "DamageTakenConsecratedGround") * effect, "Consecrated Ground") + end + + -- Defence/offence calculations + calcs.defence(env, env.player) + local function getSkillExposureEffect(source, element) + local effect = 0 + for _, activeSkill in ipairs(env.player.activeSkillList) do + if source == "Config" then + -- Config exposure is a generic 20% exposure, so use any active skill that can apply this exposure as the source for skill-specific exposure effect. + if activeSkill.skillModList:HasMod("BASE", activeSkill.skillCfg, element.."ExposureChance") or activeSkill.skillModList:HasMod("FLAG", activeSkill.skillCfg, "InflictExposure") then + effect = m_max(effect, activeSkill.skillModList:Sum("INC", { source = "Skill" }, element.."ExposureEffect")) + end + else + -- Direct skill exposure keeps the source from the active/support skill that created the exposure mod. + for _, skillEffect in ipairs(activeSkill.effectList or { }) do + if skillEffect.grantedEffect.modSource == source then + effect = m_max(effect, activeSkill.skillModList:Sum("INC", { source = "Skill" }, element.."ExposureEffect")) + break + end + end + end + end + return effect + end -- Apply exposures - for _, element in ipairs({"Fire", "Cold", "Lightning"}) do - if tonumber(major) <= 3 and tonumber(minor) <= 15 -- Elemental Equilibrium pre-3.16 does not remove Exposure effects - or not modDB:Flag(nil, "ElementalEquilibrium") -- if Elemental Equilibrium isn't active we just process Exposure normally + for _, element in ipairs({ "Fire", "Cold", "Lightning" }) do + if not modDB:Flag(nil, "ElementalEquilibrium") -- if Elemental Equilibrium isn't active we just process Exposure normally or element == "Fire" and not enemyDB:Flag(nil, "Condition:HitByFireDamage") or element == "Cold" and not enemyDB:Flag(nil, "Condition:HitByColdDamage") or element == "Lightning" and not enemyDB:Flag(nil, "Condition:HitByLightningDamage") then - local min = math.huge + local magnitude = 0 local source = "" - for _, mod in ipairs(enemyDB:Tabulate("BASE", nil, element.."Exposure")) do - if mod.value < min then - min = mod.value - source = mod.mod.source + local extraExposure = modDB:Sum("BASE", nil, "ExtraExposure", "Extra"..element.."Exposure") + local globalExposureEffect = modDB:Sum("INC", nil, element.."ExposureEffect") + local exposureEffectOnSelf = enemyDB:More(nil, "ExposureEffectOnSelf") + local function checkExposure(value, modSource, skillExposureEffect) + -- Resolve each exposure source independently so skill-specific effect only scales the exposure from that skill. + value = m_floor((value + extraExposure) * ((globalExposureEffect + skillExposureEffect) / 100 + 1) * exposureEffectOnSelf) + if value > magnitude then + magnitude = value + source = modSource end end - if min ~= math.huge then - -- Modify the magnitude of all exposures - for _, mod in ipairs(modDB:Tabulate("BASE", nil, "ExtraExposure", "Extra"..element.."Exposure")) do - min = min + mod.value + for _, mod in ipairs(enemyDB:Tabulate("BASE", nil, element.."Exposure")) do + checkExposure(mod.value, mod.mod.source, getSkillExposureEffect(mod.mod.source, element)) + end + if magnitude > 0 then + local exposureMin = modDB:Override(nil, "ExposureMin") + if exposureMin then + magnitude = m_max(magnitude, exposureMin) end - min = min * (modDB:Sum("INC", nil, element.."ExposureEffect") / 100 + 1) * enemyDB:More(nil, "ExposureEffectOnSelf") enemyDB:NewMod("Condition:Has"..element.."Exposure", "FLAG", true, "") enemyDB:NewMod("Condition:HasExposure", "FLAG", true, "") - enemyDB:NewMod(element.."Resist", "BASE", m_min(min, modDB:Override(nil, "ExposureMin")), source) + enemyDB:NewMod(element.."Resist", "BASE", -magnitude, source) modDB:NewMod("Condition:AppliedExposureRecently", "FLAG", true, "") end end end - - -- Handle consecrated ground effects on enemies - if enemyDB:Flag(nil, "Condition:OnConsecratedGround") then - local effect = 1 + modDB:Sum("INC", nil, "ConsecratedGroundEffect") / 100 - enemyDB:NewMod("DamageTaken", "INC", enemyDB:Sum("INC", nil, "DamageTakenConsecratedGround") * effect, "Consecrated Ground") - end - - -- Defence/offence calculations - calcs.defence(env, env.player) if not skipEHP then calcs.buildDefenceEstimations(env, env.player) end diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 708f9b321..9a9271200 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -1808,14 +1808,14 @@ Huge sets the radius to 11. { var = "multiplierFreezeShockIgniteOnEnemy", type = "count", label = "# of ^x3F6DB3Freeze ^7/ ^xADAA47Shock ^7/ ^xB97123Ignite ^7on enemy:", ifMult = "FreezeShockIgniteOnEnemy", apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:FreezeShockIgniteOnEnemy", "BASE", val, "Config", { type = "Condition", var = "Effective" }) end }, - { var = "conditionEnemyFireExposure", type = "check", label = "Is the enemy Exposed to ^xB97123Fire?", ifFlag = "applyFireExposure", tooltip = "This applies -20% ^xB97123Fire Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) - enemyModList:NewMod("FireExposure", "BASE", -20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyFireExposure" }) + { var = "conditionEnemyFireExposure", type = "check", label = "Is the enemy Exposed to ^xB97123Fire?", ifFlag = "Condition:CanApplyFireExposure", tooltip = "This applies -20% ^xB97123Fire Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) + enemyModList:NewMod("FireExposure", "BASE", 20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyFireExposure" }) end }, - { var = "conditionEnemyColdExposure", type = "check", label = "Is the enemy Exposed to ^x3F6DB3Cold?", ifFlag = "applyColdExposure", tooltip = "This applies -20% ^x3F6DB3Cold Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) - enemyModList:NewMod("ColdExposure", "BASE", -20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyColdExposure" }) + { var = "conditionEnemyColdExposure", type = "check", label = "Is the enemy Exposed to ^x3F6DB3Cold?", ifFlag = "Condition:CanApplyColdExposure", tooltip = "This applies -20% ^x3F6DB3Cold Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) + enemyModList:NewMod("ColdExposure", "BASE", 20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyColdExposure" }) end }, - { var = "conditionEnemyLightningExposure", type = "check", label = "Is the enemy Exposed to ^xADAA47Lightning?", ifFlag = "applyLightningExposure", tooltip = "This applies -20% ^xADAA47Lightning Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) - enemyModList:NewMod("LightningExposure", "BASE", -20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyLightningExposure" }) + { var = "conditionEnemyLightningExposure", type = "check", label = "Is the enemy Exposed to ^xADAA47Lightning?", ifFlag = "Condition:CanApplyLightningExposure", tooltip = "This applies -20% ^xADAA47Lightning Resistance ^7to the enemy.", apply = function(val, modList, enemyModList) + enemyModList:NewMod("LightningExposure", "BASE", 20, "Config", { type = "Condition", var = "Effective" }, { type = "ActorCondition", actor = "enemy", var = "CanApplyLightningExposure" }) end }, { var = "conditionEnemyIntimidated", type = "check", label = "Is the enemy Intimidated?", tooltip = "Intimidate is a Debuff that inflicts 10% increased damage taken and 10% reduced damage dealt.", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:Intimidated", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index cc20d66c3..ac4914f87 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2877,9 +2877,9 @@ local specialModList = { flag("Condition:CanGainConvergence"), }, ["(%d+)%% increased area of effect while you don't have convergence"] = function(num) return { mod("AreaOfEffect", "INC", num, { type = "Condition", neg = true, var = "Convergence" }) } end, - ["exposure you inflict applies an extra (%-?%d+)%% to the affected resistance"] = function(num) return { mod("ExtraExposure", "BASE", num) } end, - ["exposure you inflict lowers the affected resistance by an additional (%-?%d+)%%"] = function(num) return { mod("ExtraExposure", "BASE", -num) } end, - ["exposure you inflict lowers resistances by an additional (%-?%d+)%%"] = function(num) return { mod("ExtraExposure", "BASE", -num) } end, + ["exposure you inflict applies an extra (%-?%d+)%% to the affected resistance"] = function(num) return { mod("ExtraExposure", "BASE", -num) } end, + ["exposure you inflict lowers the affected resistance by an additional (%-?%d+)%%"] = function(num) return { mod("ExtraExposure", "BASE", num) } end, + ["exposure you inflict lowers resistances by an additional (%-?%d+)%%"] = function(num) return { mod("ExtraExposure", "BASE", num) } end, ["cannot take reflected elemental damage"] = { mod("ElementalReflectedDamageTaken", "MORE", -100, { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, ["every %d+ seconds:"] = { }, ["gain chilling conflux for %d seconds"] = { @@ -3156,14 +3156,14 @@ local specialModList = { ["nearby enemies have (%d+)%% less accuracy rating while you have phasing"] = function(num) return { mod("EnemyModifier", "LIST", { mod = mod("Accuracy", "MORE", -num) }, { type = "Condition", var = "Phasing" }) } end, ["immun[ei]t?y? to elemental ailments while phasing"] = { flag("ElementalAilmentImmune", { type = "Condition", var = "Phasing" }), }, ["nearby enemies have fire, cold and lightning exposure while you have phasing, applying %-(%d+)%% to those resistances"] = function(num) return { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -num) }, { type = "Condition", var = "Phasing" }), - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -num) }, { type = "Condition", var = "Phasing" }), - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -num) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", num) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", num) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", num) }, { type = "Condition", var = "Phasing" }), } end, ["nearby enemies have fire, cold and lightning exposure while you have phasing"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "Condition", var = "Phasing" }), - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "Condition", var = "Phasing" }), - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", 20) }, { type = "Condition", var = "Phasing" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20) }, { type = "Condition", var = "Phasing" }), }, -- Saboteur ["hits have (%d+)%% chance to deal (%d+)%% more area damage"] = function (num, _, more) return { @@ -3324,9 +3324,9 @@ local specialModList = { ["demonflame has no maximum"] = { mod("Multiplier:DemonFlameMaximum", "BASE", 999) }, -- Druid -- Shaman ["enemies in your presence have exposure"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", 20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20) }, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }), }, -- Druid -- Oracle ["walk the paths not taken"] = { }, @@ -4089,9 +4089,9 @@ local specialModList = { mod("SpellSuppressionEffect", "BASE", num, { type = "Multiplier", var = "HitsSuppressedRecently" }) } end, ["inflict fire, cold and lightning exposure on enemies when you suppress their spell damage"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }), - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }), - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }) + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "SuppressedRecently" }) }, ["critical hit chance is increased by chance to suppress spell damage"] = { flag("CritChanceIncreasedBySpellSuppressChance") }, ["you take (%d+)%% reduced extra damage from suppressed critical hits"] = function(num) return { mod("ReduceSuppressedCritExtraDamage", "BASE", num) } end, @@ -4213,7 +4213,7 @@ local specialModList = { ["enemies in your presence have at least (%d+)%% of life reserved"] = function(num) return { mod("EnemyModifier", "LIST", { mod = mod("LifeReservationPercent", "BASE", num, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }) }) } end, ["targets cursed by you have at least (%d+)%% of life reserved"] = function(num) return { mod("EnemyModifier", "LIST", { mod = mod("LifeReservationPercent", "BASE", num, { type = "Condition", var = "Cursed" }) }) } end, ["enemies in your presence count as being on low life"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:LowLife") }, { type = "Condition", var = "EnemyInPresence" }) }, - ["enemies in your presence have fire exposure"] = { mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }) }) }, + ["enemies in your presence have fire exposure"] = { mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20, { type = "ActorCondition", actor = "enemy", var = "EnemyInPresence" }) }) }, ["your hits inflict decay, dealing (%d+) chaos damage per second for %d+ seconds"] = function(num) return { mod("SkillData", "LIST", { key = "decay", value = num, merge = "MAX" }) } end, ["inflict decay on enemies you curse with hex or mark skills, dealing (%d+) chaos damage per second for %d+ seconds"] = function(num) return { -- typo never existed except in some items generated by PoB mod("SkillData", "LIST", { key = "decay", value = num, merge = "MAX" }, { type = "ActorCondition", actor = "enemy", var = "Cursed" }) @@ -4369,60 +4369,60 @@ local specialModList = { mod("LightningExposureChance", "BASE", 100, { type = "Condition", var = "Effective" }), }, ["nearby enemies have fire exposure"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }), }, ["nearby enemies have cold exposure"] = { - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }), }, ["nearby enemies have lightning exposure"] = { - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }), }, ["nearby enemies have fire exposure while you are affected by herald of ash"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofAsh" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofAsh" }), }, ["nearby enemies have cold exposure while you are affected by herald of ice"] = { - mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofIce" }), + mod("EnemyModifier", "LIST", { mod = mod("ColdExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofIce" }), }, ["nearby enemies have lightning exposure while you are affected by herald of thunder"] = { - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofThunder" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "AffectedByHeraldofThunder" }), }, ["i?n?f?l?i?c?t? ?(%a-) exposure on hit if you've cast (.-) in the past (%d+) seconds"] = function (_, exposureType, curse) return { - mod("EnemyModifier", "LIST", { mod = mod(exposureType:gsub("^%l", string.upper).."Exposure", "BASE", -20) }, nil, ModFlag.Hit, { type = "Condition", var = "SelfCast"..curse:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", "") }, { type = "Condition", var = "Effective" }) + mod("EnemyModifier", "LIST", { mod = mod(exposureType:gsub("^%l", string.upper).."Exposure", "BASE", 20) }, nil, ModFlag.Hit, { type = "Condition", var = "SelfCast"..curse:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", "") }, { type = "Condition", var = "Effective" }) } end, ["inflict fire, cold and lightning exposure on nearby enemies when used"] = { - mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", -20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "UsingFlask" }), - 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" }), + mod("EnemyModifier", "LIST", { mod = mod("FireExposure", "BASE", 20) }, { type = "Condition", var = "Effective" }, { type = "Condition", var = "UsingFlask" }), + 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) }), + 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" }), - mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", -20, { type = "Condition", var = "NearLinkedTarget" }) }, { type = "Condition", var = "Effective" }), + 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" }), + mod("EnemyModifier", "LIST", { mod = mod("LightningExposure", "BASE", 20, { type = "Condition", var = "NearLinkedTarget" }) }, { type = "Condition", var = "Effective" }), }, ["inflict (%w+) exposure on hit, applying %-(%d+)%% to (%w+) resistance"] = function(_, element1, num, element2) return { mod( firstToUpper(element1).."ExposureChance", "BASE", 100, { type = "Condition", var = "Effective" }), - mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", -num) }, { type = "Condition", var = "Effective" }), + mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", num) }, { type = "Condition", var = "Effective" }), } end, ["while a unique enemy is in your presence, inflict (%w+) exposure on hit, applying %-(%d+)%% to (%w+) resistance"] = function(_, element1, num, element2) return { mod( firstToUpper(element1).."ExposureChance", "BASE", 100, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }, { type = "Condition", var = "Effective" }), - mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", -num, { type = "Condition", var = "RareOrUnique" }) }, { type = "Condition", var = "Effective" }), + mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", num, { type = "Condition", var = "RareOrUnique" }) }, { type = "Condition", var = "Effective" }), } end, ["while a pinnacle atlas boss is in your presence, inflict (%w+) exposure on hit, applying %-(%d+)%% to (%w+) resistance"] = function(_, element1, num, element2) return { mod( firstToUpper(element1).."ExposureChance", "BASE", 100, { type = "ActorCondition", actor = "enemy", var = "PinnacleBoss" }, { type = "Condition", var = "Effective" }), - mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", -num, { type = "Condition", var = "PinnacleBoss" }) }, { type = "Condition", var = "Effective" }), - } end, - ["fire exposure you inflict applies an extra (%-?%d+)%% to fire resistance"] = function(num) return { mod("ExtraFireExposure", "BASE", num) } end, - ["fire exposure you inflict lowers total fire resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraFireExposure", "BASE", -num) } end, - ["cold exposure you inflict applies an extra (%-?%d+)%% to cold resistance"] = function(num) return { mod("ExtraColdExposure", "BASE", num) } end, - ["cold exposure you inflict lowers total cold resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraColdExposure", "BASE", -num) } end, - ["lightning exposure you inflict applies an extra (%-?%d+)%% to lightning resistance"] = function(num) return { mod("ExtraLightningExposure", "BASE", num) } end, - ["lightning exposure you inflict lowers total lightning resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraLightningExposure", "BASE", -num) } end, - ["exposure you inflict applies at least (%-%d+)%% to the affected resistance"] = function(num) return { mod("ExposureMin", "OVERRIDE", num) } end, + mod("EnemyModifier", "LIST", { mod = mod(firstToUpper(element2).."Exposure", "BASE", num, { type = "Condition", var = "PinnacleBoss" }) }, { type = "Condition", var = "Effective" }), + } end, + ["fire exposure you inflict applies an extra (%-?%d+)%% to fire resistance"] = function(num) return { mod("ExtraFireExposure", "BASE", -num) } end, + ["fire exposure you inflict lowers total fire resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraFireExposure", "BASE", num) } end, + ["cold exposure you inflict applies an extra (%-?%d+)%% to cold resistance"] = function(num) return { mod("ExtraColdExposure", "BASE", -num) } end, + ["cold exposure you inflict lowers total cold resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraColdExposure", "BASE", num) } end, + ["lightning exposure you inflict applies an extra (%-?%d+)%% to lightning resistance"] = function(num) return { mod("ExtraLightningExposure", "BASE", -num) } end, + ["lightning exposure you inflict lowers total lightning resistance by an extra (%d+)%%"] = function(num) return { mod("ExtraLightningExposure", "BASE", num) } end, + ["exposure you inflict applies at least (%-%d+)%% to the affected resistance"] = function(num) return { mod("ExposureMin", "OVERRIDE", -num) } end, ["enemies in your presence gain critical weakness every second"] = { flag("ApplyCriticalWeakness") }, ["every second, inflicts critical weakness on enemies in your presence for %d+ seconds?"] = { flag("ApplyCriticalWeakness") }, ["applies critical weakness to enemies every ([%d%.]+) seconds?"] = { flag("ApplyCriticalWeakness") },