diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 619f94bb89..1e04f5a1e5 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -7687,38 +7687,16 @@ skills["MoltenStrike"] = { t_insert(breakdown.OverlapChance, s_format("^8=^7 %.2f^8%%", output.OverlapChance)) end - local numProjectiles = skillModList:Sum("BASE", skillCfg, "ProjectileCount") + local numProjectiles = output.ProjectileCount local dpsMult = 1 - if skillPart == 3 or skillPart == 5 or skillPart == 6 then + if skillPart == 3 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 + 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 if dpsMult ~= 1 then @@ -7856,16 +7834,89 @@ skills["MoltenStrikeAltX"] = { area = true, }, }, - preDamageFunc = skills.MoltenStrike.preDamageFunc, + 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 doesn't 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 = output.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 fifthAttackMulti = 1 + skillData.FifthStrikeDamage / 100 + local fifthAttackOverallMulti = fifthAttackMulti * overlapChance * (numProjectiles + skillData.FifthStrikeProjectiles) + 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, s_format("^8= (0.8 * normal ball hit * overlap chance * number of projectiles) " .. + "+ (0.2 * ball hit * 5th attack multiplier * overlap chance * (number of projectiles + %d))", skillData.FifthStrikeProjectiles)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * overlap chance * (0.8 * number of projectiles " .. + "+ 0.2 * 5th attack multiplier * (number of projectiles + %d))", skillData.FifthStrikeProjectiles)) + 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 + skillData.FifthStrikeProjectiles)) + 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", 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", skillPartList = { 4, 5 } }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 4, 5 } }), + skill("FifthStrikeDamage", nil), }, ["molten_strike_every_5th_attack_fire_X_additional_projectiles"] = { - mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }) + mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }), + skill("FifthStrikeProjectiles", nil), }, }, baseFlags = { diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index 4d2478c56e..d5da4291fb 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -1386,38 +1386,16 @@ local skills, mod, flag, skill = ... t_insert(breakdown.OverlapChance, s_format("^8=^7 %.2f^8%%", output.OverlapChance)) end - local numProjectiles = skillModList:Sum("BASE", skillCfg, "ProjectileCount") + local numProjectiles = output.ProjectileCount local dpsMult = 1 - if skillPart == 3 or skillPart == 5 or skillPart == 6 then + if skillPart == 3 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 + 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 if dpsMult ~= 1 then @@ -1480,16 +1458,89 @@ local skills, mod, flag, skill = ... area = true, }, }, - preDamageFunc = skills.MoltenStrike.preDamageFunc, + 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 doesn't 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 = output.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 fifthAttackMulti = 1 + skillData.FifthStrikeDamage / 100 + local fifthAttackOverallMulti = fifthAttackMulti * overlapChance * (numProjectiles + skillData.FifthStrikeProjectiles) + 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, s_format("^8= (0.8 * normal ball hit * overlap chance * number of projectiles) " .. + "+ (0.2 * ball hit * 5th attack multiplier * overlap chance * (number of projectiles + %d))", skillData.FifthStrikeProjectiles)) + t_insert(breakdown.SkillDPSMultiplier, s_format("^8= ball hit * overlap chance * (0.8 * number of projectiles " .. + "+ 0.2 * 5th attack multiplier * (number of projectiles + %d))", skillData.FifthStrikeProjectiles)) + 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 + skillData.FifthStrikeProjectiles)) + 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", 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", skillPartList = { 4, 5 } }) + mod("Damage", "MORE", nil, bit.band(ModFlag.Hit, ModFlag.Ailment), 0, { type = "SkillPart", skillPartList = { 4, 5 } }), + skill("FifthStrikeDamage", nil), }, ["molten_strike_every_5th_attack_fire_X_additional_projectiles"] = { - mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }) + mod("ProjectileCount", "BASE", nil, 0, 0, { type = "SkillPart", skillPartList = { 4, 5 } }), + skill("FifthStrikeProjectiles", nil), }, }, #baseMod skill("projectileSpeedAppliesToMSAreaOfEffect", true)