From 8b8d651a6e55b416cb46a32eb6ce5a40ee34daaf Mon Sep 17 00:00:00 2001 From: unrealdreamz <132005717+unrealdreamz@users.noreply.github.com> Date: Mon, 18 May 2026 21:14:46 -0400 Subject: [PATCH] Scale Vile Effusion by Chaos DoT debuffs --- spec/System/TestSkills_spec.lua | 53 ++++++++++++++++++++++++++++++++- src/Modules/CalcOffence.lua | 35 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index 3afa41ce0..5aa681057 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -238,6 +238,57 @@ describe("TestSkills", function() assert.True(curseList:match("Flammability") ~= nil and curseList:match("Elemental Weakness") ~= nil) end) + it("Dark Effigy scales Vile Effusion with Chaos DoT debuffs", function() + build.skillsTab:PasteSocketGroup("Dark Effigy 20/0 1") + runCallback("OnFrame") + + local noDebuffOutput = build.calcsTab.mainOutput.Minion + assert.True(noDebuffOutput ~= nil) + assert.are.equals(0, noDebuffOutput.ProjectileCount) + assert.are.equals(0, noDebuffOutput.TotalDPS or 0) + + build.skillsTab:PasteSocketGroup("Contagion 20/0 1") + runCallback("OnFrame") + + local oneDebuffOutput = build.calcsTab.mainOutput.Minion + assert.are.equals(1, oneDebuffOutput.ProjectileCount) + assert.True(oneDebuffOutput.TotalDPS > 0) + local oneDebuffDPS = oneDebuffOutput.TotalDPS + + build.skillsTab:PasteSocketGroup("Essence Drain 20/0 1") + runCallback("OnFrame") + + local twoDebuffOutput = build.calcsTab.mainOutput.Minion + assert.are.equals(2, twoDebuffOutput.ProjectileCount) + assert.True(twoDebuffOutput.TotalDPS > oneDebuffDPS * 1.9) + local twoDebuffDPS = twoDebuffOutput.TotalDPS + + build.skillsTab:PasteSocketGroup("Temporal Chains 20/0 1\nDecaying Hex 1/0 1") + runCallback("OnFrame") + + local decayingHexOutput = build.calcsTab.mainOutput.Minion + assert.are.equals(3, decayingHexOutput.ProjectileCount) + assert.True(decayingHexOutput.TotalDPS > twoDebuffDPS * 1.4) + local decayingHexDPS = decayingHexOutput.TotalDPS + + build.skillsTab:PasteSocketGroup("Essence Drain 20/0 1\nPoison I 1/0 1") + runCallback("OnFrame") + + local poisonSupportOutput = build.calcsTab.mainOutput.Minion + assert.are.equals(4, poisonSupportOutput.ProjectileCount) + assert.True(poisonSupportOutput.TotalDPS > decayingHexDPS * 1.3) + local poisonSupportDPS = poisonSupportOutput.TotalDPS + + build.configTab.input.conditionEnemyPoisoned = true + build.configTab:BuildModList() + runCallback("OnFrame") + + local poisonedOutput = build.calcsTab.mainOutput.Minion + assert.are.equals(4, poisonedOutput.ProjectileCount) + assert.True(poisonedOutput.TotalDPS > poisonSupportDPS * 0.99) + assert.True(poisonedOutput.TotalDPS < poisonSupportDPS * 1.01) + end) + -- skills that don't have a base CD and have more than one use need to use the added cooldown by whatever support allows the +1 limit to be supportable it("Test Added Cooldown interaction with +1 Limit", function() build.skillsTab:PasteSocketGroup("Thunderstorm 20/0 1\nHourglass 1/0 1\nOverabundance I 1/0 1\n") @@ -245,4 +296,4 @@ describe("TestSkills", function() assert.True(build.calcsTab.calcsOutput.Cooldown == 10) end) -end) \ No newline at end of file +end) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index abf822011..8895cc015 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -65,6 +65,36 @@ end }) local globalOutput = nil local globalBreakdown = nil +local function isActiveSkillDisabled(env, activeSkill) + local statSet = env.mode == "CALCS" and activeSkill.activeEffect.statSetCalcs or activeSkill.activeEffect.statSet + return statSet and statSet.skillFlags and statSet.skillFlags.disable +end + +local function countActiveChaosDotDebuffs(env, enemyDB, currentActiveSkill) + local count = 0 + local hasPoisonDebuff = enemyDB:GetCondition("Poisoned") + local countedSkills = { } + for _, activeSkill in ipairs(env.player.activeSkillList) do + if activeSkill ~= currentActiveSkill and not isActiveSkillDisabled(env, activeSkill) then + local skillName = activeSkill.activeEffect.grantedEffect.name + local skillData = activeSkill.skillData or { } + local isChaosDotSkill = (activeSkill.skillTypes[SkillType.Chaos] and activeSkill.skillTypes[SkillType.DamageOverTime]) + or skillData.ChaosDot or skillData.decay + if not countedSkills[skillName] and isChaosDotSkill then + countedSkills[skillName] = true + count = count + 1 + end + if not hasPoisonDebuff and activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "PoisonChance", "ChaosPoisonChance") > 0 then + hasPoisonDebuff = true + end + end + end + if hasPoisonDebuff then + count = count + 1 + end + return count +end + local function calcConvertedDamage(activeSkill, output, cfg, damageType) local skillModList = activeSkill.skillModList -- Calculate conversions @@ -1247,6 +1277,11 @@ function calcs.offence(env, actor, activeSkill) local projMore = skillModList:More(skillCfg, "ProjectileCount") output.ProjectileCount = projBase * projMore end + if activeSkill.activeEffect.grantedEffect.name == "Vile Effusion" then + local chaosDotDebuffs = countActiveChaosDotDebuffs(env, enemyDB, activeSkill) + output.ProjectileCount = chaosDotDebuffs + skillModList:NewMod("DPS", "MORE", (chaosDotDebuffs - 1) * 100, "Vile Effusion") + end if skillModList:Flag(skillCfg, "AdditionalProjectilesAddBouncesInstead") then local projBase = skillModList:Sum("BASE", skillCfg, "ProjectileCount") + 2 * skillModList:Sum("BASE", skillCfg, "TwoAdditionalProjectilesChance") / 100 + skillModList:Sum("BASE", skillCfg, "SurpassingProjectileChance") / 100 + skillModList:Sum("BASE", skillCfg, "BounceCount") - 1 local projMore = skillModList:More(skillCfg, "ProjectileCount")