Skip to content

Commit 293de26

Browse files
PaliakWires77
andauthored
Add showcased Mercenaries of Trarthus uniques (#8619)
* FEAT(items): Add showcased uniques to New.lua * FEAT(mods): add handling for new mods on Scornflux * FEAT(mods): add handling for "Take X Fire Damage when you use a Skill" * FEAT(mods): add handling for Damage penetrates "Fire Resistance equal to your overcapped Fire Resistance" * FEAT(mods): add handling for "Warcries have an additional Life Cost equal to 15% of your Maximum Life" * FEAT(mods): add handling for "Warcry Skills have X increased Area of Effect" * FEAT(mods): add handling for `Gain no armour from equipped body armour` * FEAT(mods): port generalized "doubled" mod handling from POB2 PathOfBuildingCommunity/PathOfBuilding-PoE2#1095 * Update spelling and ModCache --------- Co-authored-by: Wires77 <Wires77@users.noreply.github.com>
1 parent a47d56f commit 293de26

9 files changed

Lines changed: 227 additions & 93 deletions

File tree

docs/modSyntax.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Often a mod will only apply under certain conditions, apply multiple times based
3636
* var: mod to multiply by
3737
* limit: The maximum number the mod can go up to
3838
* limitTotal: boolean that changes the behavior of limit to apply after multiplication. Defaults to false.
39+
* globalLimit: The maximum global number the mod can go up to, even with multiple sources. Useful for mods that say "up to a maximum of ..."
40+
* globalLimitKey: string identifier for the global limit. Mods with identical keys cannot go over the globalLimit.
3941
* MultiplierThreshold: Similar to a condition that only applies when the variable is above a specified threshold
4042
* var: name of the mod
4143
* threshold: number to reach before the mod applies

src/Classes/ModDB.lua

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,28 @@ end
123123
function ModDBClass:MoreInternal(context, cfg, flags, keywordFlags, source, ...)
124124
local result = 1
125125
local modPrecision = nil
126+
local globalLimits = { }
126127
for i = 1, select('#', ...) do
127128
local modList = self.mods[select(i, ...)]
128129
local modResult = 1 --The more multipliers for each mod are computed to the nearest percent then applied.
129130
if modList then
130131
for i = 1, #modList do
131132
local mod = modList[i]
132133
if mod.type == "MORE" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then
134+
local value
133135
if mod[1] then
134-
modResult = modResult * (1 + (context:EvalMod(mod, cfg) or 0) / 100)
136+
value = context:EvalMod(mod, cfg) or 0
137+
if mod[1].globalLimit and mod[1].globalLimitKey then
138+
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] or 0
139+
if globalLimits[mod[1].globalLimitKey] + value > mod[1].globalLimit then
140+
value = mod[1].globalLimit - globalLimits[mod[1].globalLimitKey]
141+
end
142+
globalLimits[mod[1].globalLimitKey] = globalLimits[mod[1].globalLimitKey] + value
143+
end
135144
else
136-
modResult = modResult * (1 + mod.value / 100)
145+
value = mod.value or 0
137146
end
147+
modResult = modResult * (1 + value / 100)
138148
if modPrecision then
139149
modPrecision = m_max(modPrecision, (data.highPrecisionMods[mod.name] and data.highPrecisionMods[mod.name][mod.type]) or modPrecision)
140150
else

src/Classes/ModStore.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ function ModStoreClass:GetCondition(var, cfg, noMod)
228228
end
229229

230230
function ModStoreClass:GetMultiplier(var, cfg, noMod)
231-
return (self.multipliers[var] or 0) + (self.parent and self.parent:GetMultiplier(var, cfg, true) or 0) + (not noMod and self:Sum("BASE", cfg, multiplierName[var]) or 0)
231+
return (not noMod and self:Override(cfg, multiplierName[var])) or (self.multipliers[var] or 0) + (self.parent and self.parent:GetMultiplier(var, cfg, true) or 0) + (not noMod and self:Sum("BASE", cfg, multiplierName[var]) or 0)
232232
end
233233

234234
function ModStoreClass:GetStat(stat, cfg)

src/Data/ModCache.lua

Lines changed: 35 additions & 10 deletions
Large diffs are not rendered by default.

src/Data/Uniques/Special/New.lua

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,70 @@
33
--
44

55
data.uniques.new = {
6-
76
-- New
8-
}
7+
8+
[[
9+
Starcaller
10+
Abyssal Axe
11+
League: Mercenaries of Trarthus
12+
Requires Level 55, 128 Str, 60 Dex
13+
Trigger Level 20 Starfall on Melee Critical Strike
14+
+17 to all Attributes
15+
168% increased Physical Damage
16+
22% increased Critical Strike Chance
17+
20% increased Area of Effect
18+
Gain 46% of Weapon Physical Damage as Extra Damage of a Random Element
19+
]],[[
20+
Wine of the Prophet
21+
Gold Flask
22+
League: Mercenaries of Trarthus
23+
Requires Level 27
24+
+60 to Maximum Charges
25+
89% increased Charges per Use
26+
Grants a random Divination buff for 20 seconds when used
27+
]],[[
28+
Scornflux
29+
Satin Slippers
30+
League: Mercenaries of Trarthus
31+
Requires Level 54, 69 Int
32+
+10 to Intelligence
33+
+66 to Maximum Mana
34+
+12% to all Elemental Resistances
35+
Gain Arcane Surge when you use a Movement Skill
36+
Increase to Cast Speed from Arcane Surge also applies to Movement Speed
37+
]],[[
38+
Prospero's Protection
39+
Iron Ring
40+
League: Mercenaries of Trarthus
41+
Requires Level 32
42+
Implicits: 1
43+
Adds 1 to 4 Physical Damage to Attacks
44+
5% chance to Block Attack Damage
45+
+18 to Strength
46+
+53 to Maximum Life
47+
Armour from equipped shield is doubled
48+
Gain no armour from equipped body armour
49+
]],[[
50+
Howlcrack
51+
Ezomyte Burgonet
52+
League: Mercenaries of Trarthus
53+
Requires Level 60, 138 Str
54+
+33 to Strength
55+
121% increased Armour
56+
Non-instant Warcries you use yourself have no Cooldown
57+
Warcries have an additional Life Cost equal to 15% of your Maximum Life
58+
Warcry Skills have 16% increased Area of Effect
59+
]],[[
60+
Enmity's Embrace
61+
Vermillion Ring
62+
League: Mercenaries of Trarthus
63+
Requires Level 80
64+
Implicits: 1
65+
6% increased Maximum Life
66+
+49 to Strength
67+
14% increased Fire Damage
68+
55% reduced Fire Resistance
69+
Take 449 Fire Damage when you use a Skill
70+
Damage penetrates Fire Resistance equal to your overcapped Fire Resistance
71+
]]
72+
}

src/Modules/CalcDefence.lua

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -480,42 +480,20 @@ function calcs.defence(env, actor)
480480
for _, slot in pairs({"Helmet","Gloves","Boots","Body Armour","Weapon 2","Weapon 3"}) do
481481
local armourData = actor.itemList[slot] and actor.itemList[slot].armourData
482482
if armourData then
483-
wardBase = armourData.Ward or 0
483+
wardBase = not modDB:Flag(nil, "GainNoWardFrom" .. slot) and armourData.Ward or 0
484484
if wardBase > 0 then
485-
if slot == "Body Armour" and modDB:Flag(nil, "DoubleBodyArmourDefence") then
486-
wardBase = wardBase * 2
487-
end
488485
output["WardOn"..slot] = wardBase
489486
end
490-
energyShieldBase = armourData.EnergyShield or 0
487+
energyShieldBase = not modDB:Flag(nil, "GainNoEnergyShieldFrom" .. slot) and armourData.EnergyShield or 0
491488
if energyShieldBase > 0 then
492-
if slot == "Body Armour" and modDB:Flag(nil, "DoubleBodyArmourDefence") then
493-
energyShieldBase = energyShieldBase * 2
494-
end
495489
output["EnergyShieldOn"..slot] = energyShieldBase
496490
end
497-
armourBase = armourData.Armour or 0
491+
armourBase = not modDB:Flag(nil, "GainNoArmourFrom" .. slot) and armourData.Armour or 0
498492
if armourBase > 0 then
499-
if slot == "Body Armour" then
500-
if modDB:Flag(nil, "DoubleBodyArmourDefence") then
501-
armourBase = armourBase * 2
502-
end
503-
if modDB:Flag(nil, "Unbreakable") then
504-
armourBase = armourBase * 2
505-
end
506-
end
507493
output["ArmourOn"..slot] = armourBase
508494
end
509-
evasionBase = armourData.Evasion or 0
495+
evasionBase = not modDB:Flag(nil, "GainNoEvasionFrom" .. slot) and armourData.Evasion or 0
510496
if evasionBase > 0 then
511-
if slot == "Body Armour" then
512-
if modDB:Flag(nil, "DoubleBodyArmourDefence") then
513-
evasionBase = evasionBase * 2
514-
end
515-
if modDB:Flag(nil, "Unbreakable") and modDB:Flag(nil, "IronReflexes") then
516-
evasionBase = evasionBase * 2
517-
end
518-
end
519497
output["EvasionOn"..slot] = evasionBase
520498
end
521499
end
@@ -819,11 +797,8 @@ function calcs.defence(env, actor)
819797
local armourData = actor.itemList[slot] and actor.itemList[slot].armourData
820798
if armourData then
821799
slotCfg.slotName = slot
822-
wardBase = armourData.Ward or 0
800+
wardBase = not modDB:Flag(nil, "GainNoWardFrom" .. slot) and armourData.Ward or 0
823801
if wardBase > 0 then
824-
if slot == "Body Armour" and modDB:Flag(nil, "DoubleBodyArmourDefence") then
825-
wardBase = wardBase * 2
826-
end
827802
if modDB:Flag(nil, "EnergyShieldToWard") then
828803
local inc = modDB:Sum("INC", slotCfg, "Ward", "Defences", "EnergyShield")
829804
local more = modDB:More(slotCfg, "Ward", "Defences")
@@ -847,11 +822,8 @@ function calcs.defence(env, actor)
847822
end
848823
end
849824
end
850-
energyShieldBase = armourData.EnergyShield or 0
825+
energyShieldBase = not modDB:Flag(nil, "GainNoEnergyShieldFrom" .. slot) and armourData.EnergyShield or 0
851826
if energyShieldBase > 0 then
852-
if slot == "Body Armour" and modDB:Flag(nil, "DoubleBodyArmourDefence") then
853-
energyShieldBase = energyShieldBase * 2
854-
end
855827
if modDB:Flag(nil, "EnergyShieldToWard") then
856828
local more = modDB:More(slotCfg, "EnergyShield", "Defences")
857829
energyShield = energyShield + energyShieldBase * more
@@ -873,37 +845,21 @@ function calcs.defence(env, actor)
873845
end
874846
end
875847
end
876-
armourBase = armourData.Armour or 0
848+
armourBase = not modDB:Flag(nil, "GainNoArmourFrom" .. slot) and armourData.Armour or 0
877849
if armourBase > 0 then
878-
if slot == "Body Armour" then
879-
if modDB:Flag(nil, "DoubleBodyArmourDefence") then
880-
armourBase = armourBase * 2
881-
end
882-
if modDB:Flag(nil, "Unbreakable") then
883-
armourBase = armourBase * 2
884-
end
885-
if modDB:Flag(nil, "ConvertBodyArmourArmourEvasionToWard") then
886-
armourBase = armourBase * (1 - ((m_min(modDB:Sum("BASE", nil, "BodyArmourArmourEvasionToWardPercent"), 100) or 0) / 100))
887-
end
850+
if slot == "Body Armour" and modDB:Flag(nil, "ConvertBodyArmourArmourEvasionToWard")then
851+
armourBase = armourBase * (1 - ((m_min(modDB:Sum("BASE", nil, "BodyArmourArmourEvasionToWardPercent"), 100) or 0) / 100))
888852
end
889853
armour = armour + armourBase * calcLib.mod(modDB, slotCfg, "Armour", "ArmourAndEvasion", "Defences", slot.."ESAndArmour")
890854
gearArmour = gearArmour + armourBase
891855
if breakdown then
892856
breakdown.slot(slot, nil, slotCfg, armourBase, nil, "Armour", "ArmourAndEvasion", "Defences", slot.."ESAndArmour")
893857
end
894858
end
895-
evasionBase = armourData.Evasion or 0
859+
evasionBase = not modDB:Flag(nil, "GainNoEvasionFrom" .. slot) and armourData.Evasion or 0
896860
if evasionBase > 0 then
897-
if slot == "Body Armour" then
898-
if modDB:Flag(nil, "DoubleBodyArmourDefence") then
899-
evasionBase = evasionBase * 2
900-
end
901-
if modDB:Flag(nil, "Unbreakable") and ironReflexes then
902-
evasionBase = evasionBase * 2
903-
end
904-
if modDB:Flag(nil, "ConvertBodyArmourArmourEvasionToWard") then
905-
evasionBase = evasionBase * (1 - ((m_min(modDB:Sum("BASE", nil, "BodyArmourArmourEvasionToWardPercent"), 100) or 0) / 100))
906-
end
861+
if slot == "Body Armour" and modDB:Flag(nil, "ConvertBodyArmourArmourEvasionToWard")then
862+
evasionBase = evasionBase * (1 - ((m_min(modDB:Sum("BASE", nil, "BodyArmourArmourEvasionToWardPercent"), 100) or 0) / 100))
907863
end
908864
gearEvasion = gearEvasion + evasionBase
909865
if breakdown then

src/Modules/CalcOffence.lua

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,13 @@ function calcs.offence(env, actor, activeSkill)
688688
skillModList:NewMod("CritChance", "INC", output.SpellSuppressionChance, mod.source)
689689
break
690690
end
691-
691+
end
692+
if skillModList:Flag(nil, "FirePenIncreasedByUncappedFireRes") then
693+
for i, value in ipairs(modDB:Tabulate("FLAG", nil, "FirePenIncreasedByUncappedFireRes")) do
694+
local mod = value.mod
695+
skillModList:NewMod("FirePenetration", "BASE", output.FireResistOverCap, mod.source)
696+
break
697+
end
692698
end
693699
if skillModList:Flag(nil, "LightRadiusAppliesToAccuracy") then
694700
-- Light Radius conversion from Corona Solaris
@@ -5471,8 +5477,21 @@ function calcs.offence(env, actor, activeSkill)
54715477
return dmgBreakdown, totalDmgTaken
54725478
end
54735479
end,
5480+
["Enmity's Embrace"] = function(activeSkill, output, breakdown)
5481+
local dmgType, dmgVal
5482+
for _, value in ipairs(activeSkill.skillModList:List(nil, "EnmitysEmbraceSelfDamage")) do -- Combines dmg taken from both rings accounting for catalysts
5483+
dmgVal = (dmgVal or 0) + value.baseDamage
5484+
dmgType = string.gsub(" "..value.damageType, "%W%l", string.upper):sub(2) -- This assumes both rings deal the same damage type
5485+
end
5486+
if dmgType and dmgVal then
5487+
local dmgBreakdown, totalDmgTaken = calcs.applyDmgTakenConversion(activeSkill, output, breakdown, dmgType, dmgVal)
5488+
t_insert(dmgBreakdown, 1, s_format("Enmity's Embrace base damage: %d", dmgVal))
5489+
t_insert(dmgBreakdown, 2, s_format(""))
5490+
t_insert(dmgBreakdown, s_format("Total Enmity's Embrace damage taken per cast/attack: %.2f ", totalDmgTaken))
5491+
return dmgBreakdown, totalDmgTaken
5492+
end
5493+
end
54745494
}
5475-
54765495
for _, sourceFunc in pairs(nameToHandler) do
54775496
local selfHitBreakdown, dmgTaken = sourceFunc(activeSkill, output, breakdown)
54785497
if dmgTaken then

src/Modules/CalcPerform.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,11 @@ local function doActorMisc(env, actor)
658658
modDB.conditions["AffectedByArcaneSurge"] = true
659659
local effect = 1 + modDB:Sum("INC", nil, "ArcaneSurgeEffect", "BuffEffectOnSelf") / 100
660660
modDB:NewMod("ManaRegen", "INC", (modDB:Max(nil, "ArcaneSurgeManaRegen") or 30) * effect, "Arcane Surge")
661-
modDB:NewMod("Speed", "INC", (modDB:Max(nil, "ArcaneSurgeCastSpeed") or 20) * effect, "Arcane Surge", ModFlag.Cast)
661+
local arcaneSurgeCastSpeed = (modDB:Max(nil, "ArcaneSurgeCastSpeed") or 20) * effect
662+
modDB:NewMod("Speed", "INC", arcaneSurgeCastSpeed, "Arcane Surge", ModFlag.Cast)
663+
if modDB:Flag(nil, "ArcaneSurgeCastSpeedToMovementSpeed") then
664+
modDB:NewMod("MovementSpeed", "INC", arcaneSurgeCastSpeed, "Arcane Surge")
665+
end
662666
local arcaneSurgeDamage = modDB:Max(nil, "ArcaneSurgeDamage") or 0
663667
if arcaneSurgeDamage ~= 0 then modDB:NewMod("Damage", "MORE", arcaneSurgeDamage * effect, "Arcane Surge", ModFlag.Spell) end
664668
end

0 commit comments

Comments
 (0)