Skip to content

Commit 5a86559

Browse files
committed
Add thorns damage support and thorns-based support interactions
1 parent 4b3ae4e commit 5a86559

11 files changed

Lines changed: 360 additions & 29 deletions

File tree

src/Data/ModCache.lua

Lines changed: 18 additions & 14 deletions
Large diffs are not rendered by default.

src/Data/SkillStatMap.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ return {
996996
mod("ImprovedSpellDamageAppliesToAttacks", "MAX", nil),
997997
},
998998
["additive_thorns_damage_modifiers_apply_to_attack_damage"] = {
999-
flag("ThornsDamageAppliesToHits"),
999+
flag("ThornsModifiersApplyToHits"),
10001000
},
10011001
["active_skill_main_hand_weapon_damage_+%_final"] = {
10021002
mod("Damage", "MORE", nil, 0, 0, { type = "Condition", var = "MainHandAttack" }),

src/Data/Skills/other.lua

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,86 @@ skills["AcidicConcoctionPlayer"] = {
228228
},
229229
}
230230
}
231+
skills["ThornsPlayer"] = {
232+
name = "Thorns",
233+
hidden = true,
234+
fromItem = true,
235+
skillTypes = { [SkillType.Damage] = true },
236+
qualityStats = {},
237+
levels = {
238+
[1] = { levelRequirement = 0 },
239+
},
240+
preDamageFunc = function(activeSkill, output, breakdown)
241+
local skillModList = activeSkill.skillModList
242+
local cfg = activeSkill.skillCfg
243+
244+
if activeSkill.actor and activeSkill.actor.modDB and activeSkill.actor.modDB:Flag(nil, "Condition:Shapeshifted") then
245+
skillModList:NewMod("Condition:Shapeshifted", "FLAG", true, "Thorns")
246+
end
247+
248+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsDamage")) do
249+
local mod = value.mod
250+
skillModList:NewMod("Damage", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
251+
end
252+
local function remapThornsBase(fromStat, toStat)
253+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, fromStat)) do
254+
local mod = value.mod
255+
skillModList:NewMod(toStat, "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
256+
end
257+
end
258+
259+
remapThornsBase("PhysicalThornsMin", "PhysicalMin")
260+
remapThornsBase("PhysicalThornsMax", "PhysicalMax")
261+
remapThornsBase("FireThornsMin", "FireMin")
262+
remapThornsBase("FireThornsMax", "FireMax")
263+
remapThornsBase("ColdThornsMin", "ColdMin")
264+
remapThornsBase("ColdThornsMax", "ColdMax")
265+
remapThornsBase("LightningThornsMin", "LightningMin")
266+
remapThornsBase("LightningThornsMax", "LightningMax")
267+
remapThornsBase("ChaosThornsMin", "ChaosMin")
268+
remapThornsBase("ChaosThornsMax", "ChaosMax")
269+
270+
-- Crit calculations
271+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "ThornsCritChance")) do
272+
local mod = value.mod
273+
skillModList:NewMod("CritChance", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
274+
end
275+
276+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsCritChance")) do
277+
local mod = value.mod
278+
skillModList:NewMod("CritChance", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
279+
end
280+
281+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsCritMultiplier")) do
282+
local mod = value.mod
283+
skillModList:NewMod("CritMultiplier", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
284+
end
285+
286+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "ThornsChanceToIgnoreEnemyArmour")) do
287+
local mod = value.mod
288+
skillModList:NewMod("ChanceToIgnoreEnemyPhysicalDamageReduction", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
289+
end
290+
end,
291+
statSets = {
292+
[1] = {
293+
label = "Thorns",
294+
incrementalEffectiveness = 0,
295+
statDescriptionScope = "skill_stat_descriptions",
296+
baseFlags = {
297+
thorns = true,
298+
},
299+
baseMods = {
300+
flag("CannotBleed"),
301+
flag("CannotPoison"),
302+
},
303+
constantStats = {},
304+
stats = {},
305+
levels = {
306+
[1] = {},
307+
},
308+
},
309+
}
310+
}
231311
skills["AlignFatePlayer"] = {
232312
name = "Align Fate",
233313
baseTypeName = "Align Fate",

src/Data/Skills/sup_str.lua

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,11 @@ skills["SupportBarbsPlayer"] = {
540540
label = "Barbs I",
541541
incrementalEffectiveness = 0.054999999701977,
542542
statDescriptionScope = "gem_stat_descriptions",
543+
statMap = {
544+
["deal_thorns_damage_on_hit_for_X_hits_after_thorns_trigger"] = {
545+
flag("ThornsDamageAppliesToHits"),
546+
},
547+
},
543548
baseFlags = {
544549
},
545550
constantStats = {
@@ -571,6 +576,11 @@ skills["SupportBarbsPlayerTwo"] = {
571576
label = "Barbs II",
572577
incrementalEffectiveness = 0.054999999701977,
573578
statDescriptionScope = "gem_stat_descriptions",
579+
statMap = {
580+
["deal_thorns_damage_on_hit_for_X_hits_after_thorns_trigger"] = {
581+
flag("ThornsDamageAppliesToHits"),
582+
},
583+
},
574584
baseFlags = {
575585
},
576586
constantStats = {
@@ -602,6 +612,12 @@ skills["SupportBarbsPlayerThree"] = {
602612
label = "Barbs III",
603613
incrementalEffectiveness = 0.054999999701977,
604614
statDescriptionScope = "gem_stat_descriptions",
615+
statMap = {
616+
["deal_thorns_damage_twice_on_hit_for_X_hits_after_thorns_trigger"] = {
617+
flag("ThornsDamageAppliesToHits"),
618+
flag("BarbsThornsTwiceOnHit"),
619+
},
620+
},
605621
baseFlags = {
606622
},
607623
constantStats = {
@@ -5200,6 +5216,11 @@ skills["SupportQuillburstPlayer"] = {
52005216
label = "Quill Burst",
52015217
incrementalEffectiveness = 0.054999999701977,
52025218
statDescriptionScope = "gem_stat_descriptions",
5219+
statMap = {
5220+
["trigger_spiked_gauntlets_for_X_hits_after_thorns_trigger"] = {
5221+
flag("EnableTriggeredQuillburst"),
5222+
},
5223+
},
52035224
baseFlags = {
52045225
},
52055226
constantStats = {
@@ -5221,6 +5242,53 @@ skills["TriggeredQuillburstPlayer"] = {
52215242
castTime = 1,
52225243
qualityStats = {
52235244
},
5245+
preDamageFunc = function(activeSkill, output, breakdown)
5246+
local skillModList = activeSkill.skillModList
5247+
local cfg = activeSkill.skillCfg
5248+
5249+
local function remapThornsBase(fromStat, toStat)
5250+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, fromStat)) do
5251+
local mod = value.mod
5252+
skillModList:NewMod(toStat, "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5253+
end
5254+
end
5255+
5256+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsDamage")) do
5257+
local mod = value.mod
5258+
skillModList:NewMod("Damage", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5259+
end
5260+
5261+
remapThornsBase("PhysicalThornsMin", "PhysicalMin")
5262+
remapThornsBase("PhysicalThornsMax", "PhysicalMax")
5263+
remapThornsBase("FireThornsMin", "FireMin")
5264+
remapThornsBase("FireThornsMax", "FireMax")
5265+
remapThornsBase("ColdThornsMin", "ColdMin")
5266+
remapThornsBase("ColdThornsMax", "ColdMax")
5267+
remapThornsBase("LightningThornsMin", "LightningMin")
5268+
remapThornsBase("LightningThornsMax", "LightningMax")
5269+
remapThornsBase("ChaosThornsMin", "ChaosMin")
5270+
remapThornsBase("ChaosThornsMax", "ChaosMax")
5271+
5272+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "ThornsCritChance")) do
5273+
local mod = value.mod
5274+
skillModList:NewMod("CritChance", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5275+
end
5276+
5277+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsCritChance")) do
5278+
local mod = value.mod
5279+
skillModList:NewMod("CritChance", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5280+
end
5281+
5282+
for _, value in ipairs(skillModList:Tabulate("INC", cfg, "ThornsCritMultiplier")) do
5283+
local mod = value.mod
5284+
skillModList:NewMod("CritMultiplier", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5285+
end
5286+
5287+
for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "ThornsChanceToIgnoreEnemyArmour")) do
5288+
local mod = value.mod
5289+
skillModList:NewMod("ChanceToIgnoreEnemyPhysicalDamageReduction", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
5290+
end
5291+
end,
52245292
levels = {
52255293
[1] = { cooldown = 0.15, levelRequirement = 0, storedUses = 1, },
52265294
},
@@ -5230,6 +5298,7 @@ skills["TriggeredQuillburstPlayer"] = {
52305298
incrementalEffectiveness = 0.054999999701977,
52315299
statDescriptionScope = "triggered_spiked_gauntlets",
52325300
baseFlags = {
5301+
thorns = true,
52335302
},
52345303
constantStats = {
52355304
{ "triggered_by_spiked_gauntlets_support_%", 100 },

src/Export/Skills/sup_str.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,32 @@ statMap = {
107107

108108
#skill SupportBarbsPlayer
109109
#set SupportBarbsPlayer
110+
statMap = {
111+
["deal_thorns_damage_on_hit_for_X_hits_after_thorns_trigger"] = {
112+
flag("ThornsDamageAppliesToHits"),
113+
},
114+
}
110115
#mods
111116
#skillEnd
112117

113118
#skill SupportBarbsPlayerTwo
114119
#set SupportBarbsPlayerTwo
120+
statMap = {
121+
["deal_thorns_damage_on_hit_for_X_hits_after_thorns_trigger"] = {
122+
flag("ThornsDamageAppliesToHits"),
123+
},
124+
}
115125
#mods
116126
#skillEnd
117127

118128
#skill SupportBarbsPlayerThree
119129
#set SupportBarbsPlayerThree
130+
statMap = {
131+
["deal_thorns_damage_twice_on_hit_for_X_hits_after_thorns_trigger"] = {
132+
flag("ThornsDamageAppliesToHits"),
133+
flag("BarbsThornsTwiceOnHit"),
134+
},
135+
}
120136
#mods
121137
#skillEnd
122138

@@ -1211,6 +1227,11 @@ statMap = {
12111227

12121228
#skill SupportQuillburstPlayer
12131229
#set SupportQuillburstPlayer
1230+
statMap = {
1231+
["trigger_spiked_gauntlets_for_X_hits_after_thorns_trigger"] = {
1232+
flag("EnableTriggeredQuillburst"),
1233+
},
1234+
}
12141235
#mods
12151236
#skillEnd
12161237

src/Modules/CalcOffence.lua

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -725,28 +725,62 @@ function calcs.offence(env, actor, activeSkill)
725725
end
726726
end
727727
end
728-
if skillModList:Flag(nil, "ThornsDamageAppliesToHits") then
729-
-- Caltrops mod
730-
for i, value in ipairs(skillModList:Tabulate("INC", { }, "ThornsDamage")) do
728+
729+
-- Apply thorns-derived modifiers to hits
730+
if skillModList:Flag(nil, "ThornsModifiersApplyToHits") or skillModList:Flag(nil, "ThornsDamageAppliesToHits") then
731+
-- % increased Thorns damage
732+
for _, value in ipairs(skillModList:Tabulate("INC", {}, "ThornsDamage")) do
731733
local mod = value.mod
732734
skillModList:NewMod("Damage", "INC", mod.value, mod.source, ModFlag.Hit, mod.keywordFlags, unpack(mod))
733735
end
734-
-- Increased Thorns critical damage bonus
735-
for i, value in ipairs(skillModList:Tabulate("INC", { }, "ThornsCritMultiplier")) do
736+
737+
-- Thorns crit chance
738+
for _, value in ipairs(skillModList:Tabulate("BASE", {}, "ThornsCritChance")) do
736739
local mod = value.mod
737-
skillModList:NewMod("CritMultiplier", "INC", mod.value, mod.source, 0, 0)
740+
skillModList:NewMod("CritChance", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
738741
end
739-
-- +#% to Thorns critical hit chance
740-
for _, value in ipairs(skillModList:Tabulate("BASE", {}, "ThornsCritChance")) do
742+
for _, value in ipairs(skillModList:Tabulate("INC", {}, "ThornsCritChance")) do
741743
local mod = value.mod
742-
skillModList:NewMod("CritChance", "BASE", mod.value, mod.source, 0, 0)
744+
skillModList:NewMod("CritChance", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
743745
end
744-
-- Thorns damage has +#% chance to ignore enemy armour
746+
747+
-- Thorns crit multiplier
748+
for _, value in ipairs(skillModList:Tabulate("INC", {}, "ThornsCritMultiplier")) do
749+
local mod = value.mod
750+
skillModList:NewMod("CritMultiplier", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
751+
end
752+
753+
-- Thorns chance to ignore enemy armour
745754
for _, value in ipairs(skillModList:Tabulate("BASE", {}, "ThornsChanceToIgnoreEnemyArmour")) do
746755
local mod = value.mod
747-
skillModList:NewMod("ChanceToIgnoreEnemyPhysicalDamageReduction", "BASE", mod.value, mod.source, 0, 0)
756+
skillModList:NewMod("ChanceToIgnoreEnemyPhysicalDamageReduction", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod))
748757
end
749758
end
759+
760+
-- Apply full thorns damage payload to hits
761+
if skillModList:Flag(nil, "ThornsDamageAppliesToHits") then
762+
local multiplier = skillModList:Flag(nil, "BarbsThornsTwiceOnHit") and 2 or 1
763+
764+
local function remapThornsBase(fromStat, toStat)
765+
for _, value in ipairs(skillModList:Tabulate("BASE", {}, fromStat)) do
766+
local mod = value.mod
767+
skillModList:NewMod(toStat, "BASE", mod.value * multiplier, mod.source, ModFlag.Hit, mod.keywordFlags, unpack(mod))
768+
end
769+
end
770+
771+
-- Base thorns damage to hits
772+
remapThornsBase("PhysicalThornsMin", "PhysicalMin")
773+
remapThornsBase("PhysicalThornsMax", "PhysicalMax")
774+
remapThornsBase("FireThornsMin", "FireMin")
775+
remapThornsBase("FireThornsMax", "FireMax")
776+
remapThornsBase("ColdThornsMin", "ColdMin")
777+
remapThornsBase("ColdThornsMax", "ColdMax")
778+
remapThornsBase("LightningThornsMin", "LightningMin")
779+
remapThornsBase("LightningThornsMax", "LightningMax")
780+
remapThornsBase("ChaosThornsMin", "ChaosMin")
781+
remapThornsBase("ChaosThornsMax", "ChaosMax")
782+
end
783+
750784
if skillModList:Flag(nil, "CastSpeedAppliesToAttacks") then
751785
-- Get all increases for this; assumption is that multiple sources would not stack, so find the max
752786
local multiplier = (skillModList:Max(skillCfg, "ImprovedCastSpeedAppliesToAttacks") or 100) / 100

src/Modules/CalcPerform.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ local function doActorAttribsConditions(env, actor)
265265
condList["Channelling"] = true
266266
end
267267
end
268+
269+
if env.configInput.conditionShapeshifted then
270+
condList["Shapeshifted"] = true
271+
end
272+
268273
if actor.mainSkill.skillTypes[SkillType.Bear] then
269274
condList["Shapeshifted"] = true
270275
condList["BearForm"] = true

src/Modules/CalcSections.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ return {
623623
} }
624624
} },
625625
{ 1, "SkillTypeStats", 1, colorCodes.OFFENCE, {{ defaultCollapsed = false, label = "Skill type-specific Stats", data = {
626-
{ label = "Gem Level", haveOutput = "GemHasLevel", { format = "{0:output:GemLevel}", { breakdown = "GemLevel" }, { modName = { "GemLevel" }, cfg = "skill" },{ modName = { "GemSupportLevel" }, cfg = "skill" }, { modName = { "GemItemLevel" }, cfg = "skill" }, }, },
626+
{ label = "Gem Level", notFlag = "thorns", haveOutput = "GemHasLevel", { format = "{0:output:GemLevel}", { breakdown = "GemLevel" }, { modName = { "GemLevel" }, cfg = "skill" }, { modName = { "GemSupportLevel" }, cfg = "skill" }, { modName = { "GemItemLevel" }, cfg = "skill" }, }, },
627627
{ label = "Spirit Cost", color = colorCodes.SPIRIT, haveOutput = "SpiritHasCost", { format = "{0:output:SpiritCost}", { breakdown = "SpiritCost" }, { modName = { "SpiritCost", "Cost", "SpiritCostNoMult" }, cfg = "skill" }, }, },
628628
{ label = "Spirit % Cost", color = colorCodes.SPIRIT, haveOutput = "SpiritPercentHasCost", { format = "{0:output:SpiritPercentCost}", { breakdown = "SpiritPercentCost" }, { modName = { "SpiritCost", "Cost", "SpiritCostNoMult" }, cfg = "skill" }, }, },
629629
{ label = "Mana Cost", color = colorCodes.MANA, haveOutput = "ManaHasCost", { format = "{0:output:ManaCost}", { breakdown = "ManaCost" }, { modName = { "ManaCost", "Cost", "ManaCostNoMult" }, cfg = "skill" }, }, },
@@ -721,7 +721,7 @@ return {
721721
{ modName = { "CurseDelay" }, cfg = "skill" },
722722
{ modName = { "CurseActivation" }, cfg = "skill" },
723723
} },
724-
{ label = "Curse Limit", haveOutput = "EnemyCurseLimit", { format = "{0:output:EnemyCurseLimit}",
724+
{ label = "Curse Limit", notFlag = "thorns", haveOutput = "EnemyCurseLimit", { format = "{0:output:EnemyCurseLimit}",
725725
{ breakdown = "EnemyCurseLimit" },
726726
{ modName = { "CurseLimitIsMaximumPowerCharges", "EnemyCurseLimit" } },
727727
}, },

0 commit comments

Comments
 (0)