From 3972a7ebb13e571ffdca2905d4c3b54f0d031fcd Mon Sep 17 00:00:00 2001 From: Igor Wessel Date: Mon, 20 Jan 2025 17:54:04 -0300 Subject: [PATCH 1/3] add tag spell, curse and mods for Temporal Chains --- src/Data/Skills/act_int.lua | 10 ++++++++++ src/Export/Skills/act_int.txt | 10 +++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Data/Skills/act_int.lua b/src/Data/Skills/act_int.lua index b5c421d817..fd730cfdf7 100644 --- a/src/Data/Skills/act_int.lua +++ b/src/Data/Skills/act_int.lua @@ -16578,9 +16578,19 @@ skills["TemporalChainsPlayer"] = { baseEffectiveness = 0, incrementalEffectiveness = 0.092720001935959, statDescriptionScope = "temporal_chains", + statMap = { + ["temporal_chains_base_action_speed_+%_final_to_apply"] = { + mod("TemporalChainsActionSpeed", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), + }, + ["buff_time_passed_+%_other_than_temporal_chains"] = { + mod("BuffExpireFaster", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), + } + }, baseFlags = { + spell = true, area = true, duration = true, + curse = true, }, constantStats = { { "curse_delay_duration_ms", 1000 }, diff --git a/src/Export/Skills/act_int.txt b/src/Export/Skills/act_int.txt index 2e2d8f77fb..bd86f3ba8b 100644 --- a/src/Export/Skills/act_int.txt +++ b/src/Export/Skills/act_int.txt @@ -1098,7 +1098,15 @@ statMap = { #skill TemporalChainsPlayer #startSets #set TemporalChainsPlayer -#flags area duration +#flags spell area duration curse +statMap = { + ["temporal_chains_base_action_speed_+%_final_to_apply"] = { + mod("TemporalChainsActionSpeed", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), + }, + ["buff_time_passed_+%_other_than_temporal_chains"] = { + mod("BuffExpireFaster", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), + } +}, #mods #skillEnd From ea31b13c4007a338ab26ce1865458c9547c86862 Mon Sep 17 00:00:00 2001 From: Igor Wessel Date: Mon, 20 Jan 2025 22:04:06 -0300 Subject: [PATCH 2/3] add support for Now and Again --- src/Data/ModCache.lua | 2 +- src/Modules/CalcOffence.lua | 27 ++++++++++++++++++++++++--- src/Modules/CalcSections.lua | 5 +++-- src/Modules/ConfigOptions.lua | 1 + src/Modules/ModParser.lua | 4 ++++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index b868fd8d0e..42acd7391c 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2936,7 +2936,7 @@ c["Skills gain a Base Life Cost equal to 50% of Base Mana Cost"]={{[1]={flags=0, c["Skills gain a Base Life Cost equal to Base Mana Cost"]={{[1]={flags=0,keywordFlags=0,name="ManaCostAsLifeCost",type="BASE",value=100}},nil} c["Skills have +1 to Limit"]={{}," Limit "} c["Skills have -2 seconds to Cooldown"]={{}," seconds to Cooldown "} -c["Skills have 33% chance to not consume a Cooldown when used"]={{}," to not consume a Cooldown when used "} +c["Skills have 33% chance to not consume a Cooldown when used"]={{[1]={[1]={skillType=101,type="SkillType"},flags=0,keywordFlags=0,name="CooldownChanceNotConsume",type="BASE",value=0.33}},nil} c["Skills have a 125% longer Perfect Timing window"]={{[1]={flags=0,keywordFlags=0,name="PerfectTiming",type="INC",value=125}},nil} c["Skills have a 150% longer Perfect Timing window"]={{[1]={flags=0,keywordFlags=0,name="PerfectTiming",type="INC",value=150}},nil} c["Skills reserve 50% less Spirit"]={nil,"Skills reserve 50% less Spirit "} diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index a30e31d078..edd7f5baab 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -278,15 +278,16 @@ end function calcSkillCooldown(skillModList, skillCfg, skillData) local cooldownOverride = skillModList:Override(skillCfg, "CooldownRecovery") local addedCooldown = skillModList:Sum("BASE", skillCfg, "CooldownRecovery") + local noCooldownChance = skillModList:Sum("BASE", skillCfg, "CooldownChanceNotConsume") local cooldown = cooldownOverride or ((skillData.cooldown or 0) + addedCooldown) / m_max(0, calcLib.mod(skillModList, skillCfg, "CooldownRecovery")) -- If a skill can store extra uses and has a cooldown, it doesn't round the cooldown value to server ticks local rounded = false if (skillData.storedUses and skillData.storedUses > 1) or (skillData.VaalStoredUses and skillData.VaalStoredUses > 1) or skillModList:Sum("BASE", skillCfg, "AdditionalCooldownUses") > 0 then - return cooldown, rounded + return cooldown, rounded, nil, noCooldownChance else cooldown = m_ceil(cooldown * data.misc.ServerTickRate) / data.misc.ServerTickRate rounded = true - return cooldown, rounded, addedCooldown + return cooldown, rounded, addedCooldown, noCooldownChance end end @@ -1255,13 +1256,33 @@ function calcs.offence(env, actor, activeSkill) breakdown.TrapTriggerRadius = breakdown.area(data.misc.TrapTriggerRadiusBase, areaMod, output.TrapTriggerRadius, incAreaBreakpoint, moreAreaBreakpoint, redAreaBreakpoint, lessAreaBreakpoint) end elseif skillData.cooldown or skillModList:Sum("BASE", skillCfg, "CooldownRecovery") ~= 0 then - local cooldown, rounded, addedCooldown = calcSkillCooldown(skillModList, skillCfg, skillData) + local cooldownMode = env.configInput.cooldownMode or "BASE" + local cooldown, rounded, addedCooldown, noCooldownChance = calcSkillCooldown(skillModList, skillCfg, skillData) + local effectiveCooldownMultiplier = 1 - noCooldownChance + local effectiveCooldown = cooldown * effectiveCooldownMultiplier + output.Cooldown = cooldown + output.EffectiveCooldown = cooldown + if breakdown then breakdown.Cooldown = { s_format("%.2fs ^8(base)", skillData.cooldown or 0 + addedCooldown), s_format("/ %.2f ^8(increased/reduced cooldown recovery)", 1 + skillModList:Sum("INC", skillCfg, "CooldownRecovery") / 100), } + + if cooldownMode == "AVERAGE" then + breakdown.EffectiveCooldown = { + s_format("Effective Cooldown:"), + unpack(breakdown.Cooldown) + } + if noCooldownChance > 0 then + output.EffectiveCooldown = effectiveCooldown + t_insert(breakdown.EffectiveCooldown, s_format("* %.2f ^8(effect of %d%% chance to not consume cooldown)", effectiveCooldownMultiplier, noCooldownChance * 100)) + end + + t_insert(breakdown.EffectiveCooldown, s_format("= %.3fs", output.EffectiveCooldown)) + end + if rounded then t_insert(breakdown.Cooldown, s_format("rounded up to nearest server tick")) end diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index 25b10630b5..5a58a0cff6 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -630,9 +630,10 @@ return { { breakdown = "QuantityMultiplier" }, { modName = { "QuantityMultiplier" }, cfg = "skill" }, }, }, - { label = "Skill Cooldown", haveOutput = "Cooldown", { format = "{3:output:Cooldown}s", + { label = "Skill Cooldown", haveOutput = "Cooldown", { format = "{3:output:EffectiveCooldown}s", { breakdown = "Cooldown" }, - { modName = "CooldownRecovery", cfg = "skill" }, + { breakdown = "EffectiveCooldown" }, + { modName = {"CooldownRecovery", "CooldownChanceNotConsume"}, cfg = "skill" }, }, }, { label = "Stored Uses", haveOutput = "StoredUses", { format = "{output:StoredUses}", { breakdown = "StoredUses" }, diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index a34819e668..10d5838746 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -153,6 +153,7 @@ local configSettings = { modList:NewMod("Condition:MinionsCreatedRecently", "FLAG", true, "Config") end }, { var = "ailmentMode", type = "list", label = "Ailment calculation mode:", tooltip = "Controls how the base damage for applying Ailments is calculated:\n\tAverage: damage is based on the average application, including both crits and non-crits\n\tCrits Only: damage is based solely on Ailments inflicted with crits", list = {{val="AVERAGE",label="Average"},{val="CRIT",label="Crits Only"}} }, + { var = "cooldownMode", type = "list", label = "Cooldown calculation mode:", tooltip = "Controls how the cooldown for skills is calculated:\n\tBase: The cooldown is calculated with normal behavior.\n\tAverage: The cooldown is adjusted to reflect the average time between uses, factoring in effects such as a chance to not consume a cooldown.", list = {{val="BASE",label="Base"},{val="AVERAGE",label="Average"}} }, { var = "physMode", type = "list", label = "Random element mode:", ifFlag = "randomPhys", tooltip = "Controls how modifiers which choose a random element will function.\n\tAverage: Modifiers will grant one third of their value to ^xB97123Fire^7, ^x3F6DB3Cold^7, and ^xADAA47Lightning ^7simultaneously\n\t^xB97123Fire ^7/ ^x3F6DB3Cold ^7/ ^xADAA47Lightning^7: Modifiers will grant their full value as the specified element\nIf a modifier chooses between just two elements, the full value can only be given as those two elements.", list = {{val="AVERAGE",label="Average"},{val="FIRE",label="^xB97123Fire"},{val="COLD",label="^x3F6DB3Cold"},{val="LIGHTNING",label="^xADAA47Lightning"}} }, { var = "lifeRegenMode", type = "list", label = "^xE05030Life ^7regen calculation mode:", ifCond = { "LifeRegenBurstAvg", "LifeRegenBurstFull" }, tooltip = "Controls how ^xE05030life ^7regeneration is calculated:\n\tMinimum: does not include burst regen\n\tAverage: includes burst regen, averaged based on uptime\n\tBurst: includes full burst regen", list = {{val="MIN",label="Minimum"},{val="AVERAGE",label="Average"},{val="FULL",label="Burst"}}, apply = function(val, modList, enemyModList) if val == "AVERAGE" then diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 6d958192f3..e252f05096 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2834,6 +2834,10 @@ local specialModList = { ["effect and duration of flames of chayula on you is doubled"] = function() return { mod("Multiplier:FlameEffect", "BASE", 1), } end, + -- Chronomancer + ["skills have (%d+)%% chance to not consume a cooldown when used"] = function(num) return { + mod("CooldownChanceNotConsume", "BASE", num / 100, { type = "SkillType", skillType = SkillType.Cooldown }) + } end, -- Item local modifiers ["has no sockets"] = { flag("NoSockets") }, ["reflects your other ring"] = { From e7665cb53efc1019b985de048648e28598d0e11b Mon Sep 17 00:00:00 2001 From: Igor Wessel Date: Tue, 21 Jan 2025 06:13:45 -0300 Subject: [PATCH 3/3] refactor improve condition check for cooldownMode --- src/Modules/CalcOffence.lua | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index edd7f5baab..1e593d7581 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -1270,16 +1270,13 @@ function calcs.offence(env, actor, activeSkill) s_format("/ %.2f ^8(increased/reduced cooldown recovery)", 1 + skillModList:Sum("INC", skillCfg, "CooldownRecovery") / 100), } - if cooldownMode == "AVERAGE" then + if cooldownMode == "AVERAGE" and noCooldownChance > 0 then + output.EffectiveCooldown = effectiveCooldown breakdown.EffectiveCooldown = { s_format("Effective Cooldown:"), - unpack(breakdown.Cooldown) + unpack(breakdown.Cooldown), } - if noCooldownChance > 0 then - output.EffectiveCooldown = effectiveCooldown - t_insert(breakdown.EffectiveCooldown, s_format("* %.2f ^8(effect of %d%% chance to not consume cooldown)", effectiveCooldownMultiplier, noCooldownChance * 100)) - end - + t_insert(breakdown.EffectiveCooldown, s_format("* %.2f ^8(effect of %d%% chance to not consume cooldown)", effectiveCooldownMultiplier, noCooldownChance * 100)) t_insert(breakdown.EffectiveCooldown, s_format("= %.3fs", output.EffectiveCooldown)) end