diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 99a3e994c..1e2c80fc6 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -288,6 +288,12 @@ return { mod("RepeatCount", "BASE", nil, 0, 0, { type = "ModFlagOr", modFlags = bit.bor(ModFlag.WeaponMelee, ModFlag.Unarmed) }), mod("RepeatCount", "BASE", nil, 0, 0, { type = "SkillType", skillType = SkillType.RequiresShield }), }, +["skill_repeat_count"] = { + mod("RepeatCount", "BASE", nil, 0, 0, { type = "SkillType", skillType = SkillType.Multicastable }), +}, +["disable_skill_repeats"] = { + flag("CannotRepeat"), +}, ["display_skill_minions_level_is_corpse_level"] = { skill("minionLevelIsEnemyLevel", true), }, diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 7f237aa2f..3e87cc8ac 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -919,7 +919,16 @@ function calcs.offence(env, actor, activeSkill) end end end - output.Repeats = 1 + (skillModList:Sum("BASE", skillCfg, "RepeatCount") or 0) + local function repeatSkillTypesCheck(activeSkillTypes) + local excludeSkillTypes = { SkillType.Instant, SkillType.Channel, SkillType.Triggered, SkillType.Retaliation, SkillType.NonRepeatable } + for _, type in ipairs(excludeSkillTypes) do + if activeSkillTypes[type] then + return false + end + end + return not skillModList:Flag(nil, "CannotRepeat") and ((activeSkillTypes[SkillType.Attack] or activeSkillTypes[SkillType.Spell])) + end + output.Repeats = 1 + (repeatSkillTypesCheck(activeSkill.skillTypes) and skillModList:Sum("BASE", skillCfg, "RepeatCount") or 0) if output.Repeats > 1 then output.RepeatCount = output.Repeats -- handle all the multipliers from Repeats @@ -1010,6 +1019,9 @@ function calcs.offence(env, actor, activeSkill) skillModList:NewMod("Damage", "MORE", (100 * output.Repeats + DamageFinalMoreValueTotal) / (1 + DamageFinalMoreValueTotal / 100) - 100, value.mod.source, value.mod.flags, value.mod.keywordFlags, unpack(value.mod)) end end + if skillFlags.trap or skillFlags.mine then + skillModList:NewMod("DPS", "MORE", (output.Repeats - 1) * 100, "Repeat Count") + end end end if skillData.gainPercentBaseWandDamageToSpells then @@ -5631,7 +5643,7 @@ function calcs.offence(env, actor, activeSkill) if skillFlags.trap or skillFlags.mine then local preSpeed = output.TrapThrowingSpeed or output.MineLayingSpeed local cooldown = output.TrapCooldown or output.Cooldown - useSpeed = (cooldown and cooldown > 0 and 1 / cooldown or preSpeed) / repeats + useSpeed = (cooldown and cooldown > 0 and 1 / cooldown or preSpeed) timeType = skillFlags.trap and "trap throwing" or "mine laying" elseif skillFlags.totem then useSpeed = (output.Cooldown and output.Cooldown > 0 and (output.TotemPlacementSpeed > 0 and output.TotemPlacementSpeed or 1 / output.Cooldown) or output.TotemPlacementSpeed) / repeats diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 3feb3402a..d367435c1 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2616,9 +2616,6 @@ local specialModList = { -- Exerted Attacks ["exerted attacks deal (%d+)%% increased damage"] = function(num) return { mod("ExertIncrease", "INC", num, nil, ModFlag.Attack, 0) } end, ["exerted attacks have (%d+)%% chance to deal double damage"] = function(num) return { mod("ExertDoubleDamageChance", "BASE", num, nil, ModFlag.Attack, 0) } end, - -- Duelist (Fatal flourish) - ["final repeat of attack skills deals (%d+)%% more damage"] = function(num) return { mod("RepeatFinalDamage", "MORE", num, nil, ModFlag.Attack, 0) } end, - ["non%-travel attack skills repeat an additional time"] = { mod("RepeatCount", "BASE", 1, nil, ModFlag.Attack, 0, { type = "Condition", varList = {"averageRepeat", "alwaysFinalRepeat"} }) }, -- Leech Related ["life leech is instant"] = { mod("InstantLifeLeech", "BASE", 100), }, ["mana leech is instant"] = { mod("InstantManaLeech", "BASE", 100), }, @@ -5833,6 +5830,8 @@ local specialModList = { mod("PartialIgnoreEnemyPhysicalDamageReduction", "BASE", num), } end, ["hits ignore non%-negative elemental resistances of frozen enemies"] = { flag("IgnoreNonNegativeEleRes", { type = "ActorCondition", actor = "enemy", var = "Frozen" }) }, + ["final repeat of attack skills deals (%d+)%% more damage"] = function(num) return { mod("RepeatFinalDamage", "MORE", num, nil, ModFlag.Attack, 0) } end, + ["non%-travel attack skills repeat an additional time"] = { mod("RepeatCount", "BASE", 1, nil, ModFlag.Attack, 0, { type = "Condition", varList = {"averageRepeat", "alwaysFinalRepeat"} }) }, ["viper strike and pestilent strike deal (%d+)%% increased attack damage per frenzy charge"] = function(num) return { mod("Damage", "INC", num, nil, ModFlag.Attack, { type = "Multiplier", var = "FrenzyCharge" }, { type = "SkillName", skillNameList = { "Viper Strike", "Pestilent Strike" }, includeTransfigured = true }) } end, ["shield charge and chain hook have (%d+)%% increased attack speed per (%d+) rampage kills"] = function(inc, _, num) return { mod("Speed", "INC", inc, nil, ModFlag.Attack, { type = "Multiplier", var = "Rampage", div = num, limit = 1000 / num, limitTotal = true }, { type = "SkillName", skillNameList = { "Shield Charge", "Chain Hook" }, includeTransfigured = true }) } end, ["tectonic slam and infernal blow deal (%d+)%% increased attack damage per (%d+) armour"] = function(inc, _, num) return { mod("Damage", "INC", inc, nil, ModFlag.Attack, { type = "PerStat", stat = "Armour", div = num }, { type = "SkillName", skillNameList = { "Tectonic Slam", "Infernal Blow" }, includeTransfigured = true }) } end,