Skip to content

Commit 63342aa

Browse files
PeecheyLocalIdentity
andauthored
Add support for Pinnacle of Power (#1928)
* revert CanEle changes, reset to Pinnacle of Power only * update skill for scalar, still need to figure out why it isn't applying to the damage * fix buff scaling by moving scalar logic from ModStore to CalcActiveSkill update test --------- Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent f83e18c commit 63342aa

5 files changed

Lines changed: 93 additions & 32 deletions

File tree

spec/System/TestSkills_spec.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,4 +729,30 @@ describe("TestSkills", function()
729729
assert.are.equals(hitAt20, hitAt50)
730730
end)
731731
end)
732+
733+
it("Test Pinnacle of Power", function()
734+
build.configTab.input.enemyIsBoss = "None"
735+
build.configTab.input.usePowerCharges = true
736+
build.configTab.input.overridePowerCharges = 3
737+
build.configTab:BuildModList()
738+
runCallback("OnFrame")
739+
740+
build.skillsTab:PasteSocketGroup("Fireball 20/0 1")
741+
runCallback("OnFrame")
742+
assert.True(build.calcsTab.calcsOutput.FreezeBuildupAvg == 0)
743+
assert.True(build.calcsTab.calcsOutput.ShockEffectMod == nil)
744+
745+
build.skillsTab:PasteSocketGroup("Pinnacle of Power 20/0 1")
746+
runCallback("OnFrame")
747+
local basePinnacleDamage = build.calcsTab.calcsOutput.TotalDPS
748+
assert.True(build.calcsTab.calcsOutput.FreezeBuildupAvg > 0)
749+
assert.True(build.calcsTab.calcsOutput.ShockEffectMod ~= nil)
750+
assert.are.equals(build.calcsTab.calcsOutput.BuffList, "Pinnacle of Power")
751+
752+
753+
build.skillsTab:PasteSocketGroup("Pinnacle of Power 20/0 1\nHeightened Charges 1/0 1")
754+
runCallback("OnFrame")
755+
-- Heightened Charges should increased the buff effect, therefore Fireball should have more damage than base Pinnacle of Power
756+
assert.True(build.calcsTab.calcsOutput.TotalDPS > basePinnacleDamage)
757+
end)
732758
end)

src/Classes/ModStore.lua

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,6 @@ function ModStoreClass:EvalMod(mod, cfg, globalLimits)
363363
tag.div = GetMultiplier(self, tag.divVar, cfg)
364364
end
365365
local mult = m_floor(base / (tag.div or 1) + 0.0001)
366-
-- scale effects of Multiplier mod
367-
if tag.scalar then
368-
local scalar = 1 + GetMultiplier(target, tag.scalar, cfg) / 100
369-
if scalar > 1 then
370-
mult = mult * scalar
371-
end
372-
end
373366
local limitTotal
374367
local limitNegTotal
375368
if tag.limit or tag.limitVar then
@@ -444,13 +437,6 @@ function ModStoreClass:EvalMod(mod, cfg, globalLimits)
444437
if (tag.upper and mult > threshold) or (tag.equals and mult ~= threshold) or (not (tag.upper and tag.exact) and mult < threshold) then
445438
return
446439
end
447-
-- scale effects of Multiplier mod
448-
if tag.scalar then
449-
local scalar = 1 + GetMultiplier(target, tag.scalar, cfg) / 100
450-
if scalar > 1 then
451-
value = value * scalar
452-
end
453-
end
454440
elseif tag.type == "PerStat" then
455441
local base
456442
local target = self

src/Data/Skills/other.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6036,6 +6036,21 @@ skills["PinnacleOfPowerPlayer"] = {
60366036
label = "Pinnacle of Power",
60376037
incrementalEffectiveness = 0.054999999701977,
60386038
statDescriptionScope = "pinnacle_of_power",
6039+
statMap = {
6040+
["elemental_power_elemental_damage_+%_final_per_power_charge"] = {
6041+
mod("Damage", "MORE", nil, 0, 0, { type = "SkillType", skillTypeList = { SkillType.Cold, SkillType.Fire, SkillType.Lightning } }, { type = "Multiplier", var = "RemovablePowerCharge", scalar = "ConsumedPowerChargeEffect" }, { type = "GlobalEffect", effectType = "Buff" }),
6042+
flag("ColdCanIgnite", { type = "GlobalEffect", effectType = "Buff" }), flag("ColdCanShock", { type = "GlobalEffect", effectType = "Buff" }),
6043+
flag("FireCanFreeze", { type = "GlobalEffect", effectType = "Buff" }), flag("FireCanShock", { type = "GlobalEffect", effectType = "Buff" }),
6044+
flag("LightningCanFreeze", { type = "GlobalEffect", effectType = "Buff" }), flag("LightningCanIgnite", { type = "GlobalEffect", effectType = "Buff" }),
6045+
},
6046+
["elemental_power_buff_duration_per_power_charge_ms"] = {
6047+
mod("Duration", "BASE", nil, 0, 0, { type = "Multiplier", var = "RemovablePowerCharge", scalar = "ConsumedPowerChargeEffect" }),
6048+
div = 1000,
6049+
},
6050+
["quality_stat_elemental_power_elemental_damage_+%_final_per_power_charge_is_gem"] = {
6051+
-- display only
6052+
},
6053+
},
60396054
baseFlags = {
60406055
buff = true,
60416056
duration = true,

src/Export/Skills/other.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,21 @@ statMap = {
423423
#skill PinnacleOfPowerPlayer
424424
#set PinnacleOfPowerPlayer
425425
#flags buff duration
426+
statMap = {
427+
["elemental_power_elemental_damage_+%_final_per_power_charge"] = {
428+
mod("Damage", "MORE", nil, 0, 0, { type = "SkillType", skillTypeList = { SkillType.Cold, SkillType.Fire, SkillType.Lightning } }, { type = "Multiplier", var = "RemovablePowerCharge", scalar = "ConsumedPowerChargeEffect" }, { type = "GlobalEffect", effectType = "Buff" }),
429+
flag("ColdCanIgnite", { type = "GlobalEffect", effectType = "Buff" }), flag("ColdCanShock", { type = "GlobalEffect", effectType = "Buff" }),
430+
flag("FireCanFreeze", { type = "GlobalEffect", effectType = "Buff" }), flag("FireCanShock", { type = "GlobalEffect", effectType = "Buff" }),
431+
flag("LightningCanFreeze", { type = "GlobalEffect", effectType = "Buff" }), flag("LightningCanIgnite", { type = "GlobalEffect", effectType = "Buff" }),
432+
},
433+
["elemental_power_buff_duration_per_power_charge_ms"] = {
434+
mod("Duration", "BASE", nil, 0, 0, { type = "Multiplier", var = "RemovablePowerCharge", scalar = "ConsumedPowerChargeEffect" }),
435+
div = 1000,
436+
},
437+
["quality_stat_elemental_power_elemental_damage_+%_final_per_power_charge_is_gem"] = {
438+
-- display only
439+
},
440+
},
426441
#mods
427442
#skillEnd
428443

src/Modules/CalcActiveSkill.lua

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,23 @@ local function mergeLevelMod(modList, mod, value)
4848
end
4949
end
5050

51+
-- allow Multiplier mods to be scaled by sources of the multipliedVariableEffect, e.g. var = RemovablePowerCharges, scalar = ConsumedPowerChargeEffect
52+
-- e.g. Pinnacle of Power, I had this scaling logic in ModStore prior as tag.scalar but it was not working with the Buff portion
53+
local function checkForScalarMultiplier(modOrGroup, modList)
54+
local scale = 0
55+
if modOrGroup.scalar then
56+
scale = modList:Sum("BASE", nil, "Multiplier:"..modOrGroup.scalar)
57+
else
58+
for _, config in ipairs(modOrGroup) do
59+
if config.scalar then
60+
scale = modList:Sum("BASE", nil, "Multiplier:"..config.scalar)
61+
break
62+
end
63+
end
64+
end
65+
return 1 + scale / 100
66+
end
67+
5168
-- Merge skill effect modifiers with given mod list
5269
-- If a stat set is provided, only merge modifiers from that statset
5370
function calcs.mergeSkillInstanceMods(env, modList, skillEffect, statSet, extraStats)
@@ -56,8 +73,8 @@ function calcs.mergeSkillInstanceMods(env, modList, skillEffect, statSet, extraS
5673
if statSet and not isValueInArray(skillEffect.grantedEffect.statSets, statSet) then
5774
return
5875
end
59-
local grantedEffect = skillEffect.grantedEffect
60-
for _, statSet in ipairs(statSet and {statSet} or grantedEffect.statSets) do
76+
local grantedEffect = skillEffect.grantedEffect
77+
for _, statSet in ipairs(statSet and {statSet} or grantedEffect.statSets) do
6178
local stats = calcLib.buildSkillInstanceStats(skillEffect, grantedEffect, statSet)
6279
if extraStats and extraStats[1] then
6380
for _, stat in pairs(extraStats) do
@@ -69,14 +86,16 @@ function calcs.mergeSkillInstanceMods(env, modList, skillEffect, statSet, extraS
6986
if map then
7087
-- Some mods need different scalars for different stats, but the same value. Putting them in a group allows this
7188
for _, modOrGroup in ipairs(map) do
89+
local scalar = checkForScalarMultiplier(modOrGroup, modList)
7290
-- Found a mod, since all mods have names
7391
if modOrGroup.name then
7492
modOrGroup.source = string.format("Skill:%s", grantedEffect.id)
75-
mergeLevelMod(modList, modOrGroup, map.value or statValue * (map.mult or 1) / (map.div or 1) + (map.base or 0))
93+
mergeLevelMod(modList, modOrGroup, map.value or statValue * (map.mult or 1) * scalar / (map.div or 1) + (map.base or 0))
7694
else
7795
for _, mod in ipairs(modOrGroup) do
96+
local scalar = checkForScalarMultiplier(mod)
7897
mod.source = string.format("Skill:%s", grantedEffect.id)
79-
mergeLevelMod(modList, mod, modOrGroup.value or statValue * (modOrGroup.mult or 1) / (modOrGroup.div or 1) + (modOrGroup.base or 0))
98+
mergeLevelMod(modList, mod, modOrGroup.value or statValue * (modOrGroup.mult or 1) * scalar / (modOrGroup.div or 1) + (modOrGroup.base or 0))
8099
end
81100
end
82101
end
@@ -100,7 +119,7 @@ function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGr
100119
}
101120

102121
local activeGrantedEffect = activeEffect.grantedEffect
103-
122+
104123
-- Initialise skill types
105124
activeSkill.skillTypes = copyTable(activeGrantedEffect.skillTypes)
106125
if activeGrantedEffect.minionSkillTypes then
@@ -109,12 +128,12 @@ function calcs.createActiveSkill(activeEffect, supportList, env, actor, socketGr
109128

110129
-- Initialise skill flag set ('attack', 'projectile', etc)
111130
local statSet, skillFlags
112-
if env.mode == "CALCS" then
131+
if env.mode == "CALCS" then
113132
statSet = activeEffect.grantedEffect.statSets[activeEffect.statSetCalcs.index]
114133
skillFlags = statSet and copyTable(statSet.baseFlags) or { }
115134
activeEffect.statSetCalcs.statSet = statSet
116135
activeEffect.statSetCalcs.skillFlags = skillFlags
117-
else
136+
else
118137
statSet = activeEffect.grantedEffect.statSets[activeEffect.statSet.index]
119138
skillFlags = statSet and copyTable(statSet.baseFlags) or { }
120139
activeEffect.statSet.statSet = statSet
@@ -261,7 +280,7 @@ local function getTotemBaseStats(activeSkill)
261280
totemBase.skillLevel = activeSkill.activeEffect.level
262281
elseif activeSkill.skillTypes[SkillType.UsedByTotem] then
263282
if activeSkill.activeEffect.grantedEffect.skillTypes[SkillType.UsedByTotem] then -- is totem skill by default
264-
totemBase.grantedEffect = activeSkill.activeEffect.gemData.grantedEffect
283+
totemBase.grantedEffect = activeSkill.activeEffect.gemData.grantedEffect
265284
totemBase.gemData = activeSkill.activeEffect.gemData
266285
totemBase.skillLevel = activeSkill.activeEffect.level
267286
elseif activeSkill.supportList then -- skill is receives totem status via support
@@ -703,7 +722,7 @@ function calcs.buildActiveSkillModList(env, activeSkill)
703722
skillModList:AddMod(value.mod)
704723
t_insert(activeSkill.extraSkillModList, value.mod)
705724
end
706-
725+
707726
applyExtraEmpowerMods(activeSkill)
708727

709728
-- Add active mine multiplier
@@ -722,7 +741,7 @@ function calcs.buildActiveSkillModList(env, activeSkill)
722741
local noPotentialStage = true
723742
if activeEffect.grantedEffect.parts then
724743
for _, part in ipairs(activeEffect.grantedEffect.parts) do
725-
if part.stages then
744+
if part.stages then
726745
noPotentialStage = false
727746
break
728747
end
@@ -808,12 +827,12 @@ function calcs.buildActiveSkillModList(env, activeSkill)
808827
minion.parent = env.player
809828
minion.enemy = env.enemy
810829
end
811-
minion.level = activeSkill.skillData.minionLevelIsEnemyLevel and env.enemyLevel or
812-
activeSkill.skillData.minionLevelIsTriggeredSkillLevel and activeEffect.srcInstance.supportEffect and activeEffect.srcInstance.supportEffect.activeSkillLevel and data.minionLevelTable[activeEffect.srcInstance.supportEffect.activeSkillLevel] or
813-
activeSkill.skillData.minionLevelIsPlayerLevel and (m_min(env.build and env.build.characterLevel or activeSkill.skillData.minionLevel or activeEffect.grantedEffectLevel.levelRequirement, activeSkill.skillData.minionLevelIsPlayerLevel)) or
830+
minion.level = activeSkill.skillData.minionLevelIsEnemyLevel and env.enemyLevel or
831+
activeSkill.skillData.minionLevelIsTriggeredSkillLevel and activeEffect.srcInstance.supportEffect and activeEffect.srcInstance.supportEffect.activeSkillLevel and data.minionLevelTable[activeEffect.srcInstance.supportEffect.activeSkillLevel] or
832+
activeSkill.skillData.minionLevelIsPlayerLevel and (m_min(env.build and env.build.characterLevel or activeSkill.skillData.minionLevel or activeEffect.grantedEffectLevel.levelRequirement, activeSkill.skillData.minionLevelIsPlayerLevel)) or
814833
activeSkill.skillData.minionLevel or data.minionLevelTable[activeSkill.activeEffect.level] or 1
815834
-- fix minion level between 1 and 100
816-
minion.level = m_min(m_max(minion.level,1),100)
835+
minion.level = m_min(m_max(minion.level,1),100)
817836
minion.itemList = { }
818837
minion.uses = activeGrantedEffect.minionUses
819838
minion.lifeTable = env.data.monsterAllyLifeTable
@@ -870,7 +889,7 @@ function calcs.buildActiveSkillModList(env, activeSkill)
870889
minion.weaponData1 = env.player.weaponData1
871890
end
872891
end
873-
if minion.uses["Weapon 2"] then
892+
if minion.uses["Weapon 2"] then
874893
if minion.itemSet then
875894
local item = env.build.itemsTab.items[minion.itemSet[minion.itemSet.useSecondWeaponSet and "Weapon 2 Swap" or "Weapon 2"].selItemId]
876895
if item and item.weaponData then
@@ -994,7 +1013,7 @@ function calcs.createMinionSkills(env, activeSkill)
9941013
}
9951014
local minionSkillIndex = activeSkill.activeEffect.srcInstance.skillMinionSkill
9961015
local minionSkillIndexCalcs = activeSkill.activeEffect.srcInstance.skillMinionSkillCalcs
997-
local minionStatSetIndex = activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookup and activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookup[activeSkill.activeEffect.grantedEffect.id]
1016+
local minionStatSetIndex = activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookup and activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookup[activeSkill.activeEffect.grantedEffect.id]
9981017
and activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookup[activeSkill.activeEffect.grantedEffect.id][minionSkillIndex] or 1
9991018
local minionStatSetCalcsIndex = activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookupCalcs and activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookupCalcs[activeSkill.activeEffect.grantedEffect.id]
10001019
and activeSkill.activeEffect.srcInstance.skillMinionSkillStatSetIndexLookupCalcs[activeSkill.activeEffect.grantedEffect.id][minionSkillIndexCalcs] or 1
@@ -1018,7 +1037,7 @@ function calcs.createMinionSkills(env, activeSkill)
10181037
local skillFlags
10191038
if env.mode == "CALCS" then
10201039
skillFlags = minionSkill.activeEffect.statSetCalcs.skillFlags
1021-
else
1040+
else
10221041
skillFlags = minionSkill.activeEffect.statSet.skillFlags
10231042
end
10241043
skillFlags.minion = true
@@ -1027,7 +1046,7 @@ function calcs.createMinionSkills(env, activeSkill)
10271046
minionSkill.skillData.damageEffectiveness = 1 + (activeSkill.skillData.minionDamageEffectiveness or 0) / 100
10281047
t_insert(minion.activeSkillList, minionSkill)
10291048
end
1030-
local skillIndex
1049+
local skillIndex
10311050
if env.mode == "CALCS" then
10321051
skillIndex = m_max(m_min(activeEffect.srcInstance.skillMinionSkillCalcs or 1, #minion.activeSkillList), 1)
10331052
activeEffect.srcInstance.skillMinionSkillCalcs = skillIndex

0 commit comments

Comments
 (0)