From ef8ba51e26837997387a350da3cecef1618b1184 Mon Sep 17 00:00:00 2001 From: unrealdreamz Date: Fri, 22 May 2026 15:21:29 +0000 Subject: [PATCH 1/4] Apply changes from https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/pull/1929 --- spec/Fixtures/issue1754_block_ehp.xml | 796 +++++++++++++++++++++++++ spec/System/TestDefence_spec.lua | 64 ++ spec/System/TestDefence_spec.lua.rej | 28 + spec/System/TestItemParse_spec.lua.rej | 24 + src/Data/ModCache.lua.rej | 89 +++ src/Modules/CalcDefence.lua | 1 + src/Modules/CalcDefence.lua.rej | 31 + 7 files changed, 1033 insertions(+) create mode 100644 spec/Fixtures/issue1754_block_ehp.xml create mode 100644 spec/System/TestDefence_spec.lua.rej create mode 100644 spec/System/TestItemParse_spec.lua.rej create mode 100644 src/Data/ModCache.lua.rej create mode 100644 src/Modules/CalcDefence.lua.rej diff --git a/spec/Fixtures/issue1754_block_ehp.xml b/spec/Fixtures/issue1754_block_ehp.xml new file mode 100644 index 00000000000..25f4298c63d --- /dev/null +++ b/spec/Fixtures/issue1754_block_ehp.xml @@ -0,0 +1,796 @@ + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + https://www.pathofexile.com/passive-skill-tree/AAAABgIBmLOoS-B_NJGKbCdclipOP9vFgWhlumpKQ4WadaMPYOFndqMZgWxOGXJISbq0Jhb710aZbpD4W2rtFgrJ6lMmjBfMleSg7Nq7hs48U4uSjxwyHiT562uU01NjHsudsTO7jpqu11u3nmdF0J0_KE9-axrZ-s1MlmUEsLAix7koetQKECBG7QsfgxSMu2_FO48BbNNvmSf31deWjCRhMA12mKu2W4f9CzAeKZGcBJEPlG4PJaZorn6ggqzrKw5MD232igVIcwdIxW9-r5hpyqR_wIVyi8p4aqAJuy4KlPLfbNPYZdZGT2nkKhbJabT1ZBOopqic1iLpgSEt-xzWG9ixI8v0sDtO9CIWTti2z8pBVYJZ6YnoxUKFgu7R12fIMILKFHqNgNAu4EKV9f1g5xTUs5EAAA== + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Rarity: RARE +Chimeric Sliver +Ruby +Unique ID: 3f2a054bb6d41d7fe0d14122cc3d55f5b9055285249b5bf81d740ad1d59b6136 +Item Level: 80 +LevelReq: 0 +Implicits: 0 +18% increased Armour +14% increased Attack Damage +19% increased Warcry Speed +{desecrated}2% increased Strength + + + + + + + Rarity: RARE +Loath Wound +Time-Lost Ruby +Unique ID: 79ae21e9e5c5904ecda572dff79ab1d719eac798e1d9cfb35975a9116d915bc5 +Item Level: 78 +LevelReq: 0 +Radius: Medium +Implicits: 0 +Upgrades Radius to Medium +25% increased Effect of Notable Passive Skills in Radius +25% increased Effect of Small Passive Skills in Radius + + + + + + Rarity: UNIQUE +From Nothing +Diamond +Unique ID: 60219c236ed8e1330ab16b8919afb429b870bc28c23e445c4da72a8d0b22b76c +Item Level: 84 +LevelReq: 0 +Radius: Small +Limited to: 1 +Implicits: 0 +Passives in Radius of Resolute Technique can be Allocated +without being connected to your tree +Corrupted + + + + Rarity: RARE +Ghoul Sole +Tasalian Greaves +Armour: 432 +Unique ID: 816f7b3213e27a3f552b294e0066bcb695b3c7a2075c16a000c1cd456ab4311c +Item Level: 82 +Quality: 20 +Sockets: S S +Rune: Soul Core of Tacati +Rune: Soul Core of Tacati +LevelReq: 80 +Implicits: 1 +{enchant}{rune}+22% to Chaos Resistance ++123 to Armour ++110 to maximum Life ++31% to Fire Resistance ++30% to Lightning Resistance ++32% of Armour also applies to Elemental Damage +{desecrated}35% increased Movement Speed +Corrupted + + + + + + + + + + Rarity: RARE +Torment Touch +Vaal Mitts +Armour: 485 +Unique ID: ec3d3e1408f66406a34cc183c6ffb0a87025355c3295bc90ab8be9f8d32c539e +Item Level: 79 +Quality: 20 +Sockets: S +Rune: Idol of Grold +LevelReq: 75 +Implicits: 2 +{enchant}{rune}32% increased total Power counted by Warcries +{enchant}{rune}Bonded: 32% increased Glory generation +36% increased Armour ++156 to maximum Life ++2 to Level of all Melee Skills ++42% of Armour also applies to Elemental Damage +60% increased effect of Socketed Items +{desecrated}+151 to Armour + + + + + + + + + + + Rarity: NORMAL +Evasive Leg +Unique ID: ef550b724c26f2472f48418e92bafea5c8c4a804a960cc7b09066163fba3e44e +Item Level: 99 +LevelReq: 0 +Implicits: 1 +20% increased Evasion Rating + + + + Rarity: NORMAL +Combat Arm +Unique ID: f36295e737b0e7d2e531713f8153dd41e79d029fb6591afd25302dd9f630b099 +Item Level: 99 +LevelReq: 0 +Implicits: 1 +10% increased Attack Speed + + + + Rarity: NORMAL +Guarding Arm +Unique ID: 8a1cb54bc4dfaba7a8cbdc7046e0726011a7a0424d8db8d9e9560e694079f61f +Item Level: 99 +LevelReq: 0 +Implicits: 1 +10% increased Block chance + + + + Rarity: MAGIC +Experimenter's Staunching Charm of the Bountiful +Unique ID: 7b7a2820b483555344ef9156b5dffceebb5dc44774c9109af7f472a6d9a518f8 +Item Level: 81 +Quality: 17 +LevelReq: 18 +Implicits: 1 +Used when you start Bleeding +36% increased Duration +53% increased Charges + + + + + Rarity: UNIQUE +Rite of Passage +Golden Charm +Unique ID: 897c5364a769621daab36f5fcee7e3a3264b236f7cceac264eb9f37546caf810 +Item Level: 81 +Quality: 0 +LevelReq: 50 +Implicits: 1 +Used when you kill a Rare or Unique enemy +Possessed by Spirit Of The Ox for 20 seconds on use + + + Rarity: RARE +Phoenix Bind +Plate Belt +Charm Slots: 2 +Unique ID: 430b1c0f872adfb91474657f630483dbeb06359ccc10a3de78d59f9dc469c3b4 +Item Level: 79 +LevelReq: 24 +Implicits: 2 ++121 to Armour +Has 2 Charm Slots ++142 to Armour ++169 to maximum Life ++123 to maximum Mana ++26 to Strength ++39% to Cold Resistance +{desecrated}+17% to Fire and Chaos Resistances + + + + + + + + + + + Rarity: RARE +Phoenix Pendant +Pearlescent Amulet +Unique ID: f3ab9699d86ffae4a2943e4aab99607bce30d6ae9bdb0ef28b51e1d9eab928ca +Item Level: 78 +LevelReq: 30 +Implicits: 2 +{enchant}Allocates Reinforced Barrier ++10% to all Elemental Resistances ++175 to maximum Life +9% increased maximum Life ++33 to Strength ++32% to Fire Resistance ++29% to Cold Resistance +{desecrated}34% increased Armour + + + + + + + + + + + Rarity: MAGIC +Substantial Ultimate Mana Flask of the Abundant +Unique ID: 2f3e029b0a0e34fc09b8f199f1617aab732678e3f4058ac2b4ab858a14607528 +Item Level: 80 +Quality: 10 +LevelReq: 60 +Implicits: 0 +62% increased Amount Recovered +57% increased Charges + + + + + Rarity: RARE +Onslaught Crest +Imperial Greathelm +Armour: 1269 +Unique ID: 26849265030f23ddccb3e1ddd940f30695811b039ce53ac28c6086af7ca9e2a4 +Item Level: 83 +Quality: 30 +Sockets: S +Rune: Soul Core of Tacati +LevelReq: 80 +Implicits: 1 +{enchant}{rune}+11% to Chaos Resistance ++195 to Armour +91% increased Armour ++174 to maximum Life ++29 to Strength ++29% to Cold Resistance +{desecrated}+29% of Armour also applies to Chaos Damage +Corrupted + + + + + + + + + + Rarity: MAGIC +Seething Ultimate Life Flask of the Brewer +Unique ID: 2375dec92a0147d9ea02dc37bc7f94fb4a993d0886a056c1507e2e836eea3934 +Item Level: 79 +Quality: 22 +LevelReq: 60 +Implicits: 0 +50% reduced Amount Recovered +Instant Recovery +29% reduced Charges per use + + + + + + Rarity: RARE +Armageddon Shatter +Structured Hammer +Unique ID: 0ad6ea8224a123ac010f9c13bee9c7ae415c70fd127db1c79aa110449e0eb4e5 +Item Level: 82 +Quality: 20 +Sockets: S +Rune: Farrul's Rune of the Hunt +LevelReq: 62 +Implicits: 3 +{enchant}{rune}50% increased Attack Damage against Rare or Unique Enemies +{enchant}{rune}Bonded: +1 to Level of all Attack Skills +40% chance to Daze on Hit +Adds 11 to 19 Physical Damage +96% increased Elemental Damage with Attacks ++5 to Level of all Melee Skills ++26 to Strength +Gain 20% of Damage as Extra Physical Damage +{desecrated}Break Armour equal to 4% of Physical Damage dealt + + + + + + + + + + + Rarity: RARE +Carrion Span +Tawhoan Tower Shield +Armour: 1215 +Unique ID: 2957b34aa214fbdc6d0b652646718c039598d898641ffb48e728d0266aa3343f +Item Level: 80 +Quality: 20 +Sockets: S S +Rune: Greater Iron Rune +Rune: Greater Iron Rune +LevelReq: 80 +Implicits: 4 +{enchant}{rune}36% increased Armour, Evasion and Energy Shield +{enchant}{rune}Bonded: +20 to maximum Life +{enchant}{rune}Bonded: +20 to maximum Mana +Grants Skill: Raise Shield ++253 to Armour +89% increased Armour ++185 to maximum Life ++31 to Strength +8% additional Physical Damage Reduction ++28% to Cold Resistance +Corrupted + + + + + + + + + + + + + Rarity: MAGIC +Experimenter's Grounding Charm of the Ample +Unique ID: 4a9b1924da5c16f078735bbea50effa0b1a2ed71596e0ddf13ead3596c58fc35 +Item Level: 81 +Quality: 0 +LevelReq: 32 +Implicits: 1 +Used when you become Shocked +38% increased Duration +69% increased Charges + + + + + Rarity: RARE +Demon Grip +Amethyst Ring +Unique ID: 3a9a4bc4c6c7bf6c851d9e3465e170235570e40f8d701c4bbd68eb17f54bc0e1 +Item Level: 80 +LevelReq: 20 +Implicits: 1 ++11% to Chaos Resistance ++199 to Evasion Rating ++172 to maximum Mana ++29 to Strength ++34% to Lightning Resistance +Leech 6.34% of Physical Attack Damage as Mana +{desecrated}+115 to maximum Life + + + + + + + + + + Rarity: RARE +Pain Shelter +Soldier Cuirass +Armour: 2031 +Unique ID: c1272d9098b999d72429ccdf1fe25c25781e51c8b2d9392ca792f7a41c8ab87e +Item Level: 79 +Quality: 24 +Sockets: S S +Rune: The Greatwolf's Rune of Willpower +Rune: Craiceann's Rune of Warding +LevelReq: 65 +Implicits: 4 +{enchant}{rune}50% reduced effect of Curses on you +{enchant}{rune}15% of Damage is taken from Mana before Life +{enchant}{rune}Bonded: 8% increased Curse Magnitudes +{enchant}{rune}Bonded: 8% of Maximum Life Converted to Energy Shield ++265 to Armour +105% increased Armour +10% increased maximum Life +Hits against you have 47% reduced Critical Damage Bonus ++30% to Lightning Resistance +{desecrated}+43% of Armour also applies to Elemental Damage +Corrupted + + + + + + + + + + + + + Rarity: NORMAL +Evasive Leg +Unique ID: 1170f441dfecf0cfa4c4f7b19833710477ff62ac3fb66c2c1c658daa1f097ccf +Item Level: 99 +LevelReq: 0 +Implicits: 1 +30% increased Evasion Rating + + + + Rarity: RARE +Kraken Hold +Prismatic Ring +Unique ID: 5942bb3b406d8bb45907c9efb803bc7c1e516064294f1739977e1d4f5fcb112c +Item Level: 80 +LevelReq: 35 +Implicits: 1 ++12% to all Elemental Resistances ++164 to Evasion Rating ++116 to maximum Life ++156 to maximum Mana ++35% to Fire Resistance +Leech 7.39% of Physical Attack Damage as Life +{desecrated}+20% to Lightning and Chaos Resistances + + + + + + + + + + Rarity: UNIQUE +Carrion Span +Tawhoan Tower Shield +Armour: 1215 +Unique ID: 2957b34aa214fbdc6d0b652646718c039598d898641ffb48e728d0266aa3343f +Item Level: 80 +Quality: 20 +Sockets: S S +Rune: Greater Iron Rune +Rune: Greater Iron Rune +LevelReq: 80 +Implicits: 4 +{enchant}{rune}36% increased Armour, Evasion and Energy Shield +{enchant}{rune}Bonded: +20 to maximum Life +{enchant}{rune}Bonded: +20 to maximum Mana +Grants Skill: Raise Shield ++253 to Armour +89% increased Armour ++185 to maximum Life ++31 to Strength ++28% to Cold Resistance +Corrupted + + + + + + + + + + + + Rarity: UNIQUE +Undying Hate +Timeless Jewel +Variant: Amanamu +Variant: Kulemak +Variant: Kurgal +Variant: Tecrod +Variant: Ulaman +Selected Variant: 1 +LevelReq: 0 +Radius: Very Large +Limited to: 1 +Implicits: 0 +{variant:1}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Amanamu +{variant:2}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Kulemak +{variant:3}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Kurgal +{variant:4}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Tecrod +{variant:5}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Ulaman +Passives in radius are Conquered by the Abyssals +Historic + + + + + + + + + + Rarity: UNIQUE +Pain Shelter +Soldier Cuirass +Armour: 2031 +Unique ID: c1272d9098b999d72429ccdf1fe25c25781e51c8b2d9392ca792f7a41c8ab87e +Item Level: 79 +Quality: 24 +Sockets: S S +Rune: The Greatwolf's Rune of Willpower +Rune: Craiceann's Rune of Warding +LevelReq: 65 +Implicits: 4 +{enchant}{rune}50% reduced effect of Curses on you +{enchant}{rune}Bonded: 8% increased Curse Magnitudes +{enchant}{rune}Bonded: 8% of Maximum Life Converted to Energy Shield ++265 to Armour +105% increased Armour +10% increased maximum Life +Hits against you have 47% reduced Critical Damage Bonus ++30% to Lightning Resistance +{desecrated}+43% of Armour also applies to Elemental Damage +Corrupted + + + + + + + + + + + + Rarity: UNIQUE +Torment Touch +Vaal Mitts +Armour: 485 +Unique ID: ec3d3e1408f66406a34cc183c6ffb0a87025355c3295bc90ab8be9f8d32c539e +Item Level: 79 +Quality: 20 +Sockets: S +Rune: Idol of Grold +LevelReq: 75 +Implicits: 2 +{enchant}{rune}32% increased total Power counted by Warcries +{enchant}{rune}Bonded: 32% increased Glory generation +36% increased Armour ++156 to maximum Life ++2 to Level of all Melee Skills ++42% of Armour also applies to Elemental Damage ++170 to mana +{desecrated}+151 to Armour + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/System/TestDefence_spec.lua b/spec/System/TestDefence_spec.lua index f7df77a0567..16a16ce4b68 100644 --- a/spec/System/TestDefence_spec.lua +++ b/spec/System/TestDefence_spec.lua @@ -1283,4 +1283,68 @@ describe("TestDefence", function() assert.are.equals(0, floor(poolsRemaining.Life)) assert.are.equals(0, floor(poolsRemaining.OverkillDamage)) end) + + it("uses block chance against projectile spells", function() + build.configTab.input.enemyIsBoss = "None" + build.configTab.input.enemyDamageType = "SpellProjectile" + build.configTab.input.customMods = [[ + 20% chance to block + ]] + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveBlockChance) + assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveProjectileBlockChance) + assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveSpellProjectileBlockChance) + assert.are.equals(80, build.calcsTab.calcsOutput.ConfiguredDamageChance) + + build.configTab.input.enemyDamageType = "Average" + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(15, build.calcsTab.calcsOutput.EffectiveAverageBlockChance) + assert.are.equals(85, build.calcsTab.calcsOutput.ConfiguredDamageChance) + end) + + it("limits EHP speedup when hit damage is delayed", function() + local function assertClose(actual, expected) + assert.is_true(math.abs(actual - expected) < 0.01) + end + + local function calcEHP(extraMods) + newBuild() + build.configTab.input.enemyPhysicalDamage = "1000" + build.configTab.input.enemyFireDamage = "1000" + build.configTab.input.enemyColdDamage = "1000" + build.configTab.input.enemyLightningDamage = "1000" + build.configTab.input.enemyChaosDamage = "0" + build.configTab.input.customMods = [[ ++4000 to maximum Life ++4000 to maximum Mana +75% of Damage is taken from Mana before Life +25% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead ++75% to all Elemental Resistances ++75% to Chaos Resistance +]] .. (extraMods or "") + build.configTab:BuildModList() + runCallback("OnFrame") + runCallback("OnFrame") + local calcsOutput = build.calcsTab.calcsOutput + return { + TotalEHP = calcsOutput.TotalEHP, + EffectiveBlockChance = calcsOutput.EffectiveBlockChance, + NumberOfMitigatedDamagingHits = calcsOutput.NumberOfMitigatedDamagingHits, + } + end + + local base = calcEHP() + local block = calcEHP("\n+10% to Block chance\n") + + newBuild() + + assertClose(base.TotalEHP, 17582.417582418) + assertClose(block.TotalEHP, 19008.019008019) + assertClose(block.EffectiveBlockChance, 10) + assert.is_true(block.TotalEHP > base.TotalEHP) + end) end) diff --git a/spec/System/TestDefence_spec.lua.rej b/spec/System/TestDefence_spec.lua.rej new file mode 100644 index 00000000000..744786a97c8 --- /dev/null +++ b/spec/System/TestDefence_spec.lua.rej @@ -0,0 +1,28 @@ +diff a/spec/System/TestDefence_spec.lua b/spec/System/TestDefence_spec.lua (rejected hunks) +@@ -557,20 +557,18 @@ describe("TestDefence", function() + + local function calcEHP(extraMods) + newBuild() +- build.configTab.input.enemyPhysicalDamage = "1000" +- build.configTab.input.enemyFireDamage = "1000" +- build.configTab.input.enemyColdDamage = "1000" +- build.configTab.input.enemyLightningDamage = "1000" ++ build.configTab.input.enemyPhysicalDamage = "500" ++ build.configTab.input.enemyFireDamage = "500" ++ build.configTab.input.enemyColdDamage = "500" ++ build.configTab.input.enemyLightningDamage = "500" + build.configTab.input.enemyChaosDamage = "0" + build.configTab.input.customMods = [[ + +4000 to maximum Life +- +4000 to maximum Mana +- 75% of Damage is taken from Mana before Life +- 25% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead ++ 75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead + +75% to all Elemental Resistances + +75% to Chaos Resistance + ]] .. (extraMods or "") +- build.configTab:BuildModList() ++ pob1and2Compat() + runCallback("OnFrame") + runCallback("OnFrame") + local calcsOutput = build.calcsTab.calcsOutput diff --git a/spec/System/TestItemParse_spec.lua.rej b/spec/System/TestItemParse_spec.lua.rej new file mode 100644 index 00000000000..de9206ca0af --- /dev/null +++ b/spec/System/TestItemParse_spec.lua.rej @@ -0,0 +1,24 @@ +diff a/spec/System/TestItemParse_spec.lua b/spec/System/TestItemParse_spec.lua (rejected hunks) +@@ -142,22 +142,6 @@ describe("TestItemParse", function() + assert.are.equals("Adds 39 to 62 Fire Damage", item.explicitModLines[1].line) + end) + +- it("Pasted variable-level base granted skills parse at exact exported levels", function() +- local cases = { +- { base = "Bone Wand", line = "Grants Skill: Level 11 Bone Blast", skillId = "BoneBlastPlayer", level = 11 }, +- { base = "Withered Wand", line = "Grants Skill: Level 20 Chaos Bolt", skillId = "WeaponGrantedChaosboltPlayer", level = 20 }, +- { base = "Stoic Sceptre", line = "Grants Skill: Level 20 Discipline", skillId = "DisciplinePlayer", level = 20 }, +- } +- +- for _, case in ipairs(cases) do +- local item = new("Item", "Rarity: Normal\n" .. case.base .. "\nImplicits: 1\n" .. case.line) +- +- assert.are.equals(1, #item.grantedSkills) +- assert.are.equals(case.skillId, item.grantedSkills[1].skillId) +- assert.are.equals(case.level, item.grantedSkills[1].level) +- end +- end) +- + --TODO: POB2 Leagues? + --it("League", function() + --end) diff --git a/src/Data/ModCache.lua.rej b/src/Data/ModCache.lua.rej new file mode 100644 index 00000000000..3514176b95b --- /dev/null +++ b/src/Data/ModCache.lua.rej @@ -0,0 +1,89 @@ +diff a/src/Data/ModCache.lua b/src/Data/ModCache.lua (rejected hunks) +@@ -5146,13 +5146,20 @@ c["Grants Skill: Kelari's Malediction"]={{[1]={flags=0,keywordFlags=0,name="Extr + c["Grants Skill: Kelari, the Tainted Sands"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="SummonSandDjinnPlayer"}}},nil} + c["Grants Skill: Level 11 Black Powder Blitz"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BlackPowderBlitzReservationPlayer"}}},nil} + c["Grants Skill: Level 11 Blink"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BlinkReservationPlayer"}}},nil} ++c["Grants Skill: Level 11 Bone Blast"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BoneBlastPlayer"}}},nil} + c["Grants Skill: Level 11 Bursting Fen Toad"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ExplodingPoisonToadPlayer"}}},nil} ++c["Grants Skill: Level 11 Chaos Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="WeaponGrantedChaosboltPlayer"}}},nil} + c["Grants Skill: Level 11 Compose Requiem"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CrossbowRequiemAmmoPlayer"}}},nil} + c["Grants Skill: Level 11 Crackling Palm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CracklingPalmPlayer"}}},nil} + c["Grants Skill: Level 11 Decompose"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CorpseCloudPlayer"}}},nil} ++c["Grants Skill: Level 11 Discipline"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="DisciplinePlayer"}}},nil} + c["Grants Skill: Level 11 Ember Fusillade"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="EmberFusilladePlayer"}}},nil} ++c["Grants Skill: Level 11 Feast of Flesh"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FeastOfFleshPlayer"}}},nil} ++c["Grants Skill: Level 11 Firebolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FireboltPlayer"}}},nil} ++c["Grants Skill: Level 11 Freezing Shards"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FreezingShardsPlayer"}}},nil} + c["Grants Skill: Level 11 Future-Past"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FuturePastPlayer"}}},nil} + c["Grants Skill: Level 11 Gemini Surge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="GeminiSurgePlayer"}}},nil} ++c["Grants Skill: Level 11 Heart of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeartOfIcePlayer"}}},nil} + c["Grants Skill: Level 11 Herald of Ash"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfAshPlayer"}}},nil} + c["Grants Skill: Level 11 Herald of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfIcePlayer"}}},nil} + c["Grants Skill: Level 11 Herald of Thunder"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfThunderPlayer"}}},nil} +@@ -5160,26 +5167,42 @@ c["Grants Skill: Level 11 Icestorm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSk + c["Grants Skill: Level 11 Impurity"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ImpurityPlayer"}}},nil} + c["Grants Skill: Level 11 Lightning Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="UniqueBreachLightningBoltPlayer"}}},nil} + c["Grants Skill: Level 11 Living Bomb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="LivingBombPlayer"}}},nil} ++c["Grants Skill: Level 11 Malice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="MalicePlayer"}}},nil} ++c["Grants Skill: Level 11 Mana Drain"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ManaDrainPlayer"}}},nil} ++c["Grants Skill: Level 11 Parry"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ParryPlayer"}}},nil} + c["Grants Skill: Level 11 Phantasmal Arrow"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PhantasmalArrowPlayer"}}},nil} ++c["Grants Skill: Level 11 Power Siphon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PowerSiphonPlayer"}}},nil} + c["Grants Skill: Level 11 Purity of Fire"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfFirePlayer"}}},nil} + c["Grants Skill: Level 11 Purity of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfIcePlayer"}}},nil} + c["Grants Skill: Level 11 Purity of Lightning"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfLightningPlayer"}}},nil} ++c["Grants Skill: Level 11 Raise Shield"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ShieldBlockPlayer"}}},nil} ++c["Grants Skill: Level 11 Sigil of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SigilOfPowerPlayer"}}},nil} ++c["Grants Skill: Level 11 Skeletal Warrior Minion"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SummonSkeletalWarriorsPlayer"}}},nil} ++c["Grants Skill: Level 11 Solar Orb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SolarOrbPlayer"}}},nil} + c["Grants Skill: Level 11 Spark"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SparkPlayer"}}},nil} + c["Grants Skill: Level 11 Thundergod's Wrath"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="MetaCastLightningSpellOnHitPlayer"}}},nil} + c["Grants Skill: Level 11 Valako's Charge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ValakosChargePlayer"}}},nil} ++c["Grants Skill: Level 11 Volatile Dead"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="VolatileDeadPlayer"}}},nil} + c["Grants Skill: Level 11 Withering Presence"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="WitheringPresencePlayer"}}},nil} + c["Grants Skill: Level 14 Life Remnants"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=14,skillId="LifeRemnantsPlayer"}}},nil} + c["Grants Skill: Level 20 Black Powder Blitz"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BlackPowderBlitzReservationPlayer"}}},nil} + c["Grants Skill: Level 20 Blink"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BlinkReservationPlayer"}}},nil} ++c["Grants Skill: Level 20 Bone Blast"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BoneBlastPlayer"}}},nil} + c["Grants Skill: Level 20 Bursting Fen Toad"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ExplodingPoisonToadPlayer"}}},nil} ++c["Grants Skill: Level 20 Chaos Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="WeaponGrantedChaosboltPlayer"}}},nil} + c["Grants Skill: Level 20 Chaotic Infusion"]={nil,nil} + c["Grants Skill: Level 20 Chaotic Infusion 20% increased Attack Speed"]={nil,nil} + c["Grants Skill: Level 20 Compose Requiem"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CrossbowRequiemAmmoPlayer"}}},nil} + c["Grants Skill: Level 20 Crackling Palm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CracklingPalmPlayer"}}},nil} + c["Grants Skill: Level 20 Decompose"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CorpseCloudPlayer"}}},nil} ++c["Grants Skill: Level 20 Discipline"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="DisciplinePlayer"}}},nil} + c["Grants Skill: Level 20 Ember Fusillade"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="EmberFusilladePlayer"}}},nil} ++c["Grants Skill: Level 20 Feast of Flesh"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FeastOfFleshPlayer"}}},nil} ++c["Grants Skill: Level 20 Firebolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FireboltPlayer"}}},nil} ++c["Grants Skill: Level 20 Freezing Shards"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FreezingShardsPlayer"}}},nil} + c["Grants Skill: Level 20 Future-Past"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FuturePastPlayer"}}},nil} + c["Grants Skill: Level 20 Gemini Surge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="GeminiSurgePlayer"}}},nil} ++c["Grants Skill: Level 20 Heart of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeartOfIcePlayer"}}},nil} + c["Grants Skill: Level 20 Herald of Ash"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfAshPlayer"}}},nil} + c["Grants Skill: Level 20 Herald of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfIcePlayer"}}},nil} + c["Grants Skill: Level 20 Herald of Thunder"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfThunderPlayer"}}},nil} +@@ -5195,14 +5218,23 @@ c["Grants Skill: Level 20 Icestorm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSk + c["Grants Skill: Level 20 Impurity"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ImpurityPlayer"}}},nil} + c["Grants Skill: Level 20 Lightning Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="UniqueBreachLightningBoltPlayer"}}},nil} + c["Grants Skill: Level 20 Living Bomb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="LivingBombPlayer"}}},nil} ++c["Grants Skill: Level 20 Malice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="MalicePlayer"}}},nil} ++c["Grants Skill: Level 20 Mana Drain"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ManaDrainPlayer"}}},nil} ++c["Grants Skill: Level 20 Parry"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ParryPlayer"}}},nil} + c["Grants Skill: Level 20 Phantasmal Arrow"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PhantasmalArrowPlayer"}}},nil} + c["Grants Skill: Level 20 Pinnacle of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PinnacleOfPowerPlayer"}}},nil} ++c["Grants Skill: Level 20 Power Siphon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PowerSiphonPlayer"}}},nil} + c["Grants Skill: Level 20 Purity of Fire"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfFirePlayer"}}},nil} + c["Grants Skill: Level 20 Purity of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfIcePlayer"}}},nil} + c["Grants Skill: Level 20 Purity of Lightning"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfLightningPlayer"}}},nil} ++c["Grants Skill: Level 20 Raise Shield"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ShieldBlockPlayer"}}},nil} ++c["Grants Skill: Level 20 Sigil of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SigilOfPowerPlayer"}}},nil} ++c["Grants Skill: Level 20 Skeletal Warrior Minion"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SummonSkeletalWarriorsPlayer"}}},nil} ++c["Grants Skill: Level 20 Solar Orb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SolarOrbPlayer"}}},nil} + c["Grants Skill: Level 20 Spark"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SparkPlayer"}}},nil} + c["Grants Skill: Level 20 Thundergod's Wrath"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="MetaCastLightningSpellOnHitPlayer"}}},nil} + c["Grants Skill: Level 20 Valako's Charge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ValakosChargePlayer"}}},nil} ++c["Grants Skill: Level 20 Volatile Dead"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="VolatileDeadPlayer"}}},nil} + c["Grants Skill: Level 20 Withering Presence"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="WitheringPresencePlayer"}}},nil} + c["Grants Skill: Life Remnants"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="LifeRemnantsPlayer"}}},nil} + c["Grants Skill: Manifest Weapon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="ManifestWeaponPlayer"}}},nil} diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 6f73ef814b7..8ae924ed542 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -2740,6 +2740,7 @@ function calcs.buildDefenceEstimations(env, actor) for _, damageType in ipairs(dmgTypeList) do DamageIn[damageType] = output[damageType.."TakenHit"] end + DamageIn["LimitEHPSpeedup"] = output["preventedLifeLossTotal"] > 0 output["NumberOfDamagingHits"] = numberOfHitsToDie(DamageIn) end diff --git a/src/Modules/CalcDefence.lua.rej b/src/Modules/CalcDefence.lua.rej new file mode 100644 index 00000000000..1f80c752666 --- /dev/null +++ b/src/Modules/CalcDefence.lua.rej @@ -0,0 +1,31 @@ +diff a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua (rejected hunks) +@@ -3077,16 +3077,16 @@ function calcs.buildDefenceEstimations(env, actor) + end + iterationMultiplier = 1 + -- to speed it up, run recursively but accelerated +- -- Stateful pool mechanics are not associative: collapsing too many hits into one +- -- can cross MoM/life-loss-prevention boundaries differently from repeated hits. +- local speedUp = DamageIn["StatefulEHP"] and m_min(data.misc.ehpCalcSpeedUp, 4) or data.misc.ehpCalcSpeedUp ++ -- MoM/life-loss-prevention mechanics can collapse too many hits into one ++ -- resulting in eHP jumps so we slow the acceleration. ++ local speedUp = DamageIn["LimitEHPSpeedup"] and 4 or data.misc.ehpCalcSpeedUp + DamageIn["cyclesRan"] = DamageIn["cyclesRan"] or false + if not DamageIn["cyclesRan"] and poolTable.Life > 0 and DamageIn["iterations"] < maxIterations then + Damage = { } + for _, damageType in ipairs(dmgTypeList) do + Damage[damageType] = DamageIn[damageType] * speedUp + end +- Damage["StatefulEHP"] = DamageIn["StatefulEHP"] ++ Damage["LimitEHPSpeedup"] = DamageIn["LimitEHPSpeedup"] + if DamageIn.GainWhenHit then + Damage.GainWhenHit = true + Damage.LifeWhenHit = DamageIn.LifeWhenHit +@@ -3230,7 +3230,7 @@ function calcs.buildDefenceEstimations(env, actor) + output["LifeLossLostOverTime"] = 0 + output["LifeBelowHalfLossLostOverTime"] = 0 + end +- DamageIn["StatefulEHP"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit ++ DamageIn["LimitEHPSpeedup"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit + averageAvoidChance = averageAvoidChance / 5 + output["ConfiguredDamageChance"] = 100 * (blockEffect * suppressionEffect * effectiveDeflectMulti * (1 - averageAvoidChance / 100)) + output["NumberOfMitigatedDamagingHits"] = (output["ConfiguredDamageChance"] ~= 100 or DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit) and numberOfHitsToDie(DamageIn) or output["NumberOfDamagingHits"] From 8a126c85610c79b87b5252e2c6cdd5e2f6f2cb57 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Thu, 23 Jul 2026 09:00:15 +1000 Subject: [PATCH 2/4] Fix merge --- spec/Fixtures/issue1754_block_ehp.xml | 796 ------------------------- spec/System/TestDefence_spec.lua.rej | 28 - spec/System/TestItemParse_spec.lua.rej | 24 - src/Data/ModCache.lua.rej | 89 --- src/Modules/CalcDefence.lua | 6 +- src/Modules/CalcDefence.lua.rej | 31 - 6 files changed, 5 insertions(+), 969 deletions(-) delete mode 100644 spec/Fixtures/issue1754_block_ehp.xml delete mode 100644 spec/System/TestDefence_spec.lua.rej delete mode 100644 spec/System/TestItemParse_spec.lua.rej delete mode 100644 src/Data/ModCache.lua.rej delete mode 100644 src/Modules/CalcDefence.lua.rej diff --git a/spec/Fixtures/issue1754_block_ehp.xml b/spec/Fixtures/issue1754_block_ehp.xml deleted file mode 100644 index 25f4298c63d..00000000000 --- a/spec/Fixtures/issue1754_block_ehp.xml +++ /dev/null @@ -1,796 +0,0 @@ - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - https://www.pathofexile.com/passive-skill-tree/AAAABgIBmLOoS-B_NJGKbCdclipOP9vFgWhlumpKQ4WadaMPYOFndqMZgWxOGXJISbq0Jhb710aZbpD4W2rtFgrJ6lMmjBfMleSg7Nq7hs48U4uSjxwyHiT562uU01NjHsudsTO7jpqu11u3nmdF0J0_KE9-axrZ-s1MlmUEsLAix7koetQKECBG7QsfgxSMu2_FO48BbNNvmSf31deWjCRhMA12mKu2W4f9CzAeKZGcBJEPlG4PJaZorn6ggqzrKw5MD232igVIcwdIxW9-r5hpyqR_wIVyi8p4aqAJuy4KlPLfbNPYZdZGT2nkKhbJabT1ZBOopqic1iLpgSEt-xzWG9ixI8v0sDtO9CIWTti2z8pBVYJZ6YnoxUKFgu7R12fIMILKFHqNgNAu4EKV9f1g5xTUs5EAAA== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: RARE -Chimeric Sliver -Ruby -Unique ID: 3f2a054bb6d41d7fe0d14122cc3d55f5b9055285249b5bf81d740ad1d59b6136 -Item Level: 80 -LevelReq: 0 -Implicits: 0 -18% increased Armour -14% increased Attack Damage -19% increased Warcry Speed -{desecrated}2% increased Strength - - - - - - - Rarity: RARE -Loath Wound -Time-Lost Ruby -Unique ID: 79ae21e9e5c5904ecda572dff79ab1d719eac798e1d9cfb35975a9116d915bc5 -Item Level: 78 -LevelReq: 0 -Radius: Medium -Implicits: 0 -Upgrades Radius to Medium -25% increased Effect of Notable Passive Skills in Radius -25% increased Effect of Small Passive Skills in Radius - - - - - - Rarity: UNIQUE -From Nothing -Diamond -Unique ID: 60219c236ed8e1330ab16b8919afb429b870bc28c23e445c4da72a8d0b22b76c -Item Level: 84 -LevelReq: 0 -Radius: Small -Limited to: 1 -Implicits: 0 -Passives in Radius of Resolute Technique can be Allocated -without being connected to your tree -Corrupted - - - - Rarity: RARE -Ghoul Sole -Tasalian Greaves -Armour: 432 -Unique ID: 816f7b3213e27a3f552b294e0066bcb695b3c7a2075c16a000c1cd456ab4311c -Item Level: 82 -Quality: 20 -Sockets: S S -Rune: Soul Core of Tacati -Rune: Soul Core of Tacati -LevelReq: 80 -Implicits: 1 -{enchant}{rune}+22% to Chaos Resistance -+123 to Armour -+110 to maximum Life -+31% to Fire Resistance -+30% to Lightning Resistance -+32% of Armour also applies to Elemental Damage -{desecrated}35% increased Movement Speed -Corrupted - - - - - - - - - - Rarity: RARE -Torment Touch -Vaal Mitts -Armour: 485 -Unique ID: ec3d3e1408f66406a34cc183c6ffb0a87025355c3295bc90ab8be9f8d32c539e -Item Level: 79 -Quality: 20 -Sockets: S -Rune: Idol of Grold -LevelReq: 75 -Implicits: 2 -{enchant}{rune}32% increased total Power counted by Warcries -{enchant}{rune}Bonded: 32% increased Glory generation -36% increased Armour -+156 to maximum Life -+2 to Level of all Melee Skills -+42% of Armour also applies to Elemental Damage -60% increased effect of Socketed Items -{desecrated}+151 to Armour - - - - - - - - - - - Rarity: NORMAL -Evasive Leg -Unique ID: ef550b724c26f2472f48418e92bafea5c8c4a804a960cc7b09066163fba3e44e -Item Level: 99 -LevelReq: 0 -Implicits: 1 -20% increased Evasion Rating - - - - Rarity: NORMAL -Combat Arm -Unique ID: f36295e737b0e7d2e531713f8153dd41e79d029fb6591afd25302dd9f630b099 -Item Level: 99 -LevelReq: 0 -Implicits: 1 -10% increased Attack Speed - - - - Rarity: NORMAL -Guarding Arm -Unique ID: 8a1cb54bc4dfaba7a8cbdc7046e0726011a7a0424d8db8d9e9560e694079f61f -Item Level: 99 -LevelReq: 0 -Implicits: 1 -10% increased Block chance - - - - Rarity: MAGIC -Experimenter's Staunching Charm of the Bountiful -Unique ID: 7b7a2820b483555344ef9156b5dffceebb5dc44774c9109af7f472a6d9a518f8 -Item Level: 81 -Quality: 17 -LevelReq: 18 -Implicits: 1 -Used when you start Bleeding -36% increased Duration -53% increased Charges - - - - - Rarity: UNIQUE -Rite of Passage -Golden Charm -Unique ID: 897c5364a769621daab36f5fcee7e3a3264b236f7cceac264eb9f37546caf810 -Item Level: 81 -Quality: 0 -LevelReq: 50 -Implicits: 1 -Used when you kill a Rare or Unique enemy -Possessed by Spirit Of The Ox for 20 seconds on use - - - Rarity: RARE -Phoenix Bind -Plate Belt -Charm Slots: 2 -Unique ID: 430b1c0f872adfb91474657f630483dbeb06359ccc10a3de78d59f9dc469c3b4 -Item Level: 79 -LevelReq: 24 -Implicits: 2 -+121 to Armour -Has 2 Charm Slots -+142 to Armour -+169 to maximum Life -+123 to maximum Mana -+26 to Strength -+39% to Cold Resistance -{desecrated}+17% to Fire and Chaos Resistances - - - - - - - - - - - Rarity: RARE -Phoenix Pendant -Pearlescent Amulet -Unique ID: f3ab9699d86ffae4a2943e4aab99607bce30d6ae9bdb0ef28b51e1d9eab928ca -Item Level: 78 -LevelReq: 30 -Implicits: 2 -{enchant}Allocates Reinforced Barrier -+10% to all Elemental Resistances -+175 to maximum Life -9% increased maximum Life -+33 to Strength -+32% to Fire Resistance -+29% to Cold Resistance -{desecrated}34% increased Armour - - - - - - - - - - - Rarity: MAGIC -Substantial Ultimate Mana Flask of the Abundant -Unique ID: 2f3e029b0a0e34fc09b8f199f1617aab732678e3f4058ac2b4ab858a14607528 -Item Level: 80 -Quality: 10 -LevelReq: 60 -Implicits: 0 -62% increased Amount Recovered -57% increased Charges - - - - - Rarity: RARE -Onslaught Crest -Imperial Greathelm -Armour: 1269 -Unique ID: 26849265030f23ddccb3e1ddd940f30695811b039ce53ac28c6086af7ca9e2a4 -Item Level: 83 -Quality: 30 -Sockets: S -Rune: Soul Core of Tacati -LevelReq: 80 -Implicits: 1 -{enchant}{rune}+11% to Chaos Resistance -+195 to Armour -91% increased Armour -+174 to maximum Life -+29 to Strength -+29% to Cold Resistance -{desecrated}+29% of Armour also applies to Chaos Damage -Corrupted - - - - - - - - - - Rarity: MAGIC -Seething Ultimate Life Flask of the Brewer -Unique ID: 2375dec92a0147d9ea02dc37bc7f94fb4a993d0886a056c1507e2e836eea3934 -Item Level: 79 -Quality: 22 -LevelReq: 60 -Implicits: 0 -50% reduced Amount Recovered -Instant Recovery -29% reduced Charges per use - - - - - - Rarity: RARE -Armageddon Shatter -Structured Hammer -Unique ID: 0ad6ea8224a123ac010f9c13bee9c7ae415c70fd127db1c79aa110449e0eb4e5 -Item Level: 82 -Quality: 20 -Sockets: S -Rune: Farrul's Rune of the Hunt -LevelReq: 62 -Implicits: 3 -{enchant}{rune}50% increased Attack Damage against Rare or Unique Enemies -{enchant}{rune}Bonded: +1 to Level of all Attack Skills -40% chance to Daze on Hit -Adds 11 to 19 Physical Damage -96% increased Elemental Damage with Attacks -+5 to Level of all Melee Skills -+26 to Strength -Gain 20% of Damage as Extra Physical Damage -{desecrated}Break Armour equal to 4% of Physical Damage dealt - - - - - - - - - - - Rarity: RARE -Carrion Span -Tawhoan Tower Shield -Armour: 1215 -Unique ID: 2957b34aa214fbdc6d0b652646718c039598d898641ffb48e728d0266aa3343f -Item Level: 80 -Quality: 20 -Sockets: S S -Rune: Greater Iron Rune -Rune: Greater Iron Rune -LevelReq: 80 -Implicits: 4 -{enchant}{rune}36% increased Armour, Evasion and Energy Shield -{enchant}{rune}Bonded: +20 to maximum Life -{enchant}{rune}Bonded: +20 to maximum Mana -Grants Skill: Raise Shield -+253 to Armour -89% increased Armour -+185 to maximum Life -+31 to Strength -8% additional Physical Damage Reduction -+28% to Cold Resistance -Corrupted - - - - - - - - - - - - - Rarity: MAGIC -Experimenter's Grounding Charm of the Ample -Unique ID: 4a9b1924da5c16f078735bbea50effa0b1a2ed71596e0ddf13ead3596c58fc35 -Item Level: 81 -Quality: 0 -LevelReq: 32 -Implicits: 1 -Used when you become Shocked -38% increased Duration -69% increased Charges - - - - - Rarity: RARE -Demon Grip -Amethyst Ring -Unique ID: 3a9a4bc4c6c7bf6c851d9e3465e170235570e40f8d701c4bbd68eb17f54bc0e1 -Item Level: 80 -LevelReq: 20 -Implicits: 1 -+11% to Chaos Resistance -+199 to Evasion Rating -+172 to maximum Mana -+29 to Strength -+34% to Lightning Resistance -Leech 6.34% of Physical Attack Damage as Mana -{desecrated}+115 to maximum Life - - - - - - - - - - Rarity: RARE -Pain Shelter -Soldier Cuirass -Armour: 2031 -Unique ID: c1272d9098b999d72429ccdf1fe25c25781e51c8b2d9392ca792f7a41c8ab87e -Item Level: 79 -Quality: 24 -Sockets: S S -Rune: The Greatwolf's Rune of Willpower -Rune: Craiceann's Rune of Warding -LevelReq: 65 -Implicits: 4 -{enchant}{rune}50% reduced effect of Curses on you -{enchant}{rune}15% of Damage is taken from Mana before Life -{enchant}{rune}Bonded: 8% increased Curse Magnitudes -{enchant}{rune}Bonded: 8% of Maximum Life Converted to Energy Shield -+265 to Armour -105% increased Armour -10% increased maximum Life -Hits against you have 47% reduced Critical Damage Bonus -+30% to Lightning Resistance -{desecrated}+43% of Armour also applies to Elemental Damage -Corrupted - - - - - - - - - - - - - Rarity: NORMAL -Evasive Leg -Unique ID: 1170f441dfecf0cfa4c4f7b19833710477ff62ac3fb66c2c1c658daa1f097ccf -Item Level: 99 -LevelReq: 0 -Implicits: 1 -30% increased Evasion Rating - - - - Rarity: RARE -Kraken Hold -Prismatic Ring -Unique ID: 5942bb3b406d8bb45907c9efb803bc7c1e516064294f1739977e1d4f5fcb112c -Item Level: 80 -LevelReq: 35 -Implicits: 1 -+12% to all Elemental Resistances -+164 to Evasion Rating -+116 to maximum Life -+156 to maximum Mana -+35% to Fire Resistance -Leech 7.39% of Physical Attack Damage as Life -{desecrated}+20% to Lightning and Chaos Resistances - - - - - - - - - - Rarity: UNIQUE -Carrion Span -Tawhoan Tower Shield -Armour: 1215 -Unique ID: 2957b34aa214fbdc6d0b652646718c039598d898641ffb48e728d0266aa3343f -Item Level: 80 -Quality: 20 -Sockets: S S -Rune: Greater Iron Rune -Rune: Greater Iron Rune -LevelReq: 80 -Implicits: 4 -{enchant}{rune}36% increased Armour, Evasion and Energy Shield -{enchant}{rune}Bonded: +20 to maximum Life -{enchant}{rune}Bonded: +20 to maximum Mana -Grants Skill: Raise Shield -+253 to Armour -89% increased Armour -+185 to maximum Life -+31 to Strength -+28% to Cold Resistance -Corrupted - - - - - - - - - - - - Rarity: UNIQUE -Undying Hate -Timeless Jewel -Variant: Amanamu -Variant: Kulemak -Variant: Kurgal -Variant: Tecrod -Variant: Ulaman -Selected Variant: 1 -LevelReq: 0 -Radius: Very Large -Limited to: 1 -Implicits: 0 -{variant:1}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Amanamu -{variant:2}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Kulemak -{variant:3}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Kurgal -{variant:4}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Tecrod -{variant:5}{range:0.5}Glorifying the defilement of (100-8000) souls in tribute to Ulaman -Passives in radius are Conquered by the Abyssals -Historic - - - - - - - - - - Rarity: UNIQUE -Pain Shelter -Soldier Cuirass -Armour: 2031 -Unique ID: c1272d9098b999d72429ccdf1fe25c25781e51c8b2d9392ca792f7a41c8ab87e -Item Level: 79 -Quality: 24 -Sockets: S S -Rune: The Greatwolf's Rune of Willpower -Rune: Craiceann's Rune of Warding -LevelReq: 65 -Implicits: 4 -{enchant}{rune}50% reduced effect of Curses on you -{enchant}{rune}Bonded: 8% increased Curse Magnitudes -{enchant}{rune}Bonded: 8% of Maximum Life Converted to Energy Shield -+265 to Armour -105% increased Armour -10% increased maximum Life -Hits against you have 47% reduced Critical Damage Bonus -+30% to Lightning Resistance -{desecrated}+43% of Armour also applies to Elemental Damage -Corrupted - - - - - - - - - - - - Rarity: UNIQUE -Torment Touch -Vaal Mitts -Armour: 485 -Unique ID: ec3d3e1408f66406a34cc183c6ffb0a87025355c3295bc90ab8be9f8d32c539e -Item Level: 79 -Quality: 20 -Sockets: S -Rune: Idol of Grold -LevelReq: 75 -Implicits: 2 -{enchant}{rune}32% increased total Power counted by Warcries -{enchant}{rune}Bonded: 32% increased Glory generation -36% increased Armour -+156 to maximum Life -+2 to Level of all Melee Skills -+42% of Armour also applies to Elemental Damage -+170 to mana -{desecrated}+151 to Armour - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spec/System/TestDefence_spec.lua.rej b/spec/System/TestDefence_spec.lua.rej deleted file mode 100644 index 744786a97c8..00000000000 --- a/spec/System/TestDefence_spec.lua.rej +++ /dev/null @@ -1,28 +0,0 @@ -diff a/spec/System/TestDefence_spec.lua b/spec/System/TestDefence_spec.lua (rejected hunks) -@@ -557,20 +557,18 @@ describe("TestDefence", function() - - local function calcEHP(extraMods) - newBuild() -- build.configTab.input.enemyPhysicalDamage = "1000" -- build.configTab.input.enemyFireDamage = "1000" -- build.configTab.input.enemyColdDamage = "1000" -- build.configTab.input.enemyLightningDamage = "1000" -+ build.configTab.input.enemyPhysicalDamage = "500" -+ build.configTab.input.enemyFireDamage = "500" -+ build.configTab.input.enemyColdDamage = "500" -+ build.configTab.input.enemyLightningDamage = "500" - build.configTab.input.enemyChaosDamage = "0" - build.configTab.input.customMods = [[ - +4000 to maximum Life -- +4000 to maximum Mana -- 75% of Damage is taken from Mana before Life -- 25% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead -+ 75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead - +75% to all Elemental Resistances - +75% to Chaos Resistance - ]] .. (extraMods or "") -- build.configTab:BuildModList() -+ pob1and2Compat() - runCallback("OnFrame") - runCallback("OnFrame") - local calcsOutput = build.calcsTab.calcsOutput diff --git a/spec/System/TestItemParse_spec.lua.rej b/spec/System/TestItemParse_spec.lua.rej deleted file mode 100644 index de9206ca0af..00000000000 --- a/spec/System/TestItemParse_spec.lua.rej +++ /dev/null @@ -1,24 +0,0 @@ -diff a/spec/System/TestItemParse_spec.lua b/spec/System/TestItemParse_spec.lua (rejected hunks) -@@ -142,22 +142,6 @@ describe("TestItemParse", function() - assert.are.equals("Adds 39 to 62 Fire Damage", item.explicitModLines[1].line) - end) - -- it("Pasted variable-level base granted skills parse at exact exported levels", function() -- local cases = { -- { base = "Bone Wand", line = "Grants Skill: Level 11 Bone Blast", skillId = "BoneBlastPlayer", level = 11 }, -- { base = "Withered Wand", line = "Grants Skill: Level 20 Chaos Bolt", skillId = "WeaponGrantedChaosboltPlayer", level = 20 }, -- { base = "Stoic Sceptre", line = "Grants Skill: Level 20 Discipline", skillId = "DisciplinePlayer", level = 20 }, -- } -- -- for _, case in ipairs(cases) do -- local item = new("Item", "Rarity: Normal\n" .. case.base .. "\nImplicits: 1\n" .. case.line) -- -- assert.are.equals(1, #item.grantedSkills) -- assert.are.equals(case.skillId, item.grantedSkills[1].skillId) -- assert.are.equals(case.level, item.grantedSkills[1].level) -- end -- end) -- - --TODO: POB2 Leagues? - --it("League", function() - --end) diff --git a/src/Data/ModCache.lua.rej b/src/Data/ModCache.lua.rej deleted file mode 100644 index 3514176b95b..00000000000 --- a/src/Data/ModCache.lua.rej +++ /dev/null @@ -1,89 +0,0 @@ -diff a/src/Data/ModCache.lua b/src/Data/ModCache.lua (rejected hunks) -@@ -5146,13 +5146,20 @@ c["Grants Skill: Kelari's Malediction"]={{[1]={flags=0,keywordFlags=0,name="Extr - c["Grants Skill: Kelari, the Tainted Sands"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="SummonSandDjinnPlayer"}}},nil} - c["Grants Skill: Level 11 Black Powder Blitz"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BlackPowderBlitzReservationPlayer"}}},nil} - c["Grants Skill: Level 11 Blink"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BlinkReservationPlayer"}}},nil} -+c["Grants Skill: Level 11 Bone Blast"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="BoneBlastPlayer"}}},nil} - c["Grants Skill: Level 11 Bursting Fen Toad"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ExplodingPoisonToadPlayer"}}},nil} -+c["Grants Skill: Level 11 Chaos Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="WeaponGrantedChaosboltPlayer"}}},nil} - c["Grants Skill: Level 11 Compose Requiem"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CrossbowRequiemAmmoPlayer"}}},nil} - c["Grants Skill: Level 11 Crackling Palm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CracklingPalmPlayer"}}},nil} - c["Grants Skill: Level 11 Decompose"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="CorpseCloudPlayer"}}},nil} -+c["Grants Skill: Level 11 Discipline"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="DisciplinePlayer"}}},nil} - c["Grants Skill: Level 11 Ember Fusillade"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="EmberFusilladePlayer"}}},nil} -+c["Grants Skill: Level 11 Feast of Flesh"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FeastOfFleshPlayer"}}},nil} -+c["Grants Skill: Level 11 Firebolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FireboltPlayer"}}},nil} -+c["Grants Skill: Level 11 Freezing Shards"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FreezingShardsPlayer"}}},nil} - c["Grants Skill: Level 11 Future-Past"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="FuturePastPlayer"}}},nil} - c["Grants Skill: Level 11 Gemini Surge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="GeminiSurgePlayer"}}},nil} -+c["Grants Skill: Level 11 Heart of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeartOfIcePlayer"}}},nil} - c["Grants Skill: Level 11 Herald of Ash"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfAshPlayer"}}},nil} - c["Grants Skill: Level 11 Herald of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfIcePlayer"}}},nil} - c["Grants Skill: Level 11 Herald of Thunder"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="HeraldOfThunderPlayer"}}},nil} -@@ -5160,26 +5167,42 @@ c["Grants Skill: Level 11 Icestorm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSk - c["Grants Skill: Level 11 Impurity"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ImpurityPlayer"}}},nil} - c["Grants Skill: Level 11 Lightning Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="UniqueBreachLightningBoltPlayer"}}},nil} - c["Grants Skill: Level 11 Living Bomb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="LivingBombPlayer"}}},nil} -+c["Grants Skill: Level 11 Malice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="MalicePlayer"}}},nil} -+c["Grants Skill: Level 11 Mana Drain"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ManaDrainPlayer"}}},nil} -+c["Grants Skill: Level 11 Parry"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ParryPlayer"}}},nil} - c["Grants Skill: Level 11 Phantasmal Arrow"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PhantasmalArrowPlayer"}}},nil} -+c["Grants Skill: Level 11 Power Siphon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PowerSiphonPlayer"}}},nil} - c["Grants Skill: Level 11 Purity of Fire"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfFirePlayer"}}},nil} - c["Grants Skill: Level 11 Purity of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfIcePlayer"}}},nil} - c["Grants Skill: Level 11 Purity of Lightning"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="PurityOfLightningPlayer"}}},nil} -+c["Grants Skill: Level 11 Raise Shield"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ShieldBlockPlayer"}}},nil} -+c["Grants Skill: Level 11 Sigil of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SigilOfPowerPlayer"}}},nil} -+c["Grants Skill: Level 11 Skeletal Warrior Minion"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SummonSkeletalWarriorsPlayer"}}},nil} -+c["Grants Skill: Level 11 Solar Orb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SolarOrbPlayer"}}},nil} - c["Grants Skill: Level 11 Spark"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="SparkPlayer"}}},nil} - c["Grants Skill: Level 11 Thundergod's Wrath"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="MetaCastLightningSpellOnHitPlayer"}}},nil} - c["Grants Skill: Level 11 Valako's Charge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="ValakosChargePlayer"}}},nil} -+c["Grants Skill: Level 11 Volatile Dead"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="VolatileDeadPlayer"}}},nil} - c["Grants Skill: Level 11 Withering Presence"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=11,skillId="WitheringPresencePlayer"}}},nil} - c["Grants Skill: Level 14 Life Remnants"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=14,skillId="LifeRemnantsPlayer"}}},nil} - c["Grants Skill: Level 20 Black Powder Blitz"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BlackPowderBlitzReservationPlayer"}}},nil} - c["Grants Skill: Level 20 Blink"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BlinkReservationPlayer"}}},nil} -+c["Grants Skill: Level 20 Bone Blast"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="BoneBlastPlayer"}}},nil} - c["Grants Skill: Level 20 Bursting Fen Toad"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ExplodingPoisonToadPlayer"}}},nil} -+c["Grants Skill: Level 20 Chaos Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="WeaponGrantedChaosboltPlayer"}}},nil} - c["Grants Skill: Level 20 Chaotic Infusion"]={nil,nil} - c["Grants Skill: Level 20 Chaotic Infusion 20% increased Attack Speed"]={nil,nil} - c["Grants Skill: Level 20 Compose Requiem"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CrossbowRequiemAmmoPlayer"}}},nil} - c["Grants Skill: Level 20 Crackling Palm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CracklingPalmPlayer"}}},nil} - c["Grants Skill: Level 20 Decompose"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="CorpseCloudPlayer"}}},nil} -+c["Grants Skill: Level 20 Discipline"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="DisciplinePlayer"}}},nil} - c["Grants Skill: Level 20 Ember Fusillade"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="EmberFusilladePlayer"}}},nil} -+c["Grants Skill: Level 20 Feast of Flesh"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FeastOfFleshPlayer"}}},nil} -+c["Grants Skill: Level 20 Firebolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FireboltPlayer"}}},nil} -+c["Grants Skill: Level 20 Freezing Shards"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FreezingShardsPlayer"}}},nil} - c["Grants Skill: Level 20 Future-Past"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="FuturePastPlayer"}}},nil} - c["Grants Skill: Level 20 Gemini Surge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="GeminiSurgePlayer"}}},nil} -+c["Grants Skill: Level 20 Heart of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeartOfIcePlayer"}}},nil} - c["Grants Skill: Level 20 Herald of Ash"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfAshPlayer"}}},nil} - c["Grants Skill: Level 20 Herald of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfIcePlayer"}}},nil} - c["Grants Skill: Level 20 Herald of Thunder"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="HeraldOfThunderPlayer"}}},nil} -@@ -5195,14 +5218,23 @@ c["Grants Skill: Level 20 Icestorm"]={{[1]={flags=0,keywordFlags=0,name="ExtraSk - c["Grants Skill: Level 20 Impurity"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ImpurityPlayer"}}},nil} - c["Grants Skill: Level 20 Lightning Bolt"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="UniqueBreachLightningBoltPlayer"}}},nil} - c["Grants Skill: Level 20 Living Bomb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="LivingBombPlayer"}}},nil} -+c["Grants Skill: Level 20 Malice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="MalicePlayer"}}},nil} -+c["Grants Skill: Level 20 Mana Drain"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ManaDrainPlayer"}}},nil} -+c["Grants Skill: Level 20 Parry"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ParryPlayer"}}},nil} - c["Grants Skill: Level 20 Phantasmal Arrow"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PhantasmalArrowPlayer"}}},nil} - c["Grants Skill: Level 20 Pinnacle of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PinnacleOfPowerPlayer"}}},nil} -+c["Grants Skill: Level 20 Power Siphon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PowerSiphonPlayer"}}},nil} - c["Grants Skill: Level 20 Purity of Fire"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfFirePlayer"}}},nil} - c["Grants Skill: Level 20 Purity of Ice"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfIcePlayer"}}},nil} - c["Grants Skill: Level 20 Purity of Lightning"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="PurityOfLightningPlayer"}}},nil} -+c["Grants Skill: Level 20 Raise Shield"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ShieldBlockPlayer"}}},nil} -+c["Grants Skill: Level 20 Sigil of Power"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SigilOfPowerPlayer"}}},nil} -+c["Grants Skill: Level 20 Skeletal Warrior Minion"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SummonSkeletalWarriorsPlayer"}}},nil} -+c["Grants Skill: Level 20 Solar Orb"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SolarOrbPlayer"}}},nil} - c["Grants Skill: Level 20 Spark"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="SparkPlayer"}}},nil} - c["Grants Skill: Level 20 Thundergod's Wrath"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="MetaCastLightningSpellOnHitPlayer"}}},nil} - c["Grants Skill: Level 20 Valako's Charge"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="ValakosChargePlayer"}}},nil} -+c["Grants Skill: Level 20 Volatile Dead"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="VolatileDeadPlayer"}}},nil} - c["Grants Skill: Level 20 Withering Presence"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=20,skillId="WitheringPresencePlayer"}}},nil} - c["Grants Skill: Life Remnants"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="LifeRemnantsPlayer"}}},nil} - c["Grants Skill: Manifest Weapon"]={{[1]={flags=0,keywordFlags=0,name="ExtraSkill",type="LIST",value={level=1,skillId="ManifestWeaponPlayer"}}},nil} diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 8ae924ed542..2e109d14f57 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -2681,7 +2681,9 @@ function calcs.buildDefenceEstimations(env, actor) end iterationMultiplier = 1 -- to speed it up, run recursively but accelerated - local speedUp = data.misc.ehpCalcSpeedUp + -- MoM/life-loss-prevention mechanics can collapse too many hits into one + -- resulting in eHP jumps so we slow the acceleration. + local speedUp = DamageIn["LimitEHPSpeedup"] and 4 or data.misc.ehpCalcSpeedUp DamageIn["cyclesRan"] = DamageIn["cyclesRan"] or false local wardAvoidBreakActive = wardAvoidBreakChance < 1 and (poolTable.WardActiveChance or 0) > 0.01 if not DamageIn["cyclesRan"] and not wardAvoidBreakActive and poolTable.Life > 0 and DamageIn["iterations"] < maxIterations then @@ -2689,6 +2691,7 @@ function calcs.buildDefenceEstimations(env, actor) for _, damageType in ipairs(dmgTypeList) do Damage[damageType] = DamageIn[damageType] * speedUp end + Damage["LimitEHPSpeedup"] = DamageIn["LimitEHPSpeedup"] if DamageIn.GainWhenHit then Damage.GainWhenHit = true Damage.LifeWhenHit = DamageIn.LifeWhenHit @@ -2835,6 +2838,7 @@ function calcs.buildDefenceEstimations(env, actor) output["LifeLossLostOverTime"] = 0 output["LifeBelowHalfLossLostOverTime"] = 0 end + DamageIn["LimitEHPSpeedup"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit averageAvoidChance = averageAvoidChance / 5 output["ConfiguredDamageChance"] = 100 * (blockEffect * suppressionEffect * (1 - averageAvoidChance / 100)) output["NumberOfMitigatedDamagingHits"] = (output["ConfiguredDamageChance"] ~= 100 or DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit) and numberOfHitsToDie(DamageIn) or output["NumberOfDamagingHits"] diff --git a/src/Modules/CalcDefence.lua.rej b/src/Modules/CalcDefence.lua.rej deleted file mode 100644 index 1f80c752666..00000000000 --- a/src/Modules/CalcDefence.lua.rej +++ /dev/null @@ -1,31 +0,0 @@ -diff a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua (rejected hunks) -@@ -3077,16 +3077,16 @@ function calcs.buildDefenceEstimations(env, actor) - end - iterationMultiplier = 1 - -- to speed it up, run recursively but accelerated -- -- Stateful pool mechanics are not associative: collapsing too many hits into one -- -- can cross MoM/life-loss-prevention boundaries differently from repeated hits. -- local speedUp = DamageIn["StatefulEHP"] and m_min(data.misc.ehpCalcSpeedUp, 4) or data.misc.ehpCalcSpeedUp -+ -- MoM/life-loss-prevention mechanics can collapse too many hits into one -+ -- resulting in eHP jumps so we slow the acceleration. -+ local speedUp = DamageIn["LimitEHPSpeedup"] and 4 or data.misc.ehpCalcSpeedUp - DamageIn["cyclesRan"] = DamageIn["cyclesRan"] or false - if not DamageIn["cyclesRan"] and poolTable.Life > 0 and DamageIn["iterations"] < maxIterations then - Damage = { } - for _, damageType in ipairs(dmgTypeList) do - Damage[damageType] = DamageIn[damageType] * speedUp - end -- Damage["StatefulEHP"] = DamageIn["StatefulEHP"] -+ Damage["LimitEHPSpeedup"] = DamageIn["LimitEHPSpeedup"] - if DamageIn.GainWhenHit then - Damage.GainWhenHit = true - Damage.LifeWhenHit = DamageIn.LifeWhenHit -@@ -3230,7 +3230,7 @@ function calcs.buildDefenceEstimations(env, actor) - output["LifeLossLostOverTime"] = 0 - output["LifeBelowHalfLossLostOverTime"] = 0 - end -- DamageIn["StatefulEHP"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit -+ DamageIn["LimitEHPSpeedup"] = DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit - averageAvoidChance = averageAvoidChance / 5 - output["ConfiguredDamageChance"] = 100 * (blockEffect * suppressionEffect * effectiveDeflectMulti * (1 - averageAvoidChance / 100)) - output["NumberOfMitigatedDamagingHits"] = (output["ConfiguredDamageChance"] ~= 100 or DamageIn["TrackRecoupable"] or DamageIn["TrackLifeLossOverTime"] or DamageIn.GainWhenHit) and numberOfHitsToDie(DamageIn) or output["NumberOfDamagingHits"] From 8864f6e6792a188573d34cfa520496e268cd06da Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Thu, 23 Jul 2026 09:02:19 +1000 Subject: [PATCH 3/4] Fix test --- spec/System/TestDefence_spec.lua | 44 ++++++++------------------------ 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/spec/System/TestDefence_spec.lua b/spec/System/TestDefence_spec.lua index 16a16ce4b68..bbf964e2830 100644 --- a/spec/System/TestDefence_spec.lua +++ b/spec/System/TestDefence_spec.lua @@ -1283,28 +1283,6 @@ describe("TestDefence", function() assert.are.equals(0, floor(poolsRemaining.Life)) assert.are.equals(0, floor(poolsRemaining.OverkillDamage)) end) - - it("uses block chance against projectile spells", function() - build.configTab.input.enemyIsBoss = "None" - build.configTab.input.enemyDamageType = "SpellProjectile" - build.configTab.input.customMods = [[ - 20% chance to block - ]] - build.configTab:BuildModList() - runCallback("OnFrame") - - assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveBlockChance) - assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveProjectileBlockChance) - assert.are.equals(20, build.calcsTab.calcsOutput.EffectiveSpellProjectileBlockChance) - assert.are.equals(80, build.calcsTab.calcsOutput.ConfiguredDamageChance) - - build.configTab.input.enemyDamageType = "Average" - build.configTab:BuildModList() - runCallback("OnFrame") - - assert.are.equals(15, build.calcsTab.calcsOutput.EffectiveAverageBlockChance) - assert.are.equals(85, build.calcsTab.calcsOutput.ConfiguredDamageChance) - end) it("limits EHP speedup when hit damage is delayed", function() local function assertClose(actual, expected) @@ -1313,20 +1291,18 @@ describe("TestDefence", function() local function calcEHP(extraMods) newBuild() - build.configTab.input.enemyPhysicalDamage = "1000" - build.configTab.input.enemyFireDamage = "1000" - build.configTab.input.enemyColdDamage = "1000" - build.configTab.input.enemyLightningDamage = "1000" + build.configTab.input.enemyPhysicalDamage = "500" + build.configTab.input.enemyFireDamage = "500" + build.configTab.input.enemyColdDamage = "500" + build.configTab.input.enemyLightningDamage = "500" build.configTab.input.enemyChaosDamage = "0" build.configTab.input.customMods = [[ -+4000 to maximum Life -+4000 to maximum Mana -75% of Damage is taken from Mana before Life -25% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead -+75% to all Elemental Resistances -+75% to Chaos Resistance -]] .. (extraMods or "") - build.configTab:BuildModList() + +4000 to maximum Life + 75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead + +75% to all Elemental Resistances + +75% to Chaos Resistance + ]] .. (extraMods or "") + pob1and2Compat() runCallback("OnFrame") runCallback("OnFrame") local calcsOutput = build.calcsTab.calcsOutput From 4763ce3a0b6bf6245cd3b1fd04202f69708c61bc Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Thu, 23 Jul 2026 09:12:45 +1000 Subject: [PATCH 4/4] Fix test --- spec/System/TestDefence_spec.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/spec/System/TestDefence_spec.lua b/spec/System/TestDefence_spec.lua index bbf964e2830..d0c33555fdb 100644 --- a/spec/System/TestDefence_spec.lua +++ b/spec/System/TestDefence_spec.lua @@ -1286,7 +1286,8 @@ describe("TestDefence", function() it("limits EHP speedup when hit damage is delayed", function() local function assertClose(actual, expected) - assert.is_true(math.abs(actual - expected) < 0.01) + assert.is_true(math.abs(actual - expected) < 0.01, + string.format("expected %.12f, got %.12f", expected, actual)) end local function calcEHP(extraMods) @@ -1296,13 +1297,14 @@ describe("TestDefence", function() build.configTab.input.enemyColdDamage = "500" build.configTab.input.enemyLightningDamage = "500" build.configTab.input.enemyChaosDamage = "0" + build.configTab.input.conditionUsingFlask = true build.configTab.input.customMods = [[ +4000 to maximum Life - 75% of Life Loss from Hits is prevented, then that much Life is lost over 4 seconds instead + When Hit during effect, 75% of Life loss from Damage taken occurs over 4 seconds instead +75% to all Elemental Resistances +75% to Chaos Resistance - ]] .. (extraMods or "") - pob1and2Compat() + ]] .. (extraMods or "") + build.configTab:BuildModList() runCallback("OnFrame") runCallback("OnFrame") local calcsOutput = build.calcsTab.calcsOutput @@ -1318,8 +1320,8 @@ describe("TestDefence", function() newBuild() - assertClose(base.TotalEHP, 17582.417582418) - assertClose(block.TotalEHP, 19008.019008019) + assertClose(base.TotalEHP, 17570.183511070) + assertClose(block.TotalEHP, 18488.832919738) assertClose(block.EffectiveBlockChance, 10) assert.is_true(block.TotalEHP > base.TotalEHP) end)