From 0a63c72c4cdd4092632579f1e90c490ab1957f65 Mon Sep 17 00:00:00 2001 From: andyli00 Date: Sun, 19 Jan 2025 22:39:21 -0500 Subject: [PATCH 1/3] add average ball overlap calcs for molten strike --- src/Data/Skills/act_str.lua | 72 +++++++++++++++++++++++++++++++---- src/Modules/ConfigOptions.lua | 6 +-- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 3da344b332..1ab8cc8eb4 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -6975,10 +6975,68 @@ skills["MoltenStrike"] = { projectile = true, area = true, }, + { + name = "Average Balls Hitting", + melee = false, + projectile = true, + area = true, + }, }, + preDamageFunc = function(activeSkill, output, breakdown) + local skillCfg = activeSkill.skillCfg + local skillData = activeSkill.skillData + local skillPart = activeSkill.skillPart + local skillModList = activeSkill.skillModList + local t_insert = table.insert + local s_format = string.format + + -- melee part doesnt need to calc balls + if skillPart == 1 then + return + end + + local enemyRadius = skillModList:Override(skillCfg, "EnemyRadius") or skillModList:Sum("BASE", skillCfg, "EnemyRadius") + local ballRadius = output.AreaOfEffectRadius + local innerRadius = output.AreaOfEffectRadiusSecondary + local outerRadius = output.AreaOfEffectRadiusTertiary + + -- logic adapted from MoldyDwarf's calculator + local hitRange = enemyRadius + ballRadius - innerRadius + local landingRange = outerRadius - innerRadius + local overlapChance = math.min(1, hitRange / landingRange) + output.OverlapChance = overlapChance * 100 + + if breakdown then + breakdown.OverlapChance = { } + t_insert(breakdown.OverlapChance, "Chance for individual balls to land on the enemy:") + t_insert(breakdown.OverlapChance, "^8= (area where a ball can land on enemy) / (total area)") + t_insert(breakdown.OverlapChance, "^8= (enemy radius + ball radius - min travel) / (max travel - min travel)") + t_insert(breakdown.OverlapChance, s_format("^8= (^7%d^8 + ^7%d^8 - ^7%d) / (^7%d^8 - ^7%d)", + enemyRadius, ballRadius, innerRadius, outerRadius, innerRadius)) + t_insert(breakdown.OverlapChance, s_format("^8=^7 %.2f^8%%", output.OverlapChance)) + end + + local numProjectiles = skillModList:Sum("BASE", skillCfg, "ProjectileCount") + local dpsMult = 1 + ConPrintf(skillPart) + if skillPart == 3 then + dpsMult = overlapChance * numProjectiles + end + if dpsMult ~= 1 then + skillData.dpsMultiplier = (skillData.dpsMultiplier or 1) * dpsMult + output.SkillDPSMultiplier = (output.SkillDPSMultiplier or 1) * dpsMult + if breakdown then + breakdown.SkillDPSMultiplier = {} + t_insert(breakdown.SkillDPSMultiplier, "DPS multiplier") + t_insert(breakdown.SkillDPSMultiplier, "^8= number of projectiles * overlap chance") + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ^7 %d^8 *^7 %.3f^8", numProjectiles, overlapChance)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %.3f", dpsMult)) + end + end + end, statMap = { ["active_skill_hit_ailment_damage_with_projectile_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPart = 2 }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3 } }) }, }, baseFlags = { @@ -6989,12 +7047,12 @@ skills["MoltenStrike"] = { }, baseMods = { skill("projectileSpeedAppliesToMSAreaOfEffect", true), - skill("radius", 9, { type = "SkillPart", skillPart = 2 }), - skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPart = 2 }), - skill("radiusSecondary", 2, { type = "SkillPart", skillPart = 2 }), - skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPart = 2 }), - skill("radiusTertiary", 25, { type = "SkillPart", skillPart = 2 }), - skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPart = 2 }), + skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3 }}), + skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3 } }), + skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3 } }), + skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }), + skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3 } }), + skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }), flag("CannotSplit"), }, qualityStats = { diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index c0683e116b..768f7a2bd3 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -667,8 +667,8 @@ return { { var = "VaalMoltenShellDamageMitigated", type = "count", label = "Damage mitigated:", tooltip = "Vaal Molten Shell reflects damage to the enemy,\nbased on the amount of damage it has mitigated in the last second.", ifSkill = "Vaal Molten Shell", apply = function(val, modList, enemyModList) modList:NewMod("SkillData", "LIST", { key = "VaalMoltenShellDamageMitigated", value = val }, "Config", { type = "SkillName", skillName = "Molten Shell" }) end }, - { label = "Multi-part area skills:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap" }, includeTransfigured = true }, - { var = "enemySizePreset", type = "list", label = "Enemy size preset:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap" }, includeTransfigured = true, defaultIndex = 2, tooltip = [[ + { label = "Multi-part area skills:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap", "Molten Strike" }, includeTransfigured = true }, + { var = "enemySizePreset", type = "list", label = "Enemy size preset:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap", "Molten Strike" }, includeTransfigured = true, defaultIndex = 2, tooltip = [[ Configure the radius of an enemy hitbox which is used in calculating some area multi-hitting (shotgunning) effects. Small sets the radius to 2. @@ -693,7 +693,7 @@ Huge sets the radius to 11. modList:NewMod("EnemyRadius", "BASE", 11, "Config") end end }, - { var = "enemyRadius", type = "integer", label = "Enemy radius:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap" }, includeTransfigured = true, tooltip = "Configure the radius of an enemy hitbox to calculate some area overlapping (shotgunning) effects.", apply = function(val, modList, enemyModList) + { var = "enemyRadius", type = "integer", label = "Enemy radius:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap", "Molten Strike" }, includeTransfigured = true, tooltip = "Configure the radius of an enemy hitbox to calculate some area overlapping (shotgunning) effects.", apply = function(val, modList, enemyModList) modList:NewMod("EnemyRadius", "OVERRIDE", m_max(val, 1), "Config") end }, { var = "TotalSpectreLife", type = "integer", label = "Total Spectre Life:", ifMod = "takenFromSpectresBeforeYou", ifSkill = "Raise Spectre", includeTransfigured = true, tooltip = "The total life of your Spectres that can be taken before yours (used by jinxed juju)", apply = function(val, modList, enemyModList) From 83b8c6e0732851e92fa9eeff143ada45e9791050 Mon Sep 17 00:00:00 2001 From: andyli00 Date: Tue, 21 Jan 2025 13:18:14 -0500 Subject: [PATCH 2/3] add average ball overlap calcs for molten strike of the zenith as well as a total weighted average of normal balls and 5th attack balls --- src/Data/Skills/act_str.lua | 76 ++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 1ab8cc8eb4..d898e140ca 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -7018,20 +7018,41 @@ skills["MoltenStrike"] = { local numProjectiles = skillModList:Sum("BASE", skillCfg, "ProjectileCount") local dpsMult = 1 - ConPrintf(skillPart) - if skillPart == 3 then + if skillPart == 3 or skillPart == 5 or skillPart == 6 then dpsMult = overlapChance * numProjectiles + + if skillPart ~= 6 then + if breakdown then + breakdown.SkillDPSMultiplier = {} + t_insert(breakdown.SkillDPSMultiplier, "DPS multiplier") + t_insert(breakdown.SkillDPSMultiplier, "^8= number of projectiles * overlap chance") + t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %d^8 *^7 %.3f^8", numProjectiles, overlapChance)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %.3f", dpsMult)) + end + else + -- zenith: make an effective dpsMult for the weighted average of normal and 5th attack balls + local gemQuality = activeSkill.activeEffect.quality + local fifthAttackMulti = 1 + 8 + 0.1 * gemQuality + local fifthAttackOverallMulti = fifthAttackMulti * overlapChance * (numProjectiles + 5) + dpsMult = 0.8 * dpsMult + 0.2 * fifthAttackOverallMulti + + if breakdown then + breakdown.SkillDPSMultiplier = {} + t_insert(breakdown.SkillDPSMultiplier, "Weighted average DPS multiplier for balls") + t_insert(breakdown.SkillDPSMultiplier, "^8= (0.8 * balls dps) + (0.2 * 5th attack balls dps)") + t_insert(breakdown.SkillDPSMultiplier, "^8= (0.8 * normal ball hit * overlap chance * number of projectiles) " .. + "+ (0.2 * ball hit * 5th attack multiplier * overlap chance * (number of projectiles + 5))") + t_insert(breakdown.SkillDPSMultiplier, "^8= ball hit * overlap chance * (0.8 * number of projectiles " .. + "+ 0.2 * 5th attack multiplier * (number of projectiles + 5))") + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * ^7%.3f ^8* (0.8 * ^7%d ^8+ 0.2 * ^7%.1f ^8* ^7%d^8)", + overlapChance, numProjectiles, fifthAttackMulti, numProjectiles + 5)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * ^7 %.3f", dpsMult)) + end + end end if dpsMult ~= 1 then skillData.dpsMultiplier = (skillData.dpsMultiplier or 1) * dpsMult output.SkillDPSMultiplier = (output.SkillDPSMultiplier or 1) * dpsMult - if breakdown then - breakdown.SkillDPSMultiplier = {} - t_insert(breakdown.SkillDPSMultiplier, "DPS multiplier") - t_insert(breakdown.SkillDPSMultiplier, "^8= number of projectiles * overlap chance") - t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ^7 %d^8 *^7 %.3f^8", numProjectiles, overlapChance)) - t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %.3f", dpsMult)) - end end end, statMap = { @@ -7139,22 +7160,41 @@ skills["MoltenStrikeAltX"] = { projectile = true, area = true, }, + { + name = "Average Balls Hitting", + melee = false, + projectile = true, + area = true, + }, { name = "Magma Balls (5th attack)", melee = false, projectile = true, area = true, }, + { + name = "Average Balls (5th attack)", + melee = false, + projectile = true, + area = true, + }, + { + name = "Total Weighted Ball Average", + melee = false, + projectile = true, + area = true, + }, }, + preDamageFunc = skills.MoltenStrike.preDamageFunc, statMap = { ["active_skill_hit_ailment_damage_with_projectile_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3 } }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) }, ["molten_strike_every_5th_attack_projectiles_damage_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPart = 3 }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 4, 5 } }) }, ["molten_strike_every_5th_attack_fire_X_additional_projectiles"] = { - mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPart = 3 }) + mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }) }, }, baseFlags = { @@ -7165,12 +7205,12 @@ skills["MoltenStrikeAltX"] = { }, baseMods = { skill("projectileSpeedAppliesToMSAreaOfEffect", true), - skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3 } }), - skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3 } }), - skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3 } }), - skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }), - skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3 } }), - skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }), + skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), + skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), + skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), + skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), + skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), + skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }), flag("CannotSplit"), }, qualityStats = { From 78e6596c3aff892d0f5339088785ac6f327de8a9 Mon Sep 17 00:00:00 2001 From: andyli00 Date: Tue, 21 Jan 2025 13:33:10 -0500 Subject: [PATCH 3/3] copy molten strike overlap changes to export scripts --- src/Export/Skills/act_str.txt | 130 +++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 16 deletions(-) diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index 5f442ef4e7..63b1d12d11 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -1246,19 +1246,98 @@ local skills, mod, flag, skill = ... projectile = true, area = true, }, + { + name = "Average Balls Hitting", + melee = false, + projectile = true, + area = true, + }, }, + preDamageFunc = function(activeSkill, output, breakdown) + local skillCfg = activeSkill.skillCfg + local skillData = activeSkill.skillData + local skillPart = activeSkill.skillPart + local skillModList = activeSkill.skillModList + local t_insert = table.insert + local s_format = string.format + + -- melee part doesnt need to calc balls + if skillPart == 1 then + return + end + + local enemyRadius = skillModList:Override(skillCfg, "EnemyRadius") or skillModList:Sum("BASE", skillCfg, "EnemyRadius") + local ballRadius = output.AreaOfEffectRadius + local innerRadius = output.AreaOfEffectRadiusSecondary + local outerRadius = output.AreaOfEffectRadiusTertiary + + -- logic adapted from MoldyDwarf's calculator + local hitRange = enemyRadius + ballRadius - innerRadius + local landingRange = outerRadius - innerRadius + local overlapChance = math.min(1, hitRange / landingRange) + output.OverlapChance = overlapChance * 100 + + if breakdown then + breakdown.OverlapChance = { } + t_insert(breakdown.OverlapChance, "Chance for individual balls to land on the enemy:") + t_insert(breakdown.OverlapChance, "^8= (area where a ball can land on enemy) / (total area)") + t_insert(breakdown.OverlapChance, "^8= (enemy radius + ball radius - min travel) / (max travel - min travel)") + t_insert(breakdown.OverlapChance, s_format("^8= (^7%d^8 + ^7%d^8 - ^7%d) / (^7%d^8 - ^7%d)", + enemyRadius, ballRadius, innerRadius, outerRadius, innerRadius)) + t_insert(breakdown.OverlapChance, s_format("^8=^7 %.2f^8%%", output.OverlapChance)) + end + + local numProjectiles = skillModList:Sum("BASE", skillCfg, "ProjectileCount") + local dpsMult = 1 + if skillPart == 3 or skillPart == 5 or skillPart == 6 then + dpsMult = overlapChance * numProjectiles + + if skillPart ~= 6 then + if breakdown then + breakdown.SkillDPSMultiplier = {} + t_insert(breakdown.SkillDPSMultiplier, "DPS multiplier") + t_insert(breakdown.SkillDPSMultiplier, "^8= number of projectiles * overlap chance") + t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %d^8 *^7 %.3f^8", numProjectiles, overlapChance)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8=^7 %.3f", dpsMult)) + end + else + -- zenith: make an effective dpsMult for the weighted average of normal and 5th attack balls + local gemQuality = activeSkill.activeEffect.quality + local fifthAttackMulti = 1 + 8 + 0.1 * gemQuality + local fifthAttackOverallMulti = fifthAttackMulti * overlapChance * (numProjectiles + 5) + dpsMult = 0.8 * dpsMult + 0.2 * fifthAttackOverallMulti + + if breakdown then + breakdown.SkillDPSMultiplier = {} + t_insert(breakdown.SkillDPSMultiplier, "Weighted average DPS multiplier for balls") + t_insert(breakdown.SkillDPSMultiplier, "^8= (0.8 * balls dps) + (0.2 * 5th attack balls dps)") + t_insert(breakdown.SkillDPSMultiplier, "^8= (0.8 * normal ball hit * overlap chance * number of projectiles) " .. + "+ (0.2 * ball hit * 5th attack multiplier * overlap chance * (number of projectiles + 5))") + t_insert(breakdown.SkillDPSMultiplier, "^8= ball hit * overlap chance * (0.8 * number of projectiles " .. + "+ 0.2 * 5th attack multiplier * (number of projectiles + 5))") + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * ^7%.3f ^8* (0.8 * ^7%d ^8+ 0.2 * ^7%.1f ^8* ^7%d^8)", + overlapChance, numProjectiles, fifthAttackMulti, numProjectiles + 5)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * ^7 %.3f", dpsMult)) + end + end + end + if dpsMult ~= 1 then + skillData.dpsMultiplier = (skillData.dpsMultiplier or 1) * dpsMult + output.SkillDPSMultiplier = (output.SkillDPSMultiplier or 1) * dpsMult + end + end, statMap = { ["active_skill_hit_ailment_damage_with_projectile_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPart = 2 }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3 } }) }, }, #baseMod skill("projectileSpeedAppliesToMSAreaOfEffect", true) -#baseMod skill("radius", 9, { type = "SkillPart", skillPart = 2 }) -#baseMod skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPart = 2 }) -#baseMod skill("radiusSecondary", 2, { type = "SkillPart", skillPart = 2 }) -#baseMod skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPart = 2 }) -#baseMod skill("radiusTertiary", 25, { type = "SkillPart", skillPart = 2 }) -#baseMod skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPart = 2 }) +#baseMod skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }) #baseMod flag("CannotSplit") #mods @@ -1277,31 +1356,50 @@ local skills, mod, flag, skill = ... projectile = true, area = true, }, + { + name = "Average Balls Hitting", + melee = false, + projectile = true, + area = true, + }, { name = "Magma Balls (5th attack)", melee = false, projectile = true, area = true, }, + { + name = "Average Balls (5th attack)", + melee = false, + projectile = true, + area = true, + }, + { + name = "Total Weighted Ball Average", + melee = false, + projectile = true, + area = true, + }, }, + preDamageFunc = skills.MoltenStrike.preDamageFunc, statMap = { ["active_skill_hit_ailment_damage_with_projectile_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3 } }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) }, ["molten_strike_every_5th_attack_projectiles_damage_+%_final"] = { - mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPart = 3 }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 4, 5 } }) }, ["molten_strike_every_5th_attack_fire_X_additional_projectiles"] = { - mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPart = 3 }) + mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }) }, }, #baseMod skill("projectileSpeedAppliesToMSAreaOfEffect", true) -#baseMod skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3 } }) -#baseMod skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3 } }) -#baseMod skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3 } }) -#baseMod skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }) -#baseMod skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3 } }) -#baseMod skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3 } }) +#baseMod skill("radius", 9, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) +#baseMod skill("radiusLabel", "Ball area:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) +#baseMod skill("radiusSecondary", 2, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) +#baseMod skill("radiusSecondaryLabel", "Chain Minimum Distance:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) +#baseMod skill("radiusTertiary", 25, { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) +#baseMod skill("radiusTertiaryLabel", "Chain Maximum Distance:", { type = "SkillPart", skillPartList = { 2, 3, 4, 5, 6 } }) #baseMod flag("CannotSplit") #mods