diff --git a/spec/System/TestItemMods_spec.lua b/spec/System/TestItemMods_spec.lua index 81072e284e..610bb8f795 100644 --- a/spec/System/TestItemMods_spec.lua +++ b/spec/System/TestItemMods_spec.lua @@ -1,4 +1,4 @@ -describe("TetsItemMods", function() +describe("TestItemMods", function() before_each(function() newBuild() end) diff --git a/spec/System/TestItemParse_spec.lua b/spec/System/TestItemParse_spec.lua index 8034dc07b9..fc6c4793f5 100644 --- a/spec/System/TestItemParse_spec.lua +++ b/spec/System/TestItemParse_spec.lua @@ -1257,4 +1257,193 @@ describe("TestAdvancedItemParse #item", function() Note: ~b/o 2 chaos ]]) end) + describe("mod magnitude scaling", function() + before_each(function() + newBuild() + runCallback("onFrame") + end) + local function chaosDamageInc() + return build.calcsTab.mainEnv.modDB:Sum("INC", nil, "ChaosDamage") + end + + local function chaosResist() + return build.calcsTab.mainEnv.modDB:Sum("BASE", nil, "ChaosResist") + end + + local function spellCrit() + return build.calcsTab.mainEnv.modDB:Sum("INC", { flags = ModFlag.Spell }, "CritChance") + end + + local function spellDamage() + return build.calcsTab.mainEnv.modDB:Sum("INC", { flags = ModFlag.Spell }, "Damage") + end + + it("scales matching desecrated mods by modifier magnitude", function() + -- 130% * 1.7 = 221 + build.itemsTab:CreateDisplayItemFromRaw([[ + Rarity: RARE + Test Subject + Ravenous Staff + LevelReq: 60 + Implicits: 0 + {desecrated}{range:0.5}(100-160)% increased Chaos Damage + {range:0.5}70% increased Desecrated Modifier magnitudes + ]]) + local item = build.itemsTab.displayItem + assert.is_true(item.advancedCopy) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(221, chaosDamageInc()) + end) + + it("does not rescale old format (baked) copies", function() + -- magnitude already baked in, so no rescale + build.itemsTab:CreateDisplayItemFromRaw([[ + Rarity: RARE + Baked Subject + Ravenous Staff + LevelReq: 60 + Implicits: 0 + 130% increased Chaos Damage + 70% increased Desecrated Modifier magnitudes + ]]) + local item = build.itemsTab.displayItem + assert.is_false(item.advancedCopy) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(130, chaosDamageInc()) + end) + + it("only scales mods that share the magnitude mod's tags", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + Rarity: RARE + Test Subject + Sapphire Ring + LevelReq: 20 + Implicits: 0 + {tags:chaos,damage}{range:0.5}(100-160)% increased Chaos Damage + {tags:resistance}{range:0.5}+(20-40)% to Chaos Resistance + {range:0.5}100% increased resistance modifier magnitudes + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(60, chaosResist()) + assert.are.equals(130, chaosDamageInc()) + end) + + it("only scales the modifier type named by the magnitude mod", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + Rarity: RARE + Test Subject + Sapphire Ring + LevelReq: 20 + Implicits: 1 + {range:0.5}(100-160)% increased Chaos Damage + {range:0.5}+(20-40)% to Chaos Resistance + {range:0.5}100% increased explicit modifier magnitudes + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(130, chaosDamageInc()) + assert.are.equals(60, chaosResist()) + end) + + it("scales only prefixes for increased effect of prefixes", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + Rarity: RARE + Test Subject + Sapphire Ring + LevelReq: 20 + Implicits: 0 + {prefix}{range:0.5}(100-160)% increased Chaos Damage + {suffix}{range:0.5}+(20-40)% to Chaos Resistance + {range:0.5}50% increased effect of prefixes + ]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(195, chaosDamageInc()) + assert.are.equals(30, chaosResist()) + end) + + -- actually a ring so we don't have to allocate a socket + local realJewel = [[ + Rarity: Rare + Pandemonium Desire + Ruby Ring + -------- + Quality (Caster Modifiers): +20% (augmented) + -------- + Item Level: 80 + -------- + { Corruption Enhancement — Elemental, Cold, Resistance } + +7(5-10)% to Cold Resistance + { Corruption Enhancement — Attribute } + +6(4-6) to Intelligence + -------- + { Fractured Crafted Prefix Modifier "" } + 60(40-60)% increased Effect of Suffixes — Unscalable Value + { Prefix Modifier "Mystic" (Tier: 1) — Damage, Caster — 20% Increased } + 7(5-15)% increased Spell Damage + { Suffix Modifier "of Unmaking" (Tier: 1) — Damage, Caster, Critical — 80% Increased } + 20(10-20)% increased Critical Spell Damage Bonus + { Desecrated Suffix Modifier "of Annihilating" (Tier: 1) — Caster, Critical — 80% Increased } + 15(5-15)% increased Critical Hit Chance for Spells + { Suffix Modifier "of Potency" (Tier: 1) — Damage, Critical — 60% Increased } + 20(10-20)% increased Critical Damage Bonus + -------- + Place into an allocated Jewel Socket on the Passive Skill Tree. Right click to remove from the Socket. + -------- + Twice Corrupted + -------- + Fractured Item + -------- + Note: ~b/o 1 mirror + ]] + it("scales only prefixes for increased effect of prefixes for advanced copy format", function() + assert.equal(0, spellCrit()) + local item = new("Item", realJewel) + build.itemsTab:AddItem(item) + build.itemsTab:EquipItemInSet(item, build.itemsTab.activeItemSetId) + runCallback("OnFrame") + assert.equal(26, spellCrit()) + assert.equal(8, spellDamage()) + end) + + it("does not apply scaling twice when saving and loading", function() + local item = new("Item", new("Item", realJewel):BuildRaw()) + build.itemsTab:AddItem(item) + build.itemsTab:EquipItemInSet(item, build.itemsTab.activeItemSetId) + runCallback("OnFrame") + assert.equal(26, spellCrit()) + assert.equal(8, spellDamage()) + end) + + it("The Unborn Lich scales its desecrated mods", function() + local raw + for _, itemStr in ipairs(data.uniques.staff) do + if itemStr:find("Unborn Lich") then + raw = itemStr + end + end + if not raw then + error("Couldn't find unborn lich") + end + build.itemsTab:CreateDisplayItemFromRaw(raw) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + assert.are.equals(221, chaosDamageInc()) + + -- the tooltip advertises the same scaled value the calculation uses + local tooltip = new("Tooltip") + build.itemsTab:AddItemTooltip(tooltip, new("Item", raw)) + local found = false + for _, section in ipairs(tooltip.lines) do + if section.text and section.text:find("221% increased Chaos Damage", 1, true) then + found = true + break + end + end + assert.is_true(found) + end) + end) end) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index affafee709..f2e7cbc4cd 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -60,7 +60,7 @@ local function getRangedModList(item, modLine) if not modLine.range or not modLine.line:find("%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)") then return end - local line = itemLib.applyRange(modLine.line:gsub("\n", " "), modLine.range, getCatalystScalar(item.catalyst, modLine, item.catalystQuality), modLine.corruptedRange) + local line = itemLib.applyRange(modLine.line:gsub("\n", " "), modLine.range, modLine.valueScalar, modLine.corruptedRange) local list, extra = modLib.parseMod(line) if itemLib.isZeroValueLine(line) then return { } @@ -75,7 +75,7 @@ local ItemClass = newClass("Item", function(self, raw, rarity, highQuality) end) local lineFlags = { - ["custom"] = true, ["crafted"] = true, ["fractured"] = true, ["desecrated"] = true, ["mutated"] = true, ["enchant"] = true, ["implicit"] = true, ["rune"] = true, ["unscalable"] = true + ["custom"] = true, ["crafted"] = true, ["fractured"] = true, ["desecrated"] = true, ["mutated"] = true, ["enchant"] = true, ["implicit"] = true, ["rune"] = true, ["unscalable"] = true, ["prefix"] = true, ["suffix"] = true } local function baseHasImplicitLine(base, line) @@ -401,6 +401,12 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.socketedSoulCoreTypes = { } self.implicitModLines = { } self.explicitModLines = { } + -- old items or trade-sourced items have increases to modifiers baked in to the item text, which + -- means that we can't add e.g. quality or mod magnitude effect to them during parsing. we will + -- assume an item to be an advanced copy format if either has mod roll information, a modifier + -- line with a range, or advanced copy lines + self.advancedCopy = false + self.modMagnitudeMods = {} local implicitLines = 0 self.variantList = nil self.prefixes = { } @@ -451,6 +457,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end elseif line:match("^{ ") then -- We're parsing advanced copy/paste format + self.advancedCopy = true linePrefix = "" linePostfix = "" self.crafted = true @@ -737,6 +744,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) t_insert(modLine.modTags, tag) end elseif k == "range" then + self.advancedCopy = true modLine.range = tonumber(val) elseif k == "corruptedRange" then modLine.corruptedRange = tonumber(val) @@ -777,6 +785,10 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) if modLine.fractured then self.fractured = true end + -- items containing (#-#) lines are marked since the values won't have catalyst or mod magnitudes applied + if line:find("%((%-?%d+%.?%d*)%-(%-?%d+%.?%d*)%)") then + self.advancedCopy = true + end local baseName if not self.base and (self.rarity == "NORMAL" or self.rarity == "MAGIC") then -- Exact match (affix-less magic and normal items) @@ -960,6 +972,10 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end local lineLower = line:lower() + -- \d+% increased/decreased explicit/implicit/ *tags* modifier magnitudes + local modMagnitudePattern = { "(%d+)%% ([id][ne]creased) ?([%a%s]*) modifier magnitudes", + -- \d+% increased/decreased effect of suffixes/prefixes + "(%d+)%% ([id][ne]creased) effect of ([sp][ur][fe]fix)es" } if lineLower == "implicit modifiers cannot be changed" then self.implicitsCannotBeChanged = true elseif lineLower:match(" prefix modifiers? allowed") then @@ -978,6 +994,28 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.canHaveThreeEnchants = true self.canHaveFourEnchants = true end + for _, pattern in ipairs(modMagnitudePattern) do + if rangedLine:lower():find(pattern) then + local rangedLine = itemLib.applyRange(line, modLine.range or main.defaultItemAffixQuality or 1, catalystScalar, modLine.corruptedRange) + local amount, increaseOrDecrease, modTagsString = rangedLine:lower():match(pattern) + if amount and modTagsString and (increaseOrDecrease == "increased" or increaseOrDecrease == "decreased") then + local modTags = {} + local modType + -- explicit elemental damage -> tags = {elemental, damage}, modType = explicit + for word in (modTagsString .. " "):gmatch("%S+") do + word = word:lower() + if word == "implicit" or word == "explicit" or word == "enchant" then + modType = word + else + table.insert(modTags, word) + end + end + local quality = increaseOrDecrease == "increased" and tonumber(amount) or -tonumber(amount) + table.insert(self.modMagnitudeMods, { tags = modTags, quality = quality, modType = modType }) + break + end + end + end modLine.socketedAugmentTypeOverride = lineLower:match("^this item gains bonuses from socketed items as though it was a? ?(.+)$") modLine.socketedSoulCoreType = lineLower:match("^this item gains bonuses from socketed soul cores as though it was also a? ?(.+)$") @@ -1287,6 +1325,50 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.requirements.level = self.requirements.level or self.requirements.naturalLevel self.requirements.level = m_max(self.requirements.level, self.requirements.naturalLevel, self.requirements.runeLevel) end + if self.advancedCopy then + -- apply mod magnitude boost to matching mods + if #self.modMagnitudeMods > 0 then + for _, modMagnitudeMod in ipairs(self.modMagnitudeMods) do + local modLists + if modMagnitudeMod.modType then + modLists = { self[modMagnitudeMod.modType .. "ModLines"] } + else + modLists = { self.implicitModLines, self.explicitModLines, self.enchantModLines } + end + for _, mods in ipairs(modLists) do + for _, mod in ipairs(mods or {}) do + -- Create a fast lookup table for all provided tags + local tagLookup = {} + for _, curTag in ipairs(mod.modTags) do + tagLookup[curTag] = true; + end + -- these aren't actual mod tags but do appear in mod magnitude mods + for _, lineFlag in ipairs({ "desecrated", "prefix", "suffix" }) do + if mod[lineFlag] then + tagLookup[lineFlag] = true + end + end + local match = true + for _, magnitudeTag in ipairs(modMagnitudeMod.tags) do + if not tagLookup[magnitudeTag] then + match = false + end + end + if match then + mod.valueScalar = (mod.valueScalar or 1) + (modMagnitudeMod.quality / 100) + end + if mod.valueScalar and mod.valueScalar ~= 1 then + local rangedLine = itemLib.applyRange(mod.line, mod.range, mod.valueScalar, 1) + local modList, extra = modLib.parseMod(rangedLine) + mod.displayValueScalar = 1 + mod.modList = modList + mod.extra = extra + end + end + end + end + end + end self.affixLimit = 0 if self.crafted then if not self.affixes then @@ -1457,8 +1539,13 @@ function ItemClass:BuildRaw() t_insert(rawLines, "Item Level: " .. self.itemLevel) end local function writeModLine(modLine) - local displayValueScalar = modLine.displayValueScalar and (modLine.valueScalar or 1) * modLine.displayValueScalar - local line = displayValueScalar and itemLib.applyRange(modLine.line, modLine.range or main.defaultItemAffixQuality, displayValueScalar, modLine.corruptedRange) or modLine.line + local line + if modLine.rune then + local displayValueScalar = modLine.displayValueScalar and (modLine.valueScalar or 1) * modLine.displayValueScalar + line = displayValueScalar and itemLib.applyRange(modLine.line, modLine.range or main.defaultItemAffixQuality, displayValueScalar, modLine.corruptedRange) or modLine.line + else + line = modLine.line + end if modLine.range and line:match("%(%-?[%d%.]+%-%-?[%d%.]+%)") then line = "{range:" .. round(modLine.range, 3) .. "}" .. line end @@ -1489,6 +1576,12 @@ function ItemClass:BuildRaw() if modLine.unscalable then line = "{unscalable}" .. line end + if modLine.prefix then + line = "{prefix}" .. line + end + if modLine.suffix then + line = "{suffix}" .. line + end if modLine.variantList then local varSpec for varId in pairs(modLine.variantList) do @@ -1733,7 +1826,12 @@ function ItemClass:Craft() return tonumber(num) + tonumber(other) end) else - local modLine = { line = line, order = order } + local modLine = { line = line, order = order, type = mod.type } + if mod.type == "Prefix" then + modLine.prefix = true + elseif mod.type == "Suffix" then + modLine.suffix = true + end for l = 1, #self.explicitModLines + 1 do if not self.explicitModLines[l] or self.explicitModLines[l].order > order then t_insert(self.explicitModLines, l, modLine) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 797acf629c..7b2a84bab0 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -641,7 +641,7 @@ holding Shift will put it in the second.]]) self:UpdateDisplayItemTooltip() end) self.controls.displayItemCatalyst.shown = function() - return self.displayItem and (self.displayItem.crafted or self.displayItem.hasModTags) and (self.displayItem.base.type == "Amulet" or self.displayItem.base.type == "Ring") + return self.displayItem and (self.displayItem.crafted or self.displayItem.hasModTags) and (self.displayItem.base.type == "Amulet" or self.displayItem.base.type == "Ring" or self.displayItem.base.type == "Jewel") end self.controls.displayItemCatalystQualityEdit = new("EditControl", {"LEFT",self.controls.displayItemCatalyst,"RIGHT"}, {2, 0, 60, 20}, nil, nil, "%D", 2, function(buf) self.displayItem.catalystQuality = tonumber(buf) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 96c7f933cb..db8a64b65b 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -949,6 +949,7 @@ c["+80 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BA c["+80 to Stun Threshold"]={{[1]={flags=0,keywordFlags=0,name="StunThreshold",type="BASE",value=80}},nil} c["+80 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=80}},nil} c["+80 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=80}},nil} +c["+85 to Spirit"]={{[1]={flags=0,keywordFlags=0,name="Spirit",type="BASE",value=85}},nil} c["+85 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=85}},nil} c["+85 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=85}},nil} c["+86 to maximum Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShield",type="BASE",value=86}},nil} @@ -1538,6 +1539,7 @@ c["13% increased Rarity of Items found"]={{[1]={flags=0,keywordFlags=0,name="Loo c["13% increased Skill Effect Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=13}},nil} c["13% increased Skill Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="INC",value=13},[2]={flags=0,keywordFlags=0,name="WarcrySpeed",type="INC",value=13},[3]={flags=0,keywordFlags=0,name="TotemPlacementSpeed",type="INC",value=13}},nil} c["13% increased Spell damage for each 200 total Mana you have Spent Recently"]={{[1]={[1]={div=200,type="Multiplier",var="ManaSpentRecently"},flags=2,keywordFlags=0,name="Damage",type="INC",value=13}},nil} +c["13% increased Spirit Reservation Efficiency"]={{[1]={flags=0,keywordFlags=0,name="SpiritReservationEfficiency",type="INC",value=13}},nil} c["13% increased maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="INC",value=13}},nil} c["13% increased maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="INC",value=13}},nil} c["13% of Damage from Deflected Hits is taken from Damageable Companion's Life before you"]={{[1]={flags=0,keywordFlags=0,name="TakenFromCompanionBeforeYouFromDeflected",type="BASE",value=13}},nil} @@ -1549,10 +1551,7 @@ c["13% reduced Flask Charges used"]={{[1]={flags=0,keywordFlags=0,name="FlaskCha c["13% reduced Skill Effect Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=-13}},nil} c["13% reduced maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="INC",value=-13}},nil} c["130% increased Armour and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEnergyShield",type="INC",value=130}},nil} -c["130% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ChaosDamage",type="INC",value=130}},nil} -c["130% increased Elemental Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=130}},nil} c["130% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=130}},nil} -c["130% increased Spell Physical Damage"]={{[1]={flags=2,keywordFlags=0,name="PhysicalDamage",type="INC",value=130}},nil} c["135% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=135}},nil} c["14% increased Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type="INC",value=14}},nil} c["14% increased Cooldown Recovery Rate"]={{[1]={flags=0,keywordFlags=0,name="CooldownRecovery",type="INC",value=14}},nil} @@ -1641,7 +1640,6 @@ c["15% increased Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="INC" c["15% increased Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=15}},nil} c["15% increased Duration of Ailments against Enemies with Exposure"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="HasExposure"},flags=0,keywordFlags=0,name="EnemyAilmentDuration",type="INC",value=15}},nil} c["15% increased Duration of Damaging Ailments on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyIgniteDuration",type="INC",value=15},[2]={flags=0,keywordFlags=0,name="EnemyBleedDuration",type="INC",value=15},[3]={flags=0,keywordFlags=0,name="EnemyPoisonDuration",type="INC",value=15}},nil} -c["15% increased Duration of Elemental Ailments on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyElementalAilmentDuration",type="INC",value=15}},nil} c["15% increased Duration of Ignite, Shock and Chill on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockDuration",type="INC",value=15},[2]={flags=0,keywordFlags=0,name="EnemyChillDuration",type="INC",value=15},[3]={flags=0,keywordFlags=0,name="EnemyIgniteDuration",type="INC",value=15}},nil} c["15% increased Effect of Puppet Master"]={{[1]={flags=0,keywordFlags=0,name="LocalEffect",type="INC",value=15}}," of Puppet Master "} c["15% increased Electrocute Buildup"]={{[1]={flags=0,keywordFlags=0,name="EnemyElectrocuteBuildup",type="INC",value=15}},nil} @@ -2216,6 +2214,9 @@ c["22% increased Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type= c["22% increased Critical Damage Bonus for Attack Damage"]={{[1]={flags=1,keywordFlags=0,name="CritMultiplier",type="INC",value=22}},nil} c["22% increased Critical Hit Chance for Attacks"]={{[1]={flags=1,keywordFlags=0,name="CritChance",type="INC",value=22}},nil} c["22.5 Life Regeneration per second"]={{[1]={flags=0,keywordFlags=0,name="LifeRegen",type="BASE",value=22.5}},nil} +c["221% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ChaosDamage",type="INC",value=221}},nil} +c["221% increased Elemental Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=221}},nil} +c["221% increased Spell Physical Damage"]={{[1]={flags=2,keywordFlags=0,name="PhysicalDamage",type="INC",value=221}},nil} c["225% increased Armour, Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="Defences",type="INC",value=225}},nil} c["225% increased Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=225}},nil} c["225% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=225}},nil} @@ -2338,6 +2339,7 @@ c["25% increased Damage with Spears"]={{[1]={flags=268435460,keywordFlags=0,name c["25% increased Damage with Swords"]={{[1]={flags=4194308,keywordFlags=0,name="Damage",type="INC",value=25}},nil} c["25% increased Daze Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=25}}," Daze "} c["25% increased Duration"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=25}},nil} +c["25% increased Duration of Elemental Ailments on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyElementalAilmentDuration",type="INC",value=25}},nil} c["25% increased Duration of each Puppet Master stack"]={{[1]={flags=0,keywordFlags=0,name="Duration",type="INC",value=25}}," of each Puppet Master stack "} c["25% increased Electrocute Buildup"]={{[1]={flags=0,keywordFlags=0,name="EnemyElectrocuteBuildup",type="INC",value=25}},nil} c["25% increased Elemental Ailment Threshold"]={{[1]={flags=0,keywordFlags=0,name="AilmentThreshold",type="INC",value=25}},nil} @@ -2993,6 +2995,7 @@ c["400% increased Armour and Evasion"]={{[1]={flags=0,keywordFlags=0,name="Armou c["400% increased Armour, Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="Defences",type="INC",value=400}},nil} c["400% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=400}},nil} c["41% increased Cast Speed"]={{[1]={flags=16,keywordFlags=0,name="Speed",type="INC",value=41}},nil} +c["42% chance to inflict Bleeding on Hit"]={{[1]={flags=0,keywordFlags=0,name="BleedChance",type="BASE",value=42}},nil} c["43% increased Melee Damage against Heavy Stunned enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="HeavyStunned"},flags=256,keywordFlags=0,name="Damage",type="INC",value=43}},nil} c["43% reduced Effect of Chill on you"]={{[1]={flags=0,keywordFlags=0,name="SelfChillEffect",type="INC",value=-43}},nil} c["43% reduced Magnitude of Ignite on you"]={{[1]={flags=0,keywordFlags=0,name="SelfIgniteEffect",type="INC",value=-43}},nil} @@ -3416,6 +3419,7 @@ c["7% increased Exposure Effect"]={{[1]={flags=0,keywordFlags=0,name="FireExposu c["7.5 Life Regeneration per second"]={{[1]={flags=0,keywordFlags=0,name="LifeRegen",type="BASE",value=7.5}},nil} c["70% increased Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="INC",value=70}},nil} c["70% increased Armour and Evasion"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEvasion",type="INC",value=70}},nil} +c["70% increased Desecrated Modifier magnitudes"]={{},nil} c["70% increased Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShield",type="INC",value=70}},nil} c["70% increased Energy Shield from Equipped Helmet"]={{[1]={[1]={slotName="Helmet",type="SlotName"},flags=0,keywordFlags=0,name="EnergyShield",type="INC",value=70}},nil} c["70% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=70}},nil} @@ -3425,6 +3429,7 @@ c["70% increased Rarity of Items found"]={{[1]={flags=0,keywordFlags=0,name="Loo c["70% reduced Recovery rate"]={{[1]={flags=0,keywordFlags=0,name="FlaskRecoveryRate",type="INC",value=-70}},nil} c["700% increased Armour and Evasion"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEvasion",type="INC",value=700}},nil} c["700% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=700}},nil} +c["71% increased Magnitude of Unholy Might buffs you grant"]={{[1]={flags=0,keywordFlags=0,name="Condition:UnholyMight",type="INC",value=71}}," Magnitude of buffs you grant "} c["72% increased Amount Recovered"]={{[1]={flags=0,keywordFlags=0,name="FlaskRecovery",type="INC",value=72}},nil} c["74% increased Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="INC",value=74}},nil} c["74% increased Armour and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEnergyShield",type="INC",value=74}},nil} @@ -3538,7 +3543,6 @@ c["8% increased Skill Speed"]={{[1]={flags=0,keywordFlags=0,name="Speed",type="I c["8% increased Skill Speed while Shapeshifted"]={{[1]={[1]={type="Condition",var="Shapeshifted"},flags=0,keywordFlags=0,name="Speed",type="INC",value=8},[2]={[1]={type="Condition",var="Shapeshifted"},flags=0,keywordFlags=0,name="WarcrySpeed",type="INC",value=8},[3]={[1]={type="Condition",var="Shapeshifted"},flags=0,keywordFlags=0,name="TotemPlacementSpeed",type="INC",value=8}},nil} c["8% increased Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type="INC",value=8}},nil} c["8% increased Spirit"]={{[1]={flags=0,keywordFlags=0,name="Spirit",type="INC",value=8}},nil} -c["8% increased Spirit Reservation Efficiency"]={{[1]={flags=0,keywordFlags=0,name="SpiritReservationEfficiency",type="INC",value=8}},nil} c["8% increased Stun Threshold"]={{[1]={flags=0,keywordFlags=0,name="StunThreshold",type="INC",value=8}},nil} c["8% increased Warcry Speed"]={{[1]={flags=0,keywordFlags=4,name="WarcrySpeed",type="INC",value=8}},nil} c["8% increased amount of Life Leeched"]={{[1]={flags=0,keywordFlags=0,name="MaxLifeLeechRate",type="INC",value=8}},nil} @@ -3569,8 +3573,7 @@ c["80% increased Critical Damage Bonus with Crossbows"]={{[1]={flags=67108868,ke c["80% increased Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=80}},nil} c["80% increased Critical Hit Chance for Spells"]={{[1]={flags=2,keywordFlags=0,name="CritChance",type="INC",value=80}},nil} c["80% increased Damage with Hits against Enemies that are on Full Life"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="FullLife"},flags=0,keywordFlags=262144,name="Damage",type="INC",value=80}},nil} -c["80% increased Desecrated Modifier magnitudes"]={{[1]={flags=0,keywordFlags=0,name="Magnitude",type="INC",value=80}}," Desecrated Modifier "} -c["80% increased Desecrated Modifier magnitudes 160% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="Magnitude",type="INC",value=80}}," Desecrated Modifier 160% increased Chaos Damage "} +c["80% increased Desecrated Modifier magnitudes"]={{},nil} c["80% increased Elemental Damage with Attacks"]={{[1]={flags=0,keywordFlags=65536,name="ElementalDamage",type="INC",value=80}},nil} c["80% increased Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShield",type="INC",value=80}},nil} c["80% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=80}},nil} @@ -5316,9 +5319,9 @@ c["Enemies take 20% increased Damage for each Elemental Ailment type among"]={ni c["Enemies take 20% increased Damage for each Elemental Ailment type among your Ailments on them"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Frozen"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[2]={[1]={actor="enemy",type="ActorCondition",var="Chilled"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[3]={[1]={actor="enemy",type="ActorCondition",var="Ignited"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[4]={[1]={actor="enemy",type="ActorCondition",var="Shocked"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[5]={[1]={actor="enemy",type="ActorCondition",var="Scorched"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[6]={[1]={actor="enemy",type="ActorCondition",var="Brittle"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[7]={[1]={actor="enemy",type="ActorCondition",var="Sapped"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}},[8]={[1]={actor="enemy",type="ActorCondition",var="Electrocuted"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}}},nil} c["Enemies you Curse are Hindered, with 15% reduced Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Cursed"},flags=0,keywordFlags=0,name="Condition:Hindered",type="FLAG",value=true}}}},nil} c["Enemies you Curse cannot Recharge Energy Shield"]={{[1]={[1]={type="Condition",var="Curse"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="NoEnergyShieldRecharge",type="FLAG",value=true}}}},nil} +c["Enemies you Curse have -11% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Curse"},flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=-11}}}},nil} c["Enemies you Curse have -3% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Curse"},flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=-3}}}},nil} c["Enemies you Curse have -5% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Curse"},flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=-5}}}},nil} -c["Enemies you Curse have -7% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Curse"},flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=-7}}}},nil} c["Enemies you Electrocute have 20% increased Damage taken"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="Electrocuted"},flags=0,keywordFlags=0,name="DamageTaken",type="INC",value=20}}}},nil} c["Enemies you Fully Armour Break are Maimed"]={nil,"Enemies you Fully Armour Break are Maimed "} c["Enemies you Fully Armour Break cannot Regenerate Life"]={nil,"Enemies you Fully Armour Break cannot Regenerate Life "} diff --git a/src/Data/Uniques/staff.lua b/src/Data/Uniques/staff.lua index 6b63446938..196bcb3346 100644 --- a/src/Data/Uniques/staff.lua +++ b/src/Data/Uniques/staff.lua @@ -229,17 +229,17 @@ Grants Skill: Level (1-20) Feast of Flesh {variant:5}Grants Skill: Level (1-20) His Vile Intrusion {variant:6}Grants Skill: Level (1-20) His Winnowing Flame (60-80)% increased Desecrated Modifier magnitudes -{variant:9}(100-160)% increased Chaos Damage -{variant:11}(100-160)% increased Chaos Damage -{variant:10}(100-160)% increased Spell Physical Damage -{variant:8}+(40-60) to Spirit -{variant:7}(10-20)% increased Duration of Elemental Ailments on Enemies -{variant:7}(100-160)% increased Elemental Damage -{variant:11}Enemies you kill have a (5-10)% chance to explode, dealing a quarter of their maximum Life as Chaos damage -{variant:9}Enemies you Curse have -(8-5)% to Chaos Resistance -{variant:10}(20-30)% chance to inflict Bleeding on Hit -{variant:8}(6-10)% increased Spirit Reservation Efficiency -{variant:12}(28-56)% increased Magnitude of Unholy Might buffs you grant -{variant:12}You have Unholy Might +{variant:9}{desecrated}(100-160)% increased Chaos Damage +{variant:11}{desecrated}(100-160)% increased Chaos Damage +{variant:10}{desecrated}(100-160)% increased Spell Physical Damage +{variant:8}{desecrated}+(40-60) to Spirit +{variant:7}{desecrated}(10-20)% increased Duration of Elemental Ailments on Enemies +{variant:7}{desecrated}(100-160)% increased Elemental Damage +{variant:11}{desecrated}Enemies you kill have a (5-10)% chance to explode, dealing a quarter of their maximum Life as Chaos damage +{variant:9}{desecrated}Enemies you Curse have -(8-5)% to Chaos Resistance +{variant:10}{desecrated}(20-30)% chance to inflict Bleeding on Hit +{variant:8}{desecrated}(6-10)% increased Spirit Reservation Efficiency +{variant:12}{desecrated}(28-56)% increased Magnitude of Unholy Might buffs you grant +{variant:12}{desecrated}You have Unholy Might ]], } diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 52fa3b4316..3001bbb489 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -6229,7 +6229,10 @@ local specialModList = { } end, ["you can socket an additional copy of each lineage support gem, in different skills"] = { mod("MaxLineageCount", "BASE", 1) }, ["you can socket (%d+) additional copies of each lineage support gem, in different skills"] = function(num) return { mod("MaxLineageCount", "BASE", num) } end, - ["can be modified while corrupted"] = {} + ["can be modified while corrupted"] = {}, + -- handled in item parsing + ["%d+%% [id][ne]creased ?[%a%s]* modifier magnitudes"] = {}, + ["%d+%% [id][ne]creased effect of [sp][ur][fe]fixes"] = {}, } for _, name in pairs(data.keystones) do specialModList[name:lower()] = { mod("Keystone", "LIST", name) }