diff --git a/spec/System/TestItemMods_spec.lua b/spec/System/TestItemMods_spec.lua index 766c6f45fe..f49b1e7c70 100644 --- a/spec/System/TestItemMods_spec.lua +++ b/spec/System/TestItemMods_spec.lua @@ -553,4 +553,36 @@ describe("TetsItemMods", function() assert.are_not.equals(64, build.calcsTab.mainOutput.Armour) runCallback("OnFrame") end) + + it("Heralds apply exposure with Heraldry", function() + build.skillsTab:PasteSocketGroup("Arc 20/0 Default 1\nHerald of Thunder 20/0 Default 1\n") + runCallback("OnFrame") + + assert.are.equals(0.5, build.calcsTab.calcsOutput.LightningEffMult) + + build.configTab.input.customMods = [[ + Nearby Enemies have Cold Exposure while you are affected by Herald of Ice + Nearby Enemies have Fire Exposure while you are affected by Herald of Ash + Nearby Enemies have Lightning Exposure while you are affected by Herald of Thunder + ]] + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(0.6, build.calcsTab.calcsOutput.LightningEffMult) + end) + + it("Enemy self curse effect", function() + build.skillsTab:PasteSocketGroup("Arc 20/0 Default 1\nConductivity 14/0 Default 1\n") + runCallback("OnFrame") + + assert.are.equals(0.8, build.calcsTab.calcsOutput.LightningEffMult) + + build.configTab.input.customMods = [[ + Nearby Enemies have 20% increased Effect of Curses on them + ]] + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(0.86, build.calcsTab.calcsOutput.LightningEffMult) + end) end) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 0449608b3f..f89a46b773 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -565,10 +565,19 @@ local function determineCursePriority(curseName, activeSkill) return basePriority + socketPriority + slotPriority + sourcePriority end -local function applyEnemyModifiers(actor) - -- Process enemy modifiers +local function applyEnemyModifiers(actor, clearCache) + if clearCache or not actor.appliedEnemyModifiers then + actor.appliedEnemyModifiers = { } + end + local cache = actor.appliedEnemyModifiers + local enemyDB = actor.enemy.modDB for _, value in ipairs(actor.modDB:Tabulate(nil, nil, "EnemyModifier")) do - actor.enemy.modDB:AddMod(modLib.setSource(value.value.mod, value.value.mod.source or value.mod.source)) + local mod = value.value and value.value.mod + if mod and not cache[mod] then + local source = mod.source or value.mod.source + enemyDB:AddMod(modLib.setSource(mod, source)) + cache[mod] = true + end end end @@ -579,6 +588,9 @@ local function doActorMisc(env, actor) local output = actor.output local condList = modDB.conditions + -- Process enemy modifiers + applyEnemyModifiers(actor) + -- Add misc buffs/debuffs if env.mode_combat then if env.player.mainSkill.baseSkillModList:Flag(nil, "Cruelty") then @@ -1170,11 +1182,11 @@ function calcs.perform(env, skipEHP) output.WarcryPower = modDB:Override(nil, "WarcryPower") or modDB:Sum("BASE", nil, "WarcryPower") or 0 modDB.multipliers["WarcryPower"] = output.WarcryPower - applyEnemyModifiers(env.player) + applyEnemyModifiers(env.player, true) if env.minion then - applyEnemyModifiers(env.minion) + applyEnemyModifiers(env.minion, true) end - applyEnemyModifiers(env.enemy) + applyEnemyModifiers(env.enemy, true) for _, activeSkill in ipairs(env.player.activeSkillList) do if activeSkill.skillTypes[SkillType.Brand] then