From cb1faaf08fb386844dea9cfa24d26b075bc89c82 Mon Sep 17 00:00:00 2001 From: Nighty Date: Tue, 23 Jul 2024 12:37:52 +1000 Subject: [PATCH 01/26] use camelCase (#7840) --- src/Modules/Main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 806e9d383e..e5b2479b83 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -978,7 +978,7 @@ function main:OpenOptionsPopup() local initialThousandsSeparator = self.thousandsSeparator local initialDecimalSeparator = self.decimalSeparator local initialBetaTest = self.betaTest - local initialedgeSearchHighlight = self.edgeSearchHighlight + local initialEdgeSearchHighlight = self.edgeSearchHighlight local initialDefaultGemQuality = self.defaultGemQuality or 0 local initialDefaultCharLevel = self.defaultCharLevel or 1 local initialDefaultItemAffixQuality = self.defaultItemAffixQuality or 0.5 @@ -1027,7 +1027,7 @@ function main:OpenOptionsPopup() self.decimalSeparator = initialDecimalSeparator self.showTitlebarName = initialTitlebarName self.betaTest = initialBetaTest - self.edgeSearchHighlight = initialedgeSearchHighlight + self.edgeSearchHighlight = initialEdgeSearchHighlight self.defaultGemQuality = initialDefaultGemQuality self.defaultCharLevel = initialDefaultCharLevel self.defaultItemAffixQuality = initialDefaultItemAffixQuality From dd4f7a32222acc676e1cc90523cfb055a29a809c Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:47:25 +1000 Subject: [PATCH 02/26] Update Death Aura damage with 3.25 changes (#7842) Now has a base of 1000dps Co-authored-by: LocalIdentity --- src/Data/Skills/other.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index 663f6258ea..7edd0447cf 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -790,7 +790,7 @@ skills["ChaosDegenAuraUnique"] = { skill("radius", 30), }, constantStats = { - { "base_chaos_damage_to_deal_per_minute", 45500 }, + { "base_chaos_damage_to_deal_per_minute", 60000 }, }, stats = { "cast_on_gain_skill", From 606d8c1375b2ce4c2998d19a78ca0529ee55ccf1 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:47:33 +1000 Subject: [PATCH 03/26] Fix Herald of Ash Phys as extra Fire scaling (#7839) Co-authored-by: LocalIdentity --- src/Data/Skills/act_str.lua | 82 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 32bacdcd8f..f7042316ef 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -5062,56 +5062,56 @@ skills["HeraldOfAsh"] = { }, }, constantStats = { - { "physical_damage_%_to_add_as_fire", 15 }, { "base_skill_effect_duration", 4000 }, { "herald_of_ash_burning_%_overkill_damage_per_minute", 1500 }, }, stats = { "herald_of_ash_burning_damage_+%_final", + "physical_damage_%_to_add_as_fire", "is_area_damage", "quality_display_herald_of_ash_is_gem", }, levels = { - [1] = {15, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 16, statInterpolation = { 1, 1, }, }, - [2] = {15, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 20, statInterpolation = { 1, 1, }, }, - [3] = {16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 24, statInterpolation = { 1, 1, }, }, - [4] = {16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 28, statInterpolation = { 1, 1, }, }, - [5] = {16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 31, statInterpolation = { 1, 1, }, }, - [6] = {16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 34, statInterpolation = { 1, 1, }, }, - [7] = {17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 37, statInterpolation = { 1, 1, }, }, - [8] = {17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 40, statInterpolation = { 1, 1, }, }, - [9] = {17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 43, statInterpolation = { 1, 1, }, }, - [10] = {17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 46, statInterpolation = { 1, 1, }, }, - [11] = {18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 49, statInterpolation = { 1, 1, }, }, - [12] = {18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 52, statInterpolation = { 1, 1, }, }, - [13] = {18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 55, statInterpolation = { 1, 1, }, }, - [14] = {18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 58, statInterpolation = { 1, 1, }, }, - [15] = {19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 60, statInterpolation = { 1, 1, }, }, - [16] = {19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 62, statInterpolation = { 1, 1, }, }, - [17] = {19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 64, statInterpolation = { 1, 1, }, }, - [18] = {19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 66, statInterpolation = { 1, 1, }, }, - [19] = {20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 68, statInterpolation = { 1, 1, }, }, - [20] = {20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 70, statInterpolation = { 1, 1, }, }, - [21] = {20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 72, statInterpolation = { 1, 1, }, }, - [22] = {21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 74, statInterpolation = { 1, 1, }, }, - [23] = {21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 76, statInterpolation = { 1, 1, }, }, - [24] = {21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 78, statInterpolation = { 1, 1, }, }, - [25] = {21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 80, statInterpolation = { 1, 1, }, }, - [26] = {22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 82, statInterpolation = { 1, 1, }, }, - [27] = {22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 84, statInterpolation = { 1, 1, }, }, - [28] = {22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 86, statInterpolation = { 1, 1, }, }, - [29] = {22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 88, statInterpolation = { 1, 1, }, }, - [30] = {23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 90, statInterpolation = { 1, 1, }, }, - [31] = {23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 91, statInterpolation = { 1, 1, }, }, - [32] = {23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 92, statInterpolation = { 1, 1, }, }, - [33] = {23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 93, statInterpolation = { 1, 1, }, }, - [34] = {24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 94, statInterpolation = { 1, 1, }, }, - [35] = {24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 95, statInterpolation = { 1, 1, }, }, - [36] = {24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 96, statInterpolation = { 1, 1, }, }, - [37] = {24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 97, statInterpolation = { 1, 1, }, }, - [38] = {25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 98, statInterpolation = { 1, 1, }, }, - [39] = {25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 99, statInterpolation = { 1, 1, }, }, - [40] = {25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 100, statInterpolation = { 1, 1, }, }, + [1] = { 0, 15, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 16, statInterpolation = { 1, 1, }, }, + [2] = { 2, 15, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 20, statInterpolation = { 1, 1, }, }, + [3] = { 4, 16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 24, statInterpolation = { 1, 1, }, }, + [4] = { 6, 16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 28, statInterpolation = { 1, 1, }, }, + [5] = { 8, 16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 31, statInterpolation = { 1, 1, }, }, + [6] = { 10, 16, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 34, statInterpolation = { 1, 1, }, }, + [7] = { 12, 17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 37, statInterpolation = { 1, 1, }, }, + [8] = { 14, 17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 40, statInterpolation = { 1, 1, }, }, + [9] = { 16, 17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 43, statInterpolation = { 1, 1, }, }, + [10] = { 18, 17, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 46, statInterpolation = { 1, 1, }, }, + [11] = { 20, 18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 49, statInterpolation = { 1, 1, }, }, + [12] = { 22, 18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 52, statInterpolation = { 1, 1, }, }, + [13] = { 24, 18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 55, statInterpolation = { 1, 1, }, }, + [14] = { 26, 18, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 58, statInterpolation = { 1, 1, }, }, + [15] = { 28, 19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 60, statInterpolation = { 1, 1, }, }, + [16] = { 30, 19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 62, statInterpolation = { 1, 1, }, }, + [17] = { 32, 19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 64, statInterpolation = { 1, 1, }, }, + [18] = { 34, 19, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 66, statInterpolation = { 1, 1, }, }, + [19] = { 36, 20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 68, statInterpolation = { 1, 1, }, }, + [20] = { 38, 20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 70, statInterpolation = { 1, 1, }, }, + [21] = { 40, 20, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 72, statInterpolation = { 1, 1, }, }, + [22] = { 42, 21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 74, statInterpolation = { 1, 1, }, }, + [23] = { 44, 21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 76, statInterpolation = { 1, 1, }, }, + [24] = { 46, 21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 78, statInterpolation = { 1, 1, }, }, + [25] = { 48, 21, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 80, statInterpolation = { 1, 1, }, }, + [26] = { 50, 22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 82, statInterpolation = { 1, 1, }, }, + [27] = { 52, 22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 84, statInterpolation = { 1, 1, }, }, + [28] = { 54, 22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 86, statInterpolation = { 1, 1, }, }, + [29] = { 56, 22, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 88, statInterpolation = { 1, 1, }, }, + [30] = { 58, 23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 90, statInterpolation = { 1, 1, }, }, + [31] = { 59, 23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 91, statInterpolation = { 1, 1, }, }, + [32] = { 60, 23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 92, statInterpolation = { 1, 1, }, }, + [33] = { 61, 23, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 93, statInterpolation = { 1, 1, }, }, + [34] = { 62, 24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 94, statInterpolation = { 1, 1, }, }, + [35] = { 63, 24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 95, statInterpolation = { 1, 1, }, }, + [36] = { 64, 24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 96, statInterpolation = { 1, 1, }, }, + [37] = { 65, 24, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 97, statInterpolation = { 1, 1, }, }, + [38] = { 66, 25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 98, statInterpolation = { 1, 1, }, }, + [39] = { 67, 25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 99, statInterpolation = { 1, 1, }, }, + [40] = { 68, 25, storedUses = 1, manaReservationPercent = 25, cooldown = 1, levelRequirement = 100, statInterpolation = { 1, 1, }, }, }, } skills["HeraldOfPurity"] = { From 87b8ddccc2d648ada5642a440d56ed489c85b0ac Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:47:42 +1000 Subject: [PATCH 04/26] Fix Seismic Cry AoE calculation (#7837) The calculation was being based off the uptime of the Warcry instead of the uptime of the exerted attacks it provides Co-authored-by: LocalIdentity --- src/Modules/CalcOffence.lua | 6 ++++++ src/Modules/CalcPerform.lua | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 1c994e746b..db21080371 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2496,6 +2496,12 @@ function calcs.offence(env, actor, activeSkill) local baseUptimeRatio = m_min((globalOutput.SeismicExertsCount / output.Speed) / (globalOutput.SeismicCryCooldown + globalOutput.SeismicCryCastTime), 1) * 100 local storedUses = value.skillData.storedUses + value.skillModList:Sum("BASE", value.skillCfg, "AdditionalCooldownUses") globalOutput.SeismicUpTimeRatio = m_min(100, baseUptimeRatio * storedUses) + -- account for AoE increase + if activeSkill.skillModList:Flag(nil, "Condition:WarcryMaxHit") then + skillModList:NewMod("AreaOfEffect", "MORE", env.modDB:Sum("BASE", nil, "SeismicMoreAoE"), "Max Seismic Exert AoE") + else + skillModList:NewMod("AreaOfEffect", "MORE", m_floor(env.modDB:Sum("BASE", nil, "SeismicMoreAoE") / 100 * globalOutput.SeismicUpTimeRatio), "Avg Seismic Exert AoE") + end if globalBreakdown then globalBreakdown.SeismicUpTimeRatio = { } t_insert(globalBreakdown.SeismicUpTimeRatio, s_format("(%d ^8(number of exerts)", globalOutput.SeismicExertsCount)) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index f3586b4dcb..8092d033bc 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -1212,9 +1212,8 @@ function calcs.perform(env, skipEHP) elseif activeSkill.activeEffect.grantedEffect.name == "Seismic Cry" and not modDB:Flag(nil, "SeismicActive") then local seismicStunEffect = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicStunThresholdPer5MP") local seismicArmour = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicArmourPer5MP") - local SeismicAoEMoreMultiplier = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicAoEMoreMultiplier") + env.player.modDB:NewMod("SeismicMoreAoE", "BASE", activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicAoEMoreMultiplier")) env.player.modDB:NewMod("NumSeismicExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("AreaOfEffect", "MORE", SeismicAoEMoreMultiplier * uptime, "Seismic Cry") env.player.modDB:NewMod("StunThreshold", "INC", m_floor(seismicStunEffect * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) env.player.modDB:NewMod("Armour", "MORE", m_floor(seismicArmour * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) modDB:NewMod("SeismicActive", "FLAG", true) -- Prevents effect from applying multiple times From acef6f605c18f0aa80ec801e549c3005e389cc8d Mon Sep 17 00:00:00 2001 From: Cheese Date: Tue, 23 Jul 2024 17:35:39 +0200 Subject: [PATCH 05/26] Fix impale not using enemy damage taken (#7831) * Fix impale not using enemy damage taken (#7787) * Fix impale using post mitigation damage for crits `output.impaleStoredHitAvg` already combines crit and non-crits * Add tests for Impale damage Testing combinations of: - 0%/50%/100% crit chance - enemies take increased damage - physical reduction and armour - dual wield * Add extra tests for Impale damage --------- Co-authored-by: Cheese <12050603+mcheese@users.noreply.github.com> --- spec/System/TestImpale_spec.lua | 287 ++++++++++++++++++++++++++++++++ src/Modules/CalcOffence.lua | 13 +- 2 files changed, 295 insertions(+), 5 deletions(-) create mode 100644 spec/System/TestImpale_spec.lua diff --git a/spec/System/TestImpale_spec.lua b/spec/System/TestImpale_spec.lua new file mode 100644 index 0000000000..69809660b6 --- /dev/null +++ b/spec/System/TestImpale_spec.lua @@ -0,0 +1,287 @@ +describe("TestAttacks", function() + before_each(function() + newBuild() + -- exactly 200 damage + build.itemsTab:CreateDisplayItemFromRaw("New Item\nVaal Greatsword\nQuality: 0\nAdds 132 to 58 physical damage\n150% chance to Impale Enemies on Hit with Attacks") + build.itemsTab:AddDisplayItem() + build.itemsTab:CreateDisplayItemFromRaw("New Item\nPaua Amulet\nYour hits can't be evaded\n-20 strength\n") + build.itemsTab:AddDisplayItem() + end) + + teardown(function() + -- newBuild() takes care of resetting everything in setup() + end) + + it("basic impale", function() + -- 0% crit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.ImpaleChance) + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.ImpaleChanceOnCrit) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(100*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + + -- 50% crit + build.configTab.input.customMods = "\z + +45% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(300, build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(250, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(250, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(125*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + + -- 100% crit + build.configTab.input.customMods = "\z + +100% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(300, build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(300, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(150*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + end) + + it("impale with inc damage taken", function() + -- 0% crit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + Nearby enemies take 100% increased physical damage\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(400, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(200*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + + -- 50% crit + build.configTab.input.customMods = "\z + +45% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + Nearby enemies take 100% increased physical damage\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(400, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(600, build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(250, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(250, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(250*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + + -- 100% crit + build.configTab.input.customMods = "\z + +100% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + Nearby enemies take 100% increased physical damage\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(400, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(600, build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(300, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(300, build.calcsTab.mainOutput.ImpaleHit) + assert.are.equals(300*1.3, build.calcsTab.mainOutput.ImpaleDPS) -- 5 impales * 10% stored damage * 1.3 attacks per second + end) + + it("impale with physical reduction", function() + -- 0% crit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + " + build.configTab.input.enemyPhysicalReduction = 10 + build.configTab.input.enemyArmour = 1000 -- 50% dr for 200 damage, 66.6% dr for 100 dmg (impale stacks) + build.configTab:BuildModList() + runCallback("OnFrame") + + -- dam * (1 - (armourDR + additionalDR) + assert.are.equals(200 * (1 - (0.5 + 0.1)), build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + -- [5 impales * 10% stored damage] * 1.3 attacks * (armour mod - phys DR) + assert.are.near(100 * 1.3 * (1 - (2/3 + 0.1)), build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) -- floating point math + + + -- 100% crit + build.configTab.input.customMods = "\z + +100% critical strike chance\n\z + " + build.configTab.input.enemyPhysicalReduction = 10 + build.configTab.input.enemyArmour = 1500 -- 50% dr for 300 damage, 66.6% dr for 150 dmg (impale stacks) + build.configTab:BuildModList() + runCallback("OnFrame") + + -- dam * (1 - (armourDR + additionalDR) + assert.are.equals(300 * (1 - (0.5 + 0.1)), build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(300, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(300, build.calcsTab.mainOutput.ImpaleHit) + -- [5 impales * 10% stored damage] * 1.3 attacks * (armour mod - phys DR) + assert.are.near(150 * 1.3 * (1 - (2/3 + 0.1)), build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) -- floating point math + + end) + + it("impale with physical reduction and inc damage taken", function() + -- 0% crit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Nearby enemies take 100% increased physical damage\n\z + " + build.configTab.input.enemyPhysicalReduction = 10 + build.configTab.input.enemyArmour = 1000 -- 50% dr for 200 damage, 66.6% dr for 100 dmg (impale stacks) .. damage taken is after armour + build.configTab:BuildModList() + runCallback("OnFrame") + + -- taken * dam * (1 - (armourDR + additionalDR) + assert.are.equals(2 * 200 * (1 - (0.5 + 0.1)), build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + -- taken * [5 impales * 10% stored damage] * 1.3 attacks * (armour mod - phys DR) + assert.are.near(2 * 100 * 1.3 * (1 - (2/3 + 0.1)), build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) -- floating point math + + + -- 100% crit + build.configTab.input.customMods = "\z + +100% critical strike chance\n\z + Nearby enemies take 100% increased physical damage\n\z + " + build.configTab.input.enemyPhysicalReduction = 10 + build.configTab.input.enemyArmour = 1500 -- 50% dr for 300 damage, 66.6% dr for 150 dmg (impale stacks) + build.configTab:BuildModList() + runCallback("OnFrame") + + -- taken * dam * (1 - (armourDR + additionalDR) + assert.are.equals(2 * 300 * (1 - (0.5 + 0.1)), build.calcsTab.mainOutput.MainHand.PhysicalCritAverage) + assert.are.equals(300, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(300, build.calcsTab.mainOutput.ImpaleHit) + -- taken * [5 impales * 10% stored damage] * 1.3 attacks * (armour mod - phys DR) + assert.are.near(2 * 150 * 1.3 * (1 - (2/3 + 0.1)), build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) -- floating point math + + end) + + it("impale dual wield", function() + newBuild() + -- exactly 100 + build.itemsTab:CreateDisplayItemFromRaw("New Item\nVaal Blade\nQuality: 0\nAdds 54 to 14 physical damage\n150% chance to Impale Enemies on Hit with Attacks") + build.itemsTab:AddDisplayItem() + -- exactly 200 offhand + build.itemsTab:CreateDisplayItemFromRaw("New Item\nVaal Blade\nQuality: 0\nAdds 54 to 14 physical damage\n100% increased Physical Damage\n150% chance to Impale Enemies on Hit with Attacks") + build.itemsTab:AddDisplayItem() + build.itemsTab:CreateDisplayItemFromRaw("New Item\nPaua Amulet\nYour hits can't be evaded\n-20 strength\n") + build.itemsTab:AddDisplayItem() + + + -- 0% crit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.ImpaleChance) + assert.are.equals(100, build.calcsTab.mainOutput.OffHand.ImpaleChance) + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.ImpaleChanceOnCrit) + assert.are.equals(100, build.calcsTab.mainOutput.OffHand.ImpaleChanceOnCrit) + + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.OffHand.PhysicalHitAverage) + assert.are.equals(100, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.OffHand.impaleStoredHitAvg) + + assert.are.equals(150, build.calcsTab.mainOutput.ImpaleHit) + -- 5 impales * 10% stored damage * 1.3 attacks per second * 1.1 dual wield modifier + assert.are.near(75*1.3*1.1, build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) + + + -- 50% crit + build.configTab.input.customMods = "\z + +45% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(125, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(250, build.calcsTab.mainOutput.OffHand.impaleStoredHitAvg) + + assert.are.equals(187.5, build.calcsTab.mainOutput.ImpaleHit) + -- 5 impales * 10% stored damage * 1.3 attacks per second * 1.1 dual wield modifier + assert.are.near(187.5/2*1.3*1.1, build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) + + + -- 50% crit + build.configTab.input.customMods = "\z + +100% critical strike chance\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(150, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(300, build.calcsTab.mainOutput.OffHand.impaleStoredHitAvg) + + assert.are.equals(225, build.calcsTab.mainOutput.ImpaleHit) + -- 5 impales * 10% stored damage * 1.3 attacks per second * 1.1 dual wield modifier + assert.are.near(225/2*1.3*1.1, build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) + + end) + + it("impale with extra mods", function() + -- inc effect + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + 50% increased Impale Effect\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + assert.are.near(100*1.3*1.5, build.calcsTab.mainOutput.ImpaleDPS, 0.00000001) -- 5 impales * 10% stored damage * 1.3 attacks per second * 1.5 impale effect + + -- last 1 extra hit + build.configTab.input.customMods = "\z + never deal critical strikes\n\z + Impale Damage dealt to Enemies Impaled by you Overwhelms 100% Physical Damage Reduction\n\z + Overwhelm 100% physical damage reduction\n\z + Impales you inflict last 1 additional Hit\n\z + " + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.PhysicalHitAverage) + assert.are.equals(200, build.calcsTab.mainOutput.MainHand.impaleStoredHitAvg) + assert.are.equals(200, build.calcsTab.mainOutput.ImpaleHit) + assert.are.near(120*1.3, build.calcsTab.mainOutput.ImpaleDPS, 0.0000001) -- 6 impales * 10% stored damage * 1.3 attacks per second + end) + +end) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index db21080371..d62cf77ee2 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -4911,8 +4911,8 @@ function calcs.offence(env, actor, activeSkill) if skillModList:Flag(cfg, "IgnoreEnemyImpalePhysicalDamageReduction") then impaleResist = 0 end - - local impaleDMGModifier = impaleHitDamageMod * (1 - impaleResist / 100) * impaleChance + local impaleTaken = (1 + enemyDB:Sum("INC", nil, "DamageTaken", "PhysicalDamageTaken") / 100) * enemyDB:More(nil, "DamageTaken", "PhysicalDamageTaken") + local impaleDMGModifier = impaleHitDamageMod * (1 - impaleResist / 100) * impaleChance * impaleTaken globalOutput.ImpaleStacksMax = maxStacks globalOutput.ImpaleStacks = impaleStacks @@ -4932,6 +4932,9 @@ function calcs.offence(env, actor, activeSkill) t_insert(breakdown.ImpaleModifier, s_format("x %.3f ^8(stored damage)", impaleStoredDamage)) t_insert(breakdown.ImpaleModifier, s_format("x %.2f ^8(impale chance)", impaleChance)) t_insert(breakdown.ImpaleModifier, s_format("x %.2f ^8(impale enemy physical damage reduction)", (1 - impaleResist / 100))) + if impaleTaken ~= 1 then + t_insert(breakdown.ImpaleModifier, s_format("x %.2f ^8(impale enemy damage taken)", impaleTaken)) + end t_insert(breakdown.ImpaleModifier, s_format("= %.3f ^8(impale damage multiplier)", impaleDMGModifier)) end end @@ -5377,12 +5380,12 @@ function calcs.offence(env, actor, activeSkill) end if skillFlags.impale then if skillFlags.attack then - output.ImpaleHit = ((output.MainHand.impaleStoredHitAvg or output.OffHand.impaleStoredHitAvg) + (output.OffHand.impaleStoredHitAvg or output.MainHand.impaleStoredHitAvg)) / 2 * (1-output.CritChance/100) + ((output.MainHand.PhysicalCritAverage or output.OffHand.PhysicalCritAverage) + (output.OffHand.PhysicalCritAverage or output.MainHand.PhysicalCritAverage)) / 2 * (output.CritChance/100) + output.ImpaleHit = ((output.MainHand.impaleStoredHitAvg or output.OffHand.impaleStoredHitAvg) + (output.OffHand.impaleStoredHitAvg or output.MainHand.impaleStoredHitAvg)) / 2 if skillData.doubleHitsWhenDualWielding and skillFlags.bothWeaponAttack then output.ImpaleHit = output.ImpaleHit * 2 end else - output.ImpaleHit = output.impaleStoredHitAvg * (1-output.CritChance/100) + output.PhysicalCritAverage * (output.CritChance/100) + output.ImpaleHit = output.impaleStoredHitAvg end output.ImpaleDPS = output.ImpaleHit * ((output.ImpaleModifier or 1) - 1) * output.HitChance / 100 * skillData.dpsMultiplier if skillData.showAverage then @@ -5399,7 +5402,7 @@ function calcs.offence(env, actor, activeSkill) output.CombinedDPS = output.CombinedDPS + output.ImpaleDPS if breakdown then breakdown.ImpaleDPS = {} - t_insert(breakdown.ImpaleDPS, s_format("%.2f ^8(average physical hit)", output.ImpaleHit)) + t_insert(breakdown.ImpaleDPS, s_format("%.2f ^8(average physical hit before mitigation)", output.ImpaleHit)) t_insert(breakdown.ImpaleDPS, s_format("x %.2f ^8(chance to hit)", output.HitChance / 100)) if skillFlags.notAverage then t_insert(breakdown.ImpaleDPS, output.HitSpeed and s_format("x %.2f ^8(hit rate)", output.HitSpeed) or s_format("x %.2f ^8(%s rate)", output.Speed, skillFlags.attack and "attack" or "cast")) From 322741f2dd1858a3bd822460dfcfb193fc7cebcc Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 03:18:06 +1000 Subject: [PATCH 06/26] Fix Rage Effect not applying to "per x Rage" mods (#7866) Rage effect should be applying to mods that use the `per x Rage` wording as stated in the patch notes `Rage effect applies to the damage inherently granted by Rage, and other bonuses granted per X Rage if you have any. Bonuses while you have a certain amount of Rage, or other effects that refer to your Rage but do not cause Rage to grant additional stats, are not affected.` Co-authored-by: LocalIdentity --- src/Data/ModCache.lua | 12 ++++++------ src/Modules/ModParser.lua | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 1d6ecf1626..1c80ef4685 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -214,7 +214,7 @@ c["+1% to Critical Strike Chance while affected by Aspect of the Cat"]={{[1]={[1 c["+1% to Critical Strike Multiplier per 1% Block Chance"]={{[1]={[1]={div=1,stat="BlockChance",type="PerStat"},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=1}},nil} c["+1% to Critical Strike Multiplier per 1% Chance to Block Attack Damage"]={{[1]={[1]={div=1,stat="BlockChance",type="PerStat"},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=1}},nil} c["+1% to Critical Strike Multiplier per 10 Maximum Energy Shield on Shield"]={{[1]={[1]={div=10,stat="EnergyShieldOnWeapon 2",type="PerStat"},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=1}},nil} -c["+1% to Damage over Time Multiplier for Bleeding per Rage while wielding an Axe"]={{[1]={[1]={type="Multiplier",var="Rage"},[2]={type="Condition",var="UsingAxe"},flags=0,keywordFlags=4194304,name="DotMultiplier",type="BASE",value=1}},nil} +c["+1% to Damage over Time Multiplier for Bleeding per Rage while wielding an Axe"]={{[1]={[1]={type="Multiplier",var="RageEffect"},[2]={type="Condition",var="UsingAxe"},flags=0,keywordFlags=4194304,name="DotMultiplier",type="BASE",value=1}},nil} c["+1% to Off Hand Critical Strike Chance while Dual Wielding"]={{[1]={[1]={type="Condition",var="OffHandAttack"},[2]={skillType=1,type="SkillType"},[3]={type="Condition",var="DualWielding"},flags=0,keywordFlags=0,name="CritChance",type="BASE",value=1}},nil} c["+1% to all maximum Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=1}},nil} c["+1% to all maximum Elemental Resistances if Equipped Helmet, Body Armour, Gloves, and Boots all have Armour"]={{[1]={[1]={stat="ArmourOnHelmet",threshold=1,type="StatThreshold"},[2]={stat="ArmourOnBody Armour",threshold=1,type="StatThreshold"},[3]={stat="ArmourOnGloves",threshold=1,type="StatThreshold"},[4]={stat="ArmourOnBoots",threshold=1,type="StatThreshold"},flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=1}},nil} @@ -604,7 +604,7 @@ c["+2% Chance to Block Spell Damage per Power Charge"]={{[1]={[1]={type="Multipl c["+2% chance to Suppress Spell Damage"]={{[1]={flags=0,keywordFlags=0,name="SpellSuppressionChance",type="BASE",value=2}},nil} c["+2% to Critical Strike Chance against Enemies on Consecrated Ground during Effect"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="OnConsecratedGround"},[2]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="CritChance",type="BASE",value=2}},nil} c["+2% to Critical Strike Chance while affected by Hatred"]={{[1]={[1]={type="Condition",var="AffectedByHatred"},flags=0,keywordFlags=0,name="CritChance",type="BASE",value=2}},nil} -c["+2% to Damage over Time Multiplier for Bleeding per Rage while wielding an Axe"]={{[1]={[1]={type="Multiplier",var="Rage"},[2]={type="Condition",var="UsingAxe"},flags=0,keywordFlags=4194304,name="DotMultiplier",type="BASE",value=2}},nil} +c["+2% to Damage over Time Multiplier for Bleeding per Rage while wielding an Axe"]={{[1]={[1]={type="Multiplier",var="RageEffect"},[2]={type="Condition",var="UsingAxe"},flags=0,keywordFlags=4194304,name="DotMultiplier",type="BASE",value=2}},nil} c["+2% to all Elemental Resistances per 10 Devotion"]={{[1]={[1]={actor="parent",div=10,stat="Devotion",type="PerStat"},flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=2}},nil} c["+2% to all maximum Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=2}},nil} c["+2% to all maximum Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=2},[2]={flags=0,keywordFlags=0,name="ChaosResistMax",type="BASE",value=2}},nil} @@ -1917,7 +1917,7 @@ c["1% increased Maximum Life per Abyss Jewel affecting you"]={{[1]={[1]={type="M c["1% increased Maximum Mana per Abyss Jewel affecting you"]={{[1]={[1]={type="Multiplier",var="AbyssJewel"},flags=0,keywordFlags=0,name="Mana",type="INC",value=1}},nil} c["1% increased Melee Physical Damage per 10 Dexterity"]={{[1]={[1]={div=10,stat="Dex",type="PerStat"},flags=256,keywordFlags=0,name="PhysicalDamage",type="INC",value=1}},nil} c["1% increased Minion Attack and Cast Speed per 10 Devotion"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={actor="parent",div=10,stat="Devotion",type="PerStat"},flags=0,keywordFlags=0,name="Speed",type="INC",value=1}}}},nil} -c["1% increased Movement Speed per 5 Rage"]={{[1]={[1]={div=5,type="Multiplier",var="Rage"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} +c["1% increased Movement Speed per 5 Rage"]={{[1]={[1]={div=5,type="Multiplier",var="RageEffect"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} c["1% increased Movement Speed per 600 Evasion Rating, up to 75%"]={{[1]={[1]={div=600,limit=75,limitTotal=true,stat="Evasion",type="PerStat"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} c["1% increased Movement Speed per Frenzy Charge"]={{[1]={[1]={type="Multiplier",var="FrenzyCharge"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} c["1% increased Movement Speed per Summoned Totem"]={{[1]={[1]={stat="TotemsSummoned",type="PerStat"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=1}},nil} @@ -5517,7 +5517,7 @@ c["6% increased Mana Reservation Efficiency of Skills"]={{[1]={flags=0,keywordFl c["6% increased Maximum Life for each Corrupted Item Equipped"]={{[1]={[1]={type="Multiplier",var="CorruptedItem"},flags=0,keywordFlags=0,name="Life",type="INC",value=6}},nil} c["6% increased Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=6}},nil} c["6% increased Movement Speed per Frenzy Charge"]={{[1]={[1]={type="Multiplier",var="FrenzyCharge"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=6}},nil} -c["6% increased Physical Damage per 10 Rage"]={{[1]={[1]={div=10,type="Multiplier",var="Rage"},flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=6}},nil} +c["6% increased Physical Damage per 10 Rage"]={{[1]={[1]={div=10,type="Multiplier",var="RageEffect"},flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=6}},nil} c["6% increased Physical Damage per Endurance Charge"]={{[1]={[1]={type="Multiplier",var="EnduranceCharge"},flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=6}},nil} c["6% increased Quantity of Items found"]={{[1]={flags=0,keywordFlags=0,name="LootQuantity",type="INC",value=6}},nil} c["6% increased Spell Damage per 5% Chance to Block Attack Damage"]={{[1]={[1]={div=5,stat="BlockChance",type="PerStat"},flags=2,keywordFlags=0,name="Damage",type="INC",value=6}},nil} @@ -8028,7 +8028,7 @@ c["Gain 1 Unbound Fury when you inflict an Elemental Ailment with a Hit on an En c["Gain 1 Unbound Fury when you inflict an Elemental Ailment with a Hit on an Enemy, no more than once every 0.2 seconds for each type of Ailment Cannot gain Unbound Fury while Unbound Your Hits always inflict Freeze, Shock and Ignite while Unbound 80% more Elemental Damage while Unbound"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="BASE",value=1}}," Unbound Fury when you inflict an Elemental Ailment with a Hit on an Enemy, no more than once every 0.2 seconds for each type of Ailment Cannot gain Unbound Fury while Unbound Your Hits always inflict Freeze, Shock and Ignite while Unbound 80% more while Unbound "} c["Gain 1% of Cold Damage as Extra Fire Damage per 1% Chill Effect on Enemy"]={{[1]={[1]={actor="enemy",div=1,type="Multiplier",var="ChillEffect"},flags=0,keywordFlags=0,name="ColdDamageGainAsFire",type="BASE",value=1}},nil} c["Gain 1% of Lightning Damage as Extra Cold Damage per 2% Shock Effect on Enemy"]={{[1]={[1]={actor="enemy",div=2,type="Multiplier",var="ShockEffect"},flags=0,keywordFlags=0,name="LightningDamageGainAsCold",type="BASE",value=1}},nil} -c["Gain 1% of Physical Damage as Extra Fire Damage per 1 Rage"]={{[1]={[1]={div=1,type="Multiplier",var="Rage"},flags=0,keywordFlags=0,name="PhysicalDamageGainAsFire",type="BASE",value=1}},nil} +c["Gain 1% of Physical Damage as Extra Fire Damage per 1 Rage"]={{[1]={[1]={div=1,type="Multiplier",var="RageEffect"},flags=0,keywordFlags=0,name="PhysicalDamageGainAsFire",type="BASE",value=1}},nil} c["Gain 10 Life per Enemy Hit if you have used a Vaal Skill Recently"]={{[1]={[1]={type="Condition",var="UsedVaalSkillRecently"},flags=4,keywordFlags=0,name="LifeOnHit",type="BASE",value=10}},nil} c["Gain 10 Life per Enemy Hit with Attacks"]={{[1]={flags=4,keywordFlags=65536,name="LifeOnHit",type="BASE",value=10}},nil} c["Gain 10 Life per Enemy Killed"]={{[1]={flags=0,keywordFlags=0,name="LifeOnKill",type="BASE",value=10}},nil} @@ -8903,7 +8903,7 @@ c["Linked Targets always count as in range of Non-Curse Auras from your Skills N c["Linked Targets and Allies in your Link Beams have +5% to all Maximum Elemental Resistances"]={{[1]={[1]={threshold=1,type="MultiplierThreshold",var="LinkedTargets"},flags=0,keywordFlags=0,name="ExtraAura",type="LIST",value={mod={[1]={neg=true,type="Condition",var="AffectedByLink"},flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=5},onlyAllies=true}},[2]={flags=0,keywordFlags=0,name="ExtraLinkEffect",type="LIST",value={mod={[1]={effectType="Global",type="GlobalEffect",unscalable=true},flags=0,keywordFlags=0,name="ElementalResistMax",type="BASE",value=5}}}},nil} c["Linked targets share Endurance, Frenzy and Power Charges with you"]={nil,"Linked targets share Endurance, Frenzy and Power Charges with you "} c["Links take twice as long to break"]={nil,"Links take twice as long to break "} -c["Lose 0.1% of Life per second per Rage while you are not losing Rage"]={{[1]={[1]={percent=0.1,stat="Life",type="PercentStat"},[2]={type="Multiplier",var="Rage"},flags=0,keywordFlags=0,name="LifeDegen",type="BASE",value=1}},nil} +c["Lose 0.1% of Life per second per Rage while you are not losing Rage"]={{[1]={[1]={percent=0.1,stat="Life",type="PercentStat"},[2]={type="Multiplier",var="RageEffect"},flags=0,keywordFlags=0,name="LifeDegen",type="BASE",value=1}},nil} c["Lose 1 Bark when Hit by Enemy Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type="BASE",value=-1}}," Bark when Hit by Enemy "} c["Lose 1 Fragile Regrowth each second"]={{}," Fragile Regrowth each second "} c["Lose 1% of Energy Shield on Kill"]={{[1]={[1]={percent=1,stat="EnergyShield",type="PercentStat"},flags=0,keywordFlags=0,name="EnergyShieldOnKill",type="BASE",value=-1}},nil} diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index e76903035f..8f31015e93 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -1220,9 +1220,9 @@ local modTagList = { ["per blitz charge"] = { tag = { type = "Multiplier", var = "BlitzCharge" } }, ["per ghost shroud"] = { tag = { type = "Multiplier", var = "GhostShroud" } }, ["per crab barrier"] = { tag = { type = "Multiplier", var = "CrabBarrier" } }, - ["per rage"] = { tag = { type = "Multiplier", var = "Rage" } }, - ["per rage while you are not losing rage"] = { tag = { type = "Multiplier", var = "Rage" } }, - ["per (%d+) rage"] = function(num) return { tag = { type = "Multiplier", var = "Rage", div = num } } end, + ["per rage"] = { tag = { type = "Multiplier", var = "RageEffect" } }, + ["per rage while you are not losing rage"] = { tag = { type = "Multiplier", var = "RageEffect" } }, + ["per (%d+) rage"] = function(num) return { tag = { type = "Multiplier", var = "RageEffect", div = num } } end, ["per level"] = { tag = { type = "Multiplier", var = "Level" } }, ["per (%d+) player levels"] = function(num) return { tag = { type = "Multiplier", var = "Level", div = num } } end, ["per defiance"] = { tag = { type = "Multiplier", var = "Defiance" } }, @@ -2285,7 +2285,7 @@ local specialModList = { ["inherent effects from having rage are tripled"] = { mod("RageEffect", "MORE", 200) }, ["inherent effects from having rage are doubled"] = { mod("RageEffect", "MORE", 100) }, ["cannot be stunned while you have at least (%d+) rage"] = function(num) return { flag("StunImmune", { type = "MultiplierThreshold", var = "Rage", threshold = num }) } end, - ["lose ([%d%.]+)%% of life per second per rage while you are not losing rage"] = function(num) return { mod("LifeDegen", "BASE", 1, { type = "PercentStat", stat = "Life", percent = num }, { type = "Multiplier", var = "Rage" }) } end, + ["lose ([%d%.]+)%% of life per second per rage while you are not losing rage"] = function(num) return { mod("LifeDegen", "BASE", 1, { type = "PercentStat", stat = "Life", percent = num }, { type = "Multiplier", var = "RageEffect" }) } end, ["if you've warcried recently, you and nearby allies have (%d+)%% increased attack speed"] = function(num) return { mod("ExtraAura", "LIST", { mod = mod("Speed", "INC", num, nil, ModFlag.Attack) }, { type = "Condition", var = "UsedWarcryRecently" }) } end, ["gain (%d+)%% increased armour per (%d+) power for 8 seconds when you warcry, up to a maximum of (%d+)%%"] = function(num, _, div, limit) return { mod("Armour", "INC", num, { type = "Multiplier", var = "WarcryPower", div = tonumber(div), globalLimit = tonumber(limit), globalLimitKey = "WarningCall" }, { type = "Condition", var = "UsedWarcryInPast8Seconds" }) From c10b3f6cb8bc12104171033363310af395cc5045 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 03:18:15 +1000 Subject: [PATCH 07/26] Update Tattoo Keystones with 3.25 Changes (#7865) * Update Tattoo Keystones with 3.25 Changes Call to Arms, Vaal Pact, Imapaler and Perfect Agony were using the old stats from 3.24 * Modcache --------- Co-authored-by: LocalIdentity --- src/Data/ModCache.lua | 22 +++++----------------- src/Data/TattooPassives.lua | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 1c80ef4685..218af308c0 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -1474,8 +1474,6 @@ c["-200 Fire Damage taken from Hits"]={{[1]={flags=0,keywordFlags=0,name="FireDa c["-25 Physical Damage taken from Projectile Attacks"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageTakenFromProjectileAttacks",type="BASE",value=-25}},nil} c["-25% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="FireResist",type="BASE",value=-25}},nil} c["-25% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=-25}},nil} -c["-25% to maximum Chance to Block Attack Damage"]={{[1]={flags=0,keywordFlags=0,name="BlockChanceMax",type="BASE",value=-25}},nil} -c["-25% to maximum Chance to Block Spell Damage"]={{[1]={flags=0,keywordFlags=0,name="SpellBlockChanceMax",type="BASE",value=-25}},nil} c["-3 to maximum Fortification"]={{[1]={flags=0,keywordFlags=0,name="MaximumFortification",type="BASE",value=-3}},nil} c["-30% to Cold Resistance"]={{[1]={flags=0,keywordFlags=0,name="ColdResist",type="BASE",value=-30}},nil} c["-30% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="FireResist",type="BASE",value=-30}},nil} @@ -4517,7 +4515,6 @@ c["30% increased total Recovery per second from Life Leech"]={{[1]={flags=0,keyw c["30% increased total Recovery per second from Life, Mana, or Energy Shield Leech"]={{[1]={flags=0,keywordFlags=0,name="LifeLeechRate",type="INC",value=30},[2]={flags=0,keywordFlags=0,name="ManaLeechRate",type="INC",value=30},[3]={flags=0,keywordFlags=0,name="EnergyShieldLeechRate",type="INC",value=30}},nil} c["30% less Animate Weapon Duration"]={{[1]={[1]={includeTransfigured=true,skillName="Animate Weapon",type="SkillName"},flags=0,keywordFlags=0,name="Duration",type="MORE",value=-30}},nil} c["30% less Damage"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="MORE",value=-30}},nil} -c["30% less Damage with Hits"]={{[1]={flags=0,keywordFlags=262144,name="Damage",type="MORE",value=-30}},nil} c["30% less Life Recovery from Flasks"]={{[1]={flags=0,keywordFlags=0,name="FlaskLifeRecovery",type="MORE",value=-30}},nil} c["30% more Damage with Arrow Hits at Close Range while you have Iron Reflexes"]={{[1]={[1]={type="Condition",var="AtCloseRange"},[2]={type="Condition",var="HaveIronReflexes"},flags=131076,keywordFlags=0,name="Damage",type="MORE",value=30}},nil} c["30% more Damage with Hits and Ailments against Enemies that are on Low Life while you are wielding an Axe"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="LowLife"},[2]={type="Condition",var="UsingAxe"},flags=0,keywordFlags=786432,name="Damage",type="MORE",value=30}},nil} @@ -8758,10 +8755,9 @@ c["Increases and Reductions to Projectile Speed also apply to Damage with Bows"] c["Increases and Reductions to Spell Damage also apply to Attacks at 150% of their value"]={{[1]={flags=0,keywordFlags=0,name="SpellDamageAppliesToAttacks",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ImprovedSpellDamageAppliesToAttacks",type="MAX",value=150}},nil} c["Increases and Reductions to Spell Damage also apply to Attacks while wielding a Wand"]={{[1]={[1]={type="Condition",var="UsingWand"},flags=0,keywordFlags=0,name="SpellDamageAppliesToAttacks",type="FLAG",value=true},[2]={[1]={type="Condition",var="UsingWand"},flags=0,keywordFlags=0,name="ImprovedSpellDamageAppliesToAttacks",type="MAX",value=100}},nil} c["Increases and reductions to Maximum Mana also apply to Shock Effect at 30% of their value"]={{[1]={flags=0,keywordFlags=0,name="ManaAppliesToShockEffect",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ImprovedManaAppliesToShockEffect",type="MAX",value=30}},nil} -c["Inflict 4 additional Impales on Enemies you Impale"]={nil,"Inflict 4 additional Impales on Enemies you Impale "} -c["Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} -c["Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo"]={nil,"Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo "} c["Inflict 5 additional Impales on Enemies you Impale"]={nil,"Inflict 5 additional Impales on Enemies you Impale "} +c["Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} +c["Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo"]={nil,"Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo "} c["Inflict 5 additional Impales on Enemies you Impale For 5 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"Inflict 5 additional Impales on Enemies you Impale For 5 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} c["Inflict Brittle on Enemies when you Block their Damage"]={nil,"Inflict Brittle on Enemies when you Block their Damage "} c["Inflict Brittle on Enemies when you Block their Damage +92 to Evasion Rating"]={nil,"Inflict Brittle on Enemies when you Block their Damage +92 to Evasion Rating "} @@ -9022,7 +9018,6 @@ c["Maximum Life becomes 1, Immune to Chaos Damage"]={{[1]={flags=0,keywordFlags= c["Maximum Quality is 200%"]={{},"Maximum Quality "} c["Maximum Quality is 200% Corrupted"]={{},"Maximum Quality Corrupted "} c["Maximum total Energy Shield Recovery per second from Leech is doubled"]={{[1]={flags=0,keywordFlags=0,name="MaxEnergyShieldLeechRate",type="MORE",value=100}},nil} -c["Maximum total Life Recovery per second from Leech is doubled"]={{[1]={flags=0,keywordFlags=0,name="MaxLifeLeechRate",type="MORE",value=100}},nil} c["Melee Attacks Poison on Hit"]={{[1]={flags=256,keywordFlags=0,name="PoisonChance",type="BASE",value=100}},nil} c["Melee Attacks cause Bleeding"]={{[1]={flags=256,keywordFlags=0,name="BleedChance",type="BASE",value=100}},nil} c["Melee Critical Strikes have 25% chance to Poison the Enemy"]={{[1]={[1]={type="Condition",var="CriticalStrike"},flags=256,keywordFlags=0,name="PoisonChance",type="BASE",value=25}},nil} @@ -9302,7 +9297,6 @@ c["Modifiers to Chance to Suppress Spell Damage instead apply to Chance to Dodge c["Modifiers to Claw Attack Speed also apply to Unarmed Attack Speed with Melee Skills"]={{[1]={flags=0,keywordFlags=0,name="ClawAttackSpeedAppliesToUnarmed",type="FLAG",value=true}},nil} c["Modifiers to Claw Critical Strike Chance also apply to Unarmed Critical Strike Chance with Melee Skills"]={{[1]={flags=0,keywordFlags=0,name="ClawCritChanceAppliesToUnarmed",type="FLAG",value=true}},nil} c["Modifiers to Claw Damage also apply to Unarmed Attack Damage with Melee Skills"]={{[1]={flags=0,keywordFlags=0,name="ClawDamageAppliesToUnarmed",type="FLAG",value=true}},nil} -c["Modifiers to Critical Strike Multiplier also apply to Damage over Time Multiplier for Ailments from Critical Strikes at 50% of their value"]={{[1]={flags=0,keywordFlags=0,name="CritMultiplierAppliesToDegen",type="BASE",value=50}},nil} c["Modifiers to Fire Resistance also apply to Cold and Lightning Resistances at 50% of their Value"]={{[1]={flags=0,keywordFlags=0,name="FireResConvertToCold",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="FireResConvertToLightning",type="BASE",value=50}},nil} c["Modifiers to Ignite Duration on you apply to all Elemental Ailments"]={{[1]={flags=0,keywordFlags=0,name="IgniteDurationAppliesToElementalAilments",type="FLAG",value=true}},nil} c["Modifiers to Maximum Fire Resistance also apply to Maximum Cold and Lightning Resistances"]={{[1]={flags=0,keywordFlags=0,name="FireMaxResConvertToCold",type="BASE",value=100},[2]={flags=0,keywordFlags=0,name="FireMaxResConvertToLightning",type="BASE",value=100}},nil} @@ -11146,7 +11140,6 @@ c["Tinctures deactivate when you have 12 or more Mana Burn"]={nil,"Tinctures dea c["Tinctures have 40% increased effect while at or above 10 stacks of Mana Burn"]={{[1]={[1]={threshold=10,type="MultiplierThreshold",varList={[1]="ManaBurnStacks",[2]="WeepingWoundsStacks"}},flags=0,keywordFlags=0,name="TinctureEffect",type="INC",value=40}},nil} c["Tinctures inflict Weeping Wounds instead of Mana Burn"]={{[1]={flags=0,keywordFlags=0,name="Condition:WeepingWoundsInsteadOfManaBurn",type="FLAG",value=true}},nil} c["Total Recovery per second from Life Leech is Doubled"]={{[1]={flags=0,keywordFlags=0,name="LifeLeechRate",type="MORE",value=100}},nil} -c["Total Recovery per second from Life Leech is doubled"]={{[1]={flags=0,keywordFlags=0,name="LifeLeechRate",type="MORE",value=100}},nil} c["Totems Hinder Enemies near them when Summoned"]={nil,"Totems Hinder Enemies near them when Summoned "} c["Totems Reflect 100% of their maximum Life as Fire Damage to nearby Enemies when Hit"]={nil,"Totems Reflect 100% of their maximum Life as Fire Damage to nearby Enemies when Hit "} c["Totems Reflect 25% of their maximum Life as Fire Damage to nearby Enemies when Hit"]={nil,"Totems Reflect 25% of their maximum Life as Fire Damage to nearby Enemies when Hit "} @@ -11353,11 +11346,10 @@ c["Warcries Exert 1 additional Attack"]={{[1]={flags=0,keywordFlags=0,name="Extr c["Warcries Exert 2 additional Attacks"]={{[1]={flags=0,keywordFlags=0,name="ExtraExertedAttacks",type="BASE",value=2}},nil} c["Warcries Exert twice as many Attacks"]={{[1]={flags=0,keywordFlags=0,name="ExtraExertedAttacks",type="MORE",value=100}},nil} c["Warcries Knock Back and Interrupt Enemies in a smaller Area"]={nil,"Warcries Knock Back and Interrupt Enemies in a smaller Area "} -c["Warcries also grant their buffs to nearby allies"]={nil,"Warcries also grant their buffs to nearby allies "} -c["Warcries also grant their buffs to nearby allies Limited to 1 Keystone Tattoo"]={nil,"Warcries also grant their buffs to nearby allies Limited to 1 Keystone Tattoo "} c["Warcries cannot Exert Travel Skills"]={nil,"Warcries cannot Exert Travel Skills "} c["Warcries do not grant Buffs or Charges to You"]={nil,"Warcries do not grant Buffs or Charges to You "} c["Warcries do not grant Buffs or Charges to You 100% more Warcry Duration"]={nil,"Warcries do not grant Buffs or Charges to You 100% more Warcry Duration "} +c["Warcries do not grant Buffs or Charges to You 100% more Warcry Duration Limited to 1 Keystone Tattoo"]={nil,"Warcries do not grant Buffs or Charges to You 100% more Warcry Duration Limited to 1 Keystone Tattoo "} c["Warcries grant 1 Rage per 5 Enemy Power, up to 5"]={{[1]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} c["Warcries grant 5 Rage per 5 Power if you have less than 25 Rage"]={{[1]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} c["Warcries grant Arcane Surge to you and Allies, with 10% increased effect per 5 power, up to 50%"]={{[1]={[1]={type="Condition",var="UsedWarcryRecently"},flags=0,keywordFlags=0,name="ExtraAura",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:ArcaneSurge",type="FLAG",value=true}}},[2]={[1]={div=5,globalLimit=50,globalLimitKey="Brinerot Flag",stat="WarcryPower",type="PerStat"},[2]={type="Condition",var="UsedWarcryRecently"},flags=0,keywordFlags=0,name="ArcaneSurgeEffect",type="INC",value=10}},nil} @@ -11365,9 +11357,6 @@ c["Warcries have 10% chance to Exert 3 additional Attacks"]={{[1]={flags=0,keywo c["Warcries have 5% Chance to grant an Endurance, Frenzy or Power Charge per Power"]={nil,"Warcries have 5% Chance to grant an Endurance, Frenzy or Power Charge per Power "} c["Warcries have a minimum of 10 Power"]={nil,"Warcries have a minimum of 10 Power "} c["Warcries have infinite Power"]={{[1]={flags=0,keywordFlags=0,name="WarcryInfinitePower",type="FLAG",value=true}},nil} -c["Warcries no longer Exert Attacks"]={nil,"Warcries no longer Exert Attacks "} -c["Warcries no longer Exert Attacks Warcries also grant their buffs to nearby allies"]={nil,"Warcries no longer Exert Attacks Warcries also grant their buffs to nearby allies "} -c["Warcries no longer Exert Attacks Warcries also grant their buffs to nearby allies Limited to 1 Keystone Tattoo"]={nil,"Warcries no longer Exert Attacks Warcries also grant their buffs to nearby allies Limited to 1 Keystone Tattoo "} c["Warcry Skills have +2 seconds to Cooldown"]={{[1]={flags=0,keywordFlags=4,name="CooldownRecovery",type="BASE",value=2}},nil} c["Warcry Skills have 15% increased Area of Effect"]={{[1]={[1]={skillType=73,type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=15}},nil} c["Warcry Skills have 20% increased Area of Effect"]={{[1]={[1]={skillType=73,type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=20}},nil} @@ -11400,10 +11389,9 @@ c["When you kill a Poisoned Enemy during any Flask Effect, nearby Enemies are Po c["When you leave your Banner's Area, recover 30% of the Valour consumed for that Banner"]={nil,"When you leave your Banner's Area, recover 30% of the Valour consumed for that Banner "} c["When you lose Temporal Chains you gain maximum Rage"]={{[1]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} c["When your Hits Impale Enemies, also Impale other Enemies near them"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them "} -c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale "} -c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} -c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 4 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo "} c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale "} +c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} +c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them Limited to 1 Keystone Tattoo "} c["When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 5 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them"]={nil,"When your Hits Impale Enemies, also Impale other Enemies near them Inflict 5 additional Impales on Enemies you Impale For 5 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them "} c["When your Traps Trigger, your nearby Traps also Trigger"]={nil,"When your Traps Trigger, your nearby Traps also Trigger "} c["While Minions have Energy Shield, their Hits Ignore Monster Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={stat="EnergyShield",threshold=1,type="StatThreshold"},flags=0,keywordFlags=0,name="IgnoreElementalResistances",type="FLAG",value=true}}}},nil} diff --git a/src/Data/TattooPassives.lua b/src/Data/TattooPassives.lua index d6137cc5ce..446b9467a3 100644 --- a/src/Data/TattooPassives.lua +++ b/src/Data/TattooPassives.lua @@ -127,7 +127,7 @@ return { [118] = "Honoured Tattoo of the Turtle", [119] = "Tattoo of the Kitava Warrior", [120] = "Honoured Tattoo of the Mountain", - [121] = "Warlord's Call", + [121] = "Call to Arms", [122] = "Honoured Tattoo of the Hunter", [123] = "Mind Over Matter", [124] = "Honoured Tattoo of the Flood", @@ -634,10 +634,9 @@ return { ["not"] = false, ["icon"] = "Art/2DArt/SkillIcons/passives/vaalpact.png", ["sd"] = { - [1] = "Total Recovery per second from Life Leech is doubled", - [2] = "Maximum total Life Recovery per second from Leech is doubled", - [3] = "You have no Life Regeneration", - [4] = "Limited to 1 Keystone Tattoo", + [1] = "Life Leech from Melee Damage is Instant", + [2] = "Cannot Recover Life other than from Leech", + [3] = "Limited to 1 Keystone Tattoo", }, ["activeEffectImage"] = "Art/2DArt/UIImages/InGame/AncestralTrial/PassiveTreeTattoos/KeystoneHinekoraPassiveBG.png", ["targetType"] = "Keystone", @@ -663,9 +662,10 @@ return { ["not"] = false, ["icon"] = "Art/2DArt/SkillIcons/passives/CritAilments.png", ["sd"] = { - [1] = "Modifiers to Critical Strike Multiplier also apply to Damage over Time Multiplier for Ailments from Critical Strikes at 50% of their value", - [2] = "30% less Damage with Hits", - [3] = "Limited to 1 Keystone Tattoo", + [1] = "Damage over Time Multiplier for Ailments is equal to Critical Strike Multiplier", + [2] = "Critical Strikes do not deal extra Damage", + [3] = "Non-Critical Strikes cannot inflict Ailments", + [4] = "Limited to 1 Keystone Tattoo", }, ["activeEffectImage"] = "Art/2DArt/UIImages/InGame/AncestralTrial/PassiveTreeTattoos/KeystoneHinekoraPassiveBG.png", ["targetType"] = "Keystone", @@ -2371,7 +2371,7 @@ return { ["icon"] = "Art/2DArt/SkillIcons/passives/ImpaleKeystone.png", ["sd"] = { [1] = "When your Hits Impale Enemies, also Impale other Enemies near them", - [2] = "Inflict 4 additional Impales on Enemies you Impale", + [2] = "Inflict 5 additional Impales on Enemies you Impale", [3] = "For 4 seconds after you Impale Enemies, they cannot be Impaled again, and Impales cannot be Called from them", [4] = "Limited to 1 Keystone Tattoo", }, @@ -3303,7 +3303,7 @@ return { ["MaximumConnected"] = 100, ["dn"] = "Honoured Tattoo of the Mountain", }, - ["Warlord's Call"] = { + ["Call to Arms"] = { ["m"] = false, ["isTattoo"] = true, ["id"] = "call_to_arms_keystone2691", @@ -3322,8 +3322,8 @@ return { ["not"] = false, ["icon"] = "Art/2DArt/SkillIcons/passives/CallToArms.png", ["sd"] = { - [1] = "Warcries no longer Exert Attacks", - [2] = "Warcries also grant their buffs to nearby allies", + [1] = "Warcries do not grant Buffs or Charges to You", + [2] = "100% more Warcry Duration", [3] = "Limited to 1 Keystone Tattoo", }, ["activeEffectImage"] = "Art/2DArt/UIImages/InGame/AncestralTrial/PassiveTreeTattoos/KeystoneHinekoraPassiveBG.png", @@ -3499,8 +3499,8 @@ return { ["not"] = false, ["icon"] = "Art/2DArt/SkillIcons/passives/VersatileCombatant.png", ["sd"] = { - [1] = "-25% to maximum Chance to Block Attack Damage", - [2] = "-25% to maximum Chance to Block Spell Damage", + [1] = "-10% to maximum Chance to Block Attack Damage", + [2] = "-10% to maximum Chance to Block Spell Damage", [3] = "+2% Chance to Block Spell Damage for each 1% Overcapped Chance to Block Attack Damage", [4] = "Limited to 1 Keystone Tattoo", }, From 6ec0c585f2e877b3ed3647492637a670cdad6034 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 03:18:25 +1000 Subject: [PATCH 08/26] Update Legion Notables with 3.25 changes (#7864) Fixes the Rage on hit notable replacing the wrong stat Change 40% rarity stat to 12% res efficiency Co-authored-by: LocalIdentity --- src/Data/TimelessJewelData/LegionPassives.lua | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Data/TimelessJewelData/LegionPassives.lua b/src/Data/TimelessJewelData/LegionPassives.lua index caeea65399..a3a9777d0e 100644 --- a/src/Data/TimelessJewelData/LegionPassives.lua +++ b/src/Data/TimelessJewelData/LegionPassives.lua @@ -6065,12 +6065,12 @@ return { ["g"] = 1000000000, }, [144] = { - ["id"] = "eternal_notable_rarity_1", + ["id"] = "eternal_reservation_efficiency_1", ["in"] = { }, ["not"] = true, ["sd"] = { - [1] = "40% increased Rarity of Items found", + [1] = "12% increased Mana Reservation Efficiency of Skills", }, ["isMultipleChoiceOption"] = false, ["dn"] = "Discerning Taste", @@ -6084,12 +6084,12 @@ return { [1] = "base_item_found_rarity_+%", }, ["stats"] = { - ["base_item_found_rarity_+%"] = { - ["max"] = 40, + ["base_mana_reservation_efficiency_+%"] = { + ["max"] = 12, ["fmt"] = "d", ["index"] = 1, - ["min"] = 40, - ["statOrder"] = 1442, + ["min"] = 12, + ["statOrder"] = 2090, }, }, ["da"] = 0, @@ -7694,10 +7694,10 @@ return { }, }, [62] = { - ["id"] = "karui_notable_add_rage_on_hit", - ["dn"] = "Add Rage on Hit", + ["id"] = "karui_notable_add_physical_added_as_fire", + ["dn"] = "Add Physical Added As Fire", ["sd"] = { - [1] = "Gain 1 Rage on Melee Hit", + [1] = "Gain 5% of Physical Damage as Extra Fire Damage", }, ["sortedStats"] = { [1] = "physical_damage_%_to_add_as_fire", @@ -7713,20 +7713,20 @@ return { }, }, [63] = { - ["id"] = "karui_notable_add_physical_taken_as_fire", - ["dn"] = "Add Physical Taken As Fire", + ["id"] = "karui_notable_add_rage_on_hit", + ["dn"] = "Add Rage on Hit", ["sd"] = { - [1] = "5% of Physical Damage from Hits taken as Fire Damage", + [1] = "Gain 1 Rage on Melee Hit", }, ["sortedStats"] = { [1] = "physical_damage_taken_%_as_fire", }, ["stats"] = { ["physical_damage_taken_%_as_fire"] = { - ["max"] = 5, + ["max"] = 1, ["fmt"] = "d", ["index"] = 1, - ["min"] = 5, + ["min"] = 1, ["statOrder"] = 2282, }, }, From 6cb485f20dde8ef133ce970d204b07be493534ff Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 03:20:44 +1000 Subject: [PATCH 09/26] Fix Autoexertion and Call to Arms not disabling Warcry buffs (#7861) * Fix Autoexertion not disabling Warcry buffs `Supported Warcries do not grant Buffs or Charges to you or Allies` The buffs to allies will be implemented in a future PR * Add support for Call to Arms keystone --------- Co-authored-by: LocalIdentity --- src/Data/ModCache.lua | 4 +- src/Data/Skills/act_str.lua | 8 ++- src/Data/Skills/sup_str.lua | 6 +- .../skill_stat_descriptions.lua | 2 +- src/Export/Skills/act_str.txt | 6 ++ src/Export/Skills/sup_str.txt | 6 +- src/Modules/CalcPerform.lua | 71 +++++++++++-------- src/Modules/ModParser.lua | 1 + 8 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 218af308c0..0f1b3adb0a 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -11347,9 +11347,7 @@ c["Warcries Exert 2 additional Attacks"]={{[1]={flags=0,keywordFlags=0,name="Ext c["Warcries Exert twice as many Attacks"]={{[1]={flags=0,keywordFlags=0,name="ExtraExertedAttacks",type="MORE",value=100}},nil} c["Warcries Knock Back and Interrupt Enemies in a smaller Area"]={nil,"Warcries Knock Back and Interrupt Enemies in a smaller Area "} c["Warcries cannot Exert Travel Skills"]={nil,"Warcries cannot Exert Travel Skills "} -c["Warcries do not grant Buffs or Charges to You"]={nil,"Warcries do not grant Buffs or Charges to You "} -c["Warcries do not grant Buffs or Charges to You 100% more Warcry Duration"]={nil,"Warcries do not grant Buffs or Charges to You 100% more Warcry Duration "} -c["Warcries do not grant Buffs or Charges to You 100% more Warcry Duration Limited to 1 Keystone Tattoo"]={nil,"Warcries do not grant Buffs or Charges to You 100% more Warcry Duration Limited to 1 Keystone Tattoo "} +c["Warcries do not grant Buffs or Charges to You"]={{[1]={flags=0,keywordFlags=0,name="CannotGainWarcryBuffs",type="FLAG",value=true}},nil} c["Warcries grant 1 Rage per 5 Enemy Power, up to 5"]={{[1]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} c["Warcries grant 5 Rage per 5 Power if you have less than 25 Rage"]={{[1]={flags=0,keywordFlags=0,name="Condition:CanGainRage",type="FLAG",value=true}},nil} c["Warcries grant Arcane Surge to you and Allies, with 10% increased effect per 5 power, up to 50%"]={{[1]={[1]={type="Condition",var="UsedWarcryRecently"},flags=0,keywordFlags=0,name="ExtraAura",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:ArcaneSurge",type="FLAG",value=true}}},[2]={[1]={div=5,globalLimit=50,globalLimitKey="Brinerot Flag",stat="WarcryPower",type="PerStat"},[2]={type="Condition",var="UsedWarcryRecently"},flags=0,keywordFlags=0,name="ArcaneSurgeEffect",type="INC",value=10}},nil} diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index f7042316ef..3c6c80f3dd 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -291,6 +291,9 @@ skills["AncestralCry"] = { ["ancestral_cry_max_elemental_resistances_per_5_monster_power"] = { mod("AncestralMaxElementalResistancePer5MP", "BASE", nil), }, + ["skill_empower_limitation_specifier_for_stat_description"] = { + -- Display only + }, }, baseFlags = { warcry = true, @@ -3784,7 +3787,7 @@ skills["BloodSandArmour"] = { baseTypeName = "Flesh and Stone", color = 1, description = "Casts an aura that affects you and nearby enemies differently depending on your stance. Using the skill again alternates between Blood Stance and Sand Stance.", - skillTypes = { [SkillType.Spell] = true, [SkillType.Buff] = true, [SkillType.Aura] = true, [SkillType.AuraAffectsEnemies] = true, [SkillType.Instant] = true, [SkillType.HasReservation] = true, [SkillType.AppliesMaim] = true, [SkillType.Area] = true, [SkillType.InstantNoRepeatWhenHeld] = true, [SkillType.InstantShiftAttackForLeftMouse] = true, [SkillType.Cooldown] = true, [SkillType.Stance] = true, }, + skillTypes = { [SkillType.Spell] = true, [SkillType.Buff] = true, [SkillType.Aura] = true, [SkillType.AuraAffectsEnemies] = true, [SkillType.Instant] = true, [SkillType.HasReservation] = true, [SkillType.Area] = true, [SkillType.InstantNoRepeatWhenHeld] = true, [SkillType.InstantShiftAttackForLeftMouse] = true, [SkillType.Cooldown] = true, [SkillType.Stance] = true, }, statDescriptionScope = "aura_skill_stat_descriptions", castTime = 0, statMap = { @@ -8441,6 +8444,9 @@ skills["SeismicCry"] = { ["seismic_cry_+%_physical_damamge_reduction_per_5_MP"] = { mod("SeismicArmourPer5MP", "BASE", nil), }, + ["skill_empower_limitation_specifier_for_stat_description"] = { + -- Display only + }, }, baseFlags = { warcry = true, diff --git a/src/Data/Skills/sup_str.lua b/src/Data/Skills/sup_str.lua index fe51431271..b823670539 100644 --- a/src/Data/Skills/sup_str.lua +++ b/src/Data/Skills/sup_str.lua @@ -738,7 +738,10 @@ skills["CallToArms"] = { statMap = { ["call_to_arms_behaviour"] = { -- Display only - } + }, + ["warcry_skills_share_cooldowns"] = { + -- Display only + }, }, castTime = 0, baseFlags = { @@ -804,6 +807,7 @@ skills["SupportCallToArms"] = { statDescriptionScope = "gem_stat_descriptions", baseMods = { skill("SupportedByAutoexertion", true), + flag("CannotShareWarcryBuffs"), }, qualityStats = { Default = { diff --git a/src/Data/StatDescriptions/skill_stat_descriptions.lua b/src/Data/StatDescriptions/skill_stat_descriptions.lua index d0189b69d2..9d12395942 100644 --- a/src/Data/StatDescriptions/skill_stat_descriptions.lua +++ b/src/Data/StatDescriptions/skill_stat_descriptions.lua @@ -46951,7 +46951,7 @@ return { [2]="#" } }, - text="All your Warcries share their Cooldowns" + text="Supported Warcries do not grant Buffs or Charges to you or Allies" } } }, diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index 3bebec0534..bedcc047d0 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -59,6 +59,9 @@ local skills, mod, flag, skill = ... ["ancestral_cry_max_elemental_resistances_per_5_monster_power"] = { mod("AncestralMaxElementalResistancePer5MP", "BASE", nil), }, + ["skill_empower_limitation_specifier_for_stat_description"] = { + -- Display only + }, }, #baseMod skill("radius", 60) #mods @@ -1566,6 +1569,9 @@ local skills, mod, flag, skill = ... ["seismic_cry_+%_physical_damamge_reduction_per_5_MP"] = { mod("SeismicArmourPer5MP", "BASE", nil), }, + ["skill_empower_limitation_specifier_for_stat_description"] = { + -- Display only + }, }, #baseMod skill("radius", 60) #mods diff --git a/src/Export/Skills/sup_str.txt b/src/Export/Skills/sup_str.txt index e716dd1367..c913a1152f 100644 --- a/src/Export/Skills/sup_str.txt +++ b/src/Export/Skills/sup_str.txt @@ -94,13 +94,17 @@ local skills, mod, flag, skill = ... statMap = { ["call_to_arms_behaviour"] = { -- Display only - } + }, + ["warcry_skills_share_cooldowns"] = { + -- Display only + }, }, #mods #skill SupportCallToArms baseMods = { skill("SupportedByAutoexertion", true), + flag("CannotShareWarcryBuffs"), }, #mods diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 8092d033bc..c653085dc7 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -1164,58 +1164,71 @@ function calcs.perform(env, skipEHP) uptime = 1 end if activeSkill.activeEffect.grantedEffect.name == "Ancestral Cry" and not modDB:Flag(nil, "AncestralActive") then - local ancestralEleResistance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "AncestralElementalResistancePer5MP") - local ancestralMaxEleResistance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "AncestralMaxElementalResistancePer5MP") env.player.modDB:NewMod("NumAncestralExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "AncestralExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("ElementalResist", "BASE", m_floor(ancestralEleResistance * buff_inc) * uptime, "Ancestral Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) - env.player.modDB:NewMod("ElementalResistMax", "BASE", m_floor(ancestralMaxEleResistance * buff_inc) * uptime, "Ancestral Cry", { type = "Multiplier", var = "WarcryPower", div = 10, limit = 3 }) + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local ancestralEleResistance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "AncestralElementalResistancePer5MP") + local ancestralMaxEleResistance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "AncestralMaxElementalResistancePer5MP") + env.player.modDB:NewMod("ElementalResist", "BASE", m_floor(ancestralEleResistance * buff_inc) * uptime, "Ancestral Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + env.player.modDB:NewMod("ElementalResistMax", "BASE", m_floor(ancestralMaxEleResistance * buff_inc) * uptime, "Ancestral Cry", { type = "Multiplier", var = "WarcryPower", div = 10, limit = 3 }) + end modDB:NewMod("AncestralActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Enduring Cry" and not modDB:Flag(nil, "EnduringActive") then - local enduringRegen = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "EnduringCryLifeRegen") - env.player.modDB:NewMod("LifeRegenPercent", "BASE", m_floor(enduringRegen * buff_inc) * uptime, "Enduring Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local enduringRegen = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "EnduringCryLifeRegen") + env.player.modDB:NewMod("LifeRegenPercent", "BASE", m_floor(enduringRegen * buff_inc) * uptime, "Enduring Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + end modDB:NewMod("EnduringActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Infernal Cry" and not modDB:Flag(nil, "InfernalActive") then - local infernalPhysAsExtraFire = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "InfernalFireAsExtraPer5MP") env.player.modDB:NewMod("NumInfernalExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "InfernalExertedAttacks") + extraExertions) * exertMultiplier)) - if env.mode_effective then + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local infernalPhysAsExtraFire = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "InfernalFireAsExtraPer5MP") env.player.modDB:NewMod("PhysicalDamageGainAsFire", "BASE", m_floor(infernalPhysAsExtraFire * buff_inc) * uptime, "Infernal Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) end modDB:NewMod("InfernalActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Battlemage's Cry" and not modDB:Flag(nil, "BattlemageActive") then - local battlemageBaseCritChance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "BattlemageBaseCritChancePer5MP") env.player.modDB:NewMod("NumBattlemageExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "BattlemageExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("CritChance", "BASE", m_floor(battlemageBaseCritChance * buff_inc) / 100 * uptime, "Battlemage's Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local battlemageBaseCritChance = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "BattlemageBaseCritChancePer5MP") + env.player.modDB:NewMod("CritChance", "BASE", m_floor(battlemageBaseCritChance * buff_inc) / 100 * uptime, "Battlemage's Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + end modDB:NewMod("BattlemageActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Intimidating Cry" and not modDB:Flag(nil, "IntimidatingActive") then - local intimidatingMovementSpeed = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "IntimidatingMovementSpeedPer5MP") env.player.modDB:NewMod("NumIntimidatingExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "IntimidatingExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("MovementSpeed", "INC", m_floor(intimidatingMovementSpeed * buff_inc) * uptime, "Intimidating Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 6 }) + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local intimidatingMovementSpeed = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "IntimidatingMovementSpeedPer5MP") + env.player.modDB:NewMod("MovementSpeed", "INC", m_floor(intimidatingMovementSpeed * buff_inc) * uptime, "Intimidating Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 6 }) + end modDB:NewMod("IntimidatingActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Rallying Cry" and not modDB:Flag(nil, "RallyingActive") then env.player.modDB:NewMod("NumRallyingExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("RallyingExertMoreDamagePerAlly", "BASE", activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryExertDamageBonus")) - local rallyingWeaponEffect = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryAllyDamageBonusPer5Power") - local rallyingBonusMoreMultiplier = 1 + (activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryMinionDamageBonusMultiplier") or 0) - if warcryPowerBonus ~= 0 then - rallyingWeaponEffect = m_floor(rallyingWeaponEffect * warcryPowerBonus * buff_inc) / warcryPowerBonus - end - -- Special handling for the minion side to add the flat damage bonus - if env.minion then - -- Add all damage types - local dmgTypeList = {"Physical", "Lightning", "Cold", "Fire", "Chaos"} - for _, damageType in ipairs(dmgTypeList) do - env.minion.modDB:NewMod(damageType.."Min", "BASE", m_floor((env.player.weaponData1[damageType.."Min"] or 0) * rallyingBonusMoreMultiplier * rallyingWeaponEffect / 100) * uptime, "Rallying Cry", { type = "Multiplier", actor = "parent", var = "WarcryPower", div = 5, limit = 10}) - env.minion.modDB:NewMod(damageType.."Max", "BASE", m_floor((env.player.weaponData1[damageType.."Max"] or 0) * rallyingBonusMoreMultiplier * rallyingWeaponEffect / 100) * uptime, "Rallying Cry", { type = "Multiplier", actor = "parent", var = "WarcryPower", div = 5, limit = 10}) + if not activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") then + env.player.modDB:NewMod("RallyingExertMoreDamagePerAlly", "BASE", activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryExertDamageBonus")) + local rallyingWeaponEffect = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryAllyDamageBonusPer5Power") + local rallyingBonusMoreMultiplier = 1 + (activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "RallyingCryMinionDamageBonusMultiplier") or 0) + if warcryPowerBonus ~= 0 then + rallyingWeaponEffect = m_floor(rallyingWeaponEffect * warcryPowerBonus * buff_inc) / warcryPowerBonus + end + -- Special handling for the minion side to add the flat damage bonus + if env.minion then + -- Add all damage types + local dmgTypeList = {"Physical", "Lightning", "Cold", "Fire", "Chaos"} + for _, damageType in ipairs(dmgTypeList) do + env.minion.modDB:NewMod(damageType.."Min", "BASE", m_floor((env.player.weaponData1[damageType.."Min"] or 0) * rallyingBonusMoreMultiplier * rallyingWeaponEffect / 100) * uptime, "Rallying Cry", { type = "Multiplier", actor = "parent", var = "WarcryPower", div = 5, limit = 10}) + env.minion.modDB:NewMod(damageType.."Max", "BASE", m_floor((env.player.weaponData1[damageType.."Max"] or 0) * rallyingBonusMoreMultiplier * rallyingWeaponEffect / 100) * uptime, "Rallying Cry", { type = "Multiplier", actor = "parent", var = "WarcryPower", div = 5, limit = 10}) + end end end modDB:NewMod("RallyingActive", "FLAG", true) -- Prevents effect from applying multiple times elseif activeSkill.activeEffect.grantedEffect.name == "Seismic Cry" and not modDB:Flag(nil, "SeismicActive") then - local seismicStunEffect = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicStunThresholdPer5MP") - local seismicArmour = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicArmourPer5MP") env.player.modDB:NewMod("SeismicMoreAoE", "BASE", activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicAoEMoreMultiplier")) env.player.modDB:NewMod("NumSeismicExerts", "BASE", m_floor((activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicExertedAttacks") + extraExertions) * exertMultiplier)) - env.player.modDB:NewMod("StunThreshold", "INC", m_floor(seismicStunEffect * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) - env.player.modDB:NewMod("Armour", "MORE", m_floor(seismicArmour * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + if not (activeSkill.skillModList:Flag(nil, "CannotShareWarcryBuffs") or modDB:Flag(nil, "CannotGainWarcryBuffs")) then + local seismicStunEffect = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicStunThresholdPer5MP") + local seismicArmour = activeSkill.skillModList:Sum("BASE", env.player.mainSkill.skillCfg, "SeismicArmourPer5MP") + env.player.modDB:NewMod("StunThreshold", "INC", m_floor(seismicStunEffect * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + env.player.modDB:NewMod("Armour", "MORE", m_floor(seismicArmour * buff_inc) * uptime, "Seismic Cry", { type = "Multiplier", var = "WarcryPower", div = 5, limit = 5 }) + + end modDB:NewMod("SeismicActive", "FLAG", true) -- Prevents effect from applying multiple times end end diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 8f31015e93..84b58c0827 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -3585,6 +3585,7 @@ local specialModList = { ["warcries share their cooldown"] = { flag("WarcryShareCooldown") }, ["warcries have minimum of (%d+) power"] = { flag("CryWolfMinimumPower") }, ["warcries have infinite power"] = { flag("WarcryInfinitePower") }, + ["warcries do not grant buffs or charges to you"] = { flag("CannotGainWarcryBuffs") }, ["(%d+)%% chance to inflict corrosion on hit with attacks"] = { flag("Condition:CanCorrode") }, ["(%d+)%% chance to inflict withered for (%d+) seconds on hit"] = { flag("Condition:CanWither") }, ["inflict withered for (%d+) seconds on hit if you've cast (.-) in the past (%d+) seconds"] = function (_, _, curse) return { flag("Condition:CanWither", { type = "Condition", var = "SelfCast"..curse:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", "") }) } end, From 7875b2f707a3e2aa7b19f223e622223ce4b10df6 Mon Sep 17 00:00:00 2001 From: Regisle <49933620+Regisle@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:51:37 +0930 Subject: [PATCH 10/26] fix tincture mana burn rate applying inversely (#7851) --- src/Classes/Item.lua | 2 +- src/Classes/ItemsTab.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 47c404ebc6..209e5e8277 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -1487,7 +1487,7 @@ function ItemClass:BuildModListForSlotNum(baseList, slotNum) end elseif self.base.tincture then local tinctureData = self.tinctureData - tinctureData.manaBurn = self.base.tincture.manaBurn * (1 + calcLocal(modList, "TinctureManaBurnRate", "INC", 0) / 100) * (1 + calcLocal(modList, "TinctureManaBurnRate", "MORE", 0) / 100) + tinctureData.manaBurn = (self.base.tincture.manaBurn + 0.01) / (1 + calcLocal(modList, "TinctureManaBurnRate", "INC", 0) / 100) / (1 + calcLocal(modList, "TinctureManaBurnRate", "MORE", 0) / 100) tinctureData.cooldown = self.base.tincture.cooldown / (1 + calcLocal(modList, "TinctureCooldownRecovery", "INC", 0) / 100) tinctureData.effectInc = calcLocal(modList, "TinctureEffect", "INC", 0) + calcLocal(modList, "LocalEffect", "INC", 0) for _, value in ipairs(modList:List(nil, "TinctureData")) do diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index f67f086db0..9ecfae41b1 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -3632,7 +3632,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode) if effectMod ~= 1 then t_insert(stats, s_format("^8Tincture effect modifier: ^7%+d%%", effectMod * 100 - 100)) end - t_insert(stats, s_format("^8Mana Burn Inflicted Every Second: ^7%.2f", tinctureData.manaBurn * (1 + modDB:Sum("INC", { actor = "player" }, "TinctureManaBurnRate")/100) * (1 + modDB:Sum("MORE", { actor = "player" }, "TinctureManaBurnRate")/100))) + t_insert(stats, s_format("^8Mana Burn Inflicted Every Second: ^7%.2f", tinctureData.manaBurn / (1 + modDB:Sum("INC", { actor = "player" }, "TinctureManaBurnRate")/100) / (1 + modDB:Sum("MORE", { actor = "player" }, "TinctureManaBurnRate")/100))) local TincturesNotInflictManaBurn = m_min(modDB:Sum("BASE", nil, "TincturesNotInflictManaBurn"), 100) if TincturesNotInflictManaBurn ~= 0 then t_insert(stats, s_format("^8Chance to not inflict Mana Burn: ^7%d%%", TincturesNotInflictManaBurn)) From 0710e5765649dfc0f385c7762aa0e35596037855 Mon Sep 17 00:00:00 2001 From: hexeaktivitat <103838207+hexeaktivitat@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:55:48 -0400 Subject: [PATCH 11/26] Add support for changing item quality in the standard edit item interface (#5914) * add basic functionality of item quality slider * use Edit instead of Slider * remove unneeded parentheses * spawns with initial value displayed * improve display logic * fix display logic to resolve crash * initial changes for catalysts * set initial value for catalyst quality * set default value appropriately * unify quality behavior across items * fix issue with quality display by referencing correct field craft item correctly assigns quality values * reword if clause for better code legibility * Fix default missed when switching to edit box vs. slider --------- Co-authored-by: Wires77 --- src/Classes/ItemsTab.lua | 45 ++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 9ecfae41b1..46f6c4e93e 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -536,9 +536,27 @@ holding Shift will put it in the second.]]) return self.displayItem and self.displayItem.canBeInfluenced end + -- Section: Item Quality + self.controls.displayItemSectionQuality = new("Control", {"TOPLEFT",self.controls.displayItemSectionInfluence,"BOTTOMLEFT"}, 0, 0, 0, function() + return (self.controls.displayItemQuality:IsShown() and self.controls.displayItemQualityEdit:IsShown()) and 28 or 0 + end) + self.controls.displayItemQuality = new("LabelControl", {"TOPLEFT",self.controls.displayItemSectionQuality,"TOPRIGHT"}, -4, 0, 0, 16, "^7Quality:") + self.controls.displayItemQuality.shown = function() + return self.displayItem and self.displayItem.quality and (self.displayItem.base.type ~= "Amulet" or self.displayItem.base.type ~= "Belt" or self.displayItem.base.type ~= "Jewel" or self.displayItem.base.type ~= "Quiver" or self.displayItem.base.type ~= "Ring") + end + + self.controls.displayItemQualityEdit = new("EditControl", {"LEFT",self.controls.displayItemQuality,"RIGHT"},2,0,60,20,nil,nil,"%D",2,function(buf) + self.displayItem.quality = tonumber(buf) + self.displayItem:BuildAndParseRaw() + self:UpdateDisplayItemTooltip() + end) + self.controls.displayItemQualityEdit.shown = function() + return self.displayItem and self.displayItem.quality and (self.displayItem.base.type ~= "Amulet" or self.displayItem.base.type ~= "Belt" or self.displayItem.base.type ~= "Jewel" or self.displayItem.base.type ~= "Quiver" or self.displayItem.base.type ~= "Ring") + end + -- Section: Catalysts - self.controls.displayItemSectionCatalyst = new("Control", {"TOPLEFT",self.controls.displayItemSectionInfluence,"BOTTOMLEFT"}, 0, 0, 0, function() - return (self.controls.displayItemCatalyst:IsShown() or self.controls.displayItemCatalystQualitySlider:IsShown()) and 28 or 0 + self.controls.displayItemSectionCatalyst = new("Control", {"TOPLEFT",self.controls.displayItemSectionQuality,"BOTTOMLEFT"}, 0, 0, 0, function() + return (self.controls.displayItemCatalyst:IsShown() or self.controls.displayItemCatalystQualityEdit:IsShown()) and 28 or 0 end) self.controls.displayItemCatalyst = new("DropDownControl", {"TOPLEFT",self.controls.displayItemSectionCatalyst,"TOPRIGHT"}, 0, 0, 250, 20, {"Catalyst","Abrasive (Attack)","Accelerating (Speed)","Fertile (Life & Mana)","Imbued (Caster)","Intrinsic (Attribute)","Noxious (Physical & Chaos Damage)", @@ -547,6 +565,7 @@ holding Shift will put it in the second.]]) self.displayItem.catalyst = index - 1 if not self.displayItem.catalystQuality then self.displayItem.catalystQuality = 20 + self.controls.displayItemCatalystQualityEdit:SetText(self.displayItem.catalystQuality) end if self.displayItem.crafted then for i = 1, self.displayItem.affixLimit do @@ -561,8 +580,8 @@ holding Shift will put it in the second.]]) self.controls.displayItemCatalyst.shown = function() return self.displayItem and (self.displayItem.crafted or self.displayItem.hasModTags) and (self.displayItem.base.type == "Amulet" or self.displayItem.base.type == "Ring" or self.displayItem.base.type == "Belt") end - self.controls.displayItemCatalystQualitySlider = new("SliderControl", {"LEFT",self.controls.displayItemCatalyst,"RIGHT",true}, 8, 0, 200, 20, function(val) - self.displayItem.catalystQuality = round(val * 20) + self.controls.displayItemCatalystQualityEdit = new("EditControl", {"LEFT",self.controls.displayItemCatalyst,"RIGHT"},2,0,60,20,nil,nil,"%D",2,function(buf) + self.displayItem.catalystQuality = tonumber(buf) if self.displayItem.crafted then for i = 1, self.displayItem.affixLimit do -- Force affix selectors to update @@ -573,14 +592,9 @@ holding Shift will put it in the second.]]) self.displayItem:BuildAndParseRaw() self:UpdateDisplayItemTooltip() end) - self.controls.displayItemCatalystQualitySlider.shown = function() + self.controls.displayItemCatalystQualityEdit.shown = function() return self.displayItem and (self.displayItem.crafted or self.displayItem.hasModTags) and self.displayItem.catalyst and self.displayItem.catalyst > 0 end - self.controls.displayItemCatalystQualitySlider.tooltipFunc = function(tooltip, val) - local quality = round(val * 20) - tooltip:Clear() - tooltip:AddLine(16, "^7Quality: "..quality.."%") - end -- Section: Cluster Jewel self.controls.displayItemSectionClusterJewel = new("Control", {"TOPLEFT",self.controls.displayItemSectionCatalyst,"BOTTOMLEFT"}, 0, 0, 0, function() @@ -1557,11 +1571,12 @@ function ItemsTabClass:SetDisplayItem(item) end self.controls.displayItemInfluence:SetSel(influence1, true) -- Don't call the selection function for the first influence dropdown as the second dropdown isn't properly set yet. self.controls.displayItemInfluence2:SetSel(influence2) -- The selection function for the second dropdown properly handles everything for both dropdowns + self.controls.displayItemQualityEdit:SetText(item.quality) self.controls.displayItemCatalyst:SetSel((item.catalyst or 0) + 1) if item.catalystQuality then - self.controls.displayItemCatalystQualitySlider.val = m_min(item.catalystQuality / 20, 1) + self.controls.displayItemCatalystQualityEdit:SetText(m_max(item.catalystQuality, 0)) else - self.controls.displayItemCatalystQualitySlider.val = 1 + self.controls.displayItemCatalystQualityEdit:SetText(0) end self:UpdateCustomControls() self:UpdateDisplayItemRangeLines() @@ -1940,7 +1955,11 @@ function ItemsTabClass:CraftItem() item.implicitModLines = { } item.explicitModLines = { } item.crucibleModLines = { } - item.quality = 0 + if base.base.type ~= "Amulet" or base.base.type ~= "Belt" or base.base.type ~= "Jewel" or base.base.type ~= "Quiver" or base.base.type ~= "Ring" then + item.quality = nil + else + item.quality = 0 + end local raritySel = controls.rarity.selIndex if base.base.flask or (base.base.type == "Jewel" and base.base.subType == "Charm") From 709a845987cf0e5455cb653828b82d0b72407743 Mon Sep 17 00:00:00 2001 From: Juangui <80857657+justjuangui@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:00:15 -0500 Subject: [PATCH 12/26] enable recursive copyTable for ConfigSet (#7867) Co-authored-by: justjuangui --- src/Classes/ConfigSetListControl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/ConfigSetListControl.lua b/src/Classes/ConfigSetListControl.lua index b87b3f5a2b..9a7f50f34b 100644 --- a/src/Classes/ConfigSetListControl.lua +++ b/src/Classes/ConfigSetListControl.lua @@ -12,7 +12,7 @@ local ConfigSetListClass = newClass("ConfigSetListControl", "ListControl", funct self.configTab = configTab self.controls.copy = new("ButtonControl", {"BOTTOMLEFT",self,"TOP"}, 2, -4, 60, 18, "Copy", function() local configSet = configTab.configSets[self.selValue] - local newConfigSet = copyTable(configSet, true) + local newConfigSet = copyTable(configSet) newConfigSet.id = 1 while configTab.configSets[newConfigSet.id] do newConfigSet.id = newConfigSet.id + 1 From f3c227ddf96cc027628aeffc826c40ea2f1ada66 Mon Sep 17 00:00:00 2001 From: Wires77 Date: Tue, 23 Jul 2024 13:18:18 -0500 Subject: [PATCH 13/26] Fix Multishot mastery --- src/TreeData/3_25/tree.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/TreeData/3_25/tree.lua b/src/TreeData/3_25/tree.lua index 61215d329e..efd2f891d7 100644 --- a/src/TreeData/3_25/tree.lua +++ b/src/TreeData/3_25/tree.lua @@ -73602,7 +73602,6 @@ return { ["orbit"]= 2, ["orbitIndex"]= 14, ["out"]= { - "49391", "13375" }, ["in"]= { From daeec1fe671b9472466c16b39fda6b50a8f6e50b Mon Sep 17 00:00:00 2001 From: Juangui <80857657+justjuangui@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:35:58 -0500 Subject: [PATCH 14/26] Remove quality from tincture, Remove Add implicit from Tincture (#7862) Co-authored-by: justjuangui --- src/Classes/ItemsTab.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 46f6c4e93e..7c35dfdd53 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -492,7 +492,7 @@ holding Shift will put it in the second.]]) self:AddImplicitToDisplayItem() end) self.controls.displayItemAddImplicit.shown = function() - return self.displayItem and (self.displayItem.corruptible or ((self.displayItem.type ~= "Flask" or self.displayItem.type ~= "Jewel") and (self.displayItem.rarity == "NORMAL" or self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE"))) + return self.displayItem and self.displayItem.type ~= "Tincture" and (self.displayItem.corruptible or ((self.displayItem.type ~= "Flask" or self.displayItem.type ~= "Jewel") and (self.displayItem.rarity == "NORMAL" or self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE"))) end -- Section: Influence dropdowns @@ -3292,9 +3292,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode) elseif base.tincture then -- Tincture-specific info local tinctureData = item.tinctureData - if item.quality > 0 then - tooltip:AddLine(16, s_format("^x7F7F7FQuality: "..colorCodes.MAGIC.."+%d%%", item.quality)) - end + tooltip:AddLine(16, s_format("^x7F7F7FInflicts Mana Burn every %s%.2f ^x7F7F7FSeconds", main:StatColor(tinctureData.manaBurn, base.tincture.manaBurn), tinctureData.manaBurn)) tooltip:AddLine(16, s_format("^x7F7F7F%s%.2f ^x7F7F7FSecond Cooldown When Deactivated", main:StatColor(tinctureData.cooldown, base.tincture.cooldown), tinctureData.cooldown)) for _, modLine in pairs(item.buffModLines) do From 412277cebca1abce1fefe7b6d4c84ba7528eff44 Mon Sep 17 00:00:00 2001 From: Juangui <80857657+justjuangui@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:41:30 -0500 Subject: [PATCH 15/26] Add support to search Character import list by Ascendancy (#7824) * Enhance Dropdown to be able to use searchFilter or Label * Add details to Highlights Search in Dropdown --------- Co-authored-by: justjuangui --- src/Classes/DropDownControl.lua | 21 ++++++++++++++++++--- src/Classes/ImportTab.lua | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Classes/DropDownControl.lua b/src/Classes/DropDownControl.lua index 2805428b5e..27a9648209 100644 --- a/src/Classes/DropDownControl.lua +++ b/src/Classes/DropDownControl.lua @@ -19,7 +19,15 @@ local DropDownClass = newClass("DropDownControl", "Control", "ControlHost", "Too end, -- value mapping function function(listVal) - return StripEscapes(type(listVal) == "table" and listVal.label or listVal) + if type(listVal) == "table" then + if listVal.searchFilter then + return StripEscapes(listVal.searchFilter) + end + if listVal.label then + return StripEscapes(listVal.label) + end + end + return StripEscapes(listVal) end ) self.controls.scrollBar = new("ScrollBarControl", {"TOPRIGHT",self,"TOPRIGHT"}, -1, 0, 18, 0, (height - 4) * 4) @@ -359,9 +367,16 @@ function DropDownClass:Draw(viewPort, noTooltip) SetDrawColor(0.66, 0.66, 0.66) end -- draw actual item label with search match highlight if available - local label = type(listVal) == "table" and listVal.label or listVal + local label = nil + local detail = nil + if type(listVal) == "table" then + label = listVal.label + detail = listVal.detail + else + label = listVal + end DrawString(0, y, "LEFT", lineHeight, "VAR", label) - if selDetail ~= nil then + if detail ~= nil then local detail = listVal.detail dx = DrawStringWidth(lineHeight, "VAR", detail) DrawString(width - dx - 4 - 22, y, "LEFT", lineHeight, "VAR", detail) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index 37f69f6749..5dfb600046 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -522,6 +522,7 @@ function ImportTabClass:BuildCharacterList(league) t_insert(self.controls.charSelect.list, { label = charName, char = char, + searchFilter = charName.." "..charClass, detail = detail }) end From b8e314c2f008946010eb2c16bc2bc66a788a4039 Mon Sep 17 00:00:00 2001 From: Cheese Date: Wed, 24 Jul 2024 01:58:24 +0200 Subject: [PATCH 16/26] Change ArcaneSurge cast speed increase to ModFlag.Cast (Fixes #7869) (#7872) Co-authored-by: Cheese <12050603+mcheese@users.noreply.github.com> --- src/Modules/CalcPerform.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index c653085dc7..b8056050ad 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -598,7 +598,7 @@ local function doActorMisc(env, actor) modDB.conditions["AffectedByArcaneSurge"] = true local effect = 1 + modDB:Sum("INC", nil, "ArcaneSurgeEffect", "BuffEffectOnSelf") / 100 modDB:NewMod("ManaRegen", "INC", (modDB:Max(nil, "ArcaneSurgeManaRegen") or 30) * effect, "Arcane Surge") - modDB:NewMod("Speed", "INC", (modDB:Max(nil, "ArcaneSurgeCastSpeed") or 10) * effect, "Arcane Surge", ModFlag.Spell) + modDB:NewMod("Speed", "INC", (modDB:Max(nil, "ArcaneSurgeCastSpeed") or 10) * effect, "Arcane Surge", ModFlag.Cast) local arcaneSurgeDamage = modDB:Max(nil, "ArcaneSurgeDamage") or 0 if arcaneSurgeDamage ~= 0 then modDB:NewMod("Damage", "MORE", arcaneSurgeDamage * effect, "Arcane Surge", ModFlag.Spell) end end From a1f9f62a091d5045296a8fd9f896513e99d77f86 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:23:17 +1000 Subject: [PATCH 17/26] Update Fungal and Profane Ground with 3.25 changes (#7884) Changes were just added to the patch notes. We'll need some way of moving the Fungal ground aura away from ModParser and into CalcPerform or CalcOffence so the new annoint keystone works with it Co-authored-by: LocalIdentity --- src/Data/ModCache.lua | 2 +- src/Modules/ConfigOptions.lua | 9 ++++----- src/Modules/ModParser.lua | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 0f1b3adb0a..dfa33d2428 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -11725,7 +11725,7 @@ c["You have Crimson Dance if you have dealt a Critical Strike Recently"]={{[1]={ c["You have Crimson Dance while you have Cat's Stealth"]={{[1]={[1]={type="Condition",var="AffectedByCat'sStealth"},flags=0,keywordFlags=0,name="Keystone",type="LIST",value="Crimson Dance"}},nil} c["You have Culling Strike against Cursed Enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Cursed"},flags=0,keywordFlags=0,name="CullPercent",type="MAX",value=10}},nil} c["You have Far Shot while you do not have Iron Reflexes"]={{[1]={[1]={neg=true,type="Condition",var="HaveIronReflexes"},flags=0,keywordFlags=0,name="FarShot",type="FLAG",value=true}},nil} -c["You have Fungal Ground around you while stationary"]={{[1]={[1]={type="Condition",varList={[1]="OnFungalGround",[2]="Stationary"}},flags=0,keywordFlags=0,name="ExtraAura",type="LIST",value={mod={flags=0,keywordFlags=0,name="NonChaosDamageGainAsChaos",type="BASE",value=10}}},[2]={[1]={actor="enemy",type="ActorCondition",varList={[1]="OnFungalGround",[2]="Stationary"}},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="MORE",value=-10}}}},nil} +c["You have Fungal Ground around you while stationary"]={{[1]={[1]={type="Condition",varList={[1]="OnFungalGround",[2]="Stationary"}},flags=0,keywordFlags=0,name="ExtraAura",type="LIST",value={mod={flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=25}}},[2]={[1]={actor="enemy",type="ActorCondition",varList={[1]="OnFungalGround",[2]="Stationary"}},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=-10}}}},nil} c["You have Igniting, Chilling and Shocking Conflux while affected by Glorious Madness"]={{[1]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="PhysicalCanChill",type="FLAG",value=true},[2]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="LightningCanChill",type="FLAG",value=true},[3]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="FireCanChill",type="FLAG",value=true},[4]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="ChaosCanChill",type="FLAG",value=true},[5]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="EnemyIgniteChance",type="BASE",value=100},[6]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="PhysicalCanIgnite",type="FLAG",value=true},[7]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="LightningCanIgnite",type="FLAG",value=true},[8]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="ColdCanIgnite",type="FLAG",value=true},[9]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="ChaosCanIgnite",type="FLAG",value=true},[10]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="EnemyShockChance",type="BASE",value=100},[11]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="PhysicalCanShock",type="FLAG",value=true},[12]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="ColdCanShock",type="FLAG",value=true},[13]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="FireCanShock",type="FLAG",value=true},[14]={[1]={type="Condition",var="AffectedByGloriousMadness"},flags=0,keywordFlags=0,name="ChaosCanShock",type="FLAG",value=true}},nil} c["You have Iron Reflexes while at maximum Frenzy Charges"]={{[1]={[1]={stat="FrenzyCharges",thresholdStat="FrenzyChargesMax",type="StatThreshold"},flags=0,keywordFlags=0,name="Keystone",type="LIST",value="Iron Reflexes"}},nil} c["You have Lesser Brutal Shrine Buff"]={{[1]={flags=0,keywordFlags=0,name="Condition:LesserBrutalShrine",type="FLAG",value=true}},nil} diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 25684eff5e..cf162d2b13 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -989,7 +989,7 @@ Huge sets the radius to 11. { var = "conditionOnCausticGround", type = "check", label = "Are you on Caustic Ground?", ifCond = "OnCausticGround", apply = function(val, modList, enemyModList) modList:NewMod("Condition:OnCausticGround", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) end }, - { var = "conditionOnFungalGround", type = "check", label = "Are you on Fungal Ground?", ifCond = { "OnFungalGround", "CreateFungalGround" }, tooltip = "Allies on your Fungal Ground gain 10% of Non-Chaos Damage as extra ^xD02090Chaos ^7Damage.", apply = function(val, modList, enemyModList) + { var = "conditionOnFungalGround", type = "check", label = "Are you on Fungal Ground?", ifCond = { "OnFungalGround", "CreateFungalGround" }, tooltip = "Allies on your Fungal Ground gain +25% ^xD02090Chaos ^7Resistance.", apply = function(val, modList, enemyModList) modList:NewMod("Condition:OnFungalGround", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) end }, { var = "conditionOnBurningGround", type = "check", label = "Are you on ^xB97123Burning ^7Ground?", ifCond = "OnBurningGround", implyCond = "Burning", tooltip = "This also implies that you are ^xB97123Burning.", apply = function(val, modList, enemyModList) @@ -1718,16 +1718,15 @@ Huge sets the radius to 11. { var = "conditionEnemyHaveEnergyShield", type = "check", label = "Does the enemy have ^x88FFFFEnergy Shield^7?", ifEnemyCond = "HaveEnergyShield", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:HaveEnergyShield", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) end }, - { var = "conditionEnemyOnProfaneGround", type = "check", label = "Is the enemy on Profane Ground?", ifFlag = "Condition:CreateProfaneGround", tooltip = "Enemies on Profane Ground receive the following modifiers:\n\t-10% to all Resistances\n\t100% increased chance to be Critically Hit", apply = function(val, modList, enemyModList) + { var = "conditionEnemyOnProfaneGround", type = "check", label = "Is the enemy on Profane Ground?", ifFlag = "Condition:CreateProfaneGround", tooltip = "Enemies on Profane Ground receive the following modifiers:\n\t10% increased Effect of Curses\n\t100% increased chance to be Critically Hit", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:OnProfaneGround", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) - enemyModList:NewMod("ElementalResist", "BASE", -10, "Config", { type = "Condition", var = "OnProfaneGround" }) - enemyModList:NewMod("ChaosResist", "BASE", -10, "Config", { type = "Condition", var = "OnProfaneGround" }) + enemyModList:NewMod("CurseEffectOnSelf", "INC", 10, "Config", { type = "Condition", var = "OnProfaneGround" }) enemyModList:NewMod("SelfCritChance", "INC", 100, "Config", { type = "Condition", var = "OnProfaneGround" }) end }, { var = "multiplierEnemyAffectedByGraspingVines", type = "count", label = "# of Grasping Vines affecting enemy:", ifMult = "GraspingVinesAffectingEnemy", apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:GraspingVinesAffectingEnemy", "BASE", val, "Config", { type = "Condition", var = "Effective" }) end }, - { var = "conditionEnemyOnFungalGround", type = "check", label = "Is the enemy on Fungal Ground?", ifCond = { "OnFungalGround", "CreateFungalGround" }, tooltip = "Enemies on your Fungal Ground deal 10% less Damage.", apply = function(val, modList, enemyModList) + { var = "conditionEnemyOnFungalGround", type = "check", label = "Is the enemy on Fungal Ground?", ifCond = { "OnFungalGround", "CreateFungalGround" }, tooltip = "Enemies on your Fungal Ground have -10% ^xD02090Chaos ^7Resistance.", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:OnFungalGround", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) end }, { var = "conditionEnemyInChillingArea", type = "check", label = "Is the enemy in a ^x3F6DB3Chilling ^7area?", ifEnemyCond = "InChillingArea", apply = function(val, modList, enemyModList) diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 84b58c0827..0a88e9678f 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -4802,8 +4802,8 @@ local specialModList = { ["nearby enemies are crushed"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Crushed") }) }, ["crush enemies on hit with maces and sceptres"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Crushed") }, { type = "Condition", var = "UsingMace" }) }, ["you have fungal ground around you while stationary"] = { - mod("ExtraAura", "LIST", { mod = mod("NonChaosDamageGainAsChaos", "BASE", 10) }, { type = "Condition", varList = { "OnFungalGround", "Stationary" } }), - mod("EnemyModifier", "LIST", { mod = mod("Damage", "MORE", -10) }, { type = "ActorCondition", actor = "enemy", varList = { "OnFungalGround", "Stationary" } }), + mod("ExtraAura", "LIST", { mod = mod("ChaosResist", "BASE", 25) }, { type = "Condition", varList = { "OnFungalGround", "Stationary" } }), + mod("EnemyModifier", "LIST", { mod = mod("ChaosResist", "BASE", -10) }, { type = "ActorCondition", actor = "enemy", varList = { "OnFungalGround", "Stationary" } }), }, ["create fungal ground instead of consecrated ground"] = { flag("Condition:CreateFungalGround"), From 4876ed6fb632cd2401cdf6eedb3f831f08589179 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:23:25 +1000 Subject: [PATCH 18/26] Fix Cyclone of Tumult and Dual Strike of Impaling gem values (#7883) Updates the mana cost for Cyclone of Tumult and fixes the damageEffectiveness on Dual Strike of Impaling Co-authored-by: LocalIdentity --- src/Data/Skills/act_dex.lua | 158 ++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/Data/Skills/act_dex.lua b/src/Data/Skills/act_dex.lua index 37eff8b5be..8b34074237 100644 --- a/src/Data/Skills/act_dex.lua +++ b/src/Data/Skills/act_dex.lua @@ -4447,46 +4447,46 @@ skills["CycloneAltX"] = { "skill_can_add_multiple_charges_per_action", }, levels = { - [1] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.610, baseMultiplier = 0.610, levelRequirement = 28, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [2] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.636, baseMultiplier = 0.636, levelRequirement = 31, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [3] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.663, baseMultiplier = 0.663, levelRequirement = 34, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [4] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.689, baseMultiplier = 0.689, levelRequirement = 37, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [5] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.715, baseMultiplier = 0.715, levelRequirement = 40, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [6] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.742, baseMultiplier = 0.742, levelRequirement = 42, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [7] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.768, baseMultiplier = 0.768, levelRequirement = 44, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [8] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.794, baseMultiplier = 0.794, levelRequirement = 46, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [9] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.821, baseMultiplier = 0.821, levelRequirement = 48, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [10] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.847, baseMultiplier = 0.847, levelRequirement = 50, statInterpolation = { 1, 1, }, cost = { Mana = 2, }, }, - [11] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.873, baseMultiplier = 0.873, levelRequirement = 52, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [12] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.899, baseMultiplier = 0.899, levelRequirement = 54, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [13] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.926, baseMultiplier = 0.926, levelRequirement = 56, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [14] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.952, baseMultiplier = 0.952, levelRequirement = 58, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [15] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.978, baseMultiplier = 0.978, levelRequirement = 60, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [16] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.005, baseMultiplier = 1.005, levelRequirement = 62, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [17] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.031, baseMultiplier = 1.031, levelRequirement = 64, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [18] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.057, baseMultiplier = 1.057, levelRequirement = 66, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [19] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.084, baseMultiplier = 1.084, levelRequirement = 68, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [20] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.110, baseMultiplier = 1.110, levelRequirement = 70, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [21] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.136, baseMultiplier = 1.136, levelRequirement = 72, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [22] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.163, baseMultiplier = 1.163, levelRequirement = 74, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [23] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.189, baseMultiplier = 1.189, levelRequirement = 76, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [24] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.215, baseMultiplier = 1.215, levelRequirement = 78, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [25] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.242, baseMultiplier = 1.242, levelRequirement = 80, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [26] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.268, baseMultiplier = 1.268, levelRequirement = 82, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [27] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.294, baseMultiplier = 1.294, levelRequirement = 84, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [28] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.321, baseMultiplier = 1.321, levelRequirement = 86, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [29] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.347, baseMultiplier = 1.347, levelRequirement = 88, statInterpolation = { 1, 1, }, cost = { Mana = 3, }, }, - [30] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.373, baseMultiplier = 1.373, levelRequirement = 90, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [31] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.399, baseMultiplier = 1.399, levelRequirement = 91, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [32] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.426, baseMultiplier = 1.426, levelRequirement = 92, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [33] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.452, baseMultiplier = 1.452, levelRequirement = 93, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [34] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.478, baseMultiplier = 1.478, levelRequirement = 94, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [35] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.505, baseMultiplier = 1.505, levelRequirement = 95, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [36] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.531, baseMultiplier = 1.531, levelRequirement = 96, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [37] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.557, baseMultiplier = 1.557, levelRequirement = 97, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [38] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.584, baseMultiplier = 1.584, levelRequirement = 98, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [39] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.610, baseMultiplier = 1.610, levelRequirement = 99, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, - [40] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.636, baseMultiplier = 1.636, levelRequirement = 100, statInterpolation = { 1, 1, }, cost = { Mana = 4, }, }, + [1] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.610, baseMultiplier = 0.610, levelRequirement = 28, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [2] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.636, baseMultiplier = 0.636, levelRequirement = 31, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [3] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.663, baseMultiplier = 0.663, levelRequirement = 34, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [4] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.689, baseMultiplier = 0.689, levelRequirement = 37, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [5] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.715, baseMultiplier = 0.715, levelRequirement = 40, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [6] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.742, baseMultiplier = 0.742, levelRequirement = 42, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [7] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.768, baseMultiplier = 0.768, levelRequirement = 44, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [8] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.794, baseMultiplier = 0.794, levelRequirement = 46, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [9] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.821, baseMultiplier = 0.821, levelRequirement = 48, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [10] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.847, baseMultiplier = 0.847, levelRequirement = 50, statInterpolation = { 1, 1, }, cost = { Mana = 5, }, }, + [11] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.873, baseMultiplier = 0.873, levelRequirement = 52, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [12] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.899, baseMultiplier = 0.899, levelRequirement = 54, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [13] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.926, baseMultiplier = 0.926, levelRequirement = 56, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [14] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.952, baseMultiplier = 0.952, levelRequirement = 58, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [15] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 0.978, baseMultiplier = 0.978, levelRequirement = 60, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [16] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.005, baseMultiplier = 1.005, levelRequirement = 62, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [17] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.031, baseMultiplier = 1.031, levelRequirement = 64, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [18] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.057, baseMultiplier = 1.057, levelRequirement = 66, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [19] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.084, baseMultiplier = 1.084, levelRequirement = 68, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [20] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.110, baseMultiplier = 1.110, levelRequirement = 70, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [21] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.136, baseMultiplier = 1.136, levelRequirement = 72, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [22] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.163, baseMultiplier = 1.163, levelRequirement = 74, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [23] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.189, baseMultiplier = 1.189, levelRequirement = 76, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [24] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.215, baseMultiplier = 1.215, levelRequirement = 78, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [25] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.242, baseMultiplier = 1.242, levelRequirement = 80, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [26] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.268, baseMultiplier = 1.268, levelRequirement = 82, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [27] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.294, baseMultiplier = 1.294, levelRequirement = 84, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [28] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.321, baseMultiplier = 1.321, levelRequirement = 86, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [29] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.347, baseMultiplier = 1.347, levelRequirement = 88, statInterpolation = { 1, 1, }, cost = { Mana = 6, }, }, + [30] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.373, baseMultiplier = 1.373, levelRequirement = 90, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [31] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.399, baseMultiplier = 1.399, levelRequirement = 91, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [32] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.426, baseMultiplier = 1.426, levelRequirement = 92, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [33] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.452, baseMultiplier = 1.452, levelRequirement = 93, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [34] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.478, baseMultiplier = 1.478, levelRequirement = 94, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [35] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.505, baseMultiplier = 1.505, levelRequirement = 95, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [36] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.531, baseMultiplier = 1.531, levelRequirement = 96, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [37] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.557, baseMultiplier = 1.557, levelRequirement = 97, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [38] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.584, baseMultiplier = 1.584, levelRequirement = 98, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [39] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.610, baseMultiplier = 1.610, levelRequirement = 99, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, + [40] = { 500, 6, attackSpeedMultiplier = 60, PvPDamageMultiplier = -30, damageEffectiveness = 1.636, baseMultiplier = 1.636, levelRequirement = 100, statInterpolation = { 1, 1, }, cost = { Mana = 7, }, }, }, } skills["VaalCyclone"] = { @@ -5232,45 +5232,45 @@ skills["DoubleStrikeAltX"] = { }, levels = { [1] = { attackSpeedMultiplier = -20, baseMultiplier = 1.040, damageEffectiveness = 1.040, levelRequirement = 1, cost = { Mana = 7, }, }, - [2] = { attackSpeedMultiplier = -20, baseMultiplier = 1.201, damageEffectiveness = 1.201, levelRequirement = 2, cost = { Mana = 7, }, }, - [3] = { attackSpeedMultiplier = -20, baseMultiplier = 1.361, damageEffectiveness = 1.361, levelRequirement = 4, cost = { Mana = 8, }, }, - [4] = { attackSpeedMultiplier = -20, baseMultiplier = 1.522, damageEffectiveness = 1.522, levelRequirement = 7, cost = { Mana = 8, }, }, - [5] = { attackSpeedMultiplier = -20, baseMultiplier = 1.682, damageEffectiveness = 1.682, levelRequirement = 11, cost = { Mana = 8, }, }, - [6] = { attackSpeedMultiplier = -20, baseMultiplier = 1.843, damageEffectiveness = 1.843, levelRequirement = 16, cost = { Mana = 9, }, }, - [7] = { attackSpeedMultiplier = -20, baseMultiplier = 2.003, damageEffectiveness = 2.003, levelRequirement = 20, cost = { Mana = 9, }, }, - [8] = { attackSpeedMultiplier = -20, baseMultiplier = 2.164, damageEffectiveness = 2.164, levelRequirement = 24, cost = { Mana = 9, }, }, - [9] = { attackSpeedMultiplier = -20, baseMultiplier = 2.324, damageEffectiveness = 2.324, levelRequirement = 28, cost = { Mana = 10, }, }, - [10] = { attackSpeedMultiplier = -20, baseMultiplier = 2.485, damageEffectiveness = 2.485, levelRequirement = 32, cost = { Mana = 10, }, }, - [11] = { attackSpeedMultiplier = -20, baseMultiplier = 2.645, damageEffectiveness = 2.645, levelRequirement = 36, cost = { Mana = 10, }, }, - [12] = { attackSpeedMultiplier = -20, baseMultiplier = 2.806, damageEffectiveness = 2.806, levelRequirement = 40, cost = { Mana = 10, }, }, - [13] = { attackSpeedMultiplier = -20, baseMultiplier = 2.966, damageEffectiveness = 2.966, levelRequirement = 44, cost = { Mana = 11, }, }, - [14] = { attackSpeedMultiplier = -20, baseMultiplier = 3.127, damageEffectiveness = 3.127, levelRequirement = 48, cost = { Mana = 11, }, }, - [15] = { attackSpeedMultiplier = -20, baseMultiplier = 3.287, damageEffectiveness = 3.287, levelRequirement = 52, cost = { Mana = 11, }, }, - [16] = { attackSpeedMultiplier = -20, baseMultiplier = 3.448, damageEffectiveness = 3.448, levelRequirement = 56, cost = { Mana = 12, }, }, - [17] = { attackSpeedMultiplier = -20, baseMultiplier = 3.608, damageEffectiveness = 3.608, levelRequirement = 60, cost = { Mana = 12, }, }, - [18] = { attackSpeedMultiplier = -20, baseMultiplier = 3.769, damageEffectiveness = 3.769, levelRequirement = 64, cost = { Mana = 12, }, }, - [19] = { attackSpeedMultiplier = -20, baseMultiplier = 3.929, damageEffectiveness = 3.929, levelRequirement = 67, cost = { Mana = 13, }, }, - [20] = { attackSpeedMultiplier = -20, baseMultiplier = 4.090, damageEffectiveness = 4.090, levelRequirement = 70, cost = { Mana = 13, }, }, - [21] = { attackSpeedMultiplier = -20, baseMultiplier = 4.251, damageEffectiveness = 4.251, levelRequirement = 72, cost = { Mana = 13, }, }, - [22] = { attackSpeedMultiplier = -20, baseMultiplier = 4.411, damageEffectiveness = 4.411, levelRequirement = 74, cost = { Mana = 14, }, }, - [23] = { attackSpeedMultiplier = -20, baseMultiplier = 4.572, damageEffectiveness = 4.572, levelRequirement = 76, cost = { Mana = 14, }, }, - [24] = { attackSpeedMultiplier = -20, baseMultiplier = 4.732, damageEffectiveness = 4.732, levelRequirement = 78, cost = { Mana = 14, }, }, - [25] = { attackSpeedMultiplier = -20, baseMultiplier = 4.893, damageEffectiveness = 4.893, levelRequirement = 80, cost = { Mana = 15, }, }, - [26] = { attackSpeedMultiplier = -20, baseMultiplier = 5.053, damageEffectiveness = 5.053, levelRequirement = 82, cost = { Mana = 15, }, }, - [27] = { attackSpeedMultiplier = -20, baseMultiplier = 5.214, damageEffectiveness = 5.214, levelRequirement = 84, cost = { Mana = 15, }, }, - [28] = { attackSpeedMultiplier = -20, baseMultiplier = 5.374, damageEffectiveness = 5.374, levelRequirement = 86, cost = { Mana = 16, }, }, - [29] = { attackSpeedMultiplier = -20, baseMultiplier = 5.535, damageEffectiveness = 5.535, levelRequirement = 88, cost = { Mana = 16, }, }, - [30] = { attackSpeedMultiplier = -20, baseMultiplier = 5.695, damageEffectiveness = 5.695, levelRequirement = 90, cost = { Mana = 16, }, }, - [31] = { attackSpeedMultiplier = -20, baseMultiplier = 5.856, damageEffectiveness = 5.856, levelRequirement = 91, cost = { Mana = 16, }, }, - [32] = { attackSpeedMultiplier = -20, baseMultiplier = 6.016, damageEffectiveness = 6.016, levelRequirement = 92, cost = { Mana = 17, }, }, - [33] = { attackSpeedMultiplier = -20, baseMultiplier = 6.177, damageEffectiveness = 6.177, levelRequirement = 93, cost = { Mana = 17, }, }, - [34] = { attackSpeedMultiplier = -20, baseMultiplier = 6.337, damageEffectiveness = 6.337, levelRequirement = 94, cost = { Mana = 17, }, }, - [35] = { attackSpeedMultiplier = -20, baseMultiplier = 6.498, damageEffectiveness = 6.498, levelRequirement = 95, cost = { Mana = 18, }, }, - [36] = { attackSpeedMultiplier = -20, baseMultiplier = 6.658, damageEffectiveness = 6.658, levelRequirement = 96, cost = { Mana = 18, }, }, - [37] = { attackSpeedMultiplier = -20, baseMultiplier = 6.819, damageEffectiveness = 6.819, levelRequirement = 97, cost = { Mana = 18, }, }, - [38] = { attackSpeedMultiplier = -20, baseMultiplier = 6.979, damageEffectiveness = 6.979, levelRequirement = 98, cost = { Mana = 19, }, }, - [39] = { attackSpeedMultiplier = -20, baseMultiplier = 7.140, damageEffectiveness = 7.140, levelRequirement = 99, cost = { Mana = 19, }, }, - [40] = { attackSpeedMultiplier = -20, baseMultiplier = 7.301, damageEffectiveness = 7.301, levelRequirement = 100, cost= { Mana = 19, }, }, + [2] = { attackSpeedMultiplier = -20, baseMultiplier = 1.142, damageEffectiveness = 1.142, levelRequirement = 2, cost = { Mana = 7, }, }, + [3] = { attackSpeedMultiplier = -20, baseMultiplier = 1.244, damageEffectiveness = 1.244, levelRequirement = 4, cost = { Mana = 8, }, }, + [4] = { attackSpeedMultiplier = -20, baseMultiplier = 1.346, damageEffectiveness = 1.346, levelRequirement = 7, cost = { Mana = 8, }, }, + [5] = { attackSpeedMultiplier = -20, baseMultiplier = 1.448, damageEffectiveness = 1.448, levelRequirement = 11, cost = { Mana = 8, }, }, + [6] = { attackSpeedMultiplier = -20, baseMultiplier = 1.551, damageEffectiveness = 1.551, levelRequirement = 16, cost = { Mana = 9, }, }, + [7] = { attackSpeedMultiplier = -20, baseMultiplier = 1.653, damageEffectiveness = 1.653, levelRequirement = 20, cost = { Mana = 9, }, }, + [8] = { attackSpeedMultiplier = -20, baseMultiplier = 1.755, damageEffectiveness = 1.755, levelRequirement = 24, cost = { Mana = 9, }, }, + [9] = { attackSpeedMultiplier = -20, baseMultiplier = 1.857, damageEffectiveness = 1.857, levelRequirement = 28, cost = { Mana = 10, }, }, + [10] = { attackSpeedMultiplier = -20, baseMultiplier = 1.959, damageEffectiveness = 1.959, levelRequirement = 32, cost = { Mana = 10, }, }, + [11] = { attackSpeedMultiplier = -20, baseMultiplier = 2.061, damageEffectiveness = 2.061, levelRequirement = 36, cost = { Mana = 10, }, }, + [12] = { attackSpeedMultiplier = -20, baseMultiplier = 2.163, damageEffectiveness = 2.163, levelRequirement = 40, cost = { Mana = 10, }, }, + [13] = { attackSpeedMultiplier = -20, baseMultiplier = 2.265, damageEffectiveness = 2.265, levelRequirement = 44, cost = { Mana = 11, }, }, + [14] = { attackSpeedMultiplier = -20, baseMultiplier = 2.367, damageEffectiveness = 2.367, levelRequirement = 48, cost = { Mana = 11, }, }, + [15] = { attackSpeedMultiplier = -20, baseMultiplier = 2.469, damageEffectiveness = 2.469, levelRequirement = 52, cost = { Mana = 11, }, }, + [16] = { attackSpeedMultiplier = -20, baseMultiplier = 2.572, damageEffectiveness = 2.572, levelRequirement = 56, cost = { Mana = 12, }, }, + [17] = { attackSpeedMultiplier = -20, baseMultiplier = 2.674, damageEffectiveness = 2.674, levelRequirement = 60, cost = { Mana = 12, }, }, + [18] = { attackSpeedMultiplier = -20, baseMultiplier = 2.776, damageEffectiveness = 2.776, levelRequirement = 64, cost = { Mana = 12, }, }, + [19] = { attackSpeedMultiplier = -20, baseMultiplier = 2.878, damageEffectiveness = 2.878, levelRequirement = 67, cost = { Mana = 13, }, }, + [20] = { attackSpeedMultiplier = -20, baseMultiplier = 2.980, damageEffectiveness = 2.980, levelRequirement = 70, cost = { Mana = 13, }, }, + [21] = { attackSpeedMultiplier = -20, baseMultiplier = 3.082, damageEffectiveness = 3.082, levelRequirement = 72, cost = { Mana = 13, }, }, + [22] = { attackSpeedMultiplier = -20, baseMultiplier = 3.184, damageEffectiveness = 3.184, levelRequirement = 74, cost = { Mana = 14, }, }, + [23] = { attackSpeedMultiplier = -20, baseMultiplier = 3.286, damageEffectiveness = 3.286, levelRequirement = 76, cost = { Mana = 14, }, }, + [24] = { attackSpeedMultiplier = -20, baseMultiplier = 3.388, damageEffectiveness = 3.388, levelRequirement = 78, cost = { Mana = 14, }, }, + [25] = { attackSpeedMultiplier = -20, baseMultiplier = 3.491, damageEffectiveness = 3.491, levelRequirement = 80, cost = { Mana = 15, }, }, + [26] = { attackSpeedMultiplier = -20, baseMultiplier = 3.593, damageEffectiveness = 3.593, levelRequirement = 82, cost = { Mana = 15, }, }, + [27] = { attackSpeedMultiplier = -20, baseMultiplier = 3.695, damageEffectiveness = 3.695, levelRequirement = 84, cost = { Mana = 15, }, }, + [28] = { attackSpeedMultiplier = -20, baseMultiplier = 3.797, damageEffectiveness = 3.797, levelRequirement = 86, cost = { Mana = 16, }, }, + [29] = { attackSpeedMultiplier = -20, baseMultiplier = 3.899, damageEffectiveness = 3.899, levelRequirement = 88, cost = { Mana = 16, }, }, + [30] = { attackSpeedMultiplier = -20, baseMultiplier = 4.001, damageEffectiveness = 4.001, levelRequirement = 90, cost = { Mana = 16, }, }, + [31] = { attackSpeedMultiplier = -20, baseMultiplier = 4.103, damageEffectiveness = 4.103, levelRequirement = 91, cost = { Mana = 16, }, }, + [32] = { attackSpeedMultiplier = -20, baseMultiplier = 4.205, damageEffectiveness = 4.205, levelRequirement = 92, cost = { Mana = 17, }, }, + [33] = { attackSpeedMultiplier = -20, baseMultiplier = 4.307, damageEffectiveness = 4.307, levelRequirement = 93, cost = { Mana = 17, }, }, + [34] = { attackSpeedMultiplier = -20, baseMultiplier = 4.409, damageEffectiveness = 4.409, levelRequirement = 94, cost = { Mana = 17, }, }, + [35] = { attackSpeedMultiplier = -20, baseMultiplier = 4.512, damageEffectiveness = 4.512, levelRequirement = 95, cost = { Mana = 18, }, }, + [36] = { attackSpeedMultiplier = -20, baseMultiplier = 4.614, damageEffectiveness = 4.614, levelRequirement = 96, cost = { Mana = 18, }, }, + [37] = { attackSpeedMultiplier = -20, baseMultiplier = 4.716, damageEffectiveness = 4.716, levelRequirement = 97, cost = { Mana = 18, }, }, + [38] = { attackSpeedMultiplier = -20, baseMultiplier = 4.818, damageEffectiveness = 4.818, levelRequirement = 98, cost = { Mana = 19, }, }, + [39] = { attackSpeedMultiplier = -20, baseMultiplier = 4.920, damageEffectiveness = 4.920, levelRequirement = 99, cost = { Mana = 19, }, }, + [40] = { attackSpeedMultiplier = -20, baseMultiplier = 5.022, damageEffectiveness = 5.022, levelRequirement = 100, cost= { Mana = 19, }, }, }, } skills["DoubleStrikeAltY"] = { From 71aa2d15d843b5d4e1cea7771453634c378d9714 Mon Sep 17 00:00:00 2001 From: trimbe <19672127+trimbe@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:23:37 -0700 Subject: [PATCH 19/26] fix crash caused by intuitive leap-like being socketed in cluster socket (#7882) --- src/Classes/PassiveSpec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index 5e22bad794..8fb75deb6d 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -887,7 +887,7 @@ function PassiveSpecClass:NodesInIntuitiveLeapLikeRadius(node) local radiusIndex = item.jewelRadiusIndex if item and item.jewelData and item.jewelData.intuitiveLeapLike then local inRadius = self.nodes[node.id].nodesInRadius and self.nodes[node.id].nodesInRadius[radiusIndex] - for affectedNodeId, affectedNode in pairs(inRadius) do + for affectedNodeId, affectedNode in pairs(inRadius or {}) do if self.nodes[affectedNodeId].alloc then t_insert(result, self.nodes[affectedNodeId]) end From f9bbcdd450d624b544cb662152f817222e90e510 Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:24:25 +1000 Subject: [PATCH 20/26] Fix Cruel Retort granting Attack/Cast speed to all skills (#7881) The mod was missing the skillType check Co-authored-by: LocalIdentity --- src/Data/ModCache.lua | 6 +++--- src/Modules/ModParser.lua | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index dfa33d2428..15ce6ce842 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -10322,12 +10322,12 @@ c["Retaliation Skills have 10% reduced Enemy Stun Threshold"]={{[1]={[1]={type=" c["Retaliation Skills have 12% increased Cooldown Recovery Rate"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="CooldownRecovery",type="INC",value=12}},nil} c["Retaliation Skills have 15% increased Area of Effect"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=15}},nil} c["Retaliation Skills have 15% increased Cooldown Recovery Rate"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="CooldownRecovery",type="INC",value=15}},nil} -c["Retaliation Skills have 20% increased Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="INC",value=20}},nil} +c["Retaliation Skills have 20% increased Speed"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="Speed",type="INC",value=20}},nil} c["Retaliation Skills have 25% increased Stun Duration on Enemies"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="EnemyStunDuration",type="INC",value=25}},nil} c["Retaliation Skills have 30% increased Area of Effect"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=30}},nil} c["Retaliation Skills have 50% increased Stun Duration on Enemies"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="EnemyStunDuration",type="INC",value=50}},nil} -c["Retaliation Skills have 6% increased Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="INC",value=6}},nil} -c["Retaliation Skills have 8% increased Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="INC",value=8}},nil} +c["Retaliation Skills have 6% increased Speed"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="Speed",type="INC",value=6}},nil} +c["Retaliation Skills have 8% increased Speed"]={{[1]={[1]={type="SkillType"},flags=0,keywordFlags=0,name="Speed",type="INC",value=8}},nil} c["Returning Projectiles have 150% increased Speed"]={nil,"Returning Projectiles have 150% increased Speed "} c["Right Ring Slot: Your Shocking Skitterbot's Aura applies Socketed Hex Curse instead"]={{[1]={[1]={num=2,type="SlotNumber"},flags=0,keywordFlags=0,name="SkitterbotsCannotShock",type="FLAG",value=true}},nil} c["Right Ring slot: Cover Enemies in Frost for 5 seconds when you Freeze them"]={{[1]={[1]={num=2,type="SlotNumber"},[2]={actor="enemy",type="ActorCondition",var="Frozen"},flags=0,keywordFlags=0,name="CoveredInFrostEffect",type="BASE",value=20}},nil} diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 0a88e9678f..df8fcb8f50 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2521,7 +2521,7 @@ local specialModList = { mod("Damage", "MORE", num, nil, 0, bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "ActorCondition", actor = "enemy", var = "LowLife" }, { type = "Condition", var = "UsingAxe" }), } end, ["retaliation skills have (%d+)%% increased speed"] = function(num) return { - mod("Speed", "INC", num), + mod("Speed", "INC", num, { type = "SkillType", skillType = SkillType.Retaliation }), } end, -- Guardian ["grants armour equal to (%d+)%% of your reserved life to you and nearby allies"] = function(num) return { mod("GrantReservedLifeAsAura", "LIST", { mod = mod("Armour", "BASE", num / 100) }) } end, From 96d702102ef9c6e99c1a47458acf62689f6de2be Mon Sep 17 00:00:00 2001 From: LocalIdentity <31035929+LocalIdentity@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:24:38 +1000 Subject: [PATCH 21/26] Add automatic calculation for Rage sacrificed when using Rage Vortex (#7880) Adds support for Automatic calc of maximum Rage sacrificed by Rage Vortex Also allows you to overwrite the value with a config if needed Co-authored-by: LocalIdentity --- src/Data/Skills/act_str.lua | 12 +++++++++++- src/Export/Skills/act_str.txt | 12 +++++++++++- src/Modules/ConfigOptions.lua | 4 ++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Data/Skills/act_str.lua b/src/Data/Skills/act_str.lua index 3c6c80f3dd..f0b57980d3 100644 --- a/src/Data/Skills/act_str.lua +++ b/src/Data/Skills/act_str.lua @@ -7789,6 +7789,16 @@ skills["RageVortex"] = { }, statDescriptionScope = "skill_stat_descriptions", castTime = 1, + preDamageFunc = function(activeSkill, output) + if activeSkill.skillPart == 2 then + local maxRage = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "MaximumRage") + local rageVortexSacrificePercentage = activeSkill.skillData.MaxRageVortexSacrificePercentage / 100 + local configOverride= activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:RageSacrificedStacks") + local maxSacrificedRage = math.floor(rageVortexSacrificePercentage * maxRage) + local stacks = math.min((configOverride > 0 and configOverride) or maxSacrificedRage, maxSacrificedRage) + activeSkill.skillModList:NewMod("Multiplier:RageSacrificed", "BASE", stacks, "Skill:RageVortex") + end + end, parts = { { name = "Melee", @@ -7815,7 +7825,7 @@ skills["RageVortex"] = { mod("Speed", "MORE", nil, 0, 0, { type = "SkillPart", skillPart = 2 }), }, ["rage_slash_sacrifice_rage_%"] = { - mod("Multiplier:MaxRageVortexSacrificePercentage", "BASE", nil), + skill("MaxRageVortexSacrificePercentage", nil), }, ["quality_display_rage_vortex_is_gem"] = { -- Display only diff --git a/src/Export/Skills/act_str.txt b/src/Export/Skills/act_str.txt index bedcc047d0..be0c742092 100644 --- a/src/Export/Skills/act_str.txt +++ b/src/Export/Skills/act_str.txt @@ -1446,6 +1446,16 @@ local skills, mod, flag, skill = ... #skill RageVortex #flags attack melee area duration + preDamageFunc = function(activeSkill, output) + if activeSkill.skillPart == 2 then + local maxRage = activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "MaximumRage") + local rageVortexSacrificePercentage = activeSkill.skillData.MaxRageVortexSacrificePercentage / 100 + local configOverride= activeSkill.skillModList:Sum("BASE", activeSkill.skillCfg, "Multiplier:RageSacrificedStacks") + local maxSacrificedRage = math.floor(rageVortexSacrificePercentage * maxRage) + local stacks = math.min((configOverride > 0 and configOverride) or maxSacrificedRage, maxSacrificedRage) + activeSkill.skillModList:NewMod("Multiplier:RageSacrificed", "BASE", stacks, "Skill:RageVortex") + end + end, parts = { { name = "Melee", @@ -1472,7 +1482,7 @@ local skills, mod, flag, skill = ... mod("Speed", "MORE", nil, 0, 0, { type = "SkillPart", skillPart = 2 }), }, ["rage_slash_sacrifice_rage_%"] = { - mod("Multiplier:MaxRageVortexSacrificePercentage", "BASE", nil), + skill("MaxRageVortexSacrificePercentage", nil), }, ["quality_display_rage_vortex_is_gem"] = { -- Display only diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index cf162d2b13..fcaebfe12d 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -486,8 +486,8 @@ return { end end }, { label = "Rage Vortex:", ifSkill = "Rage Vortex" }, - { var = "sacrificedRageCount", type = "count", label = "Amount of Rage Sacrificed?", ifSkill = "Rage Vortex", apply = function(val, modList, enemyModList) - modList:NewMod("Multiplier:RageSacrificed", "BASE", val, "Config") + { var = "sacrificedRageCount", type = "count", label = "Amount of ^xFF9922Rage ^7Sacrificed (if not maximum):", ifSkill = "Rage Vortex", apply = function(val, modList, enemyModList) + modList:NewMod("Multiplier:RageSacrificedStacks", "BASE", val, "Config") end }, { label = "Raise Spectre:", ifSkill = "Raise Spectre", includeTransfigured = true }, { var = "raiseSpectreEnableBuffs", type = "check", defaultState = true, label = "Enable buffs:", ifSkill = "Raise Spectre", includeTransfigured = true, tooltip = "Enable any buff skills that your spectres have.", apply = function(val, modList, enemyModList) From cecda07ff09a7d53f30b2fa30f54ed532c1e0eb8 Mon Sep 17 00:00:00 2001 From: NL <56325975+NL908@users.noreply.github.com> Date: Tue, 23 Jul 2024 22:27:13 -0400 Subject: [PATCH 22/26] Add config options for # of trap/mine trap throws (#7879) --- src/Modules/CalcOffence.lua | 8 ++++---- src/Modules/ConfigOptions.lua | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index d62cf77ee2..3c9d9a7a6e 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -1130,7 +1130,7 @@ function calcs.offence(env, actor, activeSkill) if skillData.trapCooldown or skillData.cooldown then trapThrowCount = 1 end - output.TrapThrowCount = trapThrowCount + output.TrapThrowCount = env.modDB:Override(nil, "TrapThrowCount") or trapThrowCount output.TrapThrowingSpeed = m_min(output.TrapThrowingSpeed, data.misc.ServerTickRate) output.TrapThrowingTime = 1 / output.TrapThrowingSpeed skillData.timeOverride = output.TrapThrowingTime / output.TrapThrowCount @@ -1219,10 +1219,10 @@ function calcs.offence(env, actor, activeSkill) if skillData.trapCooldown or skillData.cooldown then mineThrowCount = 1 end - output.MineThrowCount = mineThrowCount - if mineThrowCount >= 1 then + output.MineThrowCount = env.modDB:Override(nil, "MineThrowCount") or mineThrowCount + if output.MineThrowCount >= 1 then -- Throwing Mines takes 10% more time for each *additional* Mine thrown - output.MineLayingSpeed = output.MineLayingSpeed / (1 + (mineThrowCount - 1) * 0.1) + output.MineLayingSpeed = output.MineLayingSpeed / (1 + (output.MineThrowCount - 1) * 0.1) end output.MineLayingSpeed = m_min(output.MineLayingSpeed, data.misc.ServerTickRate) diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index fcaebfe12d..716e3dea5a 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -1389,6 +1389,9 @@ Huge sets the radius to 11. { var = "multiplierMineDetonatedRecently", type = "count", label = "# of Mines Detonated Recently:", ifMult = "MineDetonatedRecently", implyCond = "DetonatedMinesRecently", apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:MineDetonatedRecently", "BASE", val, "Config", { type = "Condition", var = "Combat" }) end }, + { var = "minesPerThrow", type = "count", label = "# of Mines per throw:", ifFlag = "mine", tooltip = "This will override the number of Mines per throw", apply = function(val, modList, enemyModList) + modList:NewMod("MineThrowCount", "OVERRIDE", val, "Config", {type = "Condition", var = "Combat"}) + end }, { var = "TriggeredTrapsRecently", type = "check", label = "Have you Triggered a Trap Recently?", ifCond = "TriggeredTrapsRecently", apply = function(val, modList, enemyModList) modList:NewMod("Condition:TriggeredTrapsRecently", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) end }, @@ -1398,6 +1401,9 @@ Huge sets the radius to 11. { var = "conditionThrownTrapOrMineRecently", type = "check", label = "Have you thrown a Trap or Mine Recently?", ifCond = "TrapOrMineThrownRecently", apply = function(val, modList, enemyModList) modList:NewMod("Condition:TrapOrMineThrownRecently", "FLAG", true, "Config", { type = "Condition", var = "Combat" }) end }, + { var = "trapsPerThrow", type = "count", label = "# of Traps per throw:", ifFlag = "trap", tooltip = "This will override the number of Traps per throw", apply = function(val, modList, enemyModList) + modList:NewMod("TrapThrowCount", "OVERRIDE", val, "Config", {type = "Condition", var = "Combat"}) + end }, { var = "conditionCursedEnemyRecently", type = "check", label = "Have you Cursed an enemy Recently?", ifCond="CursedEnemyRecently", apply = function(val, modList, enemyModList) modList:NewMod("Condition:CursedEnemyRecently", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) end }, From cf54c76de6ed1d99ab8cf4609fa0dc4a931ed2d0 Mon Sep 17 00:00:00 2001 From: Regisle <49933620+Regisle@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:09:20 +0930 Subject: [PATCH 23/26] banner debuff change (#7853) --- src/Data/ModCache.lua | 2 +- src/Modules/CalcPerform.lua | 57 ++++++++++++++++++++++++++++++++++++- src/Modules/ModParser.lua | 28 ++++-------------- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 15ce6ce842..29518516c0 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -7194,7 +7194,7 @@ c["Banner Skills have 20% increased Duration"]={{[1]={[1]={skillType=99,type="Sk c["Banner Skills have 8% increased Duration"]={{[1]={[1]={skillType=99,type="SkillType"},flags=0,keywordFlags=0,name="Duration",type="INC",value=8}},nil} c["Banner Skills have no Reservation"]={{[1]={[1]={skillType=99,type="SkillType"},[2]={neg=true,skillType=119,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="manaReservationPercent",value=0}},[2]={[1]={skillType=99,type="SkillType"},[2]={neg=true,skillType=119,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="lifeReservationPercent",value=0}}},nil} c["Banners also Maim Enemies"]={nil,"Banners also Maim Enemies "} -c["Banners also cause Enemies to take 8% increased Damage"]={{[1]={[1]={skillType=99,type="SkillType"},flags=0,keywordFlags=0,name="ExtraAuraEffect",type="LIST",value={mod={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=8}}}}}},nil} +c["Banners also cause Enemies to take 8% increased Damage"]={{[1]={[1]={type="Condition",var="BannerPlanted"},[2]={skillType=99,type="SkillType"},flags=0,keywordFlags=0,name="ExtraAuraDebuffEffect",type="LIST",value={mod={[1]={effectType="AuraDebuff",type="GlobalEffect",unscalable=true},flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=8}}}},nil} c["Banners also cause Killed Enemies to have 20% chance to Explode, dealing a tenth of their Life as Physical Damage"]={nil,"Banners also cause Killed Enemies to have 20% chance to Explode, dealing a tenth of their Life as Physical Damage "} c["Banners also cause Killed Enemies to have 20% chance to Explode, dealing a tenth of their Life as Physical Damage Banner Skills have 20% increased Area of Effect"]={nil,"Banners also cause Killed Enemies to have 20% chance to Explode, dealing a tenth of their Life as Physical Damage Banner Skills have 20% increased Area of Effect "} c["Banners also grant +5% to all Elemental Resistances to you and Allies"]={{[1]={[1]={skillType=99,type="SkillType"},flags=0,keywordFlags=0,name="ExtraAuraEffect",type="LIST",value={mod={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=5}}}},nil} diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index b8056050ad..893f61f47c 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -2042,6 +2042,43 @@ function calcs.perform(env, skipEHP) end mergeBuff(srcList, buffs, "Totem "..buff.name) end + -- check if aura has a debuff added to it, but does not have an auraDebuff + if env.mode_effective and #modDB:List(skillCfg, "ExtraAuraDebuffEffect") > 0 and not modDB:Flag(nil, "SelfAurasOnlyAffectYou") then + local auraDebuffFound = false + for _, buff in ipairs(activeSkill.buffList) do + if buff.type == "AuraDebuff" then + auraDebuffFound = true + break + end + end + if not auraDebuffFound then + activeSkill.debuffSkill = true + local extraAuraModList = { } + for _, value in ipairs(modDB:List(skillCfg, "ExtraAuraDebuffEffect")) do + local add = true + for _, mod in ipairs(extraAuraModList) do + if modLib.compareModParams(mod, value.mod) then + mod.value = mod.value + value.mod.value + add = false + break + end + end + if add then + t_insert(extraAuraModList, copyTable(value.mod, true)) + end + end + local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect", "DebuffEffect") + local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect", "DebuffEffect") + mult = (1 + inc / 100) * more + local newModList = new("ModList") + newModList:AddList(extraAuraModList) + buffExports["Aura"][buff.name..(buffExports["Aura"][buff.name] and "_Debuff" or "")] = { effectMult = mult, modList = newModList } + if allyBuffs["AuraDebuff"] and allyBuffs["AuraDebuff"][buff.name] and allyBuffs["AuraDebuff"][buff.name].effectMult / 100 > mult then + mult = 0 + end + mergeBuff(newModList, debuffs, buff.name) + end + end end elseif buff.type == "Debuff" or buff.type == "AuraDebuff" then local stackCount @@ -2061,13 +2098,30 @@ function calcs.perform(env, skipEHP) modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true local srcList = new("ModList") local mult = 1 + local extraAuraModList = { } if buff.type == "AuraDebuff" then + for _, value in ipairs(modDB:List(skillCfg, "ExtraAuraDebuffEffect")) do + local add = true + for _, mod in ipairs(extraAuraModList) do + if modLib.compareModParams(mod, value.mod) then + mod.value = mod.value + value.mod.value + add = false + break + end + end + if add then + t_insert(extraAuraModList, copyTable(value.mod, true)) + end + end mult = 0 if not modDB:Flag(nil, "SelfAurasOnlyAffectYou") then local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect", "DebuffEffect") local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect", "DebuffEffect") mult = (1 + inc / 100) * more - buffExports["Aura"][buff.name..(buffExports["Aura"][buff.name] and "_Debuff" or "")] = { effectMult = mult, modList = buff.modList } + local newModList = new("ModList") + newModList:AddList(buff.modList) + newModList:AddList(extraAuraModList) + buffExports["Aura"][buff.name..(buffExports["Aura"][buff.name] and "_Debuff" or "")] = { effectMult = mult, modList = newModList } if allyBuffs["AuraDebuff"] and allyBuffs["AuraDebuff"][buff.name] and allyBuffs["AuraDebuff"][buff.name].effectMult / 100 > mult then mult = 0 end @@ -2079,6 +2133,7 @@ function calcs.perform(env, skipEHP) mult = (1 + inc / 100) * more end srcList:ScaleAddList(buff.modList, mult * stackCount) + srcList:ScaleAddList(extraAuraModList, mult * stackCount) if activeSkill.skillData.stackCount or buff.stackVar then srcList:NewMod("Multiplier:"..buff.name.."Stack", "BASE", stackCount, buff.name) end diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index df8fcb8f50..1d233cf8c4 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -1170,7 +1170,6 @@ local preFlagList = { ["^auras from your skills grant "] = { addToAura = true }, ["^auras grant "] = { addToAura = true }, ["^banners also grant "] = { addToAura = true, onlyAddToBanners = true }, - ["^banners also cause enemies to take "] = { addToAura = true, onlyAddToBanners = true, modSuffix = "Taken", applyToEnemy = true }, ["^you and nearby allies "] = { newAura = true }, ["^you and nearby allies [hgd][ae][via][enl] "] = { newAura = true }, ["^nearby allies [hgd][ae][via][enl] "] = { newAura = true, newAuraOnlyAllies = true }, @@ -4647,6 +4646,7 @@ local specialModList = { mod("SkillData", "LIST", { key = "lifeReservationPercent", value = 0 }, { type = "SkillType", skillType = SkillType.Banner }, { type = "SkillType", skillType = SkillType.Blessing, neg = true }), }, ["placed banners also grant (%d+)%% increased attack damage to you and allies"] = function(num) return { mod("ExtraAuraEffect", "LIST", { mod = mod("Damage", "INC", num, nil, ModFlag.Attack) }, { type = "Condition", var = "BannerPlanted" }, { type = "SkillType", skillType = SkillType.Banner }) } end, + ["banners also cause enemies to take (%d+)%% increased damage"] = function(num) return { mod("ExtraAuraDebuffEffect", "LIST", { mod = mod("DamageTaken", "INC", num, { type = "GlobalEffect", effectType = "AuraDebuff", unscalable = true }) }, { type = "Condition", var = "BannerPlanted" }, { type = "SkillType", skillType = SkillType.Banner }) } end, ["dread banner grants an additional %+(%d+) to maximum fortification when placing the banner"] = function(num) return { mod("ExtraSkillMod", "LIST", { mod = mod("MaximumFortification", "BASE", num, { type = "GlobalEffect", effectType = "Buff" }) }, { type = "Condition", var = "BannerPlanted" }, { type = "SkillName", skillName = "Dread Banner" }) } end, ["your aura skills are disabled"] = { flag("DisableSkill", { type = "SkillType", skillType = SkillType.Aura }) }, ["your blessing skills are disabled"] = { flag("DisableSkill", { type = "SkillType", skillType = SkillType.Blessing }) }, @@ -5944,31 +5944,13 @@ local function parseMod(line, order) end if modList[1] then -- Special handling for various modifier types - if misc.addToAura then - -- Modifiers that add effects to your auras + if misc.addToAura then if misc.onlyAddToBanners then - if misc.applyToEnemy then - for i, effectMod in ipairs(modList) do - local tagList = { } - if misc.playerTag then t_insert(tagList, misc.playerTag) end - if misc.playerTagList then - for _, tag in ipairs(misc.playerTagList) do - t_insert(tagList, tag) - end - end - local newMod = effectMod - if effectMod[1] and type(effectMod) == "table" and misc.actorEnemy then - newMod = copyTable(effectMod) - newMod[1]["actor"] = "enemy" - end - modList[i] = mod("ExtraAuraEffect", "LIST", { mod = mod("EnemyModifier", "LIST", { mod = newMod }, unpack(tagList)) }, { type = "SkillType", skillType = SkillType.Banner }) - end - else - for i, effectMod in ipairs(modList) do - modList[i] = mod("ExtraAuraEffect", "LIST", { mod = effectMod }, { type = "SkillType", skillType = SkillType.Banner }) - end + for i, effectMod in ipairs(modList) do + modList[i] = mod("ExtraAuraEffect", "LIST", { mod = effectMod }, { type = "SkillType", skillType = SkillType.Banner }) end else + -- Modifiers that add effects to your auras for i, effectMod in ipairs(modList) do modList[i] = mod("ExtraAuraEffect", "LIST", { mod = effectMod }) end From 118450cdcb164cc64674b8cd8d9fc17ac6e06adc Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Wed, 24 Jul 2024 06:40:18 +0200 Subject: [PATCH 24/26] Reset display group inside of skill set switching method (#7874) Closes #7826 --- src/Classes/SkillsTab.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 8142664e40..6e9838bd4b 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -95,7 +95,6 @@ local SkillsTabClass = newClass("SkillsTab", "UndoHandler", "ControlHost", "Cont -- Set selector self.controls.setSelect = new("DropDownControl", { "TOPLEFT", self, "TOPLEFT" }, 76, 8, 210, 20, nil, function(index, value) self:SetActiveSkillSet(self.skillSetOrderList[index]) - self:SetDisplayGroup(self.socketGroupList[1]) self:AddUndoState() end) self.controls.setSelect.enableDroppedWidth = true @@ -421,7 +420,6 @@ function SkillsTabClass:Load(xml, fileName) end end self:SetActiveSkillSet(tonumber(xml.attrib.activeSkillSet) or 1) - self:SetDisplayGroup(self.socketGroupList[1]) self:ResetUndo() self.build:SyncLoadouts() end @@ -1347,4 +1345,5 @@ function SkillsTabClass:SetActiveSkillSet(skillSetId) -- set the loadout option to the dummy option since it is now dirty self.build.controls.buildLoadouts:SetSel(1) + self:SetDisplayGroup(self.socketGroupList[1]) end From c79544b4135454629ad089f18f371b34ea52c34a Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Wed, 24 Jul 2024 06:44:39 +0200 Subject: [PATCH 25/26] Relax matching for loadout names and allow groups at any spot (#7847) Fixes: #7835 Signed-off-by: Tomas Slusny --- src/Modules/Build.lua | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 08de9ab398..06e4668e24 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -909,13 +909,19 @@ function buildMode:SyncLoadouts(reset) local specTitle = spec.title or "Default" -- only alphanumeric and comma are allowed in the braces { } local linkIdentifier = string.match(specTitle, "%{([%w,]+)%}") + if linkIdentifier then + local setName = specTitle:gsub("%{" .. linkIdentifier .. "%}", ""):gsub("^%s*", ""):gsub("%s*$", "") + if not setName or setName == "" then + setName = "Default" + end + -- iterate over each identifier, delimited by comma, and set the index so we can grab it later -- setId index is the id of the set in the global list needed for SetActiveSet -- setName is only used for Tree currently and we strip the braces to get the plain name of the set, this is used as the name of the loadout for linkId in string.gmatch(linkIdentifier, "[^%,]+") do transferTable["setId"] = id - transferTable["setName"] = string.match(specTitle, "(.+)% {") or "Default" + transferTable["setName"] = setName transferTable["linkId"] = linkId self.treeListSpecialLinks[linkId] = transferTable t_insert(sortedTreeListSpecialLinks, transferTable) @@ -932,12 +938,18 @@ function buildMode:SyncLoadouts(reset) for id, set in ipairs(setOrderList) do local setTitle = tabSets[set].title or "Default" local linkIdentifier = string.match(setTitle, "%{([%w,]+)%}") + -- this if/else prioritizes group identifier in case the user creates sets with same name AND same identifiers -- result is only the group is recognized and one loadout is created rather than a duplicate from each condition met if linkIdentifier then + local setName = setTitle:gsub("%{" .. linkIdentifier .. "%}", ""):gsub("^%s*", ""):gsub("%s*$", "") + if not setName or setName == "" then + setName = "Default" + end + for linkId in string.gmatch(linkIdentifier, "[^%,]+") do transferTable["setId"] = set - transferTable["setName"] = string.match(setTitle, "(.+)% {") or "Default" + transferTable["setName"] = setName specialLinks[linkId] = transferTable transferTable = {} end From 0722878906902ef895e338ea6876d4548f38ae5f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:13:24 +1000 Subject: [PATCH 26/26] Release 2.45.0 (#7887) * Prepare release 2.45.0 * Fix Changelogs --------- Co-authored-by: LocalIdentity Co-authored-by: LocalIdentity --- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++ changelog.txt | 39 +++++++++++++++++++++++++++++++++++++++ manifest.xml | 2 +- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7531696419..321610055d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # Changelog +## [v2.45.0](https://github.com/PathOfBuildingCommunity/PathOfBuilding/tree/v2.45.0) (2024/07/24) + +[Full Changelog](https://github.com/PathOfBuildingCommunity/PathOfBuilding/compare/v2.44.1...v2.45.0) + + + +## What's Changed +### New to Path of Building +- Add automatic calculation for Rage sacrificed when using Rage Vortex [\#7880](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7880) ([LocalIdentity](https://github.com/LocalIdentity)) +- Add support for changing item quality in the edit item interface [\#5914](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/5914) ([hexeaktivitat](https://github.com/hexeaktivitat)) +- Add config options to override the number of Trap/Mines per throw [\#7879](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7879) ([NL908](https://github.com/NL908)) +- Update Death Aura damage with 3.25 changes [\#7842](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7842) ([LocalIdentity](https://github.com/LocalIdentity)) +- Update Tattoo Keystones with 3.25 Changes [\#7865](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7865) ([LocalIdentity](https://github.com/LocalIdentity)) +- Update Legion Notables with 3.25 changes [\#7864](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7864) ([LocalIdentity](https://github.com/LocalIdentity)) +- Update Fungal and Profane Ground with 3.25 changes [\#7884](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7884) ([LocalIdentity](https://github.com/LocalIdentity)) +### Fixed Crashes +- Fix crash when hovering over Tinctures in Item tab [\#7862](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7862) ([justjuangui](https://github.com/justjuangui)) +- Fix crash when socketing Thread of Hope in Cluster socket [\#7882](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7882) ([trimbe](https://github.com/trimbe)) +- Fix crash when importing a build with Warcries [\#7853](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7853) ([Regisle](https://github.com/Regisle)) +### User Interface +- Add support to search Character import list by Ascendancy [\#7824](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7824) ([justjuangui](https://github.com/justjuangui), [ryuukk](https://github.com/ryuukk)) +- Relax matching for loadout names and allow groups at any spot [\#7847](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7847) ([deathbeam](https://github.com/deathbeam)) +- Show proper skill group when switching loadouts [\#7874](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7874) ([deathbeam](https://github.com/deathbeam)) +### Fixed Calculations +- Fix Seismic Cry AoE calculation [\#7837](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7837) ([LocalIdentity](https://github.com/LocalIdentity)) +- Fix Impale not using enemy damage taken [\#7831](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7831) ([mcheese](https://github.com/mcheese)) +- Fix Tincture Mana Burn rate applying inversely [\#7851](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7851) ([Regisle](https://github.com/Regisle)) +### Fixed Behaviours +- Fix Rage Effect not applying to "per x Rage" mods [\#7866](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7866) ([LocalIdentity](https://github.com/LocalIdentity)) +- Fix Autoexertion and Call to Arms not disabling Warcry buffs [\#7861](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7861) ([LocalIdentity](https://github.com/LocalIdentity)) +- Fix Arcane Surge not working with Wilma's Requital [\#7872](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7872) ([mcheese](https://github.com/mcheese)) +- Fix Cruel Retort granting Attack/Cast Speed to all skills [\#7881](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7881) ([LocalIdentity](https://github.com/LocalIdentity)) +### Accuracy Improvements +- Fix Herald of Ash Phys as extra Fire scaling [\#7839](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7839) ([LocalIdentity](https://github.com/LocalIdentity)) +- Fix Cyclone of Tumult and Dual Strike of Impaling gem values [\#7883](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7883) ([LocalIdentity](https://github.com/LocalIdentity)) +### Fixed Bugs +- Fix config set copies not having independent values [\#7867](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/7867) ([justjuangui](https://github.com/justjuangui)) + + ## [v2.44.1](https://github.com/PathOfBuildingCommunity/PathOfBuilding/tree/v2.44.1) (2024/07/23) [Full Changelog](https://github.com/PathOfBuildingCommunity/PathOfBuilding/compare/v2.44.0...v2.44.1) diff --git a/changelog.txt b/changelog.txt index 47fda96065..7cf8637ec2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,42 @@ +VERSION[2.45.0][2024/07/24] + +--- New to Path of Building --- +* Add automatic calculation for Rage sacrificed when using Rage Vortex (LocalIdentity) +* Add support for changing item quality in the edit item interface (hexeaktivitat) +* Add config options to override the number of Trap/Mines per throw (NL908) +* Update Death Aura damage with 3.25 changes (LocalIdentity) +* Update Tattoo Keystones with 3.25 Changes (LocalIdentity) +* Update Legion Notables with 3.25 changes (LocalIdentity) +* Update Fungal and Profane Ground with 3.25 changes (LocalIdentity) + +--- Fixed Crashes --- +* Fix crash when hovering over Tinctures in Item tab (justjuangui) +* Fix crash when socketing Thread of Hope in Cluster socket (trimbe) +* Fix crash when importing a build with Warcries (Regisle) + +--- User Interface --- +* Add support to search Character import list by Ascendancy (justjuangui, ryuukk) +* Relax matching for loadout names and allow groups at any spot (deathbeam) +* Show proper skill group when switching loadouts (deathbeam) + +--- Fixed Calculations --- +* Fix Seismic Cry AoE calculation (LocalIdentity) +* Fix Impale not using enemy damage taken (mcheese) +* Fix Tincture Mana Burn rate applying inversely (Regisle) + +--- Fixed Behaviours --- +* Fix Rage Effect not applying to "per x Rage" mods (LocalIdentity) +* Fix Autoexertion and Call to Arms not disabling Warcry buffs (LocalIdentity) +* Fix Arcane Surge not working with Wilma's Requital (mcheese) +* Fix Cruel Retort granting Attack/Cast Speed to all skills (LocalIdentity) + +--- Accuracy Improvements --- +* Fix Herald of Ash Phys as extra Fire scaling (LocalIdentity) +* Fix Cyclone of Tumult and Dual Strike of Impaling gem values (LocalIdentity) + +--- Fixed Bugs --- +* Fix config set copies not having independent values (justjuangui) + VERSION[2.44.1][2024/07/23] --- New to Path of Building --- diff --git a/manifest.xml b/manifest.xml index 485f473f50..e0dde93b87 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,6 +1,6 @@ - +