From 04dadccec426788a5e59b3829aa0eaa8a82dddb4 Mon Sep 17 00:00:00 2001 From: PJacek Date: Tue, 16 Sep 2025 16:52:17 +0200 Subject: [PATCH 1/2] Add support for movement speed penalty from using skills --- src/Data/ModCache.lua | 9 ++++----- src/Data/SkillStatMap.lua | 3 +++ src/Modules/CalcOffence.lua | 19 +++++++++++++++++++ src/Modules/CalcSections.lua | 3 ++- src/Modules/ModParser.lua | 1 + 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 911562ffd..2e3e1dde0 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -1184,7 +1184,7 @@ c["10% reduced Intelligence"]={{[1]={flags=0,keywordFlags=0,name="Int",type="INC c["10% reduced Light Radius"]={{[1]={flags=0,keywordFlags=0,name="LightRadius",type="INC",value=-10}},nil} c["10% reduced Magnitude of Ignite on you"]={{[1]={flags=0,keywordFlags=0,name="SelfIgniteEffect",type="INC",value=-10}},nil} c["10% reduced Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-10}},nil} -c["10% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-10}}," Penalty from using Skills "} +c["10% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="INC",value=-10}},nil} c["10% reduced Movement Speed Penalty while Actively Blocking"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-10}}," Penalty ly Blocking "} c["10% reduced Poison Duration on you"]={{[1]={flags=0,keywordFlags=0,name="SelfPoisonDuration",type="INC",value=-10}},nil} c["10% reduced Projectile Speed"]={{[1]={flags=0,keywordFlags=0,name="ProjectileSpeed",type="INC",value=-10}},nil} @@ -1344,7 +1344,7 @@ c["12% increased amount of Life Leeched"]={{[1]={flags=0,keywordFlags=0,name="Ma c["12% increased chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="INC",value=12}},nil} c["12% increased maximum Energy Shield"]={{[1]={[1]={type="Global"},flags=0,keywordFlags=0,name="EnergyShield",type="INC",value=12}},nil} c["12% of Damage is taken from Mana before Life"]={{[1]={flags=0,keywordFlags=0,name="DamageTakenFromManaBeforeLife",type="BASE",value=12}},nil} -c["12% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-12}}," Penalty from using Skills "} +c["12% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="INC",value=-12}},nil} c["12.5 Life Regeneration per second"]={{[1]={flags=0,keywordFlags=0,name="LifeRegen",type="BASE",value=12.5}},nil} c["120% increased Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="INC",value=120}},nil} c["120% increased Armour and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEnergyShield",type="INC",value=120}},nil} @@ -2197,7 +2197,7 @@ c["3% of Physical Damage taken Recouped as Life"]={{[1]={flags=0,keywordFlags=0, c["3% of Skill Mana Costs Converted to Life Costs"]={{[1]={flags=0,keywordFlags=0,name="HybridManaAndLifeCost_Life",type="BASE",value=3}},nil} c["3% reduced Accuracy Rating per 25 Tribute"]={{[1]={[1]={actor="parent",div=25,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="Accuracy",type="INC",value=-3}},nil} c["3% reduced Area of Effect"]={{[1]={flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=-3}},nil} -c["3% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-3}}," Penalty from using Skills "} +c["3% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="INC",value=-3}},nil} c["3% reduced maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="INC",value=-3}},nil} c["30 Life Regeneration per second"]={{[1]={flags=0,keywordFlags=0,name="LifeRegen",type="BASE",value=30}},nil} c["30 to 40 Physical Thorns damage"]={{[1]={flags=0,keywordFlags=0,name="ThornsDamage",type="BASE",value=30}}," to 40 Physical "} @@ -3072,8 +3072,7 @@ c["8% of Damage is taken from Mana before Life"]={{[1]={flags=0,keywordFlags=0,n c["8% of Damage taken Recouped as Life"]={{[1]={flags=0,keywordFlags=0,name="LifeRecoup",type="BASE",value=8}},nil} c["8% of Spell Mana Cost Converted to Life Cost"]={{[1]={[1]={skillType=2,type="SkillType"},flags=0,keywordFlags=0,name="HybridManaAndLifeCost_Life",type="BASE",value=8}},nil} c["8% reduced Area of Effect"]={{[1]={flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=-8}},nil} -c["8% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-8}}," Penalty from using Skills "} -c["8% reduced Movement Speed Penalty from using Skills while moving 14% increased Skill Effect Duration"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=-8}}," Penalty from using Skills 14% increased Skill Effect Duration "} +c["8% reduced Movement Speed Penalty from using Skills while moving"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="INC",value=-8}},nil} c["8% reduced Skill Effect Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=-8}},nil} c["8% reduced Slowing Potency of Debuffs on You"]={{}," Slowing Potency of Debuffs on You "} c["80% chance to Avoid being Chilled"]={{[1]={flags=0,keywordFlags=0,name="AvoidChill",type="BASE",value=80}},nil} diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 8394cbbda..6d7c1029a 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -324,6 +324,9 @@ return { ["hazard_rearm_%_chance"] = { mod("HazardRearmChance", "BASE", nil, 0, 0, { type = "SkillType", skillType = SkillType.Hazard } ), }, +["movement_speed_+%_final_while_performing_action"] = { + mod("SkillMovementSpeed", "MORE", nil), +}, -- -- Defensive modifiers -- diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 1c24a59e3..55c6f5518 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2928,6 +2928,25 @@ function calcs.offence(env, actor, activeSkill) output.QuantityMultiplier = quantityMultiplier end + do + local penaltyMod = m_max((100 + activeSkill.skillModList:Sum("INC", nil, "MovementSpeedPenalty")), 0) / 100 + local base = activeSkill.skillModList:More(activeSkill.skillCfg, "SkillMovementSpeed") or 0 + local total = (1 - base) * penaltyMod + output.MovementSpeedWhileUsingSkill = (1 - total) * output.MovementSpeedMod + if breakdown then + breakdown.MovementSpeedWhileUsingSkill = { + "Minimum Movement Speed while using this skill", + "^8(This is the lowest movement speed you will reach while using this skill,", + "^8subject to acceleration and deceleration)", + s_format("1 - (%.2f ^8(movement speed penalty from using skill)", 1 - base), + s_format("x %.2f) ^8(increased/reduced penalty)", penaltyMod), + s_format("= %.2f", 1 - total), + s_format("x %.2f ^8(movement speed modifier)", output.MovementSpeedMod), + s_format("= %.2f", output.MovementSpeedWhileUsingSkill), + } + end + end + --Calculate damage (exerts, crits, ruthless, DPS, etc) for _, pass in ipairs(passList) do globalOutput, globalBreakdown = output, breakdown diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index e237c3af4..db5106504 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -1426,7 +1426,8 @@ return { { label = "Enemy Life Recovery", haveOutput = "EnemyLifeRegen", { format = "{0:output:EnemyLifeRegen}%", { modName = "LifeRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy Mana Recovery", haveOutput = "EnemyManaRegen", { format = "{0:output:EnemyManaRegen}%", { modName = "ManaRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy ES Recovery", haveOutput = "EnemyEnergyShieldRegen", { format = "{0:output:EnemyEnergyShieldRegen}%", { modName = "EnergyShieldRegen", modType = "INC", enemy = true }, }, }, -} } + { label = "MS While Casting", { format = "{2:output:MovementSpeedWhileUsingSkill}", { breakdown = "MovementSpeedWhileUsingSkill" }, { modName = { "SkillMovementSpeed", "MovementSpeedPenalty" }, cfg = "skill" }, }, }, + } } } }, -- attributes/resists { 1, "Attributes", 2, colorCodes.NORMAL, {{ defaultCollapsed = false, label = "Attributes", data = { diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index b6fee1557..328540ef5 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -5696,6 +5696,7 @@ local specialModList = { ["attacks have added maximum lightning damage equal to (%d+)%% of maximum mana"] = function(num) return { mod("LightningMax", "BASE", 1, { type = "PercentStat", stat = "Mana" , percent = num }, { type = "SkillType", skillType = SkillType.Attack }), } end, + ["(%d+)%% reduced movement speed penalty from using skills while moving"] = function(num) return { mod("MovementSpeedPenalty", "INC", -num) } end, -- Conditional Player Quantity / Rarity ["(%d+)%% increased quantity of items dropped by slain normal enemies"] = function(num) return { mod("LootQuantityNormalEnemies", "INC", num) } end, ["(%d+)%% increased rarity of items dropped by slain magic enemies"] = function(num) return { mod("LootRarityMagicEnemies", "INC", num) } end, From d504f29c23559e36156fad7c469c3685173fada6 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 17 Sep 2025 05:10:14 +1000 Subject: [PATCH 2/2] Change breakdown + add more mods Adds mods from the 2 support gems that affect movement speed Adds supportf or the Pathfinder node Change breakdown to show % of base movement speed --- src/Data/ModCache.lua | 2 +- src/Data/SkillStatMap.lua | 6 ++++++ src/Modules/BuildDisplayStats.lua | 1 + src/Modules/CalcOffence.lua | 22 ++++++++++++++-------- src/Modules/CalcSections.lua | 4 ++-- src/Modules/ModParser.lua | 1 + 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 2e3e1dde0..5afdb18f4 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2805,7 +2805,7 @@ c["50% less Life Recovery from Flasks"]={{[1]={flags=0,keywordFlags=0,name="Flas c["50% less Lightning Resistance"]={{[1]={flags=0,keywordFlags=0,name="LightningResist",type="MORE",value=-50}},nil} c["50% less Mana Recovery Rate"]={{[1]={flags=0,keywordFlags=0,name="ManaRecoveryRate",type="MORE",value=-50}},nil} c["50% less Mana Regeneration Rate"]={{[1]={flags=0,keywordFlags=0,name="ManaRegen",type="MORE",value=-50}},nil} -c["50% less Movement Speed Penalty from using Skills while moving"]={{[1]={[1]={type="Condition",var="Moving"},flags=0,keywordFlags=0,name="MovementSpeed",type="MORE",value=-50}}," Penalty from using Skills "} +c["50% less Movement Speed Penalty from using Skills while moving"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeedPenalty",type="MORE",value=-50}},nil} c["50% more Armour from Equipped Body Armour"]={{[1]={[1]={slotName="Body Armour",type="SlotName"},flags=0,keywordFlags=0,name="Armour",type="MORE",value=50}},nil} c["50% more Critical Damage Bonus"]={{[1]={flags=0,keywordFlags=0,name="CritMultiplier",type="MORE",value=50}},nil} c["50% more Damage against Heavy Stunned Enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="HeavyStunned"},flags=0,keywordFlags=0,name="Damage",type="MORE",value=50}},nil} diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 6d7c1029a..0246f8903 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -327,6 +327,12 @@ return { ["movement_speed_+%_final_while_performing_action"] = { mod("SkillMovementSpeed", "MORE", nil), }, +["support_mobility_movement_speed_penalty_+%_final_while_performing_action"] = { + mod("MovementSpeedPenalty", "MORE", nil), +}, +["support_deliberation_movement_speed_penalty_+%_final_while_performing_action"] = { + mod("MovementSpeedPenalty", "MORE", nil), +}, -- -- Defensive modifiers -- diff --git a/src/Modules/BuildDisplayStats.lua b/src/Modules/BuildDisplayStats.lua index 0d2c19a82..4e2d3986d 100644 --- a/src/Modules/BuildDisplayStats.lua +++ b/src/Modules/BuildDisplayStats.lua @@ -188,6 +188,7 @@ local displayStats = { { label = "Chaos Resistance", val = "Immune", labelStat = "ChaosResist", color = colorCodes.CHAOS, condFunc = function(o) return o.ChaosInoculation end }, { }, { stat = "EffectiveMovementSpeedMod", label = "Movement Speed Modifier", fmt = "+.1f%%", mod = true, condFunc = function() return true end }, + { stat = "MovementSpeedWhileUsingSkill", label = "Skill Movement Speed", fmt = "+.1f%%", mod = true, condFunc = function() return true end }, { }, { stat = "PresenceRadiusMetres", label = "Presence Radius", fmt = ".1fm", compPercent = true }, --[[ potentially useful mods diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 55c6f5518..abda65e4f 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2928,21 +2928,27 @@ function calcs.offence(env, actor, activeSkill) output.QuantityMultiplier = quantityMultiplier end - do - local penaltyMod = m_max((100 + activeSkill.skillModList:Sum("INC", nil, "MovementSpeedPenalty")), 0) / 100 - local base = activeSkill.skillModList:More(activeSkill.skillCfg, "SkillMovementSpeed") or 0 + if activeSkill.skillTypes[SkillType.UsableWhileMoving] then + local inc = skillModList:Sum("INC", skillCfg, "MovementSpeedPenalty") + local more = skillModList:More(skillCfg, "MovementSpeedPenalty") + local penaltyMod = m_max(0, skillModList:Override(skillCfg, "MovementSpeedPenalty") or (1 + inc / 100) * more) + local base = calcLib.mod(skillModList, skillCfg, "SkillMovementSpeed") local total = (1 - base) * penaltyMod output.MovementSpeedWhileUsingSkill = (1 - total) * output.MovementSpeedMod + output.MovementSpeedWhileUsingSkillPercent = (1 - total) * 100 if breakdown then breakdown.MovementSpeedWhileUsingSkill = { "Minimum Movement Speed while using this skill", "^8(This is the lowest movement speed you will reach while using this skill,", "^8subject to acceleration and deceleration)", - s_format("1 - (%.2f ^8(movement speed penalty from using skill)", 1 - base), - s_format("x %.2f) ^8(increased/reduced penalty)", penaltyMod), - s_format("= %.2f", 1 - total), - s_format("x %.2f ^8(movement speed modifier)", output.MovementSpeedMod), - s_format("= %.2f", output.MovementSpeedWhileUsingSkill), + "", + s_format("%d%% ^8(movement speed penalty from using skill)", 100 - base * 100), + s_format("x %.2f) ^8(increased/reduced penalty)", 1 + inc / 100), + s_format("x %.2f) ^8(more/less penalty)", more), + s_format("= %.1f%% ^8(movement speed penalty)", 100 - output.MovementSpeedWhileUsingSkillPercent), + s_format(""), + s_format("100%% - %.1f%% ^8(100 - movement speed penalty)", 100 - output.MovementSpeedWhileUsingSkillPercent), + s_format("= %.1f%% ^8(movement speed while casting)", output.MovementSpeedWhileUsingSkillPercent), } end end diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index db5106504..3fde85108 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -1426,8 +1426,8 @@ return { { label = "Enemy Life Recovery", haveOutput = "EnemyLifeRegen", { format = "{0:output:EnemyLifeRegen}%", { modName = "LifeRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy Mana Recovery", haveOutput = "EnemyManaRegen", { format = "{0:output:EnemyManaRegen}%", { modName = "ManaRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy ES Recovery", haveOutput = "EnemyEnergyShieldRegen", { format = "{0:output:EnemyEnergyShieldRegen}%", { modName = "EnergyShieldRegen", modType = "INC", enemy = true }, }, }, - { label = "MS While Casting", { format = "{2:output:MovementSpeedWhileUsingSkill}", { breakdown = "MovementSpeedWhileUsingSkill" }, { modName = { "SkillMovementSpeed", "MovementSpeedPenalty" }, cfg = "skill" }, }, }, - } } + { label = "MS While Casting", { format = "{1:output:MovementSpeedWhileUsingSkillPercent}%", { breakdown = "MovementSpeedWhileUsingSkill" }, { modName = { "SkillMovementSpeed", "MovementSpeedPenalty" }, cfg = "skill" }, }, }, +} } } }, -- attributes/resists { 1, "Attributes", 2, colorCodes.NORMAL, {{ defaultCollapsed = false, label = "Attributes", data = { diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 328540ef5..7f72519ef 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -5697,6 +5697,7 @@ local specialModList = { mod("LightningMax", "BASE", 1, { type = "PercentStat", stat = "Mana" , percent = num }, { type = "SkillType", skillType = SkillType.Attack }), } end, ["(%d+)%% reduced movement speed penalty from using skills while moving"] = function(num) return { mod("MovementSpeedPenalty", "INC", -num) } end, + ["(%d+)%% less movement speed penalty from using skills while moving"] = function(num) return { mod("MovementSpeedPenalty", "MORE", -num) } end, -- Conditional Player Quantity / Rarity ["(%d+)%% increased quantity of items dropped by slain normal enemies"] = function(num) return { mod("LootQuantityNormalEnemies", "INC", num) } end, ["(%d+)%% increased rarity of items dropped by slain magic enemies"] = function(num) return { mod("LootRarityMagicEnemies", "INC", num) } end,