From a0c03ba48c7a5d5c9545ca29893f5f97dc3e2175 Mon Sep 17 00:00:00 2001 From: Trevor Lund Date: Fri, 12 Mar 2021 16:22:34 -0600 Subject: [PATCH 1/8] Fixes #2346 - Fanaticism should not apply to attacks --- Modules/CalcPerform.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CalcPerform.lua b/Modules/CalcPerform.lua index e5e6ec94..4638606f 100644 --- a/Modules/CalcPerform.lua +++ b/Modules/CalcPerform.lua @@ -462,8 +462,8 @@ local function doActorMisc(env, actor) if modDB:Flag(nil, "Fanaticism") and actor.mainSkill and actor.mainSkill.skillFlags.selfCast then local effect = m_floor(75 * (1 + modDB:Sum("INC", nil, "BuffEffectOnSelf") / 100)) modDB:NewMod("Speed", "MORE", effect, "Fanaticism", ModFlag.Cast) - modDB:NewMod("ManaCost", "INC", -effect, "Fanaticism") - modDB:NewMod("AreaOfEffect", "INC", effect, "Fanaticism") + modDB:NewMod("ManaCost", "INC", -effect, "Fanaticism", ModFlag.Cast) + modDB:NewMod("AreaOfEffect", "INC", effect, "Fanaticism", ModFlag.Cast) end if modDB:Flag(nil, "UnholyMight") then local effect = m_floor(30 * (1 + modDB:Sum("INC", nil, "BuffEffectOnSelf") / 100)) From d5e71af0c3589781075094a101ffc5d0dfad3eff Mon Sep 17 00:00:00 2001 From: Trevor Lund Date: Wed, 17 Mar 2021 22:48:22 -0500 Subject: [PATCH 2/8] Fixes #2351 - Add support for Flickershade spectre chaos damage conversion --- Data/Spectres.lua | 2 +- Export/Minions/modmap.ini | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Data/Spectres.lua b/Data/Spectres.lua index ebe40c36..3b413859 100644 --- a/Data/Spectres.lua +++ b/Data/Spectres.lua @@ -3067,6 +3067,6 @@ minions["Metadata/Monsters/Maligaro/SecretDesecrateMonster"] = { }, modList = { -- MonsterOneThirdDamageTaken [base_damage_taken_+% = -67] - -- MonsterConvertToChaos1 [base_physical_damage_%_to_convert_to_chaos = 50] + mod("PhysicalDamageConvertToChaos", "BASE", 50), -- MonsterConvertToChaos1 [base_physical_damage_%_to_convert_to_chaos = 50] }, } diff --git a/Export/Minions/modmap.ini b/Export/Minions/modmap.ini index dff3c0fd..75617b0a 100644 --- a/Export/Minions/modmap.ini +++ b/Export/Minions/modmap.ini @@ -5,6 +5,8 @@ mod("ProjectileCount", "BASE", 2) mod("PhysicalDamageConvertToFire", "BASE", 50) [MonsterConvertToColdDamage2] mod("PhysicalDamageConvertToCold", "BASE", 50) +[MonsterConvertToChaos1] +mod("PhysicalDamageConvertToChaos", "BASE", 50) [MonsterPhysicalAddedAsColdSkeletonMaps] mod("PhysicalDamageGainAsCold", "BASE", 100) [MonsterCurseCastSpeedPenalty] From 6d5e439f0fa13dc5a3045fb1903ddf3e6fd2a303 Mon Sep 17 00:00:00 2001 From: pundm Date: Fri, 19 Mar 2021 16:40:28 +0100 Subject: [PATCH 3/8] changed divergent nightblade from base crit to inc crit% --- Data/SkillStatMap.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Data/SkillStatMap.lua b/Data/SkillStatMap.lua index a1f83c22..7c9fd7df 100644 --- a/Data/SkillStatMap.lua +++ b/Data/SkillStatMap.lua @@ -453,7 +453,7 @@ return { mod("CritMultiplier", "BASE", nil, 0, 0, { type = "Condition", var = "Elusive" }, { type = "Condition", varList = { "UsingClaw", "UsingDagger" } }, { type = "Condition", varList = { "UsingSword", "UsingAxe", "UsingMace" }, neg = true} ), }, ["critical_strike_chance_against_enemies_on_full_life_+%"] = { - mod("CritChance", "BASE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "FullLife" }) + mod("CritChance", "INC", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "FullLife" }) }, ["critical_strike_chance_+%_vs_blinded_enemies"] = { mod("CritChance", "INC", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "Blinded"}) From 430ca0ebf31babdf18edaa68f863d5b945223d65 Mon Sep 17 00:00:00 2001 From: Trevor Lund Date: Sun, 21 Mar 2021 00:45:46 -0500 Subject: [PATCH 4/8] Fixes #2323 - Rounding values to the nearest hundredths for float precision --- Classes/ModStore.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/ModStore.lua b/Classes/ModStore.lua index 23f34be5..1bce7568 100644 --- a/Classes/ModStore.lua +++ b/Classes/ModStore.lua @@ -40,9 +40,9 @@ function ModStoreClass:ScaleAddMod(mod, scale) scale = m_max(scale, 0) local scaledMod = copyTable(mod) if type(scaledMod.value) == "number" then - scaledMod.value = (m_floor(scaledMod.value) == scaledMod.value) and m_modf(scaledMod.value * scale) or scaledMod.value * scale + scaledMod.value = (m_floor(scaledMod.value) == scaledMod.value) and m_modf(round(scaledMod.value * scale, 2)) or scaledMod.value * scale elseif type(scaledMod.value) == "table" and scaledMod.value.mod then - scaledMod.value.mod.value = (m_floor(scaledMod.value.mod.value) == scaledMod.value.mod.value) and m_modf(scaledMod.value.mod.value * scale) or scaledMod.value.mod.value * scale + scaledMod.value.mod.value = (m_floor(scaledMod.value.mod.value) == scaledMod.value.mod.value) and m_modf(round(scaledMod.value.mod.value * scale, 2)) or scaledMod.value.mod.value * scale end self:AddMod(scaledMod) end @@ -62,9 +62,9 @@ function ModStoreClass:ScaleAddList(modList, scale) for i = 1, #modList do local scaledMod = copyTable(modList[i]) if type(scaledMod.value) == "number" then - scaledMod.value = (m_floor(scaledMod.value) == scaledMod.value) and m_modf(scaledMod.value * scale) or scaledMod.value * scale + scaledMod.value = (m_floor(scaledMod.value) == scaledMod.value) and m_modf(round(scaledMod.value * scale, 2)) or scaledMod.value * scale elseif type(scaledMod.value) == "table" and scaledMod.value.mod then - scaledMod.value.mod.value = (m_floor(scaledMod.value.mod.value) == scaledMod.value.mod.value) and m_modf(scaledMod.value.mod.value * scale) or scaledMod.value.mod.value * scale + scaledMod.value.mod.value = (m_floor(scaledMod.value.mod.value) == scaledMod.value.mod.value) and m_modf(round(scaledMod.value.mod.value * scale, 2)) or scaledMod.value.mod.value * scale end self:AddMod(scaledMod) end From 1daa1b6e855f47a035d02d40aa0cc8f6be5febae Mon Sep 17 00:00:00 2001 From: Andrew Belu <3247221+andrewbelu@users.noreply.github.com> Date: Tue, 9 Mar 2021 20:21:22 -0600 Subject: [PATCH 5/8] Add handling for Doedre's Skin --- Modules/CalcPerform.lua | 76 ++++++++++++++++++++++++++--------------- Modules/ModParser.lua | 1 + 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/Modules/CalcPerform.lua b/Modules/CalcPerform.lua index d8cf4726..acfc9cba 100644 --- a/Modules/CalcPerform.lua +++ b/Modules/CalcPerform.lua @@ -1301,6 +1301,7 @@ function calcs.perform(env) fromPlayer = true, priority = activeSkill.skillTypes[SkillType.Aura] and 3 or 1, isMark = mark, + ignoreHexLimit = modDB:Flag(activeSkill.skillCfg, "CursesIgnoreHexLimit") and not mark or false } local inc = skillModList:Sum("INC", skillCfg, "CurseEffect") + enemyDB:Sum("INC", nil, "CurseEffectOnSelf") local more = skillModList:More(skillCfg, "CurseEffect") @@ -1465,36 +1466,57 @@ function calcs.perform(env) local markSlotted = false for _, source in ipairs({curses, minionCurses}) do for _, curse in ipairs(source) do - local slot - for i = 1, source.limit do - --Prevent multiple marks from being considered - if curse.isMark then - if markSlotted then - slot = nil + -- calculate curses that ignore hex limit after + if not curse.ignoreHexLimit then + local slot + for i = 1, source.limit do + --Prevent multiple marks from being considered + if curse.isMark then + if markSlotted then + slot = nil + break + end + end + if not curseSlots[i] then + slot = i + break + elseif curseSlots[i].name == curse.name then + if curseSlots[i].priority < curse.priority then + slot = i + else + slot = nil + end + break + elseif curseSlots[i].priority < curse.priority then + slot = i + end + end + if slot then + if curseSlots[slot] and curseSlots[slot].isMark then + markSlotted = false + end + curseSlots[slot] = curse + if curse.isMark then + markSlotted = true + end + end + end + end + end + + for _, source in ipairs({curses, minionCurses}) do + for _, curse in ipairs(source) do + if curse.ignoreHexLimit then + local foundLowerPriorityCurse = false + for i = 1, #curseSlots do + if curseSlots[i].name == curse.name and curseSlots[i].priority < curse.priority then + curseSlots[i] = curse + foundLowerPriorityCurse = true break end end - if not curseSlots[i] then - slot = i - break - elseif curseSlots[i].name == curse.name then - if curseSlots[i].priority < curse.priority then - slot = i - else - slot = nil - end - break - elseif curseSlots[i].priority < curse.priority then - slot = i - end - end - if slot then - if curseSlots[slot] and curseSlots[slot].isMark then - markSlotted = false - end - curseSlots[slot] = curse - if curse.isMark then - markSlotted = true + if not foundLowerPriorityCurse then + curseSlots[#curseSlots + 1] = curse end end end diff --git a/Modules/ModParser.lua b/Modules/ModParser.lua index 22402224..bf14c3a7 100644 --- a/Modules/ModParser.lua +++ b/Modules/ModParser.lua @@ -2520,6 +2520,7 @@ local specialModList = { ["[ct][ar][si][tg]g?e?r? a socketed cold s[pk][ei]ll on melee critical strike"] = { mod("ExtraSupport", "LIST", { skillId = "SupportUniqueCosprisMaliceColdSpellsCastOnMeleeCriticalStrike", level = 1 }, { type = "SocketedIn", slotName = "{SlotName}" }) }, ["your curses can apply to hexproof enemies"] = { flag("CursesIgnoreHexproof") }, ["your hexes can affect hexproof enemies"] = { flag("CursesIgnoreHexproof") }, + ["hexes from socketed skills ignore curse limit"] = { flag("CursesIgnoreHexLimit", { type = "SocketedIn", slotName = "{SlotName}" } )}, ["reserves (%d+)%% of life"] = function(num) return { mod("ExtraLifeReserved", "BASE", num) } end, ["(%d+)%% of cold damage taken as lightning"] = function(num) return { mod("ColdDamageTakenAsLightning", "BASE", num) } end, ["(%d+)%% of fire damage taken as lightning"] = function(num) return { mod("FireDamageTakenAsLightning", "BASE", num) } end, From c49f258157bfe49f9f0784ad7131bd43323837bb Mon Sep 17 00:00:00 2001 From: Andrew Belu <3247221+andrewbelu@users.noreply.github.com> Date: Mon, 22 Mar 2021 21:22:09 -0500 Subject: [PATCH 6/8] Add fix for multiple of the same curse socketed in Doedre's skin --- Modules/CalcPerform.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Modules/CalcPerform.lua b/Modules/CalcPerform.lua index acfc9cba..da5daefa 100644 --- a/Modules/CalcPerform.lua +++ b/Modules/CalcPerform.lua @@ -1507,15 +1507,18 @@ function calcs.perform(env) for _, source in ipairs({curses, minionCurses}) do for _, curse in ipairs(source) do if curse.ignoreHexLimit then - local foundLowerPriorityCurse = false + local skipAddingCurse = false for i = 1, #curseSlots do - if curseSlots[i].name == curse.name and curseSlots[i].priority < curse.priority then - curseSlots[i] = curse - foundLowerPriorityCurse = true + if curseSlots[i].name == curse.name then + -- if curse is higher priority, replace current curse with it, otherwise if same or lower priority skip it entirely + if curseSlots[i].priority < curse.priority then + curseSlots[i] = curse + end + skipAddingCurse = true break end end - if not foundLowerPriorityCurse then + if not skipAddingCurse then curseSlots[#curseSlots + 1] = curse end end From 6b2a60eb067d1ff9c9dda8e0e969fb91ba5915c7 Mon Sep 17 00:00:00 2001 From: PJacek Date: Thu, 25 Mar 2021 19:41:18 +0100 Subject: [PATCH 7/8] Add enchants and fix enchanting UI --- Classes/ItemsTab.lua | 8 ++++++-- Modules/ModParser.lua | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Classes/ItemsTab.lua b/Classes/ItemsTab.lua index ed315df9..ecf143ff 100644 --- a/Classes/ItemsTab.lua +++ b/Classes/ItemsTab.lua @@ -1736,8 +1736,12 @@ function ItemsTabClass:EnchantDisplayItem(enchantSlot) if haveSkills then for _, socketGroup in ipairs(self.build.skillsTab.socketGroupList) do for _, gemInstance in ipairs(socketGroup.gemList) do - if gemInstance.gemData and not gemInstance.gemData.grantedEffect.support and enchantments[gemInstance.nameSpec] then - skillsUsed[gemInstance.nameSpec] = true + if gemInstance.gemData then + for _, grantedEffect in ipairs(gemInstance.gemData.grantedEffectList) do + if not grantedEffect.support and enchantments[grantedEffect.name] then + skillsUsed[grantedEffect.name] = true + end + end end end end diff --git a/Modules/ModParser.lua b/Modules/ModParser.lua index eed5b5d2..66d771ed 100644 --- a/Modules/ModParser.lua +++ b/Modules/ModParser.lua @@ -2649,10 +2649,12 @@ local specialModList = { ["wintertide brand has %+(%d+) to maximum stages"] = function(num) return { mod("Multiplier:WintertideBrandMaxStages", "BASE", num, { type = "SkillName", skillName = "Wintertide Brand" }) } end, ["wave of conviction's exposure applies (%-%d+)%% elemental resistance"] = function(num) return { mod("ExtraSkillStat", "LIST", { key = "purge_expose_resist_%_matching_highest_element_damage", value = num }, { type = "SkillName", skillName = "Wave of Conviction" }) } end, ["arcane cloak spends an additional (%d+)%% of current mana"] = function(num) return { mod("ExtraSkillStat", "LIST", { key = "arcane_cloak_consume_%_of_mana", value = num }, { type = "SkillName", skillName = "Arcane Cloak" }) } end, + ["arcane cloak grants life regeneration equal to (%d+)%% of mana spent per second"] = function(num) return { mod("ExtraSkillMod", "LIST", { mod = mod("LifeRegen", "BASE", num / 100, 0, 0, { type = "Multiplier", var = "ArcaneCloakConsumedMana" }, { type = "GlobalEffect", effectType = "Buff" }) }, { type = "SkillName", skillName = "Arcane Cloak" }) } end, ["caustic arrow has (%d+)%% chance to inflict withered on hit for (%d+) seconds base duration"] = { mod("ExtraSkillMod", "LIST", { mod = mod("Condition:CanWither", "FLAG", true) }, { type = "SkillName", skillName = "Caustic Arrow" } ) }, ["venom gyre has a (%d+)%% chance to inflict withered for (%d+) seconds on hit"] = { mod("ExtraSkillMod", "LIST", { mod = mod("Condition:CanWither", "FLAG", true) }, { type = "SkillName", skillName = "Venom Gyre" } ) }, ["sigil of power's buff also grants (%d+)%% increased critical strike chance per stage"] = function(num) return { mod("CritChance", "INC", num, 0, 0, { type = "Multiplier", var = "SigilOfPowerStage", limit = 4 }, { type = "GlobalEffect", effectType = "Buff", effectName = "Sigil of Power" } ) } end, ["cobra lash chains (%d+) additional times"] = function(num) return { mod("ExtraSkillMod", "LIST", { mod = mod("ChainCountMax", "BASE", num) }, { type = "SkillName", skillName = "Cobra Lash" }) } end, + ["steelskin buff can take (%d+)%% increased amount of damage"] = function(num) return { mod("ExtraSkillStat", "LIST", { key = "steelskin_damage_limit_+%", value = num }, { type = "SkillName", skillName = "Steelskin" }) } end, -- Alternate Quality ["quality does not increase physical damage"] = { mod("AlternateQualityWeapon", "BASE", 1) }, ["(%d+)%% increased critical strike chance per 4%% quality"] = function(num) return { mod("AlternateQualityLocalCritChancePer4Quality", "INC", num) } end, From b41eabe9c9e3b7b23c7022010cc1e50e2cefb88b Mon Sep 17 00:00:00 2001 From: Trevor Lund Date: Sat, 27 Mar 2021 02:43:43 -0500 Subject: [PATCH 8/8] Fixes #1702 - Curses with two words weren't being parsed correctly --- Modules/ModParser.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/ModParser.lua b/Modules/ModParser.lua index 22402224..8c579405 100644 --- a/Modules/ModParser.lua +++ b/Modules/ModParser.lua @@ -1830,11 +1830,11 @@ local specialModList = { ["curse enemies with (%D+) on %a+"] = function(_, skill) return extraSkill(skill, 1, true) end, ["curse enemies with (%D+) on %a+, with (%d+)%% increased effect"] = function(_, skill, num) return { mod("ExtraSkill", "LIST", { skillId = gemIdLookup[skill], level = 1, noSupports = true }), - mod("CurseEffect", "INC", tonumber(num), { type = "SkillName", skillName = gemIdLookup[skill] }), + mod("CurseEffect", "INC", tonumber(num), { type = "SkillName", skillName = string.gsub(" "..skill, "%W%l", string.upper):sub(2) }), } end, ["%d+%% chance to curse n?o?n?%-?c?u?r?s?e?d? ?enemies with (%D+) on %a+, with (%d+)%% increased effect"] = function(_, skill, num) return { mod("ExtraSkill", "LIST", { skillId = gemIdLookup[skill], level = 1, noSupports = true }), - mod("CurseEffect", "INC", tonumber(num), { type = "SkillName", skillName = gemIdLookup[skill] }), + mod("CurseEffect", "INC", tonumber(num), { type = "SkillName", skillName = string.gsub(" "..skill, "%W%l", string.upper):sub(2) }), } end, ["curse enemies with level (%d+) (%D+) on %a+, which can apply to hexproof enemies"] = function(num, _, skill) return extraSkill(skill, num, true) end, ["curse enemies with level (%d+) (.+) on %a+"] = function(num, _, skill) return extraSkill(skill, num, true) end, @@ -2061,7 +2061,7 @@ local specialModList = { ["you are cursed with level (%d+) (%D+)"] = function(num, _, name) return { mod("ExtraCurse", "LIST", { skillId = gemIdLookup[name], level = num, applyToPlayer = true }) } end, ["you are cursed with (%D+), with (%d+)%% increased effect"] = function(_, skill, num) return { mod("ExtraCurse", "LIST", { skillId = gemIdLookup[skill], level = 1, applyToPlayer = true }), - mod("CurseEffectOnSelf", "INC", tonumber(num), { type = "SkillName", skillName = gemIdLookup[skill] }), + mod("CurseEffectOnSelf", "INC", tonumber(num), { type = "SkillName", skillName = string.gsub(" "..skill, "%W%l", string.upper):sub(2) }), } end, ["you count as on low life while you are cursed with vulnerability"] = { flag("Condition:LowLife", { type = "Condition", var = "AffectedByVulnerability" }) }, ["if you consumed a corpse recently, you and nearby allies regenerate (%d+)%% of life per second"] = function (num) return { mod("ExtraAura", "LIST", { mod = mod("LifeRegenPercent", "BASE", num) }, { type = "Condition", var = "ConsumedCorpseRecently" }) } end,