diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 3720f43208..c0dff62a5f 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -1263,7 +1263,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.prefixes.limit = (self.prefixes.limit or 0) + (tonumber(lineLower:match("%+(%d+) prefix modifiers? allowed")) or 0) - (tonumber(lineLower:match("%-(%d+) prefix modifiers? allowed")) or 0) elseif lineLower:match(" suffix modifiers? allowed") then self.suffixes.limit = (self.suffixes.limit or 0) + (tonumber(lineLower:match("%+(%d+) suffix modifiers? allowed")) or 0) - (tonumber(lineLower:match("%-(%d+) suffix modifiers? allowed")) or 0) - elseif lineLower == "this item can be anointed by cassia" then + elseif lineLower == "this item can be anointed by cassia" or lineLower == "raven-touched" then self.canBeAnointed = true elseif (lineLower == "can have 1 additional instilled modifier" or lineLower == "can have an additional instilled modifier") then self.canHaveTwoEnchants = true @@ -2486,6 +2486,7 @@ function ItemClass:BuildModListForSlotNum(baseList, slotNum) end self.craftedQuality = craftedQuality end + local anointableItem if self.quality then modList:NewMod("Multiplier:QualityOn"..slotName, "BASE", self.quality, "Quality") end diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 1ee55268d2..b92c803cf7 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -813,7 +813,11 @@ holding Shift will put it in the second.]]) tooltip:AddLine(14, "^7" .. s_format("Requires: Level %d", value.req)) end for _, line in ipairs(value.lines) do - tooltip:AddLine(14, colorCodes.MAGIC .. line) + -- rune mod lines don't need a range applied to them + local stripped = line:gsub("Bonded: ", "") + local modList, extra = modLib.parseMod(stripped) + local colour = ((not not modList) and not extra) and colorCodes.MAGIC or colorCodes.UNSUPPORTED + tooltip:AddLine(14, colour .. line) end -- Adding Comparison local compLines = { type = "Rune" } diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 701abf6fd2..5488885051 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2363,8 +2363,7 @@ c["15% increased Magnitude of Daze"]={{}," Magnitude of Daze "} c["15% increased Magnitude of Jagged Ground you create"]={{[1]={flags=0,keywordFlags=0,name="EnemyJaggedGroundMagnitude",type="INC",value=15}},nil} c["15% increased Magnitude of Shock you inflict"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockMagnitude",type="INC",value=15}},nil} c["15% increased Mana Cost Efficiency"]={{[1]={flags=0,keywordFlags=0,name="ManaCostEfficiency",type="INC",value=15}},nil} -c["15% increased Mana Cost Efficiency of Command Skills"]={{[1]={flags=0,keywordFlags=0,name="ManaCostEfficiency",type="INC",value=15}}," of Command Skills "} -c["15% increased Mana Cost Efficiency of Command Skills +1 maximum stacks of Puppet Master"]={{[1]={flags=0,keywordFlags=0,name="ManaCostEfficiency",type="INC",value=15}}," of Command Skills +1 maximum stacks of Puppet Master "} +c["15% increased Mana Cost Efficiency of Command Skills"]={{[1]={[1]={type="Condition",var="CommandableSkill"},flags=0,keywordFlags=0,name="ManaCostEfficiency",type="INC",value=15}},nil} c["15% increased Mana Cost of Skills"]={{[1]={flags=0,keywordFlags=0,name="ManaCost",type="INC",value=15}},nil} c["15% increased Mana Flask Charges gained"]={{[1]={flags=0,keywordFlags=0,name="ManaFlaskChargesGained",type="INC",value=15}},nil} c["15% increased Mana Recovery from Flasks"]={{[1]={flags=0,keywordFlags=0,name="FlaskManaRecovery",type="INC",value=15}},nil} @@ -3978,7 +3977,7 @@ c["35% of Maximum Life Converted to Energy Shield"]={{[1]={flags=0,keywordFlags= c["35% of Physical Damage taken as Lightning while your Shield is raised"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageTaken",type="BASE",value=35}}," as Lightning while your Shield is raised "} c["35% reduced Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type="INC",value=-35}},nil} c["35% reduced Duration of Ignite, Shock and Chill on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockDuration",type="INC",value=-35},[2]={flags=0,keywordFlags=0,name="EnemyChillDuration",type="INC",value=-35},[3]={flags=0,keywordFlags=0,name="EnemyIgniteDuration",type="INC",value=-35}},nil} -c["35% reduced Effect of Non-Damaging Ailments on you"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockMagnitude",type="INC",value=-35},[2]={flags=0,keywordFlags=0,name="EnemyChillMagnitude",type="INC",value=-35},[3]={flags=0,keywordFlags=0,name="EnemyFreezeBuildup",type="INC",value=-35}}," on you "} +c["35% reduced Effect of Non-Damaging Ailments on you"]={{[1]={flags=0,keywordFlags=0,name="SelfChillEffect",type="INC",value=-35},[2]={flags=0,keywordFlags=0,name="SelfFreezeEffect",type="INC",value=-35},[3]={flags=0,keywordFlags=0,name="SelfShockEffect",type="INC",value=-35}},nil} c["35% reduced Flask Effect Duration"]={{[1]={flags=0,keywordFlags=0,name="FlaskDuration",type="INC",value=-35}},nil} c["35% reduced Presence Area of Effect"]={{[1]={flags=0,keywordFlags=0,name="PresenceArea",type="INC",value=-35}},nil} c["350 Physical Damage taken on Minion Death"]={{[1]={flags=0,keywordFlags=0,name="HeartboundLoopSelfDamage",type="LIST",value={baseDamage=350,damageType="physical"}}},nil} @@ -5001,8 +5000,8 @@ c["75% increased chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShoc c["75% increased effect of Socketed Augment Items"]={{[1]={flags=0,keywordFlags=0,name="SocketedAugmentItemEffect",type="INC",value=75}},nil} c["75% more Stun Buildup with Lightning Damage"]={{[1]={[1]={type="Condition",var="LightningHasDamage"},flags=0,keywordFlags=0,name="EnemyHeavyStunBuildup",type="MORE",value=75}},nil} c["75% of Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="DamageConvertToFire",type="BASE",value=75}},nil} -end)();(function() c["75% of Volatility Physical Damage Taken as Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageTakenAsCold",type="BASE",value=75}}," Volatility "} +end)();(function() c["75% reduced Amount Recovered"]={{[1]={flags=0,keywordFlags=0,name="FlaskRecovery",type="INC",value=-75}},nil} c["75% reduced Charges per use"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargesUsed",type="INC",value=-75}},nil} c["75% reduced Ignite Duration on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyIgniteDuration",type="INC",value=-75}},nil} @@ -7304,6 +7303,7 @@ c["Enemies in your Presence are Slowed by 20%"]={{[1]={[1]={type="Condition",var c["Enemies in your Presence count as being on Low Life"]={{[1]={[1]={type="Condition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:LowLife",type="FLAG",value=true}}}},nil} c["Enemies in your Presence count as having double Power"]={{},"count as having Power "} c["Enemies in your Presence gain 1 Gruelling Madness each second"]={{}," Gruelling Madness each second "} +c["Enemies in your Presence gain 1 Gruelling Madness each second Raven-Touched"]={{}," Gruelling Madness each second Raven-Touched "} c["Enemies in your Presence have +1% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="FireResist",type="BASE",value=1}}}},nil} c["Enemies in your Presence have -10% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="FireResist",type="BASE",value=-10}}}},nil} c["Enemies in your Presence have -25% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={actor="enemy",type="ActorCondition",var="EnemyInPresence"},flags=0,keywordFlags=0,name="FireResist",type="BASE",value=-25}}}},nil} @@ -7443,7 +7443,7 @@ c["Fire Damage from Hits also Contributes to Poison Magnitude"]={nil,"Fire Damag c["Fire Resistance is unaffected by Area Penalties"]={nil,"Fire Resistance is unaffected by Area Penalties "} c["Fire Skills have 20% chance to Poison on Hit"]={{[1]={flags=0,keywordFlags=32,name="PoisonChance",type="BASE",value=20}},nil} c["Fire Spells Convert 100% of Fire Damage to Chaos Damage"]={{[1]={[1]={skillType=2,type="SkillType"},[2]={skillType=28,type="SkillType"},flags=0,keywordFlags=0,name="FireDamageConvertToChaos",type="BASE",value="100"}},nil} -c["Fissure Skills have +1 to Limit"]={nil,"Fissure Skills have +1 to Limit "} +c["Fissure Skills have +1 to Limit"]={{[1]={[1]={skillType=164,type="SkillType"},flags=0,keywordFlags=0,name="AdditionalCooldownUses",type="BASE",value="1"}},nil} c["Flammability Magnitude is doubled"]={{[1]={[1]={globalLimit=100,globalLimitKey="EnemyIgniteChanceDoubledLimit",type="Multiplier",var="EnemyIgniteChanceDoubled"},flags=0,keywordFlags=0,name="EnemyIgniteChance",type="MORE",value=100},[2]={flags=0,keywordFlags=0,name="Multiplier:EnemyIgniteChanceDoubled",type="OVERRIDE",value=1}},nil} c["Flammability has no Reservation if Cast as an Aura"]={{[1]={[1]={type="SkillId"},[2]={skillType=39,type="SkillType"},[3]={neg=true,skillType=109,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="manaReservationFlat",value=0}},[2]={[1]={type="SkillId"},[2]={skillType=39,type="SkillType"},[3]={neg=true,skillType=109,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="lifeReservationFlat",value=0}},[3]={[1]={type="SkillId"},[2]={skillType=39,type="SkillType"},[3]={neg=true,skillType=109,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="manaReservationPercent",value=0}},[4]={[1]={type="SkillId"},[2]={skillType=39,type="SkillType"},[3]={neg=true,skillType=109,type="SkillType"},flags=0,keywordFlags=0,name="SkillData",type="LIST",value={key="lifeReservationPercent",value=0}}},nil} c["Flasks applied to you have 8% increased Effect"]={{[1]={[1]={actor="player",type="ActorCondition"},flags=0,keywordFlags=0,name="FlaskEffect",type="INC",value=8}},nil} @@ -7481,6 +7481,7 @@ c["Gain 1 Explosive Rhythm every 3 times you use a Grenade Skill"]={{}," Explosi c["Gain 1 Explosive Rhythm every 3 times you use a Grenade Skill Remove all Explosive Rhythm on reaching 10 to gain Explosive Fervour for 10 Seconds"]={{}," Explosive Rhythm every 3 times you use a Skill Remove all Explosive Rhythm on reaching 10 to gain Explosive Fervour "} c["Gain 1 Explosive Rhythm every 3 times you use a Grenade Skill Remove all Explosive Rhythm on reaching 10 to gain Explosive Fervour for 10 Seconds"]={{}," Explosive Rhythm every 3 times you use a Skill Remove all Explosive Rhythm on reaching 10 to gain Explosive Fervour "} c["Gain 1 Fear Incarnate when you Cull a target"]={{}," Fear Incarnate when you Cull a target "} +c["Gain 1 Fear Incarnate when you Cull a target Raven-Touched"]={{}," Fear Incarnate when you Cull a target Raven-Touched "} c["Gain 1 Fear Overwhelming when you Cull a target"]={{}," Fear Overwhelming when you Cull a target "} c["Gain 1 Fragile Regrowth each second"]={{}," Fragile Regrowth each second "} c["Gain 1 Life Flask Charge per 2% Life spent"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=1}}," Flask Charge per 2% Life spent "} @@ -8854,7 +8855,7 @@ c["Only affects Passives in Small Ring"]={{[1]={flags=0,keywordFlags=0,name="Jew c["Only affects Passives in Very Large Ring"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="radiusIndex",value=11}}},nil} c["Only affects Passives in Very Small Ring"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="radiusIndex",value=5}}},nil} c["Onslaught"]={{[1]={flags=0,keywordFlags=0,name="Condition:Onslaught",type="FLAG",value=true}},nil} -c["Orb Skills have +1 to Limit"]={nil,"Orb Skills have +1 to Limit "} +c["Orb Skills have +1 to Limit"]={{[1]={[1]={skillType=101,type="SkillType"},flags=0,keywordFlags=0,name="AdditionalCooldownUses",type="BASE",value="1"}},nil} c["Other Modifiers to Movement Speed except for Sprinting do not apply"]={nil,"Other Modifiers to Movement Speed except for Sprinting do not apply "} c["Other Modifiers to Movement Speed except for Sprinting do not apply Increases Movement Speed by 25%, plus 1% per 600 Evasion Rating, up to a maximum of 75%"]={nil,"Other Modifiers to Movement Speed except for Sprinting do not apply Increases Movement Speed by 25%, plus 1% per 600 Evasion Rating, up to a maximum of 75% "} c["Other Modifiers to Movement Speed except for Sprinting do not apply Increases Movement Speed by 25%, plus 1% per 800 Evasion Rating, up to a maximum of 75%"]={nil,"Other Modifiers to Movement Speed except for Sprinting do not apply Increases Movement Speed by 25%, plus 1% per 800 Evasion Rating, up to a maximum of 75% "} @@ -9047,7 +9048,7 @@ c["Raised Zombies deal 113% more Physical Damage"]={{[1]={[1]={includeTransfigur c["Raised Zombies have +28% to all Resistances"]={{[1]={[1]={includeTransfigured=true,skillName="Raise Zombie",type="SkillName"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=28}}},[2]={[1]={includeTransfigured=true,skillName="Raise Zombie",type="SkillName"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=28}}}},nil} c["Raised Zombies have +5000 to maximum Life"]={{[1]={[1]={includeTransfigured=true,skillName="Raise Zombie",type="SkillName"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Life",type="BASE",value=5000}}}},nil} c["Rampage"]={{[1]={flags=0,keywordFlags=0,name="Condition:Rampage",type="FLAG",value=true}},nil} -c["Raven-Touched"]={nil,"Raven-Touched "} +c["Raven-Touched"]={{},nil} c["Recoup 5% of damage taken by your Totems as Life"]={nil,"Recoup 5% of damage taken by your Totems as Life "} c["Recoup 5% of damage taken by your Totems as Life Each Totem applies 2% increased Damage taken to Enemies in their Presence"]={nil,"Recoup 5% of damage taken by your Totems as Life Each Totem applies 2% increased Damage taken to Enemies in their Presence "} c["Recover 0.75% of maximum Life per Poison affecting Enemies you Kill"]={nil,"Recover 0.75% of maximum Life per Poison affecting Enemies you Kill "} @@ -10002,8 +10003,8 @@ c["being Shapeshifted for at least 8 seconds"]={nil,"being Shapeshifted for at l c["for 4 seconds, every 0.25 seconds while raised"]={nil,"for 4 seconds, every 0.25 seconds while raised "} c["gain 6 Cold Surges or 6 Fire Surges"]={{}," Cold Surges or 6 Fire Surges "} c["the enemy's Power for 20 seconds, up to a total of 500"]={nil,"the enemy's Power for 20 seconds, up to a total of 500 "} -c["their Explicit Modifiers are transformed into more powerful related Modifiers"]={nil,"their Explicit Modifiers are transformed into more powerful related Modifiers "} end)();(function() +c["their Explicit Modifiers are transformed into more powerful related Modifiers"]={nil,"their Explicit Modifiers are transformed into more powerful related Modifiers "} c["their Explicit Modifiers are transformed into more powerful related Modifiers Ignore Attribute Requirements to equip Gloves"]={nil,"their Explicit Modifiers are transformed into more powerful related Modifiers Ignore Attribute Requirements to equip Gloves "} c["until you take no Damage to Life for 3 seconds"]={nil,"until you take no Damage to Life for 3 seconds "} c["until you take no Damage to Life for 5 seconds"]={nil,"until you take no Damage to Life for 5 seconds "} diff --git a/src/Data/Uniques/body.lua b/src/Data/Uniques/body.lua index c8e7150f43..e9214b8e13 100644 --- a/src/Data/Uniques/body.lua +++ b/src/Data/Uniques/body.lua @@ -186,6 +186,7 @@ Grants Skill: Level (1-20) Mist Raven 100% increased Attribute Requirements Chance to Deflect is Lucky while on Low Life Enemies in your Presence gain 1 Gruelling Madness each second +Raven-Touched ]],[[ Briskwrap Rhoahide Coat diff --git a/src/Data/Uniques/gloves.lua b/src/Data/Uniques/gloves.lua index 0c7f29c08e..4df9023b9d 100644 --- a/src/Data/Uniques/gloves.lua +++ b/src/Data/Uniques/gloves.lua @@ -106,6 +106,7 @@ Grants Skill: Level (1-20) Crushing Fear +(13-23) to Dexterity Adds (19-23) to (31-37) Chaos Damage to Attacks Gain 1 Fear Incarnate when you Cull a target +Raven-Touched ]],[[ Idle Hands Sectioned Bracers diff --git a/src/Export/Uniques/body.lua b/src/Export/Uniques/body.lua index b195e64cb6..e067904d61 100644 --- a/src/Export/Uniques/body.lua +++ b/src/Export/Uniques/body.lua @@ -179,6 +179,7 @@ UniqueIncreasedLife57 UniqueReducedLocalAttributeRequirements6 UniqueDeflectChanceLuckyOnLowLife1 UniqueEnemiesInPresenceGainGruelingMadness1 +UniqueCanBeInstilled ]],[[ Briskwrap Rhoahide Coat diff --git a/src/Export/Uniques/gloves.lua b/src/Export/Uniques/gloves.lua index 97a01f172e..bae91e0c27 100644 --- a/src/Export/Uniques/gloves.lua +++ b/src/Export/Uniques/gloves.lua @@ -103,6 +103,7 @@ UniqueIncreasedAttackSpeed16 UniqueDexterity45 UniqueAddedChaosDamage5 UniqueGainFearIncarnateOnCulling1 +UniqueCanBeInstilled ]],[[ Idle Hands Sectioned Bracers diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index b9e0c14773..562774182a 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -1112,7 +1112,13 @@ function calcs.defence(env, actor) modDB:NewMod("EnergyShieldRecharge", "INC", m_floor(mod.value * multiplier), mod.source, mod.flags, mod.keywordFlags, unpack(modifiers)) end end - + if modDB:Flag(nil, "MovementSpeedAppliesToEnergyShieldRecharge") then + -- Jiquani's Thesis boots conversion + for i, value in ipairs(modDB:Tabulate("INC", {}, "MovementSpeed")) do + local mod = value.mod + modDB:NewMod("EnergyShieldRecharge", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + end + end if modDB:Flag(nil, "ManaRegenAppliesToEnergyShieldRecharge") then -- Mana Regen conversion from Waveshaper for i, value in ipairs(modDB:Tabulate("INC", { }, "ManaRegen")) do @@ -1120,7 +1126,13 @@ function calcs.defence(env, actor) modDB:NewMod("EnergyShieldRecharge", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) end end - + if modDB:Flag(nil, "LifeRegenAppliesToManaRegen") then + -- Life Regen conversion from Kurgal's Gaze + for i, value in ipairs(modDB:Tabulate("INC", {}, "LifeRegen")) do + local mod = value.mod + modDB:NewMod("ManaRegen", "INC", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + end + end if modDB:Flag(nil, "EnergyShieldIncreasedByOvercappedColdRes") then for i, value in ipairs(modDB:Tabulate("FLAG", nil, "EnergyShieldIncreasedByOvercappedColdRes")) do local mod = value.mod diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 6d8d909dcb..63b478bae9 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -814,6 +814,7 @@ local modNameList = { ["effect of chill on you"] = "SelfChillEffect", ["effect of freeze on you"] = "SelfFreezeEffect", ["effect of shock on you"] = "SelfShockEffect", + ["effect of non-damaging ailments on you"] = { "SelfChillEffect", "SelfFreezeEffect", "SelfShockEffect" }, ["effect of non-damaging ailments"] = { "EnemyShockMagnitude", "EnemyChillMagnitude", "EnemyFreezeBuildup" }, ["effect of non-damaging ailments you inflict"] = { "EnemyShockMagnitude", "EnemyChillMagnitude", "EnemyFreezeBuildup" }, ["magnitude of non-damaging ailments you inflict"] = { "EnemyShockMagnitude", "EnemyChillMagnitude", "EnemyFreezeBuildup" }, @@ -1120,6 +1121,7 @@ local modFlagList = { ["with hits from herald skills"] = { tag = { type = "SkillType", skillType = SkillType.Herald }, keywordFlags = KeywordFlag.Hit }, ["minion skills"] = { tag = { type = "SkillType", skillType = SkillType.Minion } }, ["of minion skills"] = { tag = { type = "SkillType", skillType = SkillType.Minion } }, + ["of command skills"] = { tag = { type = "Condition", var = "CommandableSkill" } }, ["of companion skills"] = { tag = { type = "SkillType", skillType = SkillType.CreatesCompanion } }, ["of non-companion skills"] = { tag = { type = "SkillType", skillType = SkillType.CreatesCompanion, neg = true } }, ["link skills"] = { tag = { type = "SkillType", skillType = SkillType.Link } }, @@ -1484,6 +1486,7 @@ local modTagList = { ["per (%d+)%% (%a+) effect on enemy"] = function(num, _, effectName) return { tag = { type = "Multiplier", var = firstToUpper(effectName) .. "Effect", div = num, actor = "enemy" } } end, ["per socketed rune or soul core"] = { tag = { type = "Multiplier", var = "RunesSocketedIn{SlotName}" } }, ["per socket filled"] = { tag = { type = "Multiplier", var = "RunesSocketedIn{SlotName}" } }, + ["per idol socketed in your equipment"] = { tag = { type = "Multiplier", var = "IdolsInEquipment", actor = "player" } }, ["per idol in your equipment"] = { tag = { type = "Multiplier", var = "IdolsInEquipment", actor = "player" } }, ["per non%-idol augment in your equipment"] = { tag = { type = "Multiplier", var = "NonIdolAugmentsInEquipment", actor = "player" } }, ["per (%d+) (%a+) support gems socketed"] = function(num, _, color) return { tag = { type = "Multiplier", var = firstToUpper(color) .. "SupportGems", div = num } } end, @@ -1611,6 +1614,7 @@ local modTagList = { ["equal to (%d+)%% of (y?o?u?r? ?) maximum mana"] = function(num) return { tag = { type = "PercentStat", stat = "Mana", percent = num } } end, ["equal to (%d+)%% of (i?t?e?m? ?)armour on equipped body armour"] = function(num) return { tag = { type = "PercentStat", stat = "ArmourOnBody Armour", percent = num } } end, ["per (%d+) spirit"] = function(num) return { tag = { type = "PerStat", stat = "Spirit", div = num } } end, + ["per (%d+) spirit, up to a maximum of (%d+)%%"] = function(num, _, limit) return { tag = { type = "PerStat", stat = "Spirit", div = num, limit = tonumber(limit), limitTotal = true } } end, ["per (%d+) unreserved darkness"] = function(num) return { tag = { type = "PerStat", stat = "UnreservedDarkness", div = num } } end, ["per (%d+) accuracy rating"] = function(num) return { tag = { type = "PerStat", stat = "Accuracy", div = num } } end, ["per (%d+) accuracy rating, up to (%d+)%%"] = function(num, _, limit) return { tag = { type = "PerStat", stat = "Accuracy", div = num, limit = tonumber(limit), limitTotal = true } } end, @@ -1623,6 +1627,7 @@ local modTagList = { ["per (%d+) maximum energy shield on equipped helmet"] = function(num) return { tag = { type = "PerStat", stat = "EnergyShieldOnHelmet", div = num } } end, ["per (%d+) (i?t?e?m? ?)energy shield on equipped helmet"] = function(num) return { tag = { type = "PerStat", stat = "EnergyShieldOnHelmet", div = num } } end, ["per (%d+) maximum energy shield on helmet"] = function(num) return { tag = { type = "PerStat", stat = "EnergyShieldOnHelmet", div = num } } end, + ["per (%d+) item evasion rating on equipped helmet"] = function(num) return { tag = { type = "PerStat", stat = "EvasionOnHelmet", div = num } } end, ["per (%d+) (i?t?e?m? ?)evasion rating on body armour"] = function(num) return { tag = { type = "PerStat", stat = "EvasionOnBody Armour", div = num } } end, ["per (%d+) (i?t?e?m? ?)evasion r?a?t?i?n?g? ?on equipped body armour"] = function(num) return { tag = { type = "PerStat", stat = "EvasionOnBody Armour", div = num } } end, ["for every (%d+) (i?t?e?m? ?)evasion rating on equipped body armour"] = function(num) return { tag = { type = "PerStat", stat = "EvasionOnBody Armour", div = num } } end, @@ -2252,6 +2257,7 @@ local function extraSupport(name, level, slot) end end +---@return Mod[] local explodeFunc = function(chance, amount, type, ...) local amountNumber = tonumber(amount) or (amount == "tenth" and 10) or (amount == "quarter" and 25) if not amountNumber then @@ -2268,7 +2274,7 @@ end -- forward declarations local dmgTypes -- List of special modifiers ----@type table +---@type table local specialModList = { -- Explode mods ["enemies you kill have a (%d+)%% chance to explode, dealing a (.+) of their maximum life as (.+) damage"] = function(chance, _, amount, type) -- Obliteration, Unspeakable Gifts (chaos cluster), synth implicit mod, current crusader body mod, Ngamahu Warmonger tattoo @@ -2515,6 +2521,7 @@ local specialModList = { mod("BleedChance", "BASE", 100, nil, bor(ModFlag.Attack, ModFlag.Projectile)), mod("EnemyKnockbackChance", "BASE", 100, nil, bor(ModFlag.Attack, ModFlag.Projectile)), }, + ["knocks enemies back on hit"] = {mod("EnemyKnockbackChance", "BASE", 100, KeywordFlag.Hit, nil)}, ["projectiles cannot pierce, fork or chain"] = { flag("CannotPierce", nil, ModFlag.Projectile), flag("CannotChain", nil, ModFlag.Projectile), @@ -2586,6 +2593,7 @@ local specialModList = { ["armour also applies to (%a+) damage"] = function(_, dmgType) return { mod("ArmourAppliesTo"..firstToUpper(dmgType).."DamageTaken", "BASE", 100) } end, ["%+?(%d+)%% of armour also applies to (%a+) damage taken from hits"] = function(num, _, dmgType) return { mod("ArmourAppliesTo"..firstToUpper(dmgType).."DamageTaken", "BASE", num) } end, ["%+?(%d+)%% of armour also applies to (%a+) damage"] = function(num, _, dmgType) return { mod("ArmourAppliesTo"..firstToUpper(dmgType).."DamageTaken", "BASE", num) } end, + ["%+?(%d+)%% of armour also applies to (%a+) damage while on full energy shield"] = function(num, _, dmgType) return { mod("ArmourAppliesTo" .. firstToUpper(dmgType) .. "DamageTaken", "BASE", num, { type = "Condition", var = "FullEnergyShield" }) } end, ["maximum damage reduction for any damage type is (%d+)%%"] = function(num) return { mod("DamageReductionMax", "MAX", num) } end, ["maximum (%a+) damage reduction is (%d+)%%"] = function(_, dmgType, numStr) return { mod(firstToUpper(dmgType) .. "DamageReductionMax", "MAX", tonumber(numStr)) } end, ["gain additional elemental damage reduction equal to half your chaos resistance"] = { @@ -2873,6 +2881,7 @@ local specialModList = { ["you have (%d+) fortification"] = function(num) return { mod("MinimumFortification", "BASE", num) } end, ["nearby allies count as having fortification equal to yours"] = { mod("ExtraAura", "LIST", { onlyAllies = true, mod = mod("YourFortifyEqualToParent", "FLAG", true, { type = "GlobalEffect", effectType = "Global", unscalable = true } ) }) }, ["enemies taunted by you cannot evade attacks"] = { mod("EnemyModifier", "LIST", { mod = flag("CannotEvade", { type = "Condition", var = "Taunted" }) }) }, + ["targets that are blinded, maimed, and bleeding cannot evade your hits"] = { mod("EnemyModifier", "LIST", { mod = flag("CannotEvade", { type = "ActorCondition", var = "Blinded" }, { type = "ActorCondition", var = "Maimed" }, { type = "ActorCondition", var = "Bleeding" }) }) }, ["if you've impaled an enemy recently, you and nearby allies have %+(%d+) to armour"] = function (num) return { mod("ExtraAura", "LIST", { mod = mod("Armour", "BASE", num) }, { type = "Condition", var = "ImpaledRecently" }) } end, ["your hits permanently intimidate enemies that are on full life"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Intimidated", { type = "Condition", var = "ChampionIntimidate" }) }) }, ["you and allies affected by your placed banners regenerate ([%d%.]+)%% of life per second for each stage"] = function(num) return { @@ -4546,6 +4555,7 @@ local specialModList = { ["abyssal wasting you inflict also prevents targets from inflicting elemental ailments"] = { mod("AbyssalWastingAlsoGrants", "LIST", { mod = mod("AvoidElementalAilments", "BASE", 100), unscalable = true, }), }, + ["hits against you have no critical damage bonus while on consecrated ground"] = {mod("ReduceCritExtraDamage", "BASE", 100, { type = "Condition", var = "OnConsecratedGround" })}, ["socketed skills apply fire, cold and lightning exposure on hit"] = { mod("FireExposureChance", "BASE", 100, { type = "Condition", var = "Effective" }), mod("ColdExposureChance", "BASE", 100, { type = "Condition", var = "Effective" }), @@ -4897,6 +4907,7 @@ local specialModList = { ["summoned skeleton warriors are permanent and follow you"] = { flag("RaisedSkeletonPermanentDuration", { type = "SkillName", skillName = "Summon Skeletons" }) }, ["minions recoup (%d+)%% of damage taken as life"] = function(num) return { mod("MinionModifier", "LIST", { mod = mod("LifeRecoup", "BASE", num) }) } end, ["temporary minion skills have %+(%d+) to limit of minions summoned"] = function(num) return { mod("ActiveMinionLimit", "BASE", num, { type = "BaseFlag", baseFlag = "duration", neg = true }) } end, + ["every five rage also grants you (%d+)%% increased movement speed"] = function(num) return {mod("MovementSpeed", "INC", num, { type = "PerStat", stat = "Rage", div = 5 })} end, ["every rage also grants you (%d+)%% increased minion damage"] = function(num) return { mod("MinionModifier", "LIST", { mod = mod("Damage", "INC", num, { type = "Multiplier", var = "RageEffect", actor = "player" }) }), } end, @@ -6011,6 +6022,7 @@ local specialModList = { ["you have consecrated ground around you while stationary if strength is your highest attribute"] = { flag("Condition:OnConsecratedGround", { type = "Condition", var = "StrHighestAttribute" }, { type = "Condition", var = "Stationary" }), }, + ["enemies have no critical damage bonus for %d+ seconds after you blind them"] = {mod("ReduceCritExtraDamage", "BASE", 100, {type = "ActorCondition", actor = "enemy", var = "Blinded"})}, ["you count as dual wielding while you are unencumbered"] = { flag("Condition:DualWielding", { type = "Condition", var = "Unencumbered" }) }, ["can attack as though using a quarterstaff while both of your hand slots are empty unarmed attacks that would use your quarterstaff's damage gain: physical damage based on their skill level (%d+)%% more attack speed per (%d+) item evasion rating on equipped armour items %+(%d+%.?%d*)%% to critical hit chance per (%d+) item energy shield on equipped armour items"] = function(asNum, _, evNum, critNum, esNum) return { mod("Speed", "MORE", tonumber(asNum), nil, ModFlag.Attack, { type = "Condition", var = "HollowPalm" }, { type = "PerStat", stat = "EvasionOnAllArmourItems", div = tonumber(evNum) }), @@ -6140,6 +6152,17 @@ local specialModList = { ["flamethrower, seismic and lightning spire trap have (%d+)%% increased cooldown recovery rate"] = function(num) return { mod("CooldownRecovery", "INC", num, { type = "SkillName", skillNameList = { "Flamethrower Trap", "Seismic Trap", "Lightning Spire Trap" }, includeTransfigured = true }) } end, ["flamethrower, seismic and lightning spire trap have %-(%d+) cooldown uses?"] = function(num) return { mod("AdditionalCooldownUses", "BASE", -num, { type = "SkillName", skillNameList = { "Flamethrower Trap", "Seismic Trap", "Lightning Spire Trap" }, includeTransfigured = true }) } end, ["skills have %+(%d+) to limit"] = function(num) return { mod("AdditionalCooldownUses", "BASE", num) } end, + ["(%a+) skills have %+(%d+) to limit"] = function(_, skillTypeMaybe, num) + local skillTypeMap = { + storm = "Storm", + fissure = "CreatesFissure", + orb = "Orb", + } + local skillType = SkillType?.[skillTypeMap[skillTypeMaybe]] + if skillType then + return { mod("AdditionalCooldownUses", "BASE", num, { type = "SkillType", skillType = skillType }) } + else return nil end + end, ["flameblast starts with (%d+) additional stages"] = function(num) return { mod("Multiplier:FlameblastMinimumStage", "BASE", num, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }) } end, ["incinerate starts with (%d+) additional stages"] = function(num) return { mod("Multiplier:IncinerateMinimumStage", "BASE", num, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }) } end, ["%+([%d%.]+) seconds to flameblast and incinerate cooldown"] = function(num) return { @@ -6242,6 +6265,8 @@ local specialModList = { ["%+(%d+) to maximum snipe stages"] = function(num) return { mod("Multiplier:SnipeStagesMax", "BASE", num, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }) } end, ["chain hook has %+([%d%.]+) metres? to radius per (%d+) rage"] = function(num, _, rage) return { mod("AreaOfEffect", "BASE", num * 10, { type = "PerStat", stat = "Rage", div = tonumber(rage) }, { type = "SkillName", skillName = "Chain Hook", includeTransfigured = true }) } end, ["%+([%d%.]+) metres? to discharge radius"] = function(num) return { mod("AreaOfEffect", "BASE", num * 10, { type = "SkillName", skillName = "Discharge", includeTransfigured = true }) } end, + ["increases and reductions to life regeneration rate also apply to mana regeneration rate"] = { flag("LifeRegenAppliesToManaRegen") }, + ["increases and reductions to movement speed also apply to energy shield recharge rate"] = { flag("MovementSpeedAppliesToEnergyShieldRecharge") }, -- Alternate Quality ["quality does not increase physical damage"] = { mod("AlternateQualityWeapon", "BASE", 1) }, ["(%d+)%% increased critical hit chance per 4%% quality"] = function(num) return { mod("AlternateQualityLocalCritChancePer4Quality", "INC", num) } end, @@ -6328,6 +6353,7 @@ local specialModList = { ["(%d+) body armour sockets?"] = {}, ["(%d+) gloves sockets?"] = {}, ["(%d+) boots sockets?"] = {}, + ["raven%-touched"] = {}, } for _, name in pairs(data.keystones) do specialModList[name:lower()] = { mod("Keystone", "LIST", name), flag("Condition:Have"..firstToUpper(name):gsub(" %l", string.upper):gsub(" ", "")) }