Skip to content

Commit 0cbaf58

Browse files
committed
@
Implement Idolatry (Spirit Walker) ascendancy mods Adds support for the three Idolatry notable mods: - Companions deal 10% increased damage per Idol in your Equipment - 2% increased Reservation Efficiency of Skills per Idol in your Equipment - -4% to all Elemental Resistances per non-Idol Augment in your Equipment CalcSetup now tallies socketed augments by type into IdolsInEquipment and NonIdolAugmentsInEquipment multipliers (only counting known augments, never empty sockets). ModParser gains the two "per idol/non-idol augment in your equipment" multiplier suffixes plus a companion-damage special case that reads the player count via actor = "parent". ModCache regenerated accordingly. @
1 parent b804868 commit 0cbaf58

4 files changed

Lines changed: 128 additions & 8 deletions

File tree

spec/System/TestIdolatry_spec.lua

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
describe("TestIdolatry", function()
2+
before_each(function()
3+
newBuild()
4+
end)
5+
6+
-- The Spirit Walker "Idolatry" notable grants three mods that scale with the
7+
-- number of Idols / non-Idol augments (Runes + Soul Cores) socketed across equipped items.
8+
9+
-- Counting: CalcSetup tallies socketed augments by type into the IdolsInEquipment and
10+
-- NonIdolAugmentsInEquipment multipliers, which the three Idolatry mods scale against.
11+
it("counts Idols and non-Idol augments across equipped items", function()
12+
-- Gloves with 2 Idols socketed
13+
build.itemsTab:CreateDisplayItemFromRaw([[
14+
Rarity: MAGIC
15+
Idolatry Test Gloves
16+
Vaal Gloves
17+
Sockets: S S
18+
Rune: Idol of Sirrius
19+
Rune: Idol of Sirrius
20+
Implicits: 0
21+
]])
22+
build.itemsTab:AddDisplayItem()
23+
24+
-- Quarterstaff with 3 Soul Cores socketed (non-Idol augments)
25+
build.itemsTab:CreateDisplayItemFromRaw([[
26+
Rarity: MAGIC
27+
Idolatry Test Staff
28+
Aegis Quarterstaff
29+
Sockets: S S S
30+
Rune: Soul Core of Cholotl
31+
Rune: Soul Core of Zantipi
32+
Rune: Soul Core of Atmohua
33+
Implicits: 0
34+
]])
35+
build.itemsTab:AddDisplayItem()
36+
runCallback("OnFrame")
37+
38+
local modDB = build.calcsTab.mainEnv.modDB
39+
assert.are.equals(2, modDB.multipliers.IdolsInEquipment)
40+
assert.are.equals(3, modDB.multipliers.NonIdolAugmentsInEquipment)
41+
end)
42+
43+
-- Empty sockets (itemSocketCount populated while item.runes has no entry for the slot, e.g. a
44+
-- freshly created base item) must not be counted as augments.
45+
it("does not count empty sockets as augments", function()
46+
build.itemsTab:CreateDisplayItemFromRaw([[
47+
Rarity: MAGIC
48+
Empty Socket Test Gloves
49+
Vaal Gloves
50+
Sockets: S S
51+
Implicits: 0
52+
]])
53+
build.itemsTab:AddDisplayItem()
54+
runCallback("OnFrame")
55+
56+
local modDB = build.calcsTab.mainEnv.modDB
57+
assert.is_nil(modDB.multipliers.IdolsInEquipment)
58+
assert.is_nil(modDB.multipliers.NonIdolAugmentsInEquipment)
59+
end)
60+
61+
-- Parsing: the three stat lines must resolve to mods that scale against those multipliers.
62+
it("parses the three Idolatry stat lines", function()
63+
local parseMod = LoadModule("Modules/ModParser")
64+
65+
-- Helper to find the Multiplier tag on a mod (tags are stored as array entries)
66+
local function multiplierTag(mod)
67+
for _, tag in ipairs(mod) do
68+
if tag.type == "Multiplier" then return tag end
69+
end
70+
end
71+
72+
-- 1) Companion damage scales by the player's (parent's) Idol count.
73+
local companion = parseMod("Companions deal 10% increased damage per Idol in your Equipment")
74+
assert.are.equals(1, #companion)
75+
assert.are.equals("MinionModifier", companion[1].name)
76+
local inner = companion[1].value.mod
77+
assert.are.equals("Damage", inner.name)
78+
assert.are.equals("INC", inner.type)
79+
assert.are.equals(10, inner.value)
80+
local companionTag = multiplierTag(inner)
81+
assert.is_not_nil(companionTag)
82+
assert.are.equals("IdolsInEquipment", companionTag.var)
83+
assert.are.equals("parent", companionTag.actor)
84+
85+
-- 2) Reservation Efficiency scales by the Idol count (player context).
86+
local reservation = parseMod("2% increased Reservation Efficiency of Skills per Idol in your Equipment")
87+
assert.are.equals(1, #reservation)
88+
assert.are.equals("ReservationEfficiency", reservation[1].name)
89+
assert.are.equals("INC", reservation[1].type)
90+
assert.are.equals(2, reservation[1].value)
91+
assert.are.equals("IdolsInEquipment", multiplierTag(reservation[1]).var)
92+
93+
-- 3) Elemental Resistance penalty scales by the non-Idol augment count (player context).
94+
local resist = parseMod("-4% to all Elemental Resistances per non-Idol Augment in your Equipment")
95+
assert.are.equals(1, #resist)
96+
assert.are.equals("ElementalResist", resist[1].name)
97+
assert.are.equals("BASE", resist[1].type)
98+
assert.are.equals(-4, resist[1].value)
99+
assert.are.equals("NonIdolAugmentsInEquipment", multiplierTag(resist[1]).var)
100+
end)
101+
end)

src/Data/ModCache.lua

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ c["-30% to Lightning Resistance"]={{[1]={flags=0,keywordFlags=0,name="LightningR
945945
c["-30% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=-30}},nil}
946946
c["-35% to Lightning Resistance"]={{[1]={flags=0,keywordFlags=0,name="LightningResist",type="BASE",value=-35}},nil}
947947
c["-4 Physical Damage taken from Attack Hits"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageTakenFromAttacks",type="BASE",value=-4}},nil}
948-
c["-4% to all Elemental Resistances per non-Idol Augment in your Equipment"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=-4}}," per non-Idol Augment in your Equipment "}
948+
c["-4% to all Elemental Resistances per non-Idol Augment in your Equipment"]={{[1]={[1]={type="Multiplier",var="NonIdolAugmentsInEquipment"},flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=-4}},nil}
949949
c["-5% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=-5}},nil}
950950
c["-5% to amount of Damage Prevented by Deflection"]={{[1]={flags=0,keywordFlags=0,name="DeflectEffect",type="BASE",value=-5}},nil}
951951
c["-6% to amount of Damage Prevented by Deflection"]={{[1]={flags=0,keywordFlags=0,name="DeflectEffect",type="BASE",value=-6}},nil}
@@ -1819,8 +1819,7 @@ c["2% increased Maximum Life per socketed Grand Spectrum"]={{[1]={[1]={type="Mul
18191819
c["2% increased Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=2}},nil}
18201820
c["2% increased Movement Speed while Sprinting"]={{[1]={[1]={type="Condition",var="Sprinting"},flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=2}},nil}
18211821
c["2% increased Parried Debuff Duration per 10 Tribute"]={{[1]={[1]={actor="parent",div=10,stat="Tribute",type="PerStat"},flags=0,keywordFlags=0,name="ParryDebuffDuration",type="INC",value=2}},nil}
1822-
c["2% increased Reservation Efficiency of Skills per Idol in your Equipment"]={{[1]={flags=0,keywordFlags=0,name="ReservationEfficiency",type="INC",value=2}}," per Idol in your Equipment "}
1823-
c["2% increased Reservation Efficiency of Skills per Idol in your Equipment -4% to all Elemental Resistances per non-Idol Augment in your Equipment"]={{[1]={flags=0,keywordFlags=0,name="ReservationEfficiency",type="INC",value=2}}," per Idol in your Equipment -4% to all Elemental Resistances per non-Idol Augment in your Equipment "}
1822+
c["2% increased Reservation Efficiency of Skills per Idol in your Equipment"]={{[1]={[1]={type="Multiplier",var="IdolsInEquipment"},flags=0,keywordFlags=0,name="ReservationEfficiency",type="INC",value=2}},nil}
18241823
c["2% increased Skill Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="INC",value=2},[2]={flags=0,keywordFlags=0,name="WarcrySpeed",type="INC",value=2},[3]={flags=0,keywordFlags=0,name="TotemPlacementSpeed",type="INC",value=2}},nil}
18251824
c["2% increased Skill Speed with Channelling Skills"]={{[1]={[1]={skillType=48,type="SkillType"},flags=0,keywordFlags=0,name="Speed",type="INC",value=2},[2]={[1]={skillType=48,type="SkillType"},flags=0,keywordFlags=0,name="WarcrySpeed",type="INC",value=2},[3]={[1]={skillType=48,type="SkillType"},flags=0,keywordFlags=0,name="TotemPlacementSpeed",type="INC",value=2}},nil}
18261825
c["2% increased Spell Damage per 10 Intelligence"]={{[1]={[1]={div=10,stat="Int",type="PerStat"},flags=2,keywordFlags=0,name="Damage",type="INC",value=2}},nil}
@@ -4836,9 +4835,7 @@ c["Charms use no Charges"]={{[1]={flags=0,keywordFlags=0,name="CharmsUseNoCharge
48364835
c["Cold Damage from Hits Contributes to Flammability and Ignite Magnitudes instead of Chill Magnitude or Freeze Buildup"]={{[1]={flags=0,keywordFlags=0,name="ColdCanIgnite",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ColdCannotChill",type="FLAG",value=true},[3]={flags=0,keywordFlags=0,name="ColdCannotFreeze",type="FLAG",value=true}},nil}
48374836
c["Cold Resistance is unaffected by Area Penalties"]={nil,"Cold Resistance is unaffected by Area Penalties "}
48384837
c["Companions deal 10% increased Damage"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=10}}}},nil}
4839-
c["Companions deal 10% increased damage per Idol in your Equipment"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=10}}}}," per Idol in your Equipment "}
4840-
c["Companions deal 10% increased damage per Idol in your Equipment 2% increased Reservation Efficiency of Skills per Idol in your Equipment"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=10}}}}," per Idol in your Equipment 2% increased Reservation Efficiency of Skills per Idol in your Equipment "}
4841-
c["Companions deal 10% increased damage per Idol in your Equipment 2% increased Reservation Efficiency of Skills per Idol in your Equipment -4% to all Elemental Resistances per non-Idol Augment in your Equipment"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=10}}}}," per Idol in your Equipment 2% increased Reservation Efficiency of Skills per Idol in your Equipment -4% to all Elemental Resistances per non-Idol Augment in your Equipment "}
4838+
c["Companions deal 10% increased damage per Idol in your Equipment"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={actor="parent",type="Multiplier",var="IdolsInEquipment"},flags=0,keywordFlags=0,name="Damage",type="INC",value=10}}}},nil}
48424839
c["Companions deal 12% increased Damage"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=12}}}},nil}
48434840
c["Companions deal 15% increased Damage"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=15}}}},nil}
48444841
c["Companions deal 60% increased damage against Immobilised enemies"]={{[1]={[1]={skillType=219,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="Immobilised"},flags=0,keywordFlags=0,name="Damage",type="INC",value=60}}}},nil}

src/Modules/CalcSetup.lua

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,11 +1090,28 @@ function calcs.initEnv(build, mode, override, specEnv)
10901090
Int = item.requirements.intMod,
10911091
})
10921092
end
1093-
-- Rune / Soul Core Sockets
1093+
-- Rune / Soul Core / Idol Sockets
10941094
local socketed = 0
10951095
for i = 1, item.itemSocketCount do
1096-
if item.runes[i] ~= "None" then
1096+
local runeName = item.runes[i]
1097+
if runeName and runeName ~= "None" then
10971098
socketed = socketed + 1
1099+
-- Track Idols vs non-Idol augments (Runes + Soul Cores) across all equipment
1100+
local runeData = data.itemMods.Runes[runeName]
1101+
local augType
1102+
if runeData then
1103+
for _, baseEntry in pairs(runeData) do
1104+
if type(baseEntry) == "table" and baseEntry.type then
1105+
augType = baseEntry.type
1106+
break
1107+
end
1108+
end
1109+
end
1110+
if augType == "Idol" then
1111+
env.itemModDB.multipliers["IdolsInEquipment"] = (env.itemModDB.multipliers["IdolsInEquipment"] or 0) + 1
1112+
elseif augType then
1113+
env.itemModDB.multipliers["NonIdolAugmentsInEquipment"] = (env.itemModDB.multipliers["NonIdolAugmentsInEquipment"] or 0) + 1
1114+
end
10981115
end
10991116
end
11001117
env.itemModDB.multipliers["RunesSocketedIn"..slotName] = socketed

src/Modules/ModParser.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,8 @@ local modTagList = {
14621462
["per (%d+)%% (%a+) effect on enemy"] = function(num, _, effectName) return { tag = { type = "Multiplier", var = firstToUpper(effectName) .. "Effect", div = num, actor = "enemy" } } end,
14631463
["per socketed rune or soul core"] = { tag = { type = "Multiplier", var = "RunesSocketedIn{SlotName}" } },
14641464
["per socket filled"] = { tag = { type = "Multiplier", var = "RunesSocketedIn{SlotName}" } },
1465+
["per idol in your equipment"] = { tag = { type = "Multiplier", var = "IdolsInEquipment" } },
1466+
["per non%-idol augment in your equipment"] = { tag = { type = "Multiplier", var = "NonIdolAugmentsInEquipment" } },
14651467
["per (%d+) (%a+) support gems socketed"] = function(num, _, color) return { tag = { type = "Multiplier", var = firstToUpper(color) .. "SupportGems", div = num } } end,
14661468
["per socketed (%a+) support gem"] = function(color) return { tag = { type = "Multiplier", var = firstToUpper(color) .. "SupportGems" } } end,
14671469
["for each equipped normal item"] = { tag = { type = "Multiplier", var = "NormalItem" } },
@@ -2895,6 +2897,9 @@ local specialModList = {
28952897
mod("MinionModifier", "LIST", { mod = flag("GainMainHandDmgFromParent") }, { type = "SkillType", skillType = SkillType.CreatesCompanion }),
28962898
mod("Multiplier:MainHandDamageToAllies", "BASE", num),
28972899
} end,
2900+
["companions deal (%d+)%% increased damage per idol in your equipment"] = function(num) return {
2901+
mod("MinionModifier", "LIST", { mod = mod("Damage", "INC", num, { type = "Multiplier", var = "IdolsInEquipment", actor = "parent" }) }, { type = "SkillType", skillType = SkillType.CreatesCompanion }),
2902+
} end,
28982903
-- Disciple of Varashta
28992904
["(%d+)%% of your current energy shield is added to your armour for determining your physical damage reduction from armour"] = function(num) return {
29002905
mod("EnergyShieldAppliesToPhysicalDamageTaken", "BASE", num),

0 commit comments

Comments
 (0)