diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index d97af2593d..df3b72084b 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -7,4 +7,18 @@ describe("TestSkills", function() -- newBuild() takes care of resetting everything in setup() end) + it("Test blasphemy reserving Spirit", function() + build.skillsTab:PasteSocketGroup("Blasphemy 20/0 1\nDespair 20/0 1\n") + runCallback("OnFrame") + + local oneCurseReservation = build.calcsTab.mainOutput.SpiritReservedPercent + assert.True(oneCurseReservation > 0) + + newBuild() + + build.skillsTab:PasteSocketGroup("Blasphemy 20/0 1\nDespair 20/0 1\nFlammability 20/0 1\n") + runCallback("OnFrame") + + assert.True(build.calcsTab.mainOutput.SpiritReservedPercent > oneCurseReservation) + end) end) \ No newline at end of file diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 4e219b56ee..5ddbd0a2e9 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -1138,7 +1138,7 @@ function SkillsTabClass:AddSocketGroupTooltip(tooltip, socketGroup) tooltip:AddLine(16, "^7Active Skill #"..index..":") for _, skillEffect in ipairs(activeSkill.effectList) do tooltip:AddLine(20, string.format("%s%s ^7%d%s/%d%s", - data.skillColorMap[skillEffect.grantedEffect.color], + data.skillColorMap[skillEffect.grantedEffect.color or skillEffect.gemData and skillEffect.gemData.grantedEffect.color], skillEffect.grantedEffect.name, skillEffect.srcInstance and skillEffect.srcInstance.level or skillEffect.level, (skillEffect.srcInstance and skillEffect.level > skillEffect.srcInstance.level) and colorCodes.MAGIC.."+"..(skillEffect.level - skillEffect.srcInstance.level).."^7" or "", diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index e9ec76295d..ece07bf1aa 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -3152,7 +3152,7 @@ c["Skills have -2 seconds to Cooldown"]={{}," seconds to Cooldown "} c["Skills have 33% chance to not consume a Cooldown when used"]={{[1]={[1]={skillType=101,type="SkillType"},flags=0,keywordFlags=0,name="CooldownChanceNotConsume",type="BASE",value=0.33}},nil} c["Skills have a 125% longer Perfect Timing window"]={{[1]={flags=0,keywordFlags=0,name="PerfectTiming",type="INC",value=125}},nil} c["Skills have a 150% longer Perfect Timing window"]={{[1]={flags=0,keywordFlags=0,name="PerfectTiming",type="INC",value=150}},nil} -c["Skills reserve 50% less Spirit"]={nil,"Skills reserve 50% less Spirit "} +c["Skills reserve 50% less Spirit"]={{[1]={flags=0,keywordFlags=0,name="SpiritReserved",type="MORE",value=-50}},nil} c["Skills that would Summon a Totem have 20% chance to Summon two Totems instead"]={nil,"Skills that would Summon a Totem have 20% chance to Summon two Totems instead "} c["Slam Skills have 12% increased Area of Effect"]={{[1]={[1]={skillType=103,type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=12}},nil} c["Slam Skills you use yourself cause Aftershocks"]={nil,"Slam Skills you use yourself cause Aftershocks "} @@ -3285,7 +3285,7 @@ c["Your Dexterity is added to your Minions"]={{[1]={flags=0,keywordFlags=0,name= c["Your Hits are Crushing Blows"]={nil,"Your Hits are Crushing Blows "} c["Your Hits can't be Evaded"]={{[1]={flags=0,keywordFlags=0,name="CannotBeEvaded",type="FLAG",value=true}},nil} c["Your Stun Threshold is doubled"]={{[1]={flags=0,keywordFlags=0,name="StunThreshold",type="MORE",value=100}},nil} -c["Your speed is unaffected by Slows"]={nil,"Your speed is unaffected by Slows "} +c["Your speed is unaffected by Slows"]={{[1]={flags=0,keywordFlags=0,name="UnaffectedBySlows",type="FLAG",value=true}},nil} c["dealing 10% of their Life as Physical Damage"]={nil,"dealing 10% of their Life as Physical Damage "} c["dealing 10% of their Life as Physical Damage Warcry Skills have 30% increased Area of Effect"]={nil,"dealing 10% of their Life as Physical Damage Warcry Skills have 30% increased Area of Effect "} c["dealing 25% of their Life as Physical Damage"]={nil,"dealing 25% of their Life as Physical Damage "} diff --git a/src/Data/Skills/act_int.lua b/src/Data/Skills/act_int.lua index 99b6ed071c..4a3e49c027 100644 --- a/src/Data/Skills/act_int.lua +++ b/src/Data/Skills/act_int.lua @@ -769,6 +769,11 @@ skills["BlasphemyPlayer"] = { label = "Buff", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "skill_stat_descriptions", + statMap = { + ["blasphemy_base_spirit_reservation_per_socketed_curse"] = { + mod("SkillData", "LIST", { key = "spiritReservationFlat", value = nil }) + }, + }, baseFlags = { area = true, }, diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index 2ec57c6c93..e22489b0ec 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -153,11 +153,12 @@ function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGr end end until (notAddedNewSupport) - + for _, supportEffect in ipairs(supportList) do -- Pass 2: Add all compatible supports if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then t_insert(activeSkill.effectList, supportEffect) + -- Track how many active skills are supported by this support effect if supportEffect.isSupporting and activeEffect.srcInstance then supportEffect.isSupporting[activeEffect.srcInstance] = true end diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 50a21097e6..5473a7221e 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -183,7 +183,16 @@ function calcs.doActorLifeManaSpiritReservation(actor) values.reservedFlat = values.reservedFlat * activeSkill.activeMineCount values.reservedPercent = values.reservedPercent * activeSkill.activeMineCount end - -- Blood Sacrament increases reservation per stage channelled + if activeSkill.skillTypes[SkillType.CanHaveMultipleOngoingSkillInstances] and activeSkill.activeEffect.srcInstance.supportEffect and activeSkill.activeEffect.srcInstance.supportEffect.isSupporting then + -- Sadly no better way to get key/val table element count in lua. + local instances = 0 + for _ in pairs(activeSkill.activeEffect.srcInstance.supportEffect.isSupporting) do + instances = instances + 1 + end + values.reservedFlat = values.reservedFlat * instances + values.reservedPercent = values.reservedPercent * instances + end + -- Blood Sacrament increases reservation per stage channelled if activeSkill.skillCfg.skillName == "Blood Sacrament" and activeSkill.activeStageCount then values.reservedFlat = values.reservedFlat * (activeSkill.activeStageCount + 1) values.reservedPercent = values.reservedPercent * (activeSkill.activeStageCount + 1) diff --git a/src/Modules/Calcs.lua b/src/Modules/Calcs.lua index 3a7fa59b56..871b337244 100644 --- a/src/Modules/Calcs.lua +++ b/src/Modules/Calcs.lua @@ -440,7 +440,7 @@ function calcs.buildOutput(build, mode) if not GlobalCache.cachedData[mode][uuid] then calcs.buildActiveSkill(env, mode, skill, uuid) end - if GlobalCache.cachedData[mode][uuid] then + if GlobalCache.cachedData[mode][uuid] and (not skill.triggeredBy or skill.triggeredBy.grantedEffect.id ~= "SupportBlasphemyPlayer") then output.EnergyShieldProtectsMana = env.modDB:Flag(nil, "EnergyShieldProtectsMana") for pool, costResource in pairs({["LifeUnreserved"] = "LifeCost", ["ManaUnreserved"] = "ManaCost", ["Rage"] = "RageCost", ["EnergyShield"] = "ESCost"}) do local cachedCost = GlobalCache.cachedData[mode][uuid].Env.player.output[costResource] diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index e000f56d85..0e4497b17d 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -4881,6 +4881,7 @@ local specialModList = { mod("SkillData", "LIST", { key = "manaReservationPercent", value = 0 }, { type = "SkillType", skillType = SkillType.Banner }, { type = "SkillType", skillType = SkillType.Blessing, neg = true }), mod("SkillData", "LIST", { key = "lifeReservationPercent", value = 0 }, { type = "SkillType", skillType = SkillType.Banner }, { type = "SkillType", skillType = SkillType.Blessing, neg = true }), }, + ["skills reserve (%d+)%% less (.+)"] = function(num, _, resource) return { mod(string.gsub(" "..resource, "%W%l", string.upper):sub(2) .. "Reserved", "MORE", -num) } end, ["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,