diff --git a/spec/System/TestExposureSource_spec.lua b/spec/System/TestExposureSource_spec.lua new file mode 100644 index 0000000000..3b5b092b6d --- /dev/null +++ b/spec/System/TestExposureSource_spec.lua @@ -0,0 +1,56 @@ +describe("ExposureSource", function() + before_each(function() + newBuild() + end) + + local function equipWhisperingIce() + build.itemsTab:CreateDisplayItemFromRaw([[ + New Item + Permafrost Staff + Implicits: 0 + Inflict Elemental Exposure on Hit, lowering Total Elemental Resistances by 60% + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + end + + local function canApply(element) + return build.calcsTab.calcsEnv.modDB:Flag(nil, "Condition:CanApply" .. element .. "Exposure") == true + end + + local function enemyResist(element) + return build.calcsTab.calcsEnv.enemyDB:Sum("BASE", nil, element .. "Resist") + end + + it("counts exposure granted directly to the enemy as a source", function() + equipWhisperingIce() + + -- Without this the enemy is exposed while the build is told it cannot + -- expose, which hides the "Is the enemy Exposed" config entirely. + assert.is_true(build.calcsTab.calcsEnv.enemyDB:Flag(nil, "Condition:HasFireExposure") == true) + for _, element in ipairs({ "Fire", "Cold", "Lightning" }) do + assert.is_true(canApply(element)) + end + end) + + it("does not report a source when nothing grants exposure", function() + runCallback("OnFrame") + + for _, element in ipairs({ "Fire", "Cold", "Lightning" }) do + assert.is_false(canApply(element)) + end + end) + + it("keeps the largest exposure when the config is also enabled", function() + equipWhisperingIce() + local itemOnly = enemyResist("Fire") + + build.configTab.input.conditionEnemyFireExposure = true + build.configTab:BuildModList() + runCallback("OnFrame") + + -- Exposure does not stack: the -20% from the config must not add to the + -- -60% from the item. + assert.are.equals(itemOnly, enemyResist("Fire")) + end) +end) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index dbc4bb9767..bd0058197a 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -431,6 +431,12 @@ local function doActorAttribsConditions(env, actor) if modDB:Sum("BASE", nil, modName) > 0 or modDB:HasMod("FLAG", nil, "InflictExposure") then return true end + -- Exposure granted straight to the enemy, as The Whispering Ice and + -- "Enemies in your Presence have Exposure" do, carries no chance mod + -- and no InflictExposure flag, so it has to be read off the enemy. + if env.enemy and env.enemy.modDB and env.enemy.modDB:Sum("BASE", nil, element .. "Exposure") > 0 then + return true + end for _, activeSkill in ipairs(env.player.activeSkillList) do if hasActiveSkillExposureSource(activeSkill, modName) then return true