diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 73393c449..4395c205f 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -548,7 +548,7 @@ function GemSelectClass:AddGemTooltip(gemInstance) -- Will need rework if a gem can have 2+ additional supports self:AddGrantedEffectInfo(gemInstance, grantedEffect, true) for _, statSet in ipairs(grantedEffect.statSets) do - self:AddStatSetInfo(gemInstance, grantedEffect, statSet) + self:AddStatSetInfo(gemInstance, grantedEffect, statSet, nil , _) end for _, additional in ipairs(additionalEffects or {}) do @@ -560,11 +560,11 @@ function GemSelectClass:AddGemTooltip(gemInstance) self.tooltip:AddSeparator(10) self:AddGrantedEffectInfo(gemInstance, additional) for _, statSet in ipairs(additional.statSets) do - self:AddStatSetInfo(gemInstance, additional, statSet) + self:AddStatSetInfo(gemInstance, additional, statSet, nil, _) end else for _, statSet in ipairs(additional.statSets) do - self:AddStatSetInfo(gemInstance, additional, statSet, true) + self:AddStatSetInfo(gemInstance, additional, statSet, true, _) end end end @@ -692,10 +692,10 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) end end end -function GemSelectClass:AddStatSetInfo(gemInstance, grantedEffect, statSet, noLabel) +function GemSelectClass:AddStatSetInfo(gemInstance, grantedEffect, statSet, noLabel, index) local displayInstance = gemInstance.displayEffect or gemInstance local statSetLevel = statSet.levels[displayInstance.level] or { } - if statSet.label ~= grantedEffect.name and statSet.label ~= "" and not noLabel then + if not (index == 1 and statSet.label == grantedEffect.name) and statSet.label ~= "" and not noLabel then self.tooltip:AddSeparator(10) self.tooltip:AddLine(20, colorCodes.GEM .. statSet.label) self.tooltip:AddSeparator(10) diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 0651cca20..d68c63dd2 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -136,6 +136,10 @@ return { ["spell_cast_time_cannot_be_modified"] = { skill("fixedCastTime", true), }, +["base_minimum_channel_time_ms"] = { + skill("minChannelTime", true), + div = 1000, +}, ["global_always_hit"] = { skill("cannotBeEvaded", true), }, @@ -519,6 +523,10 @@ return { ["attack_and_cast_speed_+%"] = { mod("Speed", "INC", nil), }, +["skill_speed_+%"] = { + mod("Speed", "INC", nil), + mod("WarcrySpeed", "INC", nil), +}, ["cast_speed_+%_granted_from_skill"] = { mod("Speed", "INC", nil, ModFlag.Cast), }, @@ -2761,6 +2769,9 @@ return { ["quality_display_sandstorm_swipe_is_gem"] = { -- Display Only }, +["cast_speed_modifiers_apply_to_over_time_cost"] = { + -- Display Only +}, ["quality_display_base_totem_duration_is_gem"] = { -- Display Only }, @@ -2770,4 +2781,7 @@ return { ["skill_specific_stat_description_mode"] = { -- Display Only }, +["quality_display_supercharged_slam_is_gem"] = { + -- Display Only +}, } diff --git a/src/Data/Skills/act_dex.lua b/src/Data/Skills/act_dex.lua index 853684ccd..d346b46fe 100644 --- a/src/Data/Skills/act_dex.lua +++ b/src/Data/Skills/act_dex.lua @@ -1134,6 +1134,7 @@ skills["DetonatingArrowPlayer"] = { }, preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:DetonatingArrowStage") + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:DetonatingArrowStage") end, statSets = { [1] = { @@ -7296,6 +7297,7 @@ skills["SnipePlayer"] = { }, preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, statSets = { [1] = { diff --git a/src/Data/Skills/act_int.lua b/src/Data/Skills/act_int.lua index 91d712497..ac50279c2 100644 --- a/src/Data/Skills/act_int.lua +++ b/src/Data/Skills/act_int.lua @@ -1798,6 +1798,11 @@ skills["BonestormPlayer"] = { [39] = { critChance = 15, levelRequirement = 90, cost = { ManaPerMinute = 20158, }, }, [40] = { critChance = 15, levelRequirement = 90, cost = { ManaPerMinute = 21924, }, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") / output.ProjectileCount or 1 + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") / output.ProjectileCount or 1 + activeSkill.skillData.dpsMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") + end, statSets = { [1] = { label = "Projectile", @@ -1805,9 +1810,15 @@ skills["BonestormPlayer"] = { incrementalEffectiveness = 0.12999999523163, damageIncrementalEffectiveness = 0.0068999999202788, statDescriptionScope = "bone_spike_statset_0", + statMap = { + ["base_number_of_allowed_bone_storm_projectiles"] = { + mod("Multiplier:BonestormMaxStages", "BASE", nil), + }, + }, baseFlags = { spell = true, projectile = true, + channelRelease = true, }, constantStats = { { "base_number_of_projectiles", 1 }, @@ -1886,10 +1897,22 @@ skills["BonestormPlayer"] = { incrementalEffectiveness = 0.12999999523163, damageIncrementalEffectiveness = 0.0068999999202788, statDescriptionScope = "bone_spike_statset_1", + statMap = { + ["bone_spear_power_charged_aoe_+%_final_per_additional_power_charge"] = { + mod("AreaOfEffect", "MORE", nil, 0, 0, { type = "Multiplier", var = "RemovablePowerCharge" }), + }, + ["bone_spear_power_charged_aoe_+"] = { + skill("radiusExtra", nil, { type = "MultiplierThreshold", var = "RemovablePowerCharge", threshold = 1 }), + }, + ["base_number_of_allowed_bone_storm_projectiles"] = { + mod("Multiplier:BonestormMaxStages", "BASE", nil), + }, + }, baseFlags = { spell = true, area = true, projectile = true, + channelRelease = true, }, constantStats = { { "movement_speed_+%_final_while_performing_action", -70 }, @@ -8080,6 +8103,9 @@ skills["FlameblastPlayer"] = { [39] = { critChance = 8, storedUses = 1, levelRequirement = 90, cooldown = 15, cost = { ManaPerMinute = 19137, }, }, [40] = { critChance = 8, storedUses = 1, levelRequirement = 90, cooldown = 15, cost = { ManaPerMinute = 20814, }, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:FlameblastStage") + end, statSets = { [1] = { label = "Flameblast", @@ -8087,9 +8113,21 @@ skills["FlameblastPlayer"] = { incrementalEffectiveness = 0.12999999523163, damageIncrementalEffectiveness = 0.0096000004559755, statDescriptionScope = "skill_stat_descriptions", + statMap = { + ["charged_blast_spell_damage_+%_final_per_stack"] = { + mod("Damage", "MORE", nil, ModFlag.Spell, 0, { type = "Multiplier", var = "FlameblastStage" }), + }, + ["vaal_flameblast_radius_+_per_stage"] = { + skill("radiusExtra", nil, { type = "Multiplier", var = "FlameblastStage" }), + }, + ["flameblast_maximum_stages"] = { + mod("Multiplier:FlameblastMaxStages", "BASE", nil), + }, + }, baseFlags = { spell = true, area = true, + channelRelease = true, }, constantStats = { { "charged_blast_spell_damage_+%_final_per_stack", 75 }, @@ -10292,6 +10330,7 @@ skills["GatheringStormPlayer"] = { }, preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, statSets = { [1] = { @@ -13371,6 +13410,9 @@ skills["IncineratePlayer"] = { [39] = { critChance = 6, levelRequirement = 90, }, [40] = { critChance = 6, levelRequirement = 90, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:IncinerateStage") + end, statSets = { [1] = { label = "Incinerate", @@ -13378,10 +13420,23 @@ skills["IncineratePlayer"] = { incrementalEffectiveness = 0.12999999523163, damageIncrementalEffectiveness = 0.0096000004559755, statDescriptionScope = "incinerate_player_statset_0", + statMap = { + ["incinerate_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "IncinerateStage" }), + }, + ["incinerate_maximum_stages"] = { + mod("Multiplier:IncinerateMaxStages", "BASE", nil), + }, + ["incinerate_gain_stage_every_x_ms"] = { + skill("channelTimeOverride", nil), + div = 1000, + }, + }, baseFlags = { spell = true, area = true, duration = true, + channelRelease = true, }, constantStats = { { "incinerate_cone_angle", 20 }, diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index e8e1be050..1e9ab407e 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -9233,6 +9233,9 @@ skills["PlasmaBlastPlayer"] = { [39] = { baseMultiplier = 139.44, levelRequirement = 0, }, [40] = { baseMultiplier = 150.22, levelRequirement = 0, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = 1 + end, statSets = { [1] = { label = "Projectile", @@ -11639,6 +11642,7 @@ skills["PerfectStrikePlayer"] = { }, preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, statSets = { [1] = { @@ -14079,15 +14083,33 @@ skills["SuperchargedSlamPlayer"] = { [39] = { attackTime = 1000, baseMultiplier = 8.63, levelRequirement = 90, cost = { ManaPerMinute = 11734, }, }, [40] = { attackTime = 1000, baseMultiplier = 9.21, levelRequirement = 90, cost = { ManaPerMinute = 12487, }, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:SuperchargedSlamStage") + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:SuperchargedSlamStage") + end, statSets = { [1] = { label = "Impact", incrementalEffectiveness = 0.092720001935959, statDescriptionScope = "channelled_slam_statset_0", + statMap = { + ["channelled_slam_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), + }, + ["channelled_slam_max_stages"] = { + mod("Multiplier:SuperchargedSlamMaxStages", "BASE", nil), + }, + ["base_skill_show_average_damage_instead_of_dps"] = { + }, + }, baseFlags = { attack = true, area = true, melee = true, + channelRelease = true, + }, + baseMods = { + mod("DPS", "MORE", 100, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), }, constantStats = { { "active_skill_base_area_of_effect_radius", 16 }, @@ -14150,10 +14172,27 @@ skills["SuperchargedSlamPlayer"] = { label = "Aftershock", incrementalEffectiveness = 0.092720001935959, statDescriptionScope = "channelled_slam_statset_1", + statMap = { + ["channelled_slam_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), + }, + ["channelled_slam_max_stages"] = { + mod("Multiplier:SuperchargedSlamMaxStages", "BASE", nil), + }, + ["aftershock_radius_+_per_previous_aftershock"] = { + skill("radiusExtra", nil, { type = "Multiplier", var = "SuperchargedSlamStage", limit = 30, limitTotal = true }), + }, + ["base_skill_show_average_damage_instead_of_dps"] = { + }, + }, baseFlags = { attack = true, area = true, melee = true, + channelRelease = true, + }, + baseMods = { + mod("DPS", "MORE", 100, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), }, constantStats = { { "active_skill_base_area_of_effect_radius", 16 }, diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index a913e389b..e7d9e2133 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -5824,12 +5824,22 @@ skills["TemperWeaponPlayer"] = { [39] = { storedUses = 1, levelRequirement = 90, cooldown = 5, cost = { ManaPerMinute = 4319, }, }, [40] = { storedUses = 1, levelRequirement = 90, cooldown = 5, cost = { ManaPerMinute = 4596, }, }, }, + preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:TemperWeaponStage") + end, statSets = { [1] = { label = "Temper Weapon", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "skill_stat_descriptions", + statMap = { + ["imbue_weapon_max_exerts"] = { + mod("Multiplier:TemperWeaponMaxStages", "BASE", nil), + div = 3, + }, + }, baseFlags = { + channelRelease = true, }, constantStats = { { "imbue_weapon_max_exerts", 12 }, diff --git a/src/Export/Skills/act_dex.txt b/src/Export/Skills/act_dex.txt index 23a2ca57e..f4c5db46b 100644 --- a/src/Export/Skills/act_dex.txt +++ b/src/Export/Skills/act_dex.txt @@ -104,6 +104,7 @@ statMap = { #skill DetonatingArrowPlayer preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:DetonatingArrowStage") + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:DetonatingArrowStage") end, #set DetonatingArrowPlayer #flags attack projectile channelRelease @@ -452,6 +453,7 @@ statMap = { #skill SnipePlayer preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, #set SnipePlayer #flags attack projectile channelRelease diff --git a/src/Export/Skills/act_int.txt b/src/Export/Skills/act_int.txt index ae2fc6aee..68457da8c 100644 --- a/src/Export/Skills/act_int.txt +++ b/src/Export/Skills/act_int.txt @@ -127,11 +127,32 @@ statMap = { #skillEnd #skill BonestormPlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") / output.ProjectileCount or 1 + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") / output.ProjectileCount or 1 + activeSkill.skillData.dpsMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:BonestormStage") +end, #set BonestormPlayer -#flags spell projectile +#flags spell projectile channelRelease +statMap = { + ["base_number_of_allowed_bone_storm_projectiles"] = { + mod("Multiplier:BonestormMaxStages", "BASE", nil), + }, +}, #mods #set BonestormExplosionPlayer -#flags spell area projectile +#flags spell area projectile channelRelease +statMap = { + ["bone_spear_power_charged_aoe_+%_final_per_additional_power_charge"] = { + mod("AreaOfEffect", "MORE", nil, 0, 0, { type = "Multiplier", var = "RemovablePowerCharge" }), + }, + ["bone_spear_power_charged_aoe_+"] = { + skill("radiusExtra", nil, { type = "MultiplierThreshold", var = "RemovablePowerCharge", threshold = 1 }), + }, + ["base_number_of_allowed_bone_storm_projectiles"] = { + mod("Multiplier:BonestormMaxStages", "BASE", nil), + }, +}, #mods #skillEnd @@ -488,8 +509,22 @@ statMap = { #skillEnd #skill FlameblastPlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:FlameblastStage") +end, #set FlameblastPlayer -#flags spell area +#flags spell area channelRelease +statMap = { + ["charged_blast_spell_damage_+%_final_per_stack"] = { + mod("Damage", "MORE", nil, ModFlag.Spell, 0, { type = "Multiplier", var = "FlameblastStage" }), + }, + ["vaal_flameblast_radius_+_per_stage"] = { + skill("radiusExtra", nil, { type = "Multiplier", var = "FlameblastStage" }), + }, + ["flameblast_maximum_stages"] = { + mod("Multiplier:FlameblastMaxStages", "BASE", nil), + }, +}, #mods #skillEnd @@ -618,6 +653,7 @@ statMap = { #skill GatheringStormPlayer preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, #set GatheringStormPlayer #flags attack area melee channelRelease @@ -792,8 +828,23 @@ statMap = { #skillEnd #skill IncineratePlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:IncinerateStage") +end, #set IncineratePlayer -#flags spell area duration +#flags spell area duration channelRelease +statMap = { + ["incinerate_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "IncinerateStage" }), + }, + ["incinerate_maximum_stages"] = { + mod("Multiplier:IncinerateMaxStages", "BASE", nil), + }, + ["incinerate_gain_stage_every_x_ms"] = { + skill("channelTimeOverride", nil), + div = 1000, + }, +}, #mods #set IncinerateGroundPlayer #flags spell area duration diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index a76186cd5..db1719c00 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -546,6 +546,9 @@ statMap = { #skillEnd #skill PlasmaBlastPlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = 1 +end, #set PlasmaBlastPlayer #flags attack projectile channelRelease #mods @@ -681,6 +684,7 @@ statMap = { #skill PerfectStrikePlayer preDamageFunc = function(activeSkill, output) activeSkill.skillData.hitTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillData.channelPercentOfAttackTime end, #set PerfectStrikePlayer #flags attack area melee duration channelRelease @@ -801,11 +805,40 @@ statMap = { #skillEnd #skill SuperchargedSlamPlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.hitTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:SuperchargedSlamStage") + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:SuperchargedSlamStage") +end, #set SuperchargedSlamPlayer -#flags attack area melee +#flags attack area melee channelRelease +statMap = { + ["channelled_slam_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), + }, + ["channelled_slam_max_stages"] = { + mod("Multiplier:SuperchargedSlamMaxStages", "BASE", nil), + }, + ["base_skill_show_average_damage_instead_of_dps"] = { + }, +}, +#baseMod mod("DPS", "MORE", 100, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }) #mods #set SuperchargedSlamAftershockPlayer -#flags attack area melee +#flags attack area melee channelRelease +statMap = { + ["channelled_slam_damage_+%_final_per_stage"] = { + mod("Damage", "MORE", nil, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }), + }, + ["channelled_slam_max_stages"] = { + mod("Multiplier:SuperchargedSlamMaxStages", "BASE", nil), + }, + ["aftershock_radius_+_per_previous_aftershock"] = { + skill("radiusExtra", nil, { type = "Multiplier", var = "SuperchargedSlamStage", limit = 30, limitTotal = true }), + }, + ["base_skill_show_average_damage_instead_of_dps"] = { + }, +}, +#baseMod mod("DPS", "MORE", 100, 0, 0, { type = "Multiplier", var = "SuperchargedSlamStage" }) #mods #skillEnd diff --git a/src/Export/Skills/other.txt b/src/Export/Skills/other.txt index 923fd070c..86d07e326 100644 --- a/src/Export/Skills/other.txt +++ b/src/Export/Skills/other.txt @@ -438,8 +438,17 @@ statMap = { #from tree #skill TemperWeaponPlayer +preDamageFunc = function(activeSkill, output) + activeSkill.skillData.channelTimeMultiplier = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:TemperWeaponStage") +end, #set TemperWeaponPlayer -#flags +#flags channelRelease +statMap = { + ["imbue_weapon_max_exerts"] = { + mod("Multiplier:TemperWeaponMaxStages", "BASE", nil), + div = 3, + }, +}, #mods #skillEnd diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 1ead50523..170a4ccd6 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -1793,7 +1793,7 @@ function buildMode:RefreshSkillSelectControls(controls, mainGroup, suffix) controls.mainSkillStageCount.buf = tostring(activeEffect.srcInstance["skillStageCount"..suffix] or activeEffect.grantedEffect.parts[controls.mainSkillPart.selIndex].stagesMin or 1) end end - activeSkill.activeEffect.statSet = activeSkill.activeEffect.statSet or { } + activeSkill.activeEffect.statSet = activeSkill.activeEffect.statSet or activeSkill.activeEffect.statSetCalcs or { } activeSkill.activeEffect.statSet.skillFlags = activeSkill.activeEffect.statSet.skillFlags or { } if activeSkill.activeEffect.statSet.skillFlags.mine then controls.mainSkillMineCount.shown = true diff --git a/src/Modules/BuildDisplayStats.lua b/src/Modules/BuildDisplayStats.lua index 60dfa774a..0d2c19a82 100644 --- a/src/Modules/BuildDisplayStats.lua +++ b/src/Modules/BuildDisplayStats.lua @@ -15,12 +15,12 @@ local displayStats = { { stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true, flag = "monsterExplode", condFunc = function(v,o) return o.HitChance ~= 100 end }, { stat = "AverageBurstDamage", label = "Average Burst Damage", fmt = ".1f", compPercent = true, condFunc = function(v,o) return o.AverageBurstHits and o.AverageBurstHits > 1 and v > 0 end }, { stat = "PvpAverageDamage", label = "PvP Average Damage", fmt = ".1f", compPercent = true, flag = "attackPvP" }, - { stat = "Speed", label = "Attack Rate", fmt = ".2f", compPercent = true, flag = "attack", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end }, - { stat = "Speed", label = "Cast Rate", fmt = ".2f", compPercent = true, flag = "spell", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end }, + { stat = "Speed", label = "Attack Rate", fmt = ".2f", compPercent = true, flag = "attack", condFunc = function(v,o) return v > 0 and not o.ChannelTime and (o.TriggerTime or 0) == 0 end }, + { stat = "Speed", label = "Cast Rate", fmt = ".2f", compPercent = true, flag = "spell", condFunc = function(v,o) return v > 0 and not o.ChannelTime and (o.TriggerTime or 0) == 0 end }, { stat = "Speed", label = "Effective Trigger Rate", fmt = ".2f", compPercent = true, condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end }, { stat = "WarcryCastTime", label = "Cast Time", fmt = ".2fs", compPercent = true, lowerIsBetter = true, flag = "warcry" }, + { stat = "ChannelTime", label = "Channel Time", fmt = ".2fs", compPercent = true, flag = "channelRelease", lowerIsBetter = true, condFunc = function(v,o) return not o.TriggerTime end }, { stat = "HitSpeed", label = "Hit Rate", fmt = ".2f", compPercent = true, condFunc = function(v,o) return not o.TriggerTime end }, - { stat = "HitTime", label = "Channel Time", fmt = ".2fs", compPercent = true, flag = "channelRelease", lowerIsBetter = true, condFunc = function(v,o) return not o.TriggerTime end }, { stat = "ChannelTimeToTrigger", label = "Channel Time", fmt = ".2fs", compPercent = true, lowerIsBetter = true, }, { stat = "TrapThrowingTime", label = "Trap Throwing Time", fmt = ".2fs", compPercent = true, lowerIsBetter = true, }, { stat = "TrapCooldown", label = "Trap Cooldown", fmt = ".3fs", lowerIsBetter = true }, diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index ffc4175ae..dec66a98a 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2637,6 +2637,12 @@ function calcs.offence(env, actor, activeSkill) output.Speed = output.Speed * globalOutput.ActionSpeedMod output.CastRate = output.Speed end + if skillData.channelTimeMultiplier then + local minTime = skillData.minChannelTime or 0 + local channelTime = skillData.channelTimeOverride or output.Speed + output.ChannelTime = m_max(skillData.channelTimeMultiplier / channelTime, minTime) + output.ChannelSpeed = output.Speed or output.Time + end if skillFlags.totem then -- Totem skill. Apply action speed local totemActionSpeed = 1 + (modDB:Sum("INC", nil, "TotemActionSpeed") / 100) @@ -2779,9 +2785,12 @@ function calcs.offence(env, actor, activeSkill) end elseif skillData.hitTimeMultiplier and output.Time and not skillData.triggeredOnDeath then output.HitTime = output.Time * skillData.hitTimeMultiplier + if skillFlags.channelRelease and skillData.minChannelTime then + output.HitTime = m_max(output.HitTime, skillData.minChannelTime) + end if output.Cooldown and skillData.triggered then output.HitSpeed = 1 / (m_max(output.HitTime, output.Cooldown)) - elseif output.Cooldown then + elseif output.Cooldown and not skillFlags.channelRelease then output.HitSpeed = 1 / (output.HitTime + output.Cooldown) else output.HitSpeed = 1 / output.HitTime @@ -2837,6 +2846,12 @@ function calcs.offence(env, actor, activeSkill) } end end + if skillData.channelTimeMultiplier then + local minTime = skillData.minChannelTime or 0 + local channelTime = skillData.channelTimeOverride or output.Speed + output.ChannelTime = m_max(skillData.channelTimeMultiplier / channelTime, minTime) + output.ChannelSpeed = output.Speed or output.Time + end if skillData.hitTimeOverride and not skillData.triggeredOnDeath then output.HitTime = skillData.hitTimeOverride output.HitSpeed = 1 / output.HitTime @@ -2844,6 +2859,9 @@ function calcs.offence(env, actor, activeSkill) output.Time = skillData.timeOverride elseif skillData.hitTimeMultiplier and output.Time and not skillData.triggeredOnDeath then output.HitTime = output.Time * skillData.hitTimeMultiplier + if skillFlags.channelRelease and skillData.minChannelTime then + output.HitTime = m_max(output.HitTime, skillData.minChannelTime) + end if output.Cooldown and skillData.triggered then output.HitSpeed = 1 / (m_max(output.HitTime, output.Cooldown)) elseif output.Cooldown then @@ -2854,6 +2872,20 @@ function calcs.offence(env, actor, activeSkill) end end if breakdown then + if skillData.channelTimeMultiplier and output.Time and not skillData.triggeredOnDeath then + breakdown.ChannelTime = { } + if skillData.minChannelTime then + t_insert(breakdown.ChannelTime, s_format("%.2fs ^8(minimum channel time)", skillData.minChannelTime)) + t_insert(breakdown.ChannelTime, s_format("")) + end + if isAttack then + t_insert(breakdown.ChannelTime, s_format("%.2f ^8(attack time per stage)", 1 / output.ChannelSpeed)) + else + t_insert(breakdown.ChannelTime, s_format("%.2f ^8(cast time per stage)", 1 / output.ChannelSpeed)) + end + t_insert(breakdown.ChannelTime, s_format("x %.2f ^8(channel time multiplier)", skillData.channelTimeMultiplier)) + t_insert(breakdown.ChannelTime, s_format("= %.2f", output.ChannelTime)) + end if skillData.hitTimeOverride and not skillData.triggeredOnDeath then breakdown.HitSpeed = { } t_insert(breakdown.HitSpeed, s_format("1 / %.2f ^8(hit time override)", output.HitTime)) diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index d62e9c694..69321b5d7 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -514,7 +514,7 @@ return { { label = "Skill Trigger Rate", flagList = {"triggered", "focused"}, { format = "{2:output:SkillTriggerRate}", { breakdown = "SkillTriggerRate" }, { breakdown = "SimData" }, { modName = "FocusCooldownRecovery", modType = "INC", cfg = "skill", }, }, }, { label = "Cast time", flag = "spell", notFlag = "triggered", { format = "{2:output:Time}s", }, }, { label = "CWDT Threshold", haveOutput = "CWDTThreshold", flag = "triggered", { format = "{2:output:CWDTThreshold}", { breakdown = "CWDTThreshold" }, }, }, - { label = "Channel time", flag = "channelRelease", haveOutput = "HitTime", { format = "{2:output:HitTime}s", { breakdown = "HitTime" } }, }, + { label = "Channel time", flag = "channelRelease", haveOutput = "ChannelTime", { format = "{2:output:ChannelTime}s", { breakdown = "ChannelTime" } }, }, { label = "Hit Rate", haveOutput = "HitSpeed", { format = "{2:output:HitSpeed}", { breakdown = "HitSpeed" } }, }, } } } }, diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 1ce08afeb..166897baf 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -364,10 +364,6 @@ local configSettings = { { var = "flameWallAddedDamage", type = "check", label = "Projectile Travelled through Flame Wall?", ifSkill = "Flame Wall", apply = function(val, modList, enemyModList) modList:NewMod("Condition:FlameWallAddedDamage", "FLAG", true, "Config") end }, - { label = "Bonestorm:", ifSkill = "Bonestorm" }, - { var = "bonestormAddedDamage", type = "check", label = "Enemy has Bonestorm debuff?", ifSkill = "Bonestorm", apply = function(val, modList, enemyModList) - modList:NewMod("Condition:BonestormAddedDamage", "FLAG", true, "Config") - end }, { label = "Flicker Strike:", ifSkill = "Flicker Strike", includeTransfigured = true }, { var = "FlickerStrikeBypassCD", type = "check", label = "Bypass CD?", ifSkill = "Flicker Strike", includeTransfigured = true, defaultState = true, apply = function(val, modList, enemyModList) modList:NewMod("CooldownRecovery", "OVERRIDE", 0, "Config", { type = "SkillName", skillName = "Flicker Strike", includeTransfigured = true })