diff --git a/src/Data/Skills/act_int.lua b/src/Data/Skills/act_int.lua index 4fecc8f91e..bcb93233e2 100644 --- a/src/Data/Skills/act_int.lua +++ b/src/Data/Skills/act_int.lua @@ -11063,8 +11063,17 @@ skills["KineticFusillade"] = { local maxEffectiveAPS = 1 / effectiveDelayRounded local maxEffectivePredictiveAPS = 1 / effectiveDelay local currentAPS = output.Speed + -- Network mode is selected in the Configuration tab (defaults to Lockstep) + local isPredictive = activeSkill.skillModList:Flag(activeSkill.skillCfg, "Condition:KineticFusilladePredictive") + local selectedEffectiveAPS = isPredictive and maxEffectivePredictiveAPS or maxEffectiveAPS - output.KineticFusilladeMaxEffectiveAPS = maxEffectiveAPS + output.KineticFusilladeMaxEffectiveAPS = selectedEffectiveAPS + + -- Cap the attack rate so the sidebar Attack Rate and DPS reflect the effective rate + if currentAPS > selectedEffectiveAPS then + output.Speed = selectedEffectiveAPS + output.Time = 1 / selectedEffectiveAPS + end if breakdown then local breakdownAPS = {} @@ -11107,14 +11116,9 @@ skills["KineticFusillade"] = { breakdown.KineticFusilladeMaxEffectiveAPS = breakdownAPS end - -- Adjust dpsMultiplier if attacking too fast (only for "All Projectiles" mode) - if activeSkill.skillPart == 1 then - if currentAPS and currentAPS > maxEffectiveAPS then - local efficiencyRatio = maxEffectiveAPS / currentAPS - local originalMultiplier = skillData.dpsMultiplier or output.ProjectileCount - skillData.dpsMultiplier = originalMultiplier * efficiencyRatio - end - end + -- The stock dpsMultiplier efficiency scaling is disabled: the rate reduction is + -- handled by capping output.Speed above (network-mode aware), so scaling + -- dpsMultiplier here as well would double-count the penalty. end, statMap = { ["kinetic_fusillade_damage_+%_final_per_projectile_fired"] = { @@ -11281,8 +11285,17 @@ skills["KineticFusilladeAltX"] = { local maxEffectiveAPS = 1 / effectiveDelayRounded local maxEffectivePredictiveAPS = 1 / effectiveDelay local currentAPS = output.Speed + -- Network mode is selected in the Configuration tab (defaults to Lockstep) + local isPredictive = activeSkill.skillModList:Flag(activeSkill.skillCfg, "Condition:KineticFusilladePredictive") + local selectedEffectiveAPS = isPredictive and maxEffectivePredictiveAPS or maxEffectiveAPS - output.KineticFusilladeMaxEffectiveAPS = maxEffectiveAPS + output.KineticFusilladeMaxEffectiveAPS = selectedEffectiveAPS + + -- Cap the attack rate so the sidebar Attack Rate and DPS reflect the effective rate + if currentAPS > selectedEffectiveAPS then + output.Speed = selectedEffectiveAPS + output.Time = 1 / selectedEffectiveAPS + end if breakdown then local breakdownAPS = {} @@ -11325,14 +11338,9 @@ skills["KineticFusilladeAltX"] = { breakdown.KineticFusilladeMaxEffectiveAPS = breakdownAPS end - -- Adjust dpsMultiplier if attacking too fast (only for "All Projectiles" mode) - if activeSkill.skillPart == 1 then - if currentAPS and currentAPS > maxEffectiveAPS then - local efficiencyRatio = maxEffectiveAPS / currentAPS - local originalMultiplier = skillData.dpsMultiplier or output.ProjectileCount - skillData.dpsMultiplier = originalMultiplier * efficiencyRatio - end - end + -- The stock dpsMultiplier efficiency scaling is disabled: the rate reduction is + -- handled by capping output.Speed above (network-mode aware), so scaling + -- dpsMultiplier here as well would double-count the penalty. end, statMap = { ["kinetic_fusillade_damage_+%_final_per_projectile_fired"] = { diff --git a/src/Export/Skills/act_int.txt b/src/Export/Skills/act_int.txt index 4c74613249..19d7d4c1d5 100644 --- a/src/Export/Skills/act_int.txt +++ b/src/Export/Skills/act_int.txt @@ -2345,11 +2345,21 @@ local skills, mod, flag, skill = ... local maxEffectiveAPS = 1 / effectiveDelayRounded local maxEffectivePredictiveAPS = 1 / effectiveDelay local currentAPS = output.Speed + -- Network mode is selected in the Configuration tab (defaults to Lockstep) + local isPredictive = activeSkill.skillModList:Flag(activeSkill.skillCfg, "Condition:KineticFusilladePredictive") + local selectedEffectiveAPS = isPredictive and maxEffectivePredictiveAPS or maxEffectiveAPS - output.KineticFusilladeMaxEffectiveAPS = maxEffectiveAPS + output.KineticFusilladeMaxEffectiveAPS = selectedEffectiveAPS + + -- Cap the attack rate so the sidebar Attack Rate and DPS reflect the effective rate + if currentAPS > selectedEffectiveAPS then + output.Speed = selectedEffectiveAPS + output.Time = 1 / selectedEffectiveAPS + end if breakdown then local breakdownAPS = {} + t_insert(breakdownAPS, s_format("^8Selected network mode (Configuration tab):^7 %s", isPredictive and "Predictive" or "Lockstep")) t_insert(breakdownAPS, s_format("^8Base hover delay:^7 %.1fs", hoverDelay)) t_insert(breakdownAPS, s_format("^8Base delay between projectiles:^7 %.2fs", baseDelayBetweenProjectiles)) t_insert(breakdownAPS, s_format("^8Base time for^7 %d added ^8projectiles:^7 %.2fs x %d = %.1fs", (projectileCount - 1), baseDelayBetweenProjectiles, (projectileCount - 1), baseTimeForAllProjectiles)) @@ -2389,14 +2399,9 @@ local skills, mod, flag, skill = ... breakdown.KineticFusilladeMaxEffectiveAPS = breakdownAPS end - -- Adjust dpsMultiplier if attacking too fast (only for "All Projectiles" mode) - if activeSkill.skillPart == 1 then - if currentAPS and currentAPS > maxEffectiveAPS then - local efficiencyRatio = maxEffectiveAPS / currentAPS - local originalMultiplier = skillData.dpsMultiplier or output.ProjectileCount - skillData.dpsMultiplier = originalMultiplier * efficiencyRatio - end - end + -- The stock dpsMultiplier efficiency scaling is disabled: the rate reduction is + -- handled by capping output.Speed above (network-mode aware), so scaling + -- dpsMultiplier here as well would double-count the penalty. end, statMap = { ["kinetic_fusillade_damage_+%_final_per_projectile_fired"] = { @@ -2487,11 +2492,21 @@ local skills, mod, flag, skill = ... local maxEffectiveAPS = 1 / effectiveDelayRounded local maxEffectivePredictiveAPS = 1 / effectiveDelay local currentAPS = output.Speed + -- Network mode is selected in the Configuration tab (defaults to Lockstep) + local isPredictive = activeSkill.skillModList:Flag(activeSkill.skillCfg, "Condition:KineticFusilladePredictive") + local selectedEffectiveAPS = isPredictive and maxEffectivePredictiveAPS or maxEffectiveAPS - output.KineticFusilladeMaxEffectiveAPS = maxEffectiveAPS + output.KineticFusilladeMaxEffectiveAPS = selectedEffectiveAPS + + -- Cap the attack rate so the sidebar Attack Rate and DPS reflect the effective rate + if currentAPS > selectedEffectiveAPS then + output.Speed = selectedEffectiveAPS + output.Time = 1 / selectedEffectiveAPS + end if breakdown then local breakdownAPS = {} + t_insert(breakdownAPS, s_format("^8Selected network mode (Configuration tab):^7 %s", isPredictive and "Predictive" or "Lockstep")) t_insert(breakdownAPS, s_format("^8Base hover delay:^7 %.1fs", hoverDelay)) t_insert(breakdownAPS, s_format("^8Base delay between projectiles:^7 %.2fs", baseDelayBetweenProjectiles)) t_insert(breakdownAPS, s_format("^8Base time for^7 %d added ^8projectiles:^7 %.2fs x %d = %.1fs", (projectileCount - 1), baseDelayBetweenProjectiles, (projectileCount - 1), baseTimeForAllProjectiles)) @@ -2531,14 +2546,9 @@ local skills, mod, flag, skill = ... breakdown.KineticFusilladeMaxEffectiveAPS = breakdownAPS end - -- Adjust dpsMultiplier if attacking too fast (only for "All Projectiles" mode) - if activeSkill.skillPart == 1 then - if currentAPS and currentAPS > maxEffectiveAPS then - local efficiencyRatio = maxEffectiveAPS / currentAPS - local originalMultiplier = skillData.dpsMultiplier or output.ProjectileCount - skillData.dpsMultiplier = originalMultiplier * efficiencyRatio - end - end + -- The stock dpsMultiplier efficiency scaling is disabled: the rate reduction is + -- handled by capping output.Speed above (network-mode aware), so scaling + -- dpsMultiplier here as well would double-count the penalty. end, statMap = { ["kinetic_fusillade_damage_+%_final_per_projectile_fired"] = { diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index e77099db2d..3cb71ef08e 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -501,6 +501,12 @@ return { { var = "OverloadedIntensity", type = "count", label = "# of Overloaded Intensity:", ifSkill = "Overloaded Intensity", apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:OverloadedIntensity", "BASE", m_min(val, 3), "Config") end }, + { label = "Kinetic Fusillade:", ifSkill = { "Kinetic Fusillade", "Kinetic Fusillade of Detonation" } }, + { var = "kineticFusilladeNetworkMode", type = "list", label = "Network mode:", ifSkill = { "Kinetic Fusillade", "Kinetic Fusillade of Detonation" }, tooltip = "Selects the network mode used to calculate the maximum effective attack rate:\n\tLockstep: projectile fire delay is rounded up to server ticks\n\tPredictive: no server tick rounding\nThe summary Attack Rate and DPS are capped at the effective rate.", list = {{val="LOCKSTEP",label="Lockstep"},{val="PREDICTIVE",label="Predictive"}}, apply = function(val, modList, enemyModList) + if val == "PREDICTIVE" then + modList:NewMod("Condition:KineticFusilladePredictive", "FLAG", true, "Config") + end + end }, { label = "Link Skills:", ifSkill = { "Destructive Link", "Flame Link", "Intuitive Link", "Protective Link", "Soul Link", "Vampiric Link" } }, { var = "multiplierLinkedTargets", type = "count", label = "# of linked Targets:", ifSkill = { "Destructive Link", "Flame Link", "Intuitive Link", "Protective Link", "Soul Link", "Vampiric Link" }, apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:LinkedTargets", "BASE", val, "Config")