From 1ee5ac6f1c7f97f2075b2135e85e38d415ed747a Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Mon, 3 Aug 2026 20:24:25 +0300 Subject: [PATCH 1/2] Add support for having rare mod crafting on uniques --- src/Classes/Item.lua | 64 ++++++++++++++++++++--- src/Classes/ItemsTab.lua | 29 +++++++---- src/Data/ModCache.lua | 51 ++----------------- src/Data/Uniques/helmet.lua | 1 + src/Export/Uniques/helmet.lua | 1 + src/Modules/Data.lua | 96 ++++++++++++++++++++++++++++++++++- src/Modules/ModParser.lua | 7 +++ 7 files changed, 182 insertions(+), 67 deletions(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 1274c4a401c..bc9d88ab8f5 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -494,6 +494,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.baseLines = { } self.foulborn = false self.mutatedLines = nil + ---@type RareLikeUniqueDescription? + self.rareLikeUnique = nil local importedLevelReq local flaskBuffLines local tinctureBuffLines @@ -563,15 +565,16 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) local backupAffixList = { } for modId, modData in pairs(self.affixes) do if modData.affix == modName then + local ignoreModType = self.rareLikeUnique and self.rareLikeUnique.ignorePrefixSuffix if self:CanHaveMod(modData) then - if modData.type == "Prefix" then + if modData.type == "Prefix" or ignoreModType then t_insert(self.pendingAffixList, { modId = modId, table = self.prefixes }) elseif modData.type == "Suffix" then t_insert(self.pendingAffixList, { modId = modId, table = self.suffixes }) end else -- Conqueror mods can't natively spawn on items, so we'll use those if we don't find a match otherwise - if modData.type == "Prefix" then + if modData.type == "Prefix" or ignoreModType then t_insert(backupAffixList, { modId = modId, table = self.prefixes }) elseif modData.type == "Suffix" then t_insert(backupAffixList, { modId = modId, table = self.suffixes }) @@ -752,6 +755,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.variantAlt4 = specToNumber(specVal) elseif specName == "Selected Alt Variant Five" then self.variantAlt5 = specToNumber(specVal) + elseif specName == "Allow Duplicate Variants" then + self.allowDuplicateVariants = specVal == "true" elseif specName == "Has Variants" or specName == "Selected Variants" then -- Need to skip this line for backwards compatibility -- with builds that used an old Watcher's Eye implementation @@ -1000,6 +1005,10 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.affixes = (self.base.subType and data.itemMods[self.base.type..self.base.subType]) or data.itemMods[self.base.type] or data.itemMods.Item + if self.title and data.rareLikeUniques[self.title:lower()] then + self.rareLikeUnique = data.rareLikeUniques[self.title:lower()] + self.affixes = self.rareLikeUnique.affixes + end if self.base.flask then if self.base.utility_flask then self.enchantments = data.enchantments["UtilityFlask"] @@ -1372,6 +1381,10 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end for _, mods in ipairs(modLists) do for _, mod in ipairs(mods or {}) do + -- avoid scaling variant lines which are not active + if mod.variantList and (self:GetModLineVariantCount(mod) == 0) then + goto modMagnitudeContinue + end -- Create a fast lookup table for all provided tags local tagLookup = {} for _, curTag in ipairs(mod.modTags) do @@ -1400,12 +1413,13 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end end if mod.valueScalar and mod.valueScalar ~= 1 then - local rangedLine = itemLib.applyRange(mod.line, mod.range, mod.valueScalar, 1) + local rangedLine = itemLib.applyRange(mod.line, mod.range or 1, mod.valueScalar, 1) local modList, extra = modLib.parseMod(rangedLine) mod.displayValueScalar = 1 mod.modList = modList mod.extra = extra end + ::modMagnitudeContinue:: end end end @@ -1433,6 +1447,9 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.suffixes.limit = m_max(m_min((self.suffixes.limit or 0) + self.affixLimit / 2, self.affixLimit), 0) self.affixLimit = self.prefixes.limit + self.suffixes.limit end + elseif self.rareLikeUnique then + self.affixLimit = self.rareLikeUnique.affixLimits.affixLimit + self.prefixes.limit = self.rareLikeUnique.affixLimits.prefixLimit else self.crafted = false end @@ -1910,6 +1927,9 @@ function ItemClass:BuildRaw() t_insert(rawLines, "Has Alt Variant Five: true") t_insert(rawLines, "Selected Alt Variant Five: " .. self.variantAlt5) end + if self.allowDuplicateVariants then + t_insert(rawLines, "Allow Duplicate Variants: true") + end end if not self.variantList then for _, baseLine in pairs(self.baseLines or { }) do @@ -1990,7 +2010,7 @@ function ItemClass:Craft() -- Save off any crafted or custom mods so they can be re-added at the end local savedMods = {} for _, mod in ipairs(self.explicitModLines) do - if mod.crafted or mod.custom then + if mod.crafted or mod.custom or (self.rareLikeUnique and not (mod.prefix or mod.suffix)) then t_insert(savedMods, mod) end end @@ -2000,7 +2020,8 @@ function ItemClass:Craft() self.nameSuffix = "" self.requirements.level = self.base.req.level local statOrder = { } - for _, list in ipairs({self.prefixes,self.suffixes}) do + local modLists = { self.prefixes, self.suffixes } + for _, list in ipairs(modLists) do for i = 1, (list.limit or (self.affixLimit / 2)) do local affix = list[i] if not affix then @@ -2079,6 +2100,23 @@ function ItemClass:CheckModLineVariant(modLine) or (self.hasAltVariant5 and modLine.variantList[self.variantAlt5]) end +function ItemClass:GetModLineVariantCount(modLine) + if not self.allowDuplicateVariants or not modLine.variantList then + return self:CheckModLineVariant(modLine) and 1 or 0 + end + + -- Mageblood can intentionally select the same variant more than once. + local variantList = modLine.variantList + local count = variantList[self.variant] and 1 or 0 + for i = 1, 5 do + local suffix = i == 1 and "" or i + local variant = self["variantAlt" .. suffix] + if self["hasAltVariant" .. suffix] and variant and variantList[variant] then + count = count + 1 + end + end + return count +end -- Return the name of the slot this item is equipped in function ItemClass:GetPrimarySlot() if self.base.weapon then @@ -2468,7 +2506,8 @@ function ItemClass:BuildModList() if modLine.disabled then return end - if self:CheckModLineVariant(modLine) then + local variantCount = self:GetModLineVariantCount(modLine) + if variantCount > 0 then -- special section for variant over-ride of pre-modifier item parameters if modLine.line:find("Requires Class") then self.classRestriction = modLine.line:gsub("{variant:([%d,]+)}", ""):match("Requires Class (.+)") @@ -2485,8 +2524,9 @@ function ItemClass:BuildModList() end if not modLine.extra then for _, mod in ipairs(modLine.modList) do - mod = modLib.setSource(mod, self.modSource) - baseList:AddMod(mod) + for _ = 1, variantCount do + baseList:AddMod(modLib.setSource(mod, self.modSource)) + end end if modLine.modTags and #modLine.modTags > 0 then self.hasModTags = true @@ -2546,6 +2586,7 @@ function ItemClass:BuildModList() -- Remove all sockets wipeTable(self.sockets) self.selectableSocketCount = 0 + self.abyssalSocketCount = 0 elseif socketCount > 0 then -- Force the socket count to be equal to the stated number self.selectableSocketCount = socketCount @@ -2613,6 +2654,13 @@ function ItemClass:CanHaveMod(mod) if data.minionTagCrucibleUniques[self.title] then includeTags["minion_unique_weapon"] = true end + if self.rareLikeUnique then + for _, base in ipairs(self.rareLikeUnique.validBases) do + if self:GetModSpawnWeight(mod, base.base.tags) > 0 then + return true + end + end + end if self.canHaveOnlySupportSkillsCrucibleTree then return keyMap["crucible_unique_staff"] and mod.weightVal[keyMap["crucible_unique_staff"]] ~= 0 elseif self.canHaveShieldCrucibleTree then diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 2633489f738..1b323875ad0 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -939,7 +939,10 @@ holding Shift will put it in the second.]]) drop.slider = slider self.controls["displayItemAffix"..i] = drop self.controls["displayItemAffixLabel"..i] = new("LabelControl", {"RIGHT",drop,"LEFT"}, {-4, 0, 0, 14}, function() - return drop.outputTable == "prefixes" and "^7Prefix:" or "^7Suffix:" + local ignoreModType = self.displayItem.rareLikeUnique and self.displayItem.rareLikeUnique.ignorePrefixSuffix + return ignoreModType and "Explicit:" + or drop.outputTable == "prefixes" and "^7Prefix:" + or "^7Suffix:" end) self.controls["displayItemAffixRange"..i] = slider self.controls["displayItemAffixRangeLabel"..i] = new("LabelControl", {"RIGHT",slider,"LEFT"}, {-4, 0, 0, 14}, function() @@ -956,7 +959,7 @@ holding Shift will put it in the second.]]) self:AddCustomModifierToDisplayItem() end) self.controls.displayItemAddCustom.shown = function() - return self.displayItem and (self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE") + return self.displayItem and (self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE" or self.rareLikeUnique) end -- Section: Crucible modifiers @@ -2075,9 +2078,14 @@ end function ItemsTabClass:UpdateAffixControls() local item = self.displayItem local prefixLimit = item.prefixes.limit or (item.affixLimit / 2) + local ignoreModType = item.rareLikeUnique and item.rareLikeUnique.ignorePrefixSuffix for i = 1, item.affixLimit do if i <= prefixLimit then - self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Prefix", "prefixes", i) + local modType = "Prefix" + if ignoreModType then + modType = nil + end + self:UpdateAffixControl(self.controls["displayItemAffix" .. i], item, modType, "prefixes", i) else self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Suffix", "suffixes", i - prefixLimit) end @@ -2117,8 +2125,8 @@ function ItemsTabClass:UpdateAffixControl(control, item, affixType, outputTable, local affixList = { } local retainedAffixes = { } for modId, mod in pairs(item.affixes) do - if mod.type == affixType and not excludeGroups[mod.group] and not item:CheckIfModIsDelve(mod) then - if item:GetModSpawnWeight(mod, extraTags) > 0 then + if (not affixType or (mod.type == affixType)) and not excludeGroups[mod.group] and not item:CheckIfModIsDelve(mod) then + if (item.rareLikeUnique and item:CanHaveMod(mod)) or item:GetModSpawnWeight(mod, extraTags) > 0 then t_insert(affixList, modId) elseif modId == selAffix then t_insert(affixList, modId) @@ -2223,7 +2231,7 @@ function ItemsTabClass:UpdateCustomControls() t_insert(modLines, line) end end - if item.rarity == "MAGIC" or item.rarity == "RARE" or (item.crucibleModLines and #item.crucibleModLines > 0) then + if item.rareLikeUnique or item.rarity == "MAGIC" or item.rarity == "RARE" or (item.crucibleModLines and #item.crucibleModLines > 0) then for index, modLine in ipairs(modLines) do if modLine.custom or modLine.crafted or modLine.crucible then local line = itemLib.formatModLine(modLine) @@ -4484,10 +4492,11 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) for _, modList in ipairs{item.enchantModLines, item.scourgeModLines, item.implicitModLines, item.explicitModLines, item.crucibleModLines} do if modList[1] then for _, modLine in ipairs(modList) do - if item:CheckModLineVariant(modLine) then - local formatted = itemLib.formatModLine(modLine, dbMode) - if formatted then - tooltip:AddLine(fontSizeBig, formatted, "FONTIN SC", modLine) + local variantCount = item:GetModLineVariantCount(modLine) + if variantCount > 0 then + local formattedModLine = itemLib.formatModLine(modLine, dbMode) + for _ = 1, variantCount do + tooltip:AddLine(fontSizeBig, formattedModLine, "FONTIN SC") end end end diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index d26e46498e3..0b9043d91e7 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -427,7 +427,6 @@ c["+12% to Fire Damage over Time Multiplier with Attack Skills"]={{[1]={flags=0, c["+12% to Fire and Cold Resistances"]={{[1]={flags=0,keywordFlags=0,name="FireResist",type="BASE",value=12},[2]={flags=0,keywordFlags=0,name="ColdResist",type="BASE",value=12}},nil} c["+12% to Fire and Lightning Resistances"]={{[1]={flags=0,keywordFlags=0,name="FireResist",type="BASE",value=12},[2]={flags=0,keywordFlags=0,name="LightningResist",type="BASE",value=12}},nil} c["+12% to Melee Critical Strike Multiplier"]={{[1]={flags=256,keywordFlags=0,name="CritMultiplier",type="BASE",value=12}},nil} -c["+12% to Quality of Socketed Support Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="quality",keyword="support",value=12}}},nil} c["+12% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=12}},nil} c["+12% to all Elemental Resistances for each Empty White Socket on any Equipped Item"]={{[1]={[1]={type="Multiplier",var="EmptyWhiteSocketsInAnySlot"},flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=12}},nil} c["+120 Energy Shield gained on Killing a Shocked Enemy"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Shocked"},flags=0,keywordFlags=0,name="EnergyShieldOnKill",type="BASE",value=120}},nil} @@ -922,7 +921,6 @@ c["+3 to Level of Socketed Fire Gems"]={{[1]={[1]={slotName="{SlotName}",type="S c["+3 to Level of Socketed Golem Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyword="golem",value=3}}},nil} c["+3 to Level of Socketed Lightning Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyword="lightning",value=3}}},nil} c["+3 to Level of Socketed Minion Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyword="minion",value=3}}},nil} -c["+3 to Level of Socketed Support Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyword="support",value=3}}},nil} c["+3 to Level of Socketed Warcry Gems"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyword="warcry",value=3}}},nil} c["+3 to Level of all Absolution Gems"]={{[1]={flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyOfScaledMod="value",keyword="absolution",value=3}}},nil} c["+3 to Level of all Alchemist's Mark Gems"]={{[1]={flags=0,keywordFlags=0,name="GemProperty",type="LIST",value={key="level",keyOfScaledMod="value",keyword="alchemist's mark",value=3}}},nil} @@ -1376,7 +1374,6 @@ c["+35% to all Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="Eleme c["+350 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=350}},nil} c["+350 to Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="BASE",value=350}},nil} c["+350 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=350}},nil} -c["+36% Chance to Block Attack Damage"]={{[1]={flags=0,keywordFlags=0,name="BlockChance",type="BASE",value=36}},nil} c["+36% Chance to Block Spell Damage while on Low Life"]={{[1]={[1]={type="Condition",var="LowLife"},flags=0,keywordFlags=0,name="SpellBlockChance",type="BASE",value=36}},nil} c["+36% to Chaos Resistance"]={{[1]={flags=0,keywordFlags=0,name="ChaosResist",type="BASE",value=36}},nil} c["+36% to Cold Resistance"]={{[1]={flags=0,keywordFlags=0,name="ColdResist",type="BASE",value=36}},nil} @@ -1455,7 +1452,6 @@ c["+40 to maximum Life for each Empty Red Socket on any Equipped Item"]={{[1]={[ c["+40 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=40}},nil} c["+40 to maximum Mana for each Empty Blue Socket on any Equipped Item"]={{[1]={[1]={type="Multiplier",var="EmptyBlueSocketsInAnySlot"},flags=0,keywordFlags=0,name="Mana",type="BASE",value=40}},nil} c["+40% Chance to Block Attack Damage during Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="BlockChance",type="BASE",value=40}},nil} -c["+40% Chance to Block Spell Damage"]={{[1]={flags=0,keywordFlags=0,name="SpellBlockChance",type="BASE",value=40}},nil} c["+40% Critical Strike Multiplier while a Rare or Unique Enemy is Nearby"]={{[1]={[1]={actor="enemy",type="ActorCondition",varList={[1]="NearbyRareOrUniqueEnemy",[2]="RareOrUnique"}},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=40}},nil} c["+40% Global Critical Strike Multiplier while you have a Frenzy Charge"]={{[1]={[1]={type="Global"},[2]={stat="FrenzyCharges",threshold=1,type="StatThreshold"},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=40}},nil} c["+40% chance to Suppress Spell Damage while your Off Hand is empty"]={{[1]={[1]={type="Condition",var="OffHandIsEmpty"},flags=0,keywordFlags=0,name="SpellSuppressionChance",type="BASE",value=40}},nil} @@ -1520,9 +1516,6 @@ c["+450 to Accuracy Rating while at Maximum Frenzy Charges"]={{[1]={[1]={stat="F c["+450 to Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="BASE",value=450}},nil} c["+450 to Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=450}},nil} c["+460 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=460}},nil} -c["+47 to Dexterity and Intelligence"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=47},[2]={flags=0,keywordFlags=0,name="Int",type="BASE",value=47},[3]={flags=0,keywordFlags=0,name="DexInt",type="BASE",value=47}},nil} -c["+47 to Strength and Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Str",type="BASE",value=47},[2]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=47},[3]={flags=0,keywordFlags=0,name="StrDex",type="BASE",value=47}},nil} -c["+47 to Strength and Intelligence"]={{[1]={flags=0,keywordFlags=0,name="Str",type="BASE",value=47},[2]={flags=0,keywordFlags=0,name="Int",type="BASE",value=47},[3]={flags=0,keywordFlags=0,name="StrInt",type="BASE",value=47}},nil} c["+47 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=47}},nil} c["+470 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=470}},nil} c["+475 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=475}},nil} @@ -1597,7 +1590,6 @@ c["+50 to all Attributes"]={{[1]={flags=0,keywordFlags=0,name="Str",type="BASE", c["+50 to maximum Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShield",type="BASE",value=50}},nil} c["+50 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=50}},nil} c["+50 to maximum Mana"]={{[1]={flags=0,keywordFlags=0,name="Mana",type="BASE",value=50}},nil} -c["+50% Chance to Block Attack Damage"]={{[1]={flags=0,keywordFlags=0,name="BlockChance",type="BASE",value=50}},nil} c["+50% Chance to Block Attack Damage during Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="BlockChance",type="BASE",value=50}},nil} c["+50% Global Critical Strike Multiplier while you have a Frenzy Charge"]={{[1]={[1]={type="Global"},[2]={stat="FrenzyCharges",threshold=1,type="StatThreshold"},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=50}},nil} c["+50% Global Critical Strike Multiplier while you have no Frenzy Charges"]={{[1]={[1]={type="Global"},[2]={stat="FrenzyCharges",threshold=0,type="StatThreshold",upper=true},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=50}},nil} @@ -1646,7 +1638,6 @@ c["+55% to Cold Resistance while affected by Herald of Ice"]={{[1]={[1]={type="C c["+55% to Fire Resistance"]={{[1]={flags=0,keywordFlags=0,name="FireResist",type="BASE",value=55}},nil} c["+55% to Fire Resistance while affected by Herald of Ash"]={{[1]={[1]={type="Condition",var="AffectedByHeraldofAsh"},flags=0,keywordFlags=0,name="FireResist",type="BASE",value=55}},nil} c["+55% to Lightning Resistance while affected by Herald of Thunder"]={{[1]={[1]={type="Condition",var="AffectedByHeraldofThunder"},flags=0,keywordFlags=0,name="LightningResist",type="BASE",value=55}},nil} -c["+579 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=579}},nil} c["+58 to Dexterity"]={{[1]={flags=0,keywordFlags=0,name="Dex",type="BASE",value=58}},nil} c["+6 to Armour and Evasion Rating per 1% Chance to Block Attack Damage"]={{[1]={[1]={div=1,stat="BlockChance",type="PerStat"},flags=0,keywordFlags=0,name="ArmourAndEvasion",type="BASE",value=6}},nil} c["+6 to Maximum Life per Elder Item Equipped"]={{[1]={[1]={type="Multiplier",var="ElderItem"},flags=0,keywordFlags=0,name="Life",type="BASE",value=6}},nil} @@ -1813,8 +1804,6 @@ c["+80% to Cold Damage over Time Multiplier"]={{[1]={flags=0,keywordFlags=0,name c["+80% to Critical Strike Multiplier for Spells if you haven't Killed Recently"]={{[1]={[1]={neg=true,type="Condition",var="KilledRecently"},flags=2,keywordFlags=0,name="CritMultiplier",type="BASE",value=80}},nil} c["+80% to Critical Strike Multiplier with One Handed Melee Weapons"]={{[1]={flags=335544324,keywordFlags=0,name="CritMultiplier",type="BASE",value=80}},nil} c["+80% to Damage over Time Multiplier for Bleeding from Critical Strikes"]={{[1]={[1]={type="Condition",var="CriticalStrike"},flags=0,keywordFlags=4194304,name="DotMultiplier",type="BASE",value=80}},nil} -c["+80% to Fire Damage over Time Multiplier"]={{[1]={flags=0,keywordFlags=0,name="FireDotMultiplier",type="BASE",value=80}},nil} -c["+80% to Physical Damage over Time Multiplier"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDotMultiplier",type="BASE",value=80}},nil} c["+800 Armour if you've Blocked Recently"]={{[1]={[1]={type="Condition",var="BlockedRecently"},flags=0,keywordFlags=0,name="Armour",type="BASE",value=800}},nil} c["+800 Armour while stationary"]={{[1]={[1]={type="Condition",var="Stationary"},flags=0,keywordFlags=0,name="Armour",type="BASE",value=800}},nil} c["+800 to Accuracy Rating"]={{[1]={flags=0,keywordFlags=0,name="Accuracy",type="BASE",value=800}},nil} @@ -1851,7 +1840,6 @@ c["+92 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",v c["+95 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=95}},nil} c["+96 to maximum Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShield",type="BASE",value=96}},nil} c["+99 to maximum Life"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=99}},nil} -c["+99% Critical Strike Multiplier while a Rare or Unique Enemy is Nearby"]={{[1]={[1]={actor="enemy",type="ActorCondition",varList={[1]="NearbyRareOrUniqueEnemy",[2]="RareOrUnique"}},flags=0,keywordFlags=0,name="CritMultiplier",type="BASE",value=99}},nil} c["-1 Fire Damage taken from Hits per Mana Burn"]={{[1]={[1]={type="Multiplier",var="ManaBurnStacks"},flags=0,keywordFlags=0,name="FireDamageTakenWhenHit",type="BASE",value=-1}},nil} c["-1 Physical Damage taken from Hits per Level"]={{[1]={[1]={type="Multiplier",var="Level"},flags=0,keywordFlags=0,name="PhysicalDamageTakenWhenHit",type="BASE",value=-1}},nil} c["-1 Prefix Modifier allowed"]={{},nil} @@ -3233,9 +3221,6 @@ c["14% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ChaosDamage" c["14% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} c["14% increased Damage Over Time with Bow Skills"]={{[1]={flags=8,keywordFlags=1024,name="Damage",type="INC",value=14}},nil} c["14% increased Damage if you have Consumed a corpse Recently"]={{[1]={[1]={type="Condition",var="ConsumedCorpseRecently"},flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} -c["14% increased Damage per Endurance Charge"]={{[1]={[1]={type="Multiplier",var="EnduranceCharge"},flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} -c["14% increased Damage per Frenzy Charge"]={{[1]={[1]={type="Multiplier",var="FrenzyCharge"},flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} -c["14% increased Damage per Power Charge"]={{[1]={[1]={type="Multiplier",var="PowerCharge"},flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} c["14% increased Damage while wielding a Wand"]={{[1]={[1]={type="Condition",var="UsingWand"},flags=0,keywordFlags=0,name="Damage",type="INC",value=14}},nil} c["14% increased Damage with One Handed Weapons"]={{[1]={flags=268435460,keywordFlags=0,name="Damage",type="INC",value=14}},nil} c["14% increased Elemental Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamage",type="INC",value=14}},nil} @@ -3273,7 +3258,6 @@ c["145 to 200 Added Cold Damage with Bow Attacks"]={{[1]={flags=131076,keywordFl c["145% increased Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EvasionAndEnergyShield",type="INC",value=145}},nil} c["145% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=145}},nil} c["146% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=146}},nil} -c["148% increased Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type="INC",value=148}},nil} c["15 to 289 Added Lightning Damage with Wand Attacks"]={{[1]={flags=8388612,keywordFlags=0,name="LightningMin",type="BASE",value=15},[2]={flags=8388612,keywordFlags=0,name="LightningMax",type="BASE",value=289}},nil} c["15% Chance to Block Attack Damage"]={{[1]={flags=0,keywordFlags=0,name="BlockChance",type="BASE",value=15}},nil} c["15% Chance to Block Spell Damage"]={{[1]={flags=0,keywordFlags=0,name="SpellBlockChance",type="BASE",value=15}},nil} @@ -3742,7 +3726,6 @@ c["190% increased Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name c["190% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=190}},nil} c["195% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=195}},nil} c["197% increased Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ChaosDamage",type="INC",value=197}},nil} -c["197% increased Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type="INC",value=197}},nil} c["2 Enemy Writhing Worms escape the Flask when used"]={{}," Enemy Writhing Worms escape the Flask when used "} c["2 Enemy Writhing Worms escape the Flask when used Writhing Worms are destroyed when Hit"]={{}," Enemy Writhing Worms escape the Flask when used Writhing Worms are destroyed when Hit "} c["2 to 38 Lightning Damage per Power Charge"]={{[1]={[1]={type="Multiplier",var="PowerCharge"},flags=0,keywordFlags=0,name="LightningMin",type="BASE",value=2},[2]={[1]={type="Multiplier",var="PowerCharge"},flags=0,keywordFlags=0,name="LightningMax",type="BASE",value=38}},nil} @@ -4255,7 +4238,6 @@ c["22% Chance to Block Attack Damage"]={{[1]={flags=0,keywordFlags=0,name="Block c["22% Chance to Block Spell Damage"]={{[1]={flags=0,keywordFlags=0,name="SpellBlockChance",type="BASE",value=22}},nil} c["22% chance to Freeze"]={{[1]={flags=0,keywordFlags=0,name="EnemyFreezeChance",type="BASE",value=22}},nil} c["22% chance to Ignite"]={{[1]={flags=0,keywordFlags=0,name="EnemyIgniteChance",type="BASE",value=22}},nil} -c["22% chance to deal Double Damage"]={{[1]={flags=0,keywordFlags=0,name="DoubleDamageChance",type="BASE",value=22}},nil} c["22% increased Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type="INC",value=22}},nil} c["22% increased Attack Speed while a Rare or Unique Enemy is Nearby"]={{[1]={[1]={actor="enemy",type="ActorCondition",varList={[1]="NearbyRareOrUniqueEnemy",[2]="RareOrUnique"}},flags=1,keywordFlags=0,name="Speed",type="INC",value=22}},nil} c["22% increased Cast Speed"]={{[1]={flags=16,keywordFlags=0,name="Speed",type="INC",value=22}},nil} @@ -4287,11 +4269,6 @@ c["225% increased Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EnergyShie c["225% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="INC",value=225}},nil} c["225% increased Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EvasionAndEnergyShield",type="INC",value=225}},nil} c["225% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=225}},nil} -c["227% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=227}},nil} -c["229% increased Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="ColdDamage",type="INC",value=229}},nil} -c["229% increased Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="FireDamage",type="INC",value=229}},nil} -c["229% increased Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="LightningDamage",type="INC",value=229}},nil} -c["229% increased Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type="INC",value=229}},nil} c["23% chance to Avoid Elemental Ailments"]={{[1]={flags=0,keywordFlags=0,name="AvoidElementalAilments",type="BASE",value=23}},nil} c["23% chance to Freeze"]={{[1]={flags=0,keywordFlags=0,name="EnemyFreezeChance",type="BASE",value=23}},nil} c["23% chance to Freeze, Shock and Ignite"]={{[1]={flags=0,keywordFlags=0,name="EnemyFreezeChance",type="BASE",value=23},[2]={flags=0,keywordFlags=0,name="EnemyShockChance",type="BASE",value=23},[3]={flags=0,keywordFlags=0,name="EnemyIgniteChance",type="BASE",value=23}},nil} @@ -4678,7 +4655,6 @@ c["250% increased Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="Evasion", c["250% increased Evasion and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="EvasionAndEnergyShield",type="INC",value=250}},nil} c["250% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="INC",value=250}},nil} c["250% increased bonuses gained from Equipped Quiver"]={{[1]={flags=0,keywordFlags=0,name="EffectOfBonusesFromQuiver",type="INC",value=250}},nil} -c["26% chance to gain Arcane Surge when you Kill an Enemy"]={{[1]={[1]={type="Condition",var="KilledRecently"},flags=0,keywordFlags=0,name="Condition:ArcaneSurge",type="FLAG",value=true}},nil} c["26% increased Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type="INC",value=26}},nil} c["26% increased Critical Strike Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=26}},nil} c["26% increased Effect of Lightning Ailments"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockEffect",type="INC",value=26},[2]={flags=0,keywordFlags=0,name="EnemySapEffect",type="INC",value=26}},nil} @@ -5356,16 +5332,12 @@ c["40% chance for Elemental Ailments inflicted on you to"]={{}," for Elemental A c["40% chance for Elemental Ailments inflicted on you to be inflicted on a nearby Minion instead"]={{}," for Elemental Ailments inflicted on you to be inflicted on a nearby instead "} c["40% chance for Elemental Ailments inflicted on you to be inflicted on a nearby Minion instead Limited to 1 Runegraft of Loyalty"]={{}," for Elemental Ailments inflicted on you to be inflicted on a nearby instead Limited to 1 Runegraft of Loyalty "} c["40% chance for Elemental Resistances to count as being 90% against Enemy Hits"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="BASE",value=40}}," for to count as being 90% against Enemy Hits "} -c["40% chance to Blind Enemies on hit"]={{}," to Blind Enemies "} c["40% chance to Chill Attackers for 4 seconds on Block"]={{}," to Chill Attackers on Block "} c["40% chance to Chill Attackers for 4 seconds on Block 40% chance to Shock Attackers for 4 seconds on Block"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="BASE",value=40}}," to Chill Attackers on Block 40% chance Attackers on Block "} c["40% chance to Freeze"]={{[1]={flags=0,keywordFlags=0,name="EnemyFreezeChance",type="BASE",value=40}},nil} c["40% chance to Ignite"]={{[1]={flags=0,keywordFlags=0,name="EnemyIgniteChance",type="BASE",value=40}},nil} -c["40% chance to Impale Enemies on Hit with Attacks"]={{[1]={flags=0,keywordFlags=65536,name="ImpaleChance",type="BASE",value=40}},nil} -c["40% chance to Poison on Hit"]={{[1]={flags=0,keywordFlags=0,name="PoisonChance",type="BASE",value=40}},nil} c["40% chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="BASE",value=40}},nil} c["40% chance to Shock Attackers for 4 seconds on Block"]={{[1]={flags=0,keywordFlags=0,name="ShockBase",type="BASE",value=15}},nil} -c["40% chance to cause Bleeding on Hit"]={{[1]={flags=0,keywordFlags=0,name="BleedChance",type="BASE",value=40}},nil} c["40% chance to deal Double Damage while Focused"]={{[1]={[1]={type="Condition",var="Focused"},flags=0,keywordFlags=0,name="DoubleDamageChance",type="BASE",value=40}},nil} c["40% chance to gain a Flask Charge when you deal a Critical Strike"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargeOnCritChance",type="BASE",value=40}},nil} c["40% chance to gain a Frenzy Charge for each Enemy you hit with a Critical Strike"]={nil,"a Frenzy Charge for each Enemy you hit with a Critical Strike "} @@ -5834,10 +5806,8 @@ c["50% increased Aspect of the Spider Debuff Duration"]={{[1]={[1]={skillName="A c["50% increased Attack Damage against Enemies with a higher percentage of their Life remaining than you"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="HigherLifePercentThanPlayer"},flags=1,keywordFlags=0,name="Damage",type="INC",value=50}},nil} c["50% increased Attack Speed"]={{[1]={flags=1,keywordFlags=0,name="Speed",type="INC",value=50}},nil} c["50% increased Attack Speed when on Low Life"]={{[1]={[1]={type="Condition",var="LowLife"},flags=1,keywordFlags=0,name="Speed",type="INC",value=50}},nil} -c["50% increased Attack Speed while a Rare or Unique Enemy is Nearby"]={{[1]={[1]={actor="enemy",type="ActorCondition",varList={[1]="NearbyRareOrUniqueEnemy",[2]="RareOrUnique"}},flags=1,keywordFlags=0,name="Speed",type="INC",value=50}},nil} c["50% increased Block Recovery"]={{[1]={flags=0,keywordFlags=0,name="BlockRecovery",type="INC",value=50}},nil} c["50% increased Burning Damage"]={{[1]={flags=0,keywordFlags=134217728,name="FireDamage",type="INC",value=50}},nil} -c["50% increased Cast Speed"]={{[1]={flags=16,keywordFlags=0,name="Speed",type="INC",value=50}},nil} c["50% increased Charge Recovery"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargeRecovery",type="INC",value=50}},nil} c["50% increased Charges per use"]={{[1]={flags=0,keywordFlags=0,name="FlaskChargesUsed",type="INC",value=50}},nil} c["50% increased Chill Duration on Enemies"]={{[1]={flags=0,keywordFlags=0,name="EnemyChillDuration",type="INC",value=50}},nil} @@ -6052,7 +6022,6 @@ c["500% increased Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="Physical c["51% increased Duration of Lightning Ailments"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockDuration",type="INC",value=51},[2]={flags=0,keywordFlags=0,name="EnemySapDuration",type="INC",value=51}},nil} c["51% increased Mana Recovery from Flasks"]={{[1]={flags=0,keywordFlags=0,name="FlaskManaRecovery",type="INC",value=51}},nil} c["51% increased Mana Regeneration Rate"]={{[1]={flags=0,keywordFlags=0,name="ManaRegen",type="INC",value=51}},nil} -c["52% increased Critical Strike Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=52}},nil} c["52% increased Mana Regeneration Rate"]={{[1]={flags=0,keywordFlags=0,name="ManaRegen",type="INC",value=52}},nil} c["53% increased Global Critical Strike Chance"]={{[1]={[1]={type="Global"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=53}},nil} c["53% reduced Cold Resistance"]={{[1]={flags=0,keywordFlags=0,name="ColdResist",type="INC",value=-53}},nil} @@ -6269,13 +6238,8 @@ c["65% increased Spell Damage"]={{[1]={flags=2,keywordFlags=0,name="Damage",type c["65% increased Ward"]={{[1]={flags=0,keywordFlags=0,name="Ward",type="INC",value=65}},nil} c["65% reduced Elemental Resistances"]={{[1]={flags=0,keywordFlags=0,name="ElementalResist",type="INC",value=-65}},nil} c["650% increased Armour"]={{[1]={flags=0,keywordFlags=0,name="Armour",type="INC",value=650}},nil} -c["66% chance to Freeze"]={{[1]={flags=0,keywordFlags=0,name="EnemyFreezeChance",type="BASE",value=66}},nil} -c["66% chance to Ignite"]={{[1]={flags=0,keywordFlags=0,name="EnemyIgniteChance",type="BASE",value=66}},nil} -c["66% chance to Shock"]={{[1]={flags=0,keywordFlags=0,name="EnemyShockChance",type="BASE",value=66}},nil} -c["66% chance to deal Double Damage while Focused"]={{[1]={[1]={type="Condition",var="Focused"},flags=0,keywordFlags=0,name="DoubleDamageChance",type="BASE",value=66}},nil} c["66% increased Critical Strike Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=66}},nil} c["66% increased Effect of Herald Buffs on you"]={{[1]={[1]={skillType=52,type="SkillType"},flags=0,keywordFlags=0,name="BuffEffect",type="INC",value=66}},nil} -c["66% increased Mana Regeneration Rate"]={{[1]={flags=0,keywordFlags=0,name="ManaRegen",type="INC",value=66}},nil} c["66% increased Mana Reservation Efficiency of Herald Skills"]={{[1]={[1]={skillType=52,type="SkillType"},flags=0,keywordFlags=0,name="ManaReservationEfficiency",type="INC",value=66}},nil} c["66% reduced Amount Recovered"]={{[1]={flags=0,keywordFlags=0,name="FlaskRecovery",type="INC",value=-66}},nil} c["67% increased Chance to Block"]={{[1]={flags=0,keywordFlags=0,name="BlockChance",type="INC",value=67}},nil} @@ -7824,7 +7788,6 @@ c["Attacks with this Weapon Penetrate 15% Elemental Resistances"]={{[1]={[1]={ty c["Attacks with this Weapon Penetrate 16% Chaos Resistance"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="ChaosPenetration",type="BASE",value=16}},nil} c["Attacks with this Weapon Penetrate 16% Elemental Resistances"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="ElementalPenetration",type="BASE",value=16}},nil} c["Attacks with this Weapon Penetrate 26% Chaos Resistance"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="ChaosPenetration",type="BASE",value=26}},nil} -c["Attacks with this Weapon Penetrate 26% Elemental Resistances"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="ElementalPenetration",type="BASE",value=26}},nil} c["Attacks with this Weapon Penetrate 30% Elemental Resistances"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="ElementalPenetration",type="BASE",value=30}},nil} c["Attacks with this Weapon deal 100 to 200 added Fire Damage to Bleeding Enemies"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Bleeding"},flags=0,keywordFlags=0,name="FireMin",type="BASE",value=100},[2]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Bleeding"},flags=0,keywordFlags=0,name="FireMax",type="BASE",value=200}},nil} c["Attacks with this Weapon deal 100 to 200 added Physical Damage to Ignited Enemies"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Ignited"},flags=0,keywordFlags=0,name="PhysicalMin",type="BASE",value=100},[2]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Ignited"},flags=0,keywordFlags=0,name="PhysicalMax",type="BASE",value=200}},nil} @@ -8128,7 +8091,7 @@ c["Cannot have Minions other than Summoned Skeletons"]={nil,"Cannot have Minions c["Cannot have Minions other than Summoned Skeletons Maximum number of Summoned Spectral Wolves is Doubled"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={globalLimit=100,globalLimitKey="ActiveWolfLimitDoubledLimit",type="Multiplier",var="ActiveWolfLimitDoubled"},flags=0,keywordFlags=0,name="ActiveWolfLimit",type="MORE",value=100}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Multiplier:ActiveWolfLimitDoubled",type="OVERRIDE",value=1}}}},"Cannot have s other than Summoned Skeletons "} c["Cannot have Minions other than Summoned Spectral Wolves"]={nil,"Cannot have Minions other than Summoned Spectral Wolves "} c["Cannot have Minions other than Summoned Spectral Wolves Maximum number of Living Lightning is Doubled"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={globalLimit=100,globalLimitKey="ActiveLivingLightningLimitDoubledLimit",type="Multiplier",var="ActiveLivingLightningLimitDoubled"},flags=0,keywordFlags=0,name="ActiveLivingLightningLimit",type="MORE",value=100}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Multiplier:ActiveLivingLightningLimitDoubled",type="OVERRIDE",value=1}}}},"Cannot have s other than Summoned Spectral Wolves "} -c["Cannot have non-Abyssal sockets"]={nil,"Cannot have non-Abyssal sockets "} +c["Cannot have non-Abyssal sockets"]={{[1]={flags=0,keywordFlags=0,name="NoSockets",type="FLAG",value=true}},nil} c["Cannot inflict Freeze or Chill"]={{[1]={flags=0,keywordFlags=0,name="CannotFreeze",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="CannotChill",type="FLAG",value=true}},nil} c["Cannot inflict Ignite"]={{[1]={flags=0,keywordFlags=0,name="CannotIgnite",type="FLAG",value=true}},nil} c["Cannot inflict Shock"]={{[1]={flags=0,keywordFlags=0,name="CannotShock",type="FLAG",value=true}},nil} @@ -8650,7 +8613,6 @@ c["Enemies you Kill during Effect have a 30% chance to Explode, dealing a tenth c["Enemies you Kill have a 10% chance to Explode, dealing a quarter of their maximum Life as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ExplodeMod",type="LIST",value={amount=25,chance=0.1,keyOfScaledMod="chance",type="Chaos"}},[2]={flags=0,keywordFlags=0,name="CanExplode",type="FLAG",value=true}},nil} c["Enemies you Kill have a 20% chance to Explode, dealing a quarter of their maximum Life as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ExplodeMod",type="LIST",value={amount=25,chance=0.2,keyOfScaledMod="chance",type="Chaos"}},[2]={flags=0,keywordFlags=0,name="CanExplode",type="FLAG",value=true}},nil} c["Enemies you Kill have a 25% chance to Explode, dealing a quarter of their maximum Life as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ExplodeMod",type="LIST",value={amount=25,chance=0.25,keyOfScaledMod="chance",type="Chaos"}},[2]={flags=0,keywordFlags=0,name="CanExplode",type="FLAG",value=true}},nil} -c["Enemies you Kill have a 35% chance to Explode, dealing a quarter of their maximum Life as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ExplodeMod",type="LIST",value={amount=25,chance=0.35,keyOfScaledMod="chance",type="Chaos"}},[2]={flags=0,keywordFlags=0,name="CanExplode",type="FLAG",value=true}},nil} c["Enemies you Kill that are affected by Elemental Ailments"]={nil,"Enemies you Kill that are affected by Elemental Ailments "} c["Enemies you Kill that are affected by Elemental Ailments grant 100% increased Flask Charges"]={nil,"Enemies you Kill that are affected by Elemental Ailments grant 100% increased Flask Charges "} c["Enemies you Kill that are affected by Elemental Ailments grant 40% increased Flask Charges"]={nil,"Enemies you Kill that are affected by Elemental Ailments grant 40% increased Flask Charges "} @@ -8909,7 +8871,6 @@ c["Gain 15% of Physical Damage as Extra Lightning Damage"]={{[1]={flags=0,keywor c["Gain 150 Life on Culling Strike"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=150}}," on Culling Strike "} c["Gain 150 Life on Culling Strike Gain 20 Mana on Culling Strike"]={{[1]={flags=0,keywordFlags=0,name="Life",type="BASE",value=150}}," on Culling Strike Gain 20 Mana on Culling Strike "} c["Gain 150 Life per Enemy Killed"]={{[1]={flags=0,keywordFlags=0,name="LifeOnKill",type="BASE",value=150}},nil} -c["Gain 17% of Non-Chaos Damage as extra Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="NonChaosDamageGainAsChaos",type="BASE",value=17}},nil} c["Gain 18 Energy Shield for each Enemy you Hit which is affected by a Spider's Web"]={{[1]={[1]={actor="enemy",threshold=1,type="MultiplierThreshold",var="Spider's WebStack"},flags=4,keywordFlags=0,name="EnergyShieldOnHit",type="BASE",value=18}},nil} c["Gain 18 Energy Shield per Enemy Killed"]={{[1]={flags=0,keywordFlags=0,name="EnergyShieldOnKill",type="BASE",value=18}},nil} c["Gain 18 Life per Enemy Hit with Spells"]={{[1]={flags=4,keywordFlags=131072,name="LifeOnHit",type="BASE",value=18}},nil} @@ -10168,7 +10129,6 @@ c["Minions deal 80% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="Minio c["Minions deal 80% increased Damage if you have Warcried Recently"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={[1]={actor="parent",type="ActorCondition",var="UsedWarcryRecently"},flags=0,keywordFlags=0,name="Damage",type="INC",value=80}}}},nil} c["Minions deal 9 to 15 additional Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdMin",type="BASE",value=9}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ColdMax",type="BASE",value=15}}}},nil} c["Minions deal 96 to 144 additional Physical Damage"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="PhysicalMin",type="BASE",value=96}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="PhysicalMax",type="BASE",value=144}}}},nil} -c["Minions deal 96% increased Damage"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="INC",value=96}}}},nil} c["Minions deal no Non-Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DealNoPhysical",type="FLAG",value=true}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DealNoLightning",type="FLAG",value=true}}},[3]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DealNoFire",type="FLAG",value=true}}},[4]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="DealNoChaos",type="FLAG",value=true}}}},nil} c["Minions from Herald Skills deal 25% more Damage"]={{[1]={[1]={skillType=52,type="SkillType"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Damage",type="MORE",value=25}}}},nil} c["Minions gain 10% of Non-Chaos Damage as extra Chaos Damage while you have a Spectre"]={{[1]={[1]={includeTransfigured=true,skillName="Raise Spectre",type="SkillName"},flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="NonChaosDamageGainAsChaos",type="BASE",value=10}}}}," while you have a "} @@ -10310,8 +10270,6 @@ c["Minions have 59% increased maximum Life"]={{[1]={flags=0,keywordFlags=0,name= c["Minions have 60% chance to Poison Enemies on Hit"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="PoisonChance",type="BASE",value=60}}}},nil} c["Minions have 60% chance to inflict Withered on Hit"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:CanWither",type="FLAG",value=true}}}},nil} c["Minions have 60% increased Critical Strike Chance"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="CritChance",type="INC",value=60}}}},nil} -c["Minions have 63% increased Attack Speed"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=1,keywordFlags=0,name="Speed",type="INC",value=63}}}},nil} -c["Minions have 63% increased Cast Speed"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=16,keywordFlags=0,name="Speed",type="INC",value=63}}}},nil} c["Minions have 65% increased Flask Effect Duration"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="FlaskDuration",type="INC",value=65}}}},nil} c["Minions have 7% increased Area of Effect"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=7}}}},nil} c["Minions have 75% faster start of Energy Shield Recharge"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="EnergyShieldRechargeFaster",type="INC",value=75}}}},nil} @@ -10328,7 +10286,6 @@ c["Minions have 80% increased maximum Life"]={{[1]={flags=0,keywordFlags=0,name= c["Minions have 9% increased Attack Speed"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=1,keywordFlags=0,name="Speed",type="INC",value=9}}}},nil} c["Minions have 9% increased Attack and Cast Speed"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Speed",type="INC",value=9}}}},nil} c["Minions have 90% increased Movement Speed"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="MovementSpeed",type="INC",value=90}}}},nil} -c["Minions have 96% increased maximum Life"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Life",type="INC",value=96}}}},nil} c["Minions have Unholy Might"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:UnholyMight",type="FLAG",value=true}}},[2]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:CanWither",type="FLAG",value=true}}}},nil} c["Minions have a 12% chance to Impale on Hit with Attacks"]={{[1]={flags=0,keywordFlags=0,name="MinionModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="ImpaleChance",type="BASE",value=12}}}},nil} c["Minions have the same maximum number of Endurance, Frenzy and Power Charges as you"]={nil,"the same maximum number of Endurance, Frenzy and Power Charges as you "} @@ -10499,8 +10456,7 @@ c["On Killing a Poisoned Enemy, Enemies within 3 metres are Poisoned and nearby c["On Killing a Rare monster, a random Linked Minion gains its Modifiers for 60 seconds"]={nil,"On Killing a Rare monster, a random Linked Minion gains its Modifiers for 60 seconds "} c["On non-channelling Attack, set a Life Flask with greater than 50% of maximum Charges remaining to 50%"]={nil,"On non-channelling Attack, set a Life Flask with greater than 50% of maximum Charges remaining to 50% "} c["On non-channelling Attack, set a Life Flask with greater than 50% of maximum Charges remaining to 50% For each Charge removed this way, that Attack gains +2% to Damage over time Multiplier"]={{[1]={[1]={floor=true,percent=50,stat="LifeFlaskCharges",type="PercentStat"},[2]={neg=true,skillType=48,type="SkillType"},[3]={skillType=1,type="SkillType"},flags=0,keywordFlags=0,name="DotMultiplier",type="BASE",value=2}},nil} -c["One modifier from Consumed Jewels will be retained"]={nil,"One modifier from Consumed Jewels will be retained "} -c["One modifier from Consumed Jewels will be retained Cannot have non-Abyssal sockets"]={nil,"One modifier from Consumed Jewels will be retained Cannot have non-Abyssal sockets "} +c["One modifier from Consumed Jewels will be retained"]={{},nil} c["Only affects Passives in Large Ring"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="radiusIndex",value=8}}},nil} c["Only affects Passives in Massive Ring"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="radiusIndex",value=10}}},nil} c["Only affects Passives in Medium Ring"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="radiusIndex",value=7}}},nil} @@ -12141,8 +12097,7 @@ c["Socketed Projectile Spells fire Projectiles in a circle"]={nil,"Projectiles i c["Socketed Projectile Spells fire Projectiles in a circle Socketed Projectile Spells have 80% less Skill Effect Duration"]={nil,"Projectiles in a circle Socketed Projectile Spells have 80% less Skill Effect Duration "} c["Socketed Projectile Spells have +4 seconds to Cooldown"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},[2]={skillType=3,type="SkillType"},[3]={skillType=2,type="SkillType"},flags=0,keywordFlags=0,name="CooldownRecovery",type="BASE",value=4}},nil} c["Socketed Projectile Spells have 80% less Skill Effect Duration"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="ExtraSkillMod",type="LIST",value={mod={[1]={skillType=3,type="SkillType"},[2]={skillType=2,type="SkillType"},flags=0,keywordFlags=0,name="Duration",type="MORE",value=-80}}}},nil} -c["Socketed Rare Abyssal Jewels will be Consumed"]={nil,"Socketed Rare Abyssal Jewels will be Consumed "} -c["Socketed Rare Abyssal Jewels will be Consumed One modifier from Consumed Jewels will be retained"]={nil,"Socketed Rare Abyssal Jewels will be Consumed One modifier from Consumed Jewels will be retained "} +c["Socketed Rare Abyssal Jewels will be Consumed"]={{},nil} c["Socketed Red Gems get 10% Physical Damage as Extra Fire Damage"]={{[1]={[1]={keyword="strength",slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="ExtraSkillMod",type="LIST",value={mod={flags=0,keywordFlags=0,name="PhysicalDamageGainAsFire",type="BASE",value=10}}}},nil} c["Socketed Skill Gems get a 80% Cost & Reservation Multiplier"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="ExtraSkillMod",type="LIST",value={mod={flags=0,keywordFlags=0,name="SupportManaMultiplier",type="MORE",value=-20}}}},nil} c["Socketed Skills deal Double Damage"]={{[1]={[1]={slotName="{SlotName}",type="SocketedIn"},flags=0,keywordFlags=0,name="ExtraSkillMod",type="LIST",value={mod={flags=0,keywordFlags=0,name="DoubleDamageChance",type="BASE",value=100}}}},nil} diff --git a/src/Data/Uniques/helmet.lua b/src/Data/Uniques/helmet.lua index 2e6ea697928..f223435711f 100644 --- a/src/Data/Uniques/helmet.lua +++ b/src/Data/Uniques/helmet.lua @@ -1363,6 +1363,7 @@ Faithful Helmet League: Allflame Source: Drops from unique{Zorath} Requires Level 73, 101 Str, 101 Int +Crafted: true (120-240)% increased Explicit Modifier magnitudes Has 4 Abyssal Sockets Socketed Rare Abyssal Jewels will be Consumed diff --git a/src/Export/Uniques/helmet.lua b/src/Export/Uniques/helmet.lua index c4882fe4116..0e427623a1b 100644 --- a/src/Export/Uniques/helmet.lua +++ b/src/Export/Uniques/helmet.lua @@ -1328,6 +1328,7 @@ Faithful Helmet League: Allflame Source: Drops from unique{Zorath} Requires Level 73, 101 Str, 101 Int +Crafted: true LocalExplicitModEffectUnique__1 ConsumeAbyssJewelUnique__1 LocalCannotHaveNonAbyssSocketsUnique__1 diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 10459584341..13641495ef1 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -1147,13 +1147,79 @@ data.printMissingMinionSkills = function() end end --- Item bases +---@class ItemBase +---@field type string # e.g. "Helmet", "Wand", "Body Armour", "Flask", "Jewel" +---@field subType? string # e.g. "Armour", "Evasion/Energy Shield", "Life", "Utility" +---@field socketLimit? integer # max sockets (weapons/armour only) +---@field hidden? boolean # excluded from the base-type selection lists +---@field cannotBeAnointed? boolean +---@field tags table # e.g. { armour = true, helmet = true, str_armour = true } +---@field influenceTags? table # influence -> mod tag, e.g. { shaper = "helmet_shaper" } +---@field implicit? string # implicit mod line(s), newline-separated +---@field implicitModTypes ModTypeList[] # per-implicit list of mod-type tags +---@field implicitIds? string[] # per-implicit GGG mod id +---@field enchant? string # enchant mod line(s) +---@field enchantModTypes? ModTypeList[] +---@field enchantIds? string[] +---@field flavourText? string +---@field req ItemBaseReq +---@field armour? ItemBaseArmour # present on armour bases +---@field weapon? ItemBaseWeapon # present on weapon bases +---@field flask? ItemBaseFlask # present on flask bases +---@field tincture? ItemBaseTincture # present on tincture bases + +---@alias ModTypeList string[] # list of mod-type tags, e.g. { "caster_damage", "damage", "caster" } + +---@class ItemBaseReq +---@field level? integer +---@field str? integer +---@field dex? integer +---@field int? integer + +---@class ItemBaseArmour +---@field ArmourBaseMin? number +---@field ArmourBaseMax? number +---@field EvasionBaseMin? number +---@field EvasionBaseMax? number +---@field EnergyShieldBaseMin? number +---@field EnergyShieldBaseMax? number +---@field WardBaseMin? number +---@field WardBaseMax? number +---@field BlockChance? number # shields +---@field MovementPenalty? number + +---@class ItemBaseWeapon +---@field PhysicalMin? number +---@field PhysicalMax? number +---@field CritChanceBase? number +---@field AttackRateBase? number +---@field Range? number + +---@class ItemBaseFlask +---@field life? number +---@field mana? number +---@field duration? number +---@field chargesUsed? integer +---@field chargesMax? integer +---@field buff? string[] # utility-flask granted buff line(s) + +---@class ItemBaseTincture +---@field manaBurn? number +---@field cooldown? number + +---@type table data.itemBases = { } for _, type in pairs(itemTypes) do LoadModule("Data/Bases/"..type, data.itemBases) end -- Build lists of item bases, separated by type +---@class ItemBaseEntry +---@field label string +---@field name string +---@field base ItemBase + +---@type table data.itemBaseLists = { } for name, base in pairs(data.itemBases) do if not base.hidden then @@ -1233,6 +1299,34 @@ data.minionTagCrucibleUniques = { ["United in Dream"] = true, } +-- data describing uniques which can contain rare modifiers. these can also +-- ignore prefix/suffix logic + +---@class RareLikeAffixLimits +---@field affixLimit integer Total number of possible affixes +---@field prefixLimit integer Total number of possible prefixes. This also implies suffixLimit = affixLimit - prefixLimit + +---@class RareLikeUniqueDescription +---@field validBases ItemBaseEntry[] +---@field affixes table[] Table of rare modifiers (affixes) which might spawn on the item +---@field affixLimits RareLikeAffixLimits +---@field ignorePrefixSuffix boolean +---@field baseExplicits string[] An array of mod ID strings. These should describe the unique explicits which are always present on the item, and thus are contained in ItemExclusive. +---@type table +data.rareLikeUniques = { + ["subsume the source"] = { + validBases = data.itemBaseLists["Jewel: Abyss"], + affixes = data.itemMods.JewelAbyss, + affixLimits = { + affixLimit = 4, + prefixLimit = 4, + }, + ignorePrefixSuffix = true, + baseExplicits = { "LocalExplicitModEffectUnique__1", + "ConsumeAbyssJewelUnique__1", + "LocalCannotHaveNonAbyssSocketsUnique__1" }, + } +} -- Uniques (loaded after version-specific data because reasons) data.uniques = { } for _, type in pairs(itemTypes) do diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index c3135807d27..a2af9fb00ef 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -3083,6 +3083,13 @@ local specialModList = { ["drop brine ground while moving, lasting 4 seconds"] = { flag("CanCreateBrineGround"), }, -- Item local modifiers ["has no sockets"] = { flag("NoSockets") }, + ["cannot have non%-abyssal sockets"] = { flag("NoSockets") }, + ["socketed %a+ abyssal jewels will be consumed"] = { + -- Display only Subsume The Source sockets removed by "NoSockets" + }, + ["one modifier from consumed jewels will be retained"] = { + -- Display only + }, ["reflects your o[tp][hp][eo][rs]i?t?e? ring"] = { -- Display only. For Kalandra's Touch. }, From 67dc47d853942705a1d131f4b5f11037275a1b7d Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:53:53 +0300 Subject: [PATCH 2/2] Add example for veiled mod item (crimson storm) --- src/Classes/Item.lua | 1 + src/Classes/ItemsTab.lua | 7 ++-- src/Data/Uniques/bow.lua | 80 ++++---------------------------------- src/Export/Uniques/bow.lua | 80 ++++---------------------------------- src/Modules/Data.lua | 31 ++++++++++++--- 5 files changed, 45 insertions(+), 154 deletions(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index bc9d88ab8f5..6f30f209756 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -1450,6 +1450,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) elseif self.rareLikeUnique then self.affixLimit = self.rareLikeUnique.affixLimits.affixLimit self.prefixes.limit = self.rareLikeUnique.affixLimits.prefixLimit + self.suffixes.limit = self.prefixes.limit and (self.affixLimit - self.prefixes.limit) or nil else self.crafted = false end diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 1b323875ad0..59da6230cca 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -940,7 +940,7 @@ holding Shift will put it in the second.]]) self.controls["displayItemAffix"..i] = drop self.controls["displayItemAffixLabel"..i] = new("LabelControl", {"RIGHT",drop,"LEFT"}, {-4, 0, 0, 14}, function() local ignoreModType = self.displayItem.rareLikeUnique and self.displayItem.rareLikeUnique.ignorePrefixSuffix - return ignoreModType and "Explicit:" + return ignoreModType and "^7Explicit:" or drop.outputTable == "prefixes" and "^7Prefix:" or "^7Suffix:" end) @@ -959,7 +959,7 @@ holding Shift will put it in the second.]]) self:AddCustomModifierToDisplayItem() end) self.controls.displayItemAddCustom.shown = function() - return self.displayItem and (self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE" or self.rareLikeUnique) + return self.displayItem and (self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE") end -- Section: Crucible modifiers @@ -2103,7 +2103,8 @@ function ItemsTabClass:UpdateAffixControl(control, item, affixType, outputTable, if index ~= outputIndex or table ~= outputTable then local mod = item.affixes[item[table][index] and item[table][index].modId] if mod then - if mod.group then + local allowDuplicateAffixes = item.rareLikeUnique and item.rareLikeUnique.allowsDuplicates + if mod.group and not allowDuplicateAffixes then excludeGroups[mod.group] = true end if mod.tags then diff --git a/src/Data/Uniques/bow.lua b/src/Data/Uniques/bow.lua index d9f0d2908f3..11a6587dc9b 100644 --- a/src/Data/Uniques/bow.lua +++ b/src/Data/Uniques/bow.lua @@ -73,87 +73,21 @@ The Crimson Storm Steelwood Bow League: Betrayal Source: Drops from unique{Fortification Leaders} in normal{Safehouses} -Variant: Crit Multi while Rare/Unique Nearby (Pre 3.17.0) -Variant: Attack Speed while Rare/Unique Nearby (Pre 3.17.0) -Variant: Damage per Power Charge (Pre 3.17.0) -Variant: Damage per Frenzy Charge (Pre 3.17.0) -Variant: Damage per Endurance Charge (Pre 3.17.0) -Variant: Accuracy and Quality (Pre 3.17.0) -Variant: Attack Speed and Quality (Pre 3.17.0) -Variant: Attack Speed/Trigger Blood Rage on Kill (Pre 3.17.0) -Variant: Cast Speed/Trigger Arcane Surge on Kill (Pre 3.17.0) -Variant: Minion Attack and Cast Speed (Pre 3.17.0) -Variant: Double Damage (Pre 3.17.0) -Variant: Double Damage while Focused (Pre 3.17.0) -Variant: Socketed Spell Trigger (Pre 3.17.0) +Crafted: true +Suffix: None Variant: Pre 3.17.0 -Variant: Crit Multi while Rare/Unique Nearby (Current) -Variant: Attack Speed while Rare/Unique Nearby (Current) -Variant: Damage per Power Charge (Current) -Variant: Damage per Frenzy Charge (Current) -Variant: Damage per Endurance Charge (Current) -Variant: Accuracy and Str/Dex (Current) -Variant: Attack Speed and Dex/Int (Current) -Variant: Critical Strike Chance and Str/Int (Current) -Variant: Cast Speed/Trigger Arcane Surge on Kill (Current) -Variant: Minion Attack and Cast Speed (Current) -Variant: Double Damage (Current) -Variant: Double Damage while Focused (Current) -Variant: Socketed Spell Trigger (Current) -Variant: Fire Damage over Time (Current) -Variant: Physical Damage over Time (Current) -Variant: Chaos Damage over Time (Current) Variant: Current Requires Level 57, 190 Dex -Implicits: 1 -{variant:1,2,3,4,5,6,7,8,9,10,11,12,13,14}(4-6)% increased Movement Speed -{variant:1,2,3,4,5,6,7,8,9,10,11,12,13,14}(140-170)% increased Physical Damage -{variant:15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}(60-80)% increased Physical Damage -{variant:7}(8-16)% increased Attack Speed -{variant:8}(8-16)% increased Attack Speed -{variant:9}(7-13)% increased Cast Speed +Implicits: 2 +{variant:2}6% increased Movement Speed +{variant:1}(4-6)% increased Movement Speed +{variant:1}(140-170)% increased Physical Damage +{variant:2}(60-80)% increased Physical Damage (25-35)% increased Critical Strike Chance -{variant:15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}6% increased Movement Speed 50% chance to inflict Bleeding on Critical Strike with Attacks Enemies you inflict Bleeding on grant (60-100)% increased Flask Charges Adds (100-120) to (150-165) Physical Damage against Bleeding Enemies 50% chance to Maim Enemies on Critical Strike with Attacks -{variant:1}{crafted}+(18-45)% Critical Strike Multiplier while there is a Rare or Unique Enemy Nearby -{variant:2}{crafted}(11-22)% increased Attack Speed while a Rare or Unique Enemy is Nearby -{variant:3}{crafted}(5-6)% increased Damage per Power Charge -{variant:4}{crafted}(5-6)% increased Damage per Frenzy Charge -{variant:5}{crafted}(5-6)% increased Damage per Endurance Charge -{variant:6}{crafted}+(30-250) to Accuracy Rating -{variant:6,7}{crafted}+(7-18)% to Quality -{variant:8}{crafted}10% chance to Trigger Level 1 Blood Rage when you Kill an Enemy -{variant:9}{crafted}10% chance to gain Arcane Surge when you Kill an Enemy -{variant:10}{crafted}Minions have (16-28)% increased Attack Speed -{variant:10}{crafted}Minions have (16-28)% increased Cast Speed -{variant:11}{crafted}(4-12)% chance to deal Double Damage -{variant:12}{crafted}(13-36)% chance to deal Double Damage while Focused -{variant:13}{crafted}Trigger a Socketed Spell when you Use a Skill, with a 8 second Cooldown -{variant:15}{crafted}+(54-60)% Critical Strike Multiplier while there is a Rare or Unique Enemy Nearby -{variant:16}{crafted}(27-30)% increased Attack Speed while a Rare or Unique Enemy is Nearby -{variant:17}{crafted}(7-8)% increased Damage per Power Charge -{variant:18}{crafted}(7-8)% increased Damage per Frenzy Charge -{variant:19}{crafted}(7-8)% increased Damage per Endurance Charge -{variant:20}{crafted}+(311-350) to Accuracy Rating -{variant:20}{crafted}+(25-28) to Strength and Dexterity -{variant:21}{crafted}(18-22)% increased Attack Speed -{variant:21}{crafted}+(25-28) to Dexterity and Intelligence -{variant:22}{crafted}(28-32)% increased Critical Strike Chance -{variant:22}{crafted}+(25-28) to Strength and Intelligence -{variant:23}{crafted}(26-31)% increased Cast Speed -{variant:23}{crafted}15% chance to gain Arcane Surge when you Kill an Enemy -{variant:24}{crafted}Minions have (34-38)% increased Attack Speed -{variant:24}{crafted}Minions have (34-38)% increased Cast Speed -{variant:25}{crafted}(12-14)% chance to deal Double Damage -{variant:26}{crafted}(36-40)% chance to deal Double Damage while Focused -{variant:27}{crafted}Trigger a Socketed Spell when you Use a Skill, with a 4 second Cooldown -{variant:27}{crafted}Spells Triggered this way have 150% more Cost -{variant:28}{crafted}+(24-28)% to Fire Damage over Time Multiplier -{variant:29}{crafted}+(24-28)% to Physical Damage over Time Multiplier -{variant:30}{crafted}+(24-28)% to Chaos Damage over Time Multiplier ]],[[ Darkscorn Assassin Bow diff --git a/src/Export/Uniques/bow.lua b/src/Export/Uniques/bow.lua index 752ecc23e5e..8fda9bcbf87 100644 --- a/src/Export/Uniques/bow.lua +++ b/src/Export/Uniques/bow.lua @@ -73,87 +73,21 @@ The Crimson Storm Steelwood Bow League: Betrayal Source: Drops from unique{Fortification Leaders} in normal{Safehouses} -Variant: Crit Multi while Rare/Unique Nearby (Pre 3.17.0) -Variant: Attack Speed while Rare/Unique Nearby (Pre 3.17.0) -Variant: Damage per Power Charge (Pre 3.17.0) -Variant: Damage per Frenzy Charge (Pre 3.17.0) -Variant: Damage per Endurance Charge (Pre 3.17.0) -Variant: Accuracy and Quality (Pre 3.17.0) -Variant: Attack Speed and Quality (Pre 3.17.0) -Variant: Attack Speed/Trigger Blood Rage on Kill (Pre 3.17.0) -Variant: Cast Speed/Trigger Arcane Surge on Kill (Pre 3.17.0) -Variant: Minion Attack and Cast Speed (Pre 3.17.0) -Variant: Double Damage (Pre 3.17.0) -Variant: Double Damage while Focused (Pre 3.17.0) -Variant: Socketed Spell Trigger (Pre 3.17.0) +Crafted: true +Suffix: None Variant: Pre 3.17.0 -Variant: Crit Multi while Rare/Unique Nearby (Current) -Variant: Attack Speed while Rare/Unique Nearby (Current) -Variant: Damage per Power Charge (Current) -Variant: Damage per Frenzy Charge (Current) -Variant: Damage per Endurance Charge (Current) -Variant: Accuracy and Str/Dex (Current) -Variant: Attack Speed and Dex/Int (Current) -Variant: Critical Strike Chance and Str/Int (Current) -Variant: Cast Speed/Trigger Arcane Surge on Kill (Current) -Variant: Minion Attack and Cast Speed (Current) -Variant: Double Damage (Current) -Variant: Double Damage while Focused (Current) -Variant: Socketed Spell Trigger (Current) -Variant: Fire Damage over Time (Current) -Variant: Physical Damage over Time (Current) -Variant: Chaos Damage over Time (Current) Variant: Current Requires Level 57, 190 Dex -Implicits: 1 -{variant:1,2,3,4,5,6,7,8,9,10,11,12,13,14}(4-6)% increased Movement Speed -{variant:15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}MovementVelocityMarakethBowImplicit1 -{variant:1,2,3,4,5,6,7,8,9,10,11,12,13,14}LocalIncreasedPhysicalDamagePercentUniqueBow5[140,170] -{variant:15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}LocalIncreasedPhysicalDamagePercentUniqueBow5 +Implicits: 2 +{variant:1}(4-6)% increased Movement Speed +{variant:2}MovementVelocityMarakethBowImplicit1 +{variant:1}LocalIncreasedPhysicalDamagePercentUnique__36_[140,170] +{variant:2}LocalIncreasedPhysicalDamagePercentUnique__36_ LocalCriticalStrikeChanceUnique__15 BleedOnCritUnique__1_ EnemiesYouBleedGrantIncreasedFlaskChargesUnique__1_ AddedPhysicalDamageVsBleedingEnemiesUnique__1 MaimOnCritUnique__1 -{variant:1}{crafted}+(18-45)% Critical Strike Multiplier while there is a Rare or Unique Enemy Nearby -{variant:2}{crafted}(11-22)% increased Attack Speed while a Rare or Unique Enemy is Nearby -{variant:3}{crafted}(5-6)% increased Damage per Power Charge -{variant:4}{crafted}(5-6)% increased Damage per Frenzy Charge -{variant:5}{crafted}(5-6)% increased Damage per Endurance Charge -{variant:6}{crafted}+(30-250) to Accuracy Rating -{variant:7}IncreasedAttackSpeedUnique__8[8,16] -{variant:6,7}{crafted}+(7-18)% to Quality -{variant:8}IncreasedAttackSpeedUnique__8 -{variant:8}{crafted}10% chance to Trigger Level 1 Blood Rage when you Kill an Enemy -{variant:9}IncreasedCastSpeedUniqueWand11 -{variant:9}{crafted}10% chance to gain Arcane Surge when you Kill an Enemy -{variant:10}{crafted}Minions have (16-28)% increased Attack Speed -{variant:10}{crafted}Minions have (16-28)% increased Cast Speed -{variant:11}{crafted}(4-12)% chance to deal Double Damage -{variant:12}{crafted}(13-36)% chance to deal Double Damage while Focused -{variant:13}{crafted}Trigger a Socketed Spell when you Use a Skill, with a 8 second Cooldown -{variant:15}{crafted}+(54-60)% Critical Strike Multiplier while there is a Rare or Unique Enemy Nearby -{variant:16}{crafted}(27-30)% increased Attack Speed while a Rare or Unique Enemy is Nearby -{variant:17}{crafted}(7-8)% increased Damage per Power Charge -{variant:18}{crafted}(7-8)% increased Damage per Frenzy Charge -{variant:19}{crafted}(7-8)% increased Damage per Endurance Charge -{variant:20}{crafted}+(311-350) to Accuracy Rating -{variant:20}{crafted}+(25-28) to Strength and Dexterity -{variant:21}{crafted}(18-22)% increased Attack Speed -{variant:21}{crafted}+(25-28) to Dexterity and Intelligence -{variant:22}{crafted}(28-32)% increased Critical Strike Chance -{variant:22}{crafted}+(25-28) to Strength and Intelligence -{variant:23}{crafted}(26-31)% increased Cast Speed -{variant:23}{crafted}15% chance to gain Arcane Surge when you Kill an Enemy -{variant:24}{crafted}Minions have (34-38)% increased Attack Speed -{variant:24}{crafted}Minions have (34-38)% increased Cast Speed -{variant:25}{crafted}(12-14)% chance to deal Double Damage -{variant:26}{crafted}(36-40)% chance to deal Double Damage while Focused -{variant:27}{crafted}Trigger a Socketed Spell when you Use a Skill, with a 4 second Cooldown -{variant:27}{crafted}Spells Triggered this way have 150% more Cost -{variant:28}{crafted}+(24-28)% to Fire Damage over Time Multiplier -{variant:29}{crafted}+(24-28)% to Physical Damage over Time Multiplier -{variant:30}{crafted}+(24-28)% to Chaos Damage over Time Multiplier ]],[[ Darkscorn Assassin Bow diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 13641495ef1..a7baa9605dc 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -1299,20 +1299,26 @@ data.minionTagCrucibleUniques = { ["United in Dream"] = true, } --- data describing uniques which can contain rare modifiers. these can also --- ignore prefix/suffix logic +local crimsonStormMods = {} +for modId, mod in pairs(data.veiledMods) do + if mod.affix == "of the Order" then + crimsonStormMods[modId] = mod + end +end ---@class RareLikeAffixLimits ---@field affixLimit integer Total number of possible affixes ----@field prefixLimit integer Total number of possible prefixes. This also implies suffixLimit = affixLimit - prefixLimit +---@field prefixLimit integer Total number of possible prefixes ---@class RareLikeUniqueDescription ----@field validBases ItemBaseEntry[] +---@field validBases ItemBaseEntry[] a list of bases which will have their tags compared to the given affixes ---@field affixes table[] Table of rare modifiers (affixes) which might spawn on the item ---@field affixLimits RareLikeAffixLimits ----@field ignorePrefixSuffix boolean +---@field ignorePrefixSuffix boolean? ---@field baseExplicits string[] An array of mod ID strings. These should describe the unique explicits which are always present on the item, and thus are contained in ItemExclusive. ---@type table +-- data describing uniques which can contain rare modifiers. these may also +-- ignore prefix/suffix logic data.rareLikeUniques = { ["subsume the source"] = { validBases = data.itemBaseLists["Jewel: Abyss"], @@ -1322,9 +1328,24 @@ data.rareLikeUniques = { prefixLimit = 4, }, ignorePrefixSuffix = true, + allowsDuplicates = true, baseExplicits = { "LocalExplicitModEffectUnique__1", "ConsumeAbyssJewelUnique__1", "LocalCannotHaveNonAbyssSocketsUnique__1" }, + }, + ["the crimson storm"] = { + validBases = { base = { tags = { unveiled_mod = true } } }, + affixes = crimsonStormMods, + affixLimits = { + affixLimit = 1, + prefixLimit = 0, + }, + baseExplicits = { "LocalIncreasedPhysicalDamagePercentUnique__36_", + "LocalCriticalStrikeChanceUnique__15", + "BleedOnCritUnique__1_", + "EnemiesYouBleedGrantIncreasedFlaskChargesUnique__1_", + "AddedPhysicalDamageVsBleedingEnemiesUnique__1", + "MaimOnCritUnique__1" }, } } -- Uniques (loaded after version-specific data because reasons)