diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index 4a709e3b3f..787c859ec7 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -129,6 +129,23 @@ describe("TestSkills", function() assert.True(build.calcsTab.mainOutput.SpiritReservedPercent > oneCurseReservation) end) + it("applies life reservation efficiency to Atziri's Communion Blasphemy reservation", function() + build.skillsTab:PasteSocketGroup("Blasphemy 20/0 1\nDespair 20/0 1\nAtziri's Communion 1/0 1\n") + runCallback("OnFrame") + + assert.are.equals(0, build.calcsTab.mainOutput.SpiritReserved) + assert.are.equals(0, build.calcsTab.mainOutput.SpiritReservedPercent) + assert.are.equals(26, build.calcsTab.mainOutput.LifeReserved) + assert.are.equals(40, build.calcsTab.mainOutput.LifeReservedPercent) + + build.configTab.input.customMods = "100% increased Life Reservation Efficiency" + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(13, build.calcsTab.mainOutput.LifeReserved) + assert.are.equals(20, build.calcsTab.mainOutput.LifeReservedPercent) + end) + it("rounds Blasphemy curse magnitudes to the nearest integer", function() build.configTab.input.customMods = "79% increased Curse Magnitudes" build.configTab.input.enemyIsBoss = "None" diff --git a/src/Data/Gems.lua b/src/Data/Gems.lua index dce7d86ec7..9e4ce6b68f 100644 --- a/src/Data/Gems.lua +++ b/src/Data/Gems.lua @@ -17432,6 +17432,25 @@ return { Tier = 0, naturalMaxLevel = 1, }, + ["Metadata/Items/Gems/SkillGemAtzirisCommunionSupport"] = { + name = "Atziri's Communion", + gameId = "Metadata/Items/Gem/SupportGemAtzirisCommunion", + variantId = "AtzirisCommunionSupport", + grantedEffectId = "SupportAtzirisCommunionPlayer", + tags = { + support = true, + lineage = true, + persistent = true, + }, + gemType = "Support", + gemFamily = "Atziri's Communion", + tagString = "Lineage, Persistent", + reqStr = 0, + reqDex = 0, + reqInt = 100, + Tier = 0, + naturalMaxLevel = 1, + }, ["Metadata/Items/Gems/SkillGemAtzirisImpatienceSupport"] = { name = "Atziri's Impatience", gameId = "Metadata/Items/Gem/SupportGemAtzirisImpatience", diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 5390b1ef90..3abe158a2b 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -1387,7 +1387,6 @@ c["100% increased Thorns damage if you've consumed an Endurance Charge Recently" c["100% increased amount of Life Leeched"]={{[1]={flags=0,keywordFlags=0,name="MaxLifeLeechRate",type="INC",value=100}},nil} c["100% increased chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="INC",value=100}},nil} c["100% increased effect of Socketed Augment Items"]={{[1]={flags=0,keywordFlags=0,name="SocketedAugmentItemEffect",type="INC",value=100}},nil} -c["100% increased effect of Socketed Augment Items This item gains bonuses from Socketed Items as though it was a Body Armour"]={{[1]={flags=0,keywordFlags=0,name="SocketedAugmentItemEffect",type="INC",value=100}}," This item gains bonuses from Socketed Items as though it was a Body Armour "} c["100% increased effect of Socketed Soul Cores"]={{[1]={flags=0,keywordFlags=0,name="SocketedSoulCoreEffect",type="INC",value=100}},nil} c["100% increased maximum Divinity"]={{}," maximum Divinity "} c["100% increased maximum Divinity 20% reduced maximum Divinity per Corrupted Item Equipped"]={{}," maximum Divinity 20% reduced maximum Divinity per Corrupted Item Equipped "} @@ -3448,6 +3447,7 @@ c["75% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalD c["75% increased Spirit"]={{[1]={flags=0,keywordFlags=0,name="Spirit",type="INC",value=75}},nil} c["75% increased Thorns damage if you've Blocked Recently"]={{[1]={[1]={type="Condition",var="BlockedRecently"},flags=32,keywordFlags=0,name="Damage",type="INC",value=75}},nil} c["75% increased chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="INC",value=75}},nil} +c["75% increased effect of Socketed Augment Items"]={{[1]={flags=0,keywordFlags=0,name="SocketedAugmentItemEffect",type="INC",value=75}},nil} c["75% of Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="DamageConvertToFire",type="BASE",value=75}},nil} c["75% reduced Amount Recovered"]={{[1]={flags=0,keywordFlags=0,name="FlaskRecovery",type="INC",value=-75}},nil} c["75% reduced Charges per use"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargesUsed",type="INC",value=-75}},nil} diff --git a/src/Data/SkillStatMap.lua b/src/Data/SkillStatMap.lua index 35e74316e1..c66490984c 100644 --- a/src/Data/SkillStatMap.lua +++ b/src/Data/SkillStatMap.lua @@ -179,6 +179,10 @@ return { ["base_skill_reserve_life_instead_of_mana"] = { flag("BloodMagicReserved"), }, +["skill_reserves_X_life_permyriad_per_spirit_instead_of_spirit"] = { + mod("LifeReservePercentPerSpirit", "BASE", nil), + div = 100, +}, ["base_skill_cost_life_instead_of_mana"] = { flag("CostLifeInsteadOfMana"), }, diff --git a/src/Data/Skills/sup_int.lua b/src/Data/Skills/sup_int.lua index cdaf7115e4..a4f1577cc3 100644 --- a/src/Data/Skills/sup_int.lua +++ b/src/Data/Skills/sup_int.lua @@ -694,6 +694,38 @@ skills["SupportAtzirisAllurePlayer"] = { }, } } +skills["SupportAtzirisCommunionPlayer"] = { + name = "Atziri's Communion", + description = "Supports Persistent Skills, making them Reserve Life instead of Spirit. Cannot Support Skills which create Minions.", + color = 3, + support = true, + requireSkillTypes = { SkillType.Persistent, }, + addSkillTypes = { }, + excludeSkillTypes = { SkillType.CreatesMinion, }, + gemFamily = { "AtziriCommunionLineage",}, + isLineage = true, + flavourText = {"The Red Communion was meant to transcend the limits", "of the soul, to transfigure the flesh, to bestow immortality.", "It accomplished all of these things... most horribly.", }, + levels = { + [1] = { levelRequirement = 0, }, + }, + statSets = { + [1] = { + label = "Atziri's Communion", + incrementalEffectiveness = 0.054999999701977, + statDescriptionScope = "gem_stat_descriptions", + baseFlags = { + }, + constantStats = { + { "skill_reserves_X_life_permyriad_per_spirit_instead_of_spirit", 66 }, + }, + stats = { + }, + levels = { + [1] = { actorLevel = 1, }, + }, + }, + } +} skills["SupportBhatairsVengeancePlayer"] = { name = "Bhatair's Vengeance", description = "Supports Attacks and Warcries you use yourself. Freezing an enemy with Supported Skills infuses you and your allies with Cold damage for a short time. ", diff --git a/src/Export/Skills/sup_int.txt b/src/Export/Skills/sup_int.txt index e2f32cf0f2..019af6bee6 100644 --- a/src/Export/Skills/sup_int.txt +++ b/src/Export/Skills/sup_int.txt @@ -117,6 +117,11 @@ statMap = { #mods #skillEnd +#skill SupportAtzirisCommunionPlayer +#set SupportAtzirisCommunionPlayer +#mods +#skillEnd + #skill SupportBhatairsVengeancePlayer #set SupportBhatairsVengeancePlayer #mods diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index a96b386bdd..3b20aae196 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -225,6 +225,16 @@ function calcs.doActorLifeManaSpiritReservation(actor) pool.Life.baseFlat = skillModList:Sum("BASE", skillCfg, "LifeCostBase") + (activeSkill.activeEffect.grantedEffectLevel.cost.Life or 0) end pool.Life.basePercent = activeSkill.skillData.lifeReservationPercent or activeSkill.activeEffect.grantedEffectLevel.lifeReservationPercent or 0 + if activeSkill.skillTypes[SkillType.IsBlasphemy] 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 + for name, values in pairs(pool) do + values.baseFlat = values.baseFlat + (activeSkill.skillData["blasphemyReservationFlat" .. name] or 0) * instances + end + end if skillModList:Flag(skillCfg, "BloodMagicReserved") then pool.Life.baseFlat = pool.Life.baseFlat + pool.Mana.baseFlat pool.Mana.baseFlat = 0 @@ -235,6 +245,13 @@ function calcs.doActorLifeManaSpiritReservation(actor) activeSkill.skillData["LifeReservationPercentForced"] = activeSkill.skillData["ManaReservationPercentForced"] activeSkill.skillData["ManaReservationPercentForced"] = nil end + local spiritToLifeReservation = skillModList:Sum("BASE", skillCfg, "LifeReservePercentPerSpirit") + if spiritToLifeReservation > 0 then + pool.Life.basePercent = pool.Life.basePercent + pool.Spirit.baseFlat * spiritToLifeReservation + pool.Spirit.baseFlat = 0 + pool.Life.basePercent = pool.Life.basePercent + pool.Spirit.basePercent * spiritToLifeReservation + pool.Spirit.basePercent = 0 + end for name, values in pairs(pool) do values.more = skillModList:More(skillCfg, name.."Reserved", "Reserved") values.inc = skillModList:Sum("INC", skillCfg, name.."Reserved", "Reserved") @@ -269,18 +286,6 @@ function calcs.doActorLifeManaSpiritReservation(actor) values.count = activeSkillCount local minionFreeSpiritCount = skillModList:Sum("BASE", skillCfg, "MinionFreeSpiritCount") values.reservedFlat = values.reservedFlat * m_max(activeSkillCount - minionFreeSpiritCount, 0) - end - if activeSkill.skillTypes[SkillType.IsBlasphemy] and activeSkill.activeEffect.srcInstance.supportEffect and activeSkill.activeEffect.srcInstance.supportEffect.isSupporting and activeSkill.skillData["blasphemyReservationFlat" .. name] 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 - - -- Extra reservation of blasphemy needs to be separated from the reservation caused by curses - local blasphemyFlat = activeSkill.skillData["blasphemyReservationFlat" .. name] - local blasphemyEffectiveFlat = m_max(round(blasphemyFlat * mult * (100 + values.inc) / 100 * values.more / (1 + values.efficiency / 100) / values.efficiencyMore, 0), 0) - values.reservedFlat = values.reservedFlat + blasphemyEffectiveFlat * instances end -- Blood Sacrament increases reservation per stage channelled if activeSkill.skillCfg.skillName == "Blood Sacrament" and activeSkill.activeStageCount then