Skip to content

Commit a458b6b

Browse files
majochemLocalIdentity
andauthored
Add support for Totems (#1188)
* Add 'totem' flag to Vile Effusion (Dark Effigy) The 'totem' flag was missing for the damaging part of the skill * Fix `addFlags` parsing `addFlags` functionality was accidentally broken in #62 because `mainSkillFlags` and `calcSkillFlags` variables were introduced but seemingly later made redundant to use the original `skillFlags`. However the `addFlags` section still checked the old variables which were now `nil`. This wasn't a problem until now, because the PoE2 skills had not used `addFlags` yet. * Remove "Base" mod for "ActiveTotemLimit" `CalcSetup` previous added +1 to "ActiveTotemLimit" as a base, but totem skills in PoE2 always come with "base_number_of_totems_allowed" values, which led to the values always being 1 too high * Let "Ancestral Warrior Totem" add the `totem` flag * Get totem stats from "base" totem skill This fixes previous problems that were caused by totem skills consisting of multiple parts, such as inability to get correct skillTotemId and level requirement for the "active" portion of a totem skill. The skill (or support) that provides the baseTotem data is now identified within `CalcActiveSkill` Examples: - "Shockwave Totem" -> "Wave" would not show correct totem stats - "Sunder" attached to "Ancestral Warrior Totem" would not show any totem stats at all * Reword "totemification" to "totemified" * Get rid of "totemified" * Add support for Mortar Cannon Adds support for a few stats on mortar cannon and ancestral totem too --------- Co-authored-by: majochem <[email protected]> Co-authored-by: LocalIdentity <[email protected]>
1 parent 862a737 commit a458b6b

File tree

7 files changed

+118
-22
lines changed

7 files changed

+118
-22
lines changed

src/Data/SkillStatMap.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,9 @@ return {
549549
["totem_skill_attack_speed_+%"] = {
550550
mod("Speed", "INC", nil, ModFlag.Attack, KeywordFlag.Totem)
551551
},
552+
["grenade_skill_cooldown_speed_+%"] = {
553+
mod("CooldownRecovery", "INC", nil),
554+
},
552555
-- AoE
553556
["active_skill_base_area_of_effect_radius"] = {
554557
skill("radius", nil),
@@ -2655,5 +2658,7 @@ return {
26552658
["quality_display_sandstorm_swipe_is_gem"] = {
26562659
-- Display Only
26572660
},
2658-
2661+
["quality_display_base_totem_duration_is_gem"] = {
2662+
-- Display Only
2663+
},
26592664
}

src/Data/Skills/act_int.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4628,6 +4628,7 @@ skills["DarkEffigyProjectilePlayer"] = {
46284628
spell = true,
46294629
area = true,
46304630
projectile = true,
4631+
totem = true,
46314632
},
46324633
constantStats = {
46334634
{ "skill_disabled_unless_cloned", 2 },

src/Data/Skills/act_str.lua

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,13 +563,24 @@ skills["SupportAncestralWarriorTotemPlayer"] = {
563563
[39] = { levelRequirement = 0, },
564564
[40] = { levelRequirement = 0, },
565565
},
566+
addFlags = {
567+
totem = true,
568+
},
566569
statSets = {
567570
[1] = {
568571
label = "SupportAncestralWarriorTotemPlayer",
569572
incrementalEffectiveness = 0.054999999701977,
570573
statDescriptionScope = "gem_stat_descriptions",
574+
statMap = {
575+
["support_ancestral_warrior_totem_attack_speed_+%_final"] = {
576+
mod("Speed", "MORE", nil, ModFlag.Attack),
577+
},
578+
},
571579
baseFlags = {
572580
},
581+
baseMods = {
582+
mod("ActiveTotemLimit", "BASE", 1),
583+
},
573584
constantStats = {
574585
{ "skill_disabled_unless_cloned", 2 },
575586
{ "support_ancestral_warrior_totem_attack_speed_+%_final", -25 },
@@ -1068,7 +1079,7 @@ skills["AttritionPlayer"] = {
10681079
{mod("Damage", "MORE", nil, 0, KeywordFlag.Hit, { type = "GlobalEffect", effectType = "Buff"}, { type = "Multiplier", var = "EnemyPresenceSeconds", actor = "enemy", limitVar = "AttritionMaxDamage", div = 2, limitTotal = true }, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" })},
10691080
{mod("CullPercent", "MAX", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff"}, { type = "MultiplierThreshold", var = "EnemyPresenceSeconds", actor = "enemy", thresholdVar = "AttritionCullSeconds"}, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }),
10701081
value = 10,}
1071-
},
1082+
},
10721083
},
10731084
baseFlags = {
10741085
},
@@ -3688,6 +3699,10 @@ skills["ExplosiveGrenadePlayer"] = {
36883699
label = "Explosive Grenade",
36893700
incrementalEffectiveness = 0.054999999701977,
36903701
statDescriptionScope = "explosive_grenade",
3702+
statMap = {
3703+
["base_skill_show_average_damage_instead_of_dps"] = {
3704+
},
3705+
},
36913706
baseFlags = {
36923707
attack = true,
36933708
area = true,
@@ -11222,16 +11237,27 @@ skills["SupportMortarCannonPlayer"] = {
1122211237
[39] = { levelRequirement = 0, },
1122311238
[40] = { levelRequirement = 0, },
1122411239
},
11240+
addFlags = {
11241+
totem = true,
11242+
},
1122511243
statSets = {
1122611244
[1] = {
1122711245
label = "SupportMortarCannonPlayer",
1122811246
incrementalEffectiveness = 0.054999999701977,
1122911247
statDescriptionScope = "gem_stat_descriptions",
11230-
addFlags = {
11231-
totem = true,
11248+
statMap = {
11249+
["support_grenade_ballista_damage_+%_final"] = {
11250+
mod("Damage", "MORE", nil),
11251+
},
11252+
["support_grenade_ballista_attack_speed_+%_final"] = {
11253+
mod("Speed", "MORE", nil, ModFlag.Attack),
1123211254
},
11255+
},
1123311256
baseFlags = {
1123411257
},
11258+
baseMods = {
11259+
mod("ActiveTotemLimit", "BASE", 1),
11260+
},
1123511261
constantStats = {
1123611262
{ "skill_disabled_unless_cloned", 2 },
1123711263
{ "support_grenade_ballista_attack_speed_+%_final", -50 },
@@ -13315,7 +13341,7 @@ skills["SiegeBallistaPlayer"] = {
1331513341
}
1331613342
}
1331713343
skills["SiegeBallistaProjectilePlayer"] = {
13318-
name = "",
13344+
name = "Artillery",
1331913345
hidden = true,
1332013346
skillTypes = { [SkillType.Attack] = true, [SkillType.RangedAttack] = true, [SkillType.Projectile] = true, [SkillType.Barrageable] = true, [SkillType.AttackInPlaceIsDefault] = true, [SkillType.Fire] = true, [SkillType.Area] = true, [SkillType.CannotChain] = true, [SkillType.UsedByTotem] = true, },
1332113347
weaponTypes = {

src/Export/Skills/act_int.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ statMap = {
296296

297297
#skill DarkEffigyProjectilePlayer
298298
#set DarkEffigyProjectilePlayer
299-
#flags spell area projectile
299+
#flags spell area projectile totem
300300
#mods
301301
#skillEnd
302302

src/Export/Skills/act_str.txt

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,17 @@ local skills, mod, flag, skill = ...
3030
#skillEnd
3131

3232
#skill SupportAncestralWarriorTotemPlayer
33+
addFlags = {
34+
totem = true,
35+
},
3336
#set SupportAncestralWarriorTotemPlayer
3437
#flags
38+
statMap = {
39+
["support_ancestral_warrior_totem_attack_speed_+%_final"] = {
40+
mod("Speed", "MORE", nil, ModFlag.Attack),
41+
},
42+
},
43+
#baseMod mod("ActiveTotemLimit", "BASE", 1)
3544
#mods
3645
#skillEnd
3746

@@ -67,7 +76,7 @@ statMap = {
6776
{mod("Damage", "MORE", nil, 0, KeywordFlag.Hit, { type = "GlobalEffect", effectType = "Buff"}, { type = "Multiplier", var = "EnemyPresenceSeconds", actor = "enemy", limitVar = "AttritionMaxDamage", div = 2, limitTotal = true }, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" })},
6877
{mod("CullPercent", "MAX", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff"}, { type = "MultiplierThreshold", var = "EnemyPresenceSeconds", actor = "enemy", thresholdVar = "AttritionCullSeconds"}, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }),
6978
value = 10,}
70-
},
79+
},
7180
},
7281
#mods
7382
#skillEnd
@@ -272,6 +281,10 @@ statMap = {
272281
#skill ExplosiveGrenadePlayer
273282
#set ExplosiveGrenadePlayer
274283
#flags attack area projectile
284+
statMap = {
285+
["base_skill_show_average_damage_instead_of_dps"] = {
286+
},
287+
},
275288
#mods
276289
#skillEnd
277290

@@ -631,11 +644,20 @@ statMap = {
631644
#skillEnd
632645

633646
#skill SupportMortarCannonPlayer
647+
addFlags = {
648+
totem = true,
649+
},
634650
#set SupportMortarCannonPlayer
635-
addFlags = {
636-
totem = true,
637-
},
638651
#flags
652+
statMap = {
653+
["support_grenade_ballista_damage_+%_final"] = {
654+
mod("Damage", "MORE", nil),
655+
},
656+
["support_grenade_ballista_attack_speed_+%_final"] = {
657+
mod("Speed", "MORE", nil, ModFlag.Attack),
658+
},
659+
},
660+
#baseMod mod("ActiveTotemLimit", "BASE", 1)
639661
#mods
640662
#skillEnd
641663

@@ -743,7 +765,7 @@ statMap = {
743765
#mods
744766
#skillEnd
745767

746-
#skill SiegeBallistaProjectilePlayer
768+
#skill SiegeBallistaProjectilePlayer Artillery
747769
#set SiegeBallistaProjectilePlayer
748770
#flags attack projectile totem
749771
#mods

src/Modules/CalcActiveSkill.lua

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGr
165165
if supportEffect.grantedEffect.addFlags and not summonSkill then
166166
-- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine')
167167
for k in pairs(supportEffect.grantedEffect.addFlags) do
168-
mainSkillFlags[k] = true
169-
calcsSkillFlags[k] = true
168+
skillFlags[k] = true
170169
end
171170
end
172171
end
@@ -250,6 +249,45 @@ local function getWeaponFlags(env, weaponData, weaponTypes)
250249
return flags, info
251250
end
252251

252+
-- Get stats from totem base skill in case of separate active skills or skills that receive totem status via supports
253+
---@param activeSkill table @activeSkill with totem tag
254+
local function getTotemBaseStats(activeSkill)
255+
local totemBase = {}
256+
257+
if activeSkill.skillTypes[SkillType.SummonsTotem] then -- Skill that summons totems already has stats on activeEffect
258+
totemBase.grantedEffect = activeSkill.activeEffect.grantedEffect
259+
totemBase.gemData = activeSkill.activeEffect.gemData
260+
totemBase.skillLevel = activeSkill.activeEffect.level
261+
elseif activeSkill.skillTypes[SkillType.UsedByTotem] then
262+
if activeSkill.activeEffect.grantedEffect.skillTypes[SkillType.UsedByTotem] then -- is totem skill by default
263+
totemBase.grantedEffect = activeSkill.activeEffect.gemData.grantedEffect
264+
totemBase.gemData = activeSkill.activeEffect.gemData
265+
totemBase.skillLevel = activeSkill.activeEffect.level
266+
elseif activeSkill.supportList then -- skill is receives totem status via support
267+
for _, support in ipairs(activeSkill.supportList) do
268+
if support.grantedEffect.addSkillTypes and (not support.superseded) and support.isSupporting[activeSkill.activeEffect.srcInstance] then
269+
for _, skillType in ipairs(support.grantedEffect.addSkillTypes) do
270+
if skillType == SkillType.UsedByTotem then
271+
totemBase.grantedEffect = support.gemData.grantedEffect
272+
totemBase.gemData = support.gemData
273+
break
274+
end
275+
end
276+
end
277+
if totemBase.gemData or totemBase.grantedEffect then
278+
totemBase.skillLevel = support.level
279+
break
280+
end
281+
end
282+
else
283+
-- A totem skill that neither `SummonsTotem` nor `UsedByTotem` should not be possible, but I am leaving this here to alert us in case of unexpected future edge cases
284+
error("Error: Unexpected SkillType behavior for skill with 'totem' flag")
285+
end
286+
end
287+
288+
return totemBase
289+
end
290+
253291
--- Applies additional modifiers to skills with the "Empowered" flag.
254292
--- Checks for "ExtraEmpoweredMod" mods and applies them
255293
--- if they match the conditions set by the empowering effect.
@@ -484,10 +522,19 @@ function calcs.buildActiveSkillModList(env, activeSkill)
484522
skillKeywordFlags = bor(skillKeywordFlags, KeywordFlag.Spell)
485523
end
486524

487-
-- Get skill totem ID for totem skills
488-
-- This is used to calculate totem life
525+
-- Find totem base stats
489526
if skillFlags.totem then
490-
activeSkill.skillTotemId = activeGrantedEffect.skillTotemId
527+
local totemBase = getTotemBaseStats(activeSkill)
528+
if totemBase.grantedEffect and totemBase.gemData then
529+
activeSkill.skillData.totemBase = totemBase
530+
end
531+
local totemLevelRequirement = activeSkill.skillData.totemBase and activeSkill.skillData.totemBase.grantedEffect.levels[totemBase.skillLevel].levelRequirement or activeEffect.grantedEffect.levels[activeEffect.level].levelRequirement
532+
-- Note: Some active skills related to totem base skills (e.g. on Shockwave Totem) have level requirement = 0, making the additional ` > 0` check necessary
533+
activeSkill.skillData.totemLevel = (totemLevelRequirement and (totemLevelRequirement > 0)) and totemLevelRequirement or 1
534+
535+
-- Get skill totem ID for totem skills
536+
-- This is used to calculate totem life
537+
activeSkill.skillTotemId = activeGrantedEffect.skillTotemId or (activeSkill.skillData.totemBase and activeSkill.skillData.totemBase.grantedEffect.skillTotemId)
491538
if not activeSkill.skillTotemId then
492539
if activeGrantedEffect.color == 2 then
493540
activeSkill.skillTotemId = 2
@@ -647,11 +694,6 @@ function calcs.buildActiveSkillModList(env, activeSkill)
647694

648695
applyExtraEmpowerMods(activeSkill)
649696

650-
-- Find totem level
651-
if skillFlags.totem then
652-
activeSkill.skillData.totemLevel = 1 or activeEffect.grantedEffect.levels[activeEffect.level].levelRequirement
653-
end
654-
655697
-- Add active mine multiplier
656698
if skillFlags.mine then
657699
activeSkill.activeMineCount = (env.mode == "CALCS" and activeEffect.srcInstance.skillMineCountCalcs) or (env.mode ~= "CALCS" and activeEffect.srcInstance.skillMineCount)

src/Modules/CalcSetup.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ function calcs.initModDB(env, modDB)
5555
modDB:NewMod("WarcryCastTime", "BASE", 0.8, "Base")
5656
modDB:NewMod("TotemPlacementTime", "BASE", 0.6, "Base")
5757
modDB:NewMod("BallistaPlacementTime", "BASE", 0.35, "Base")
58-
modDB:NewMod("ActiveTotemLimit", "BASE", 1, "Base")
5958
modDB:NewMod("ShockStacksMax", "BASE", 1, "Base")
6059
modDB:NewMod("ChillStacksMax", "BASE", 1, "Base")
6160
modDB:NewMod("ScorchStacksMax", "BASE", 1, "Base")
@@ -1786,6 +1785,7 @@ function calcs.initEnv(build, mode, override, specEnv)
17861785
end
17871786
end
17881787

1788+
17891789
-- Merge Requirements Tables
17901790
env.requirementsTable = tableConcat(env.requirementsTableItems, env.requirementsTableGems)
17911791

0 commit comments

Comments
 (0)