From e02a823deb51c4c8c494cfffdaed8e4a006bbec9 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:10:09 +0300 Subject: [PATCH 1/8] Add basic support for Dread Captain's Cutlass --- src/Data/Skills/other.lua | 71 ++++++++++++++++++++++++++++++++++++ src/Data/Uniques/sword.lua | 13 ++++++- src/Export/Skills/other.txt | 5 +++ src/Export/Uniques/sword.lua | 12 +++++- src/Modules/CalcTriggers.lua | 11 ++++++ src/Modules/Data.lua | 9 +++++ src/Modules/ModParser.lua | 7 ++++ 7 files changed, 124 insertions(+), 4 deletions(-) diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index 04dfd1f7d4..2ef23a5729 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -398,6 +398,9 @@ skills["BarnacleSnap"] = { skill("hitTimeOverride", nil), div = 1000, }, + ["spider_aspect_max_web_count"] = { + mod("Multiplier:SpiderWebApplyStackMax", "BASE", nil), + }, }, baseFlags = { attack = true, @@ -5878,6 +5881,74 @@ skills["TriggerSummonedAncestorUtula"] = { [20] = { 10, 50, cooldown = 20, levelRequirement = 0, storedUses = 1, statInterpolation = { 1, 1, }, }, }, } +skills["GhostCannons"] = { + name = "Ghostly Artillery", + hidden = true, + color = 2, + description = "Manifest a row of Ghostly Cannons, each of which then fires after a short delay dealing the damage of the weapon that triggered it. For each additional projectile this skill would fire, create an additional Ghostly Cannon instead.", + skillTypes = { [SkillType.Attack] = true, [SkillType.RangedAttack] = true, [SkillType.Projectile] = true, [SkillType.Triggerable] = true, [SkillType.Triggered] = true, [SkillType.Fire] = true, [SkillType.ProjectilesNotFromUser] = true, [SkillType.Area] = true, [SkillType.Cooldown] = true, }, + statDescriptionScope = "skill_stat_descriptions", + castTime = 1, + fromItem = true, + baseFlags = { + attack = true, + }, + constantStats = { + { "skill_physical_damage_%_to_convert_to_fire", 50 }, + { "active_skill_additional_projectiles_fire_parallel_x_dist", 60 }, + { "base_number_of_projectiles", 1 }, + { "active_skill_base_area_of_effect_radius", 2 }, + { "triggered_ghost_cannons_base_number_of_cannons_to_fire", 6 }, + }, + stats = { + "base_is_projectile", + "skill_has_trigger_from_unique_item", + "modifiers_to_number_of_projectiles_instead_apply_to_number_of_summoned_ghost_cannons", + "is_area_damage", + }, + levels = { + [1] = { cooldown = 0.15, levelRequirement = 12, storedUses = 1, }, + [2] = { baseMultiplier = 1.032, cooldown = 0.15, damageEffectiveness = 1.032, levelRequirement = 15, storedUses = 1, }, + [3] = { baseMultiplier = 1.063, cooldown = 0.15, damageEffectiveness = 1.063, levelRequirement = 19, storedUses = 1, }, + [4] = { baseMultiplier = 1.095, cooldown = 0.15, damageEffectiveness = 1.095, levelRequirement = 23, storedUses = 1, }, + [5] = { baseMultiplier = 1.126, cooldown = 0.15, damageEffectiveness = 1.126, levelRequirement = 27, storedUses = 1, }, + [6] = { baseMultiplier = 1.158, cooldown = 0.15, damageEffectiveness = 1.158, levelRequirement = 31, storedUses = 1, }, + [7] = { baseMultiplier = 1.189, cooldown = 0.15, damageEffectiveness = 1.189, levelRequirement = 35, storedUses = 1, }, + [8] = { baseMultiplier = 1.221, cooldown = 0.15, damageEffectiveness = 1.221, levelRequirement = 38, storedUses = 1, }, + [9] = { baseMultiplier = 1.253, cooldown = 0.15, damageEffectiveness = 1.253, levelRequirement = 41, storedUses = 1, }, + [10] = { baseMultiplier = 1.284, cooldown = 0.15, damageEffectiveness = 1.284, levelRequirement = 44, storedUses = 1, }, + [11] = { baseMultiplier = 1.316, cooldown = 0.15, damageEffectiveness = 1.316, levelRequirement = 47, storedUses = 1, }, + [12] = { baseMultiplier = 1.347, cooldown = 0.15, damageEffectiveness = 1.347, levelRequirement = 50, storedUses = 1, }, + [13] = { baseMultiplier = 1.379, cooldown = 0.15, damageEffectiveness = 1.379, levelRequirement = 53, storedUses = 1, }, + [14] = { baseMultiplier = 1.411, cooldown = 0.15, damageEffectiveness = 1.411, levelRequirement = 56, storedUses = 1, }, + [15] = { baseMultiplier = 1.442, cooldown = 0.15, damageEffectiveness = 1.442, levelRequirement = 59, storedUses = 1, }, + [16] = { baseMultiplier = 1.474, cooldown = 0.15, damageEffectiveness = 1.474, levelRequirement = 62, storedUses = 1, }, + [17] = { baseMultiplier = 1.505, cooldown = 0.15, damageEffectiveness = 1.505, levelRequirement = 64, storedUses = 1, }, + [18] = { baseMultiplier = 1.537, cooldown = 0.15, damageEffectiveness = 1.537, levelRequirement = 66, storedUses = 1, }, + [19] = { baseMultiplier = 1.568, cooldown = 0.15, damageEffectiveness = 1.568, levelRequirement = 68, storedUses = 1, }, + [20] = { baseMultiplier = 1.6, cooldown = 0.15, damageEffectiveness = 1.6, levelRequirement = 70, storedUses = 1, }, + [21] = { baseMultiplier = 1.632, cooldown = 0.15, damageEffectiveness = 1.632, levelRequirement = 72, storedUses = 1, }, + [22] = { baseMultiplier = 1.663, cooldown = 0.15, damageEffectiveness = 1.663, levelRequirement = 74, storedUses = 1, }, + [23] = { baseMultiplier = 1.695, cooldown = 0.15, damageEffectiveness = 1.695, levelRequirement = 76, storedUses = 1, }, + [24] = { baseMultiplier = 1.726, cooldown = 0.15, damageEffectiveness = 1.726, levelRequirement = 78, storedUses = 1, }, + [25] = { baseMultiplier = 1.758, cooldown = 0.15, damageEffectiveness = 1.758, levelRequirement = 80, storedUses = 1, }, + [26] = { baseMultiplier = 1.789, cooldown = 0.15, damageEffectiveness = 1.789, levelRequirement = 82, storedUses = 1, }, + [27] = { baseMultiplier = 1.821, cooldown = 0.15, damageEffectiveness = 1.821, levelRequirement = 84, storedUses = 1, }, + [28] = { baseMultiplier = 1.853, cooldown = 0.15, damageEffectiveness = 1.853, levelRequirement = 86, storedUses = 1, }, + [29] = { baseMultiplier = 1.884, cooldown = 0.15, damageEffectiveness = 1.884, levelRequirement = 88, storedUses = 1, }, + [30] = { baseMultiplier = 1.916, cooldown = 0.15, damageEffectiveness = 1.916, levelRequirement = 90, storedUses = 1, }, + [31] = { baseMultiplier = 1.932, cooldown = 0.15, damageEffectiveness = 1.932, levelRequirement = 91, storedUses = 1, }, + [32] = { baseMultiplier = 1.947, cooldown = 0.15, damageEffectiveness = 1.947, levelRequirement = 92, storedUses = 1, }, + [33] = { baseMultiplier = 1.963, cooldown = 0.15, damageEffectiveness = 1.963, levelRequirement = 93, storedUses = 1, }, + [34] = { baseMultiplier = 1.979, cooldown = 0.15, damageEffectiveness = 1.979, levelRequirement = 94, storedUses = 1, }, + [35] = { baseMultiplier = 1.995, cooldown = 0.15, damageEffectiveness = 1.995, levelRequirement = 95, storedUses = 1, }, + [36] = { baseMultiplier = 2.011, cooldown = 0.15, damageEffectiveness = 2.011, levelRequirement = 96, storedUses = 1, }, + [37] = { baseMultiplier = 2.026, cooldown = 0.15, damageEffectiveness = 2.026, levelRequirement = 97, storedUses = 1, }, + [38] = { baseMultiplier = 2.042, cooldown = 0.15, damageEffectiveness = 2.042, levelRequirement = 98, storedUses = 1, }, + [39] = { baseMultiplier = 2.058, cooldown = 0.15, damageEffectiveness = 2.058, levelRequirement = 99, storedUses = 1, }, + [40] = { baseMultiplier = 2.074, cooldown = 0.15, damageEffectiveness = 2.074, levelRequirement = 100, storedUses = 1, }, + }, +} skills["SupportUniqueCastCurseOnCurse"] = { name = "Vixen's Entrapment", hidden = true, diff --git a/src/Data/Uniques/sword.lua b/src/Data/Uniques/sword.lua index 725e345a06..e7c882524d 100644 --- a/src/Data/Uniques/sword.lua +++ b/src/Data/Uniques/sword.lua @@ -1049,7 +1049,7 @@ Your Elemental Damage can Shock 20% increased Area of Effect for Attacks Deal no Non-Elemental Damage ]], -[[ + [[ The Golden Charlatan Lion Sword Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} @@ -1063,5 +1063,14 @@ Implicits: 1 Critical Strikes with this Weapon do not deal extra Damage Gain a random Shrine Buff for 30 seconds when you Kill a Rare or Unique Enemy +1 to maximum Mana per 2 Intelligence -]], +]], [[ +Dread Captain's Cutlass +Ghostflame Blade +Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} +League: Allflame +Crafted: true +Implicits: 2 +Can be Allflame Crafted as if Rare +Cannot gain Intangibility +]] } diff --git a/src/Export/Skills/other.txt b/src/Export/Skills/other.txt index bcdd1766c9..56510ea6d5 100644 --- a/src/Export/Skills/other.txt +++ b/src/Export/Skills/other.txt @@ -1513,6 +1513,11 @@ local skills, mod, flag, skill = ... }, #mods +#skill GhostCannons Ghostly Artillery +#flags attack + fromItem = true, +#mods + #skill SupportUniqueCastCurseOnCurse Vixen's Entrapment #flags spell curse fromItem = true, diff --git a/src/Export/Uniques/sword.lua b/src/Export/Uniques/sword.lua index fb10166572..7cad56f573 100644 --- a/src/Export/Uniques/sword.lua +++ b/src/Export/Uniques/sword.lua @@ -1034,7 +1034,7 @@ ElementalDamageCanShockUnique__1__ IncreasedAttackAreaOfEffectUnique__1_ DealNoNonElementalDamageUnique__1 ]], -[[ + [[ The Golden Charlatan Lion Sword Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} @@ -1048,5 +1048,13 @@ LocalCriticalStrikeChanceUnique__24 LocalNoCriticalStrikeMultiplierUnique_1 GainShrineOnRareOrUniqueKillUnique_1 GainManaPer2IntelligenceUnique_1 -]], +]], [[ +Dread Captain's Cutlass +Ghostflame Blade +Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} +League: Allflame +Crafted: true +Implicits: 1 +CanBeGhostflameCraftedAsThoughRare +]] } diff --git a/src/Modules/CalcTriggers.lua b/src/Modules/CalcTriggers.lua index 46c61a5918..4789587b33 100644 --- a/src/Modules/CalcTriggers.lua +++ b/src/Modules/CalcTriggers.lua @@ -1522,6 +1522,17 @@ local configTable = { return skill.skillData.triggeredBySettlersEnchantTrigger and slotMatch(env, skill) end} end, + ["ghostly artillery"] = function(env) + -- Skill is triggered only when the weapon with the enchant on it hits + return { + triggerSkillCond = function(env, skill) + return skill.skillTypes[SkillType.Melee] + end, + triggeredSkillCond = function(env, skill) + return slotMatch(env, skill) + end + } + end, ["replica gifts from above"] = function() return { triggerSkillCond = function(env, skill) diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 42360b0ab6..d1151e16ad 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -1241,6 +1241,9 @@ for modId, mod in pairs(data.veiledMods) do end end +local dreadCaptainBase = { base = copyTable(data.itemBases["Ghostflame Blade"]) } +dreadCaptainBase.base.tags.deepwater_sword = true + ---@class RareLikeUniqueDescription ---@field affixes table ---@field validBases table[]? Bases used to check modifier spawn tags instead of the item's base @@ -1263,6 +1266,12 @@ data.rareLikeUniques = { affixes = crimsonStormMods, prefixLimit = 0, suffixLimit = 1, + }, + ["dread captain's cutlass"] = { + validBases = { dreadCaptainBase }, + affixes = data.itemMods.Explicit, + prefixLimit = 3, + suffixLimit = 3, } } -- Uniques (loaded after version-specific data because reasons) diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index ca197b1008..ef48ad519c 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -3094,6 +3094,12 @@ local specialModList = { ["reflects your o[tp][hp][eo][rs]i?t?e? ring"] = { -- Display only. For Kalandra's Touch. }, + ["can be allflame crafted as if rare"] = { + -- Display only. For Dread Captain's Cutlass and supported by crafting UI + }, + ["cannot gain intangibility"] = { + -- Display only. For Dread Captain's Cutlass + }, ["has (%d+) sockets?"] = function(num) return { mod("SocketCount", "BASE", num) } end, ["has (%d+) abyssal sockets?"] = function(num) return { mod("AbyssalSocketCount", "BASE", num) } end, ["no physical damage"] = { mod("WeaponData", "LIST", { key = "PhysicalMin" }), mod("WeaponData", "LIST", { key = "PhysicalMax" }), mod("WeaponData", "LIST", { key = "PhysicalDPS" }) }, @@ -3281,6 +3287,7 @@ local specialModList = { ["trigger level (%d+) (.+) when you use a skill while you have a spirit charge"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, ["trigger level (%d+) (.+) when you hit an enemy while cursed"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, ["trigger level (%d+) (.+) when you hit a bleeding enemy"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, + ["trigger level (%d+) (.+) when you attack with this weapon"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, ["trigger level (%d+) (.+) when you hit a rare or unique enemy"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, ["trigger level (%d+) (.+) when you hit a rare or unique enemy and have no mark"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, ["trigger level (%d+) (.+) when you hit a frozen enemy"] = function(num, _, skill) return triggerExtraSkill(skill, num) end, From 0f55a5b63d5e5777b076332311a3501d67ee6001 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:33:54 +0300 Subject: [PATCH 2/8] Add type hints back in since they were accidentally removed --- src/Modules/Data.lua | 76 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index d1151e16ad..5a5f7dddcd 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -1148,14 +1148,80 @@ 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 +---@class ItemBaseEntry +---@field label string +---@field name string +---@field base ItemBase + +---@type table -- Build lists of item bases, separated by type -data.itemBaseLists = { } +data.itemBaseLists = {} for name, base in pairs(data.itemBases) do if not base.hidden then local type = base.type @@ -1246,11 +1312,12 @@ dreadCaptainBase.base.tags.deepwater_sword = true ---@class RareLikeUniqueDescription ---@field affixes table ----@field validBases table[]? Bases used to check modifier spawn tags instead of the item's base +---@field validBases ItemBaseEntry[]? Bases used to check modifier spawn tags instead of the item's base ---@field prefixLimit integer ---@field suffixLimit integer ---@field ignoreModType boolean? ----@field allowDuplicateGroups boolean? +---@field allowDuplicateGroups boolean? Whether the same modifier can appear multiple times on the item. +---@field supportsCustomModifiers boolean? Whether the item can be e.g. influenced orb exalted. These mods do not appear in the regular crafter dropdowns. ---@type table -- Uniques which use the existing rare item crafting controls. data.rareLikeUniques = { @@ -1272,6 +1339,7 @@ data.rareLikeUniques = { affixes = data.itemMods.Explicit, prefixLimit = 3, suffixLimit = 3, + supportsCustomModifiers = true, } } -- Uniques (loaded after version-specific data because reasons) From 0db8b7326411e15aa5676d928740deaf013b304d Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Tue, 4 Aug 2026 18:19:46 +0300 Subject: [PATCH 3/8] Support custom modifiers --- src/Classes/ItemsTab.lua | 23 ++++++++++++++++++++--- src/Modules/Data.lua | 8 ++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index deb1fcc43f..a61947b5b0 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -607,10 +607,12 @@ holding Shift will put it in the second.]]) self.controls.displayItemSectionInfluence = new("Control", {"TOPLEFT",self.controls.displayItemSectionEnchant,"BOTTOMLEFT"}, {0, 0, 0, function() return self.displayItem and self.displayItem.canBeInfluenced and 28 or 0 end}) + local influenceTipText = table.concat(main:WrapString("Selecting an influence here will also allow the modifier dropdowns to contain influenced mods.", 16, 140), "\n") self.controls.displayItemInfluence = new("DropDownControl", {"TOPLEFT",self.controls.displayItemSectionInfluence,"TOPRIGHT"}, {0, 0, 100, 20}, influenceDisplayList, function(index, value) local otherIndex = self.controls.displayItemInfluence2.selIndex setDisplayItemInfluence({ index - 1, otherIndex - 1 }) end) + self.controls.displayItemInfluence.tooltipText = influenceTipText self.controls.displayItemInfluence.shown = function() return self.displayItem and self.displayItem.canBeInfluenced end @@ -621,6 +623,7 @@ holding Shift will put it in the second.]]) self.controls.displayItemInfluence2.shown = function() return self.displayItem and self.displayItem.canBeInfluenced end + self.controls.displayItemInfluence2.tooltipText = influenceTipText -- Section: Item Quality self.controls.displayItemSectionQuality = new("Control", {"TOPLEFT",self.controls.displayItemSectionInfluence,"BOTTOMLEFT"}, {0, 0, 0, function() @@ -959,7 +962,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.displayItem.rareLikeUnique and self.displayItem.rareLikeUnique.supportsCustomModifiers)) end -- Section: Crucible modifiers @@ -3465,6 +3468,18 @@ function ItemsTabClass:AddCustomModifierToDisplayItem() t_insert(sourceList, { label = "Suffix", sourceId = "SUFFIX" }) end end + if self.displayItem.rareLikeUnique then + local applicableSourceIds = self.displayItem.rareLikeUnique.supportsCustomModifiers + if applicableSourceIds then + local newSourceList = {} + for _, list in ipairs(sourceList) do + if applicableSourceIds[list.sourceId] then + table.insert(newSourceList, list) + end + end + sourceList = newSourceList + end + end t_insert(sourceList, { label = "Custom", sourceId = "CUSTOM" }) buildMods(sourceList[1].sourceId) local function addModifier() @@ -3477,8 +3492,10 @@ function ItemsTabClass:AddCustomModifierToDisplayItem() end else local listMod = modList[controls.modSelect.selIndex] - for _, line in ipairs(listMod.mod) do - t_insert(item.explicitModLines, { line = line, modTags = listMod.mod.modTags, [listMod.type] = true }) + if listMod then + for _, line in ipairs(listMod.mod) do + t_insert(item.explicitModLines, { line = line, modTags = listMod.mod.modTags, [listMod.type] = true }) + end end end item:BuildAndParseRaw() diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 5a5f7dddcd..fd4fa2e137 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -1317,7 +1317,7 @@ dreadCaptainBase.base.tags.deepwater_sword = true ---@field suffixLimit integer ---@field ignoreModType boolean? ---@field allowDuplicateGroups boolean? Whether the same modifier can appear multiple times on the item. ----@field supportsCustomModifiers boolean? Whether the item can be e.g. influenced orb exalted. These mods do not appear in the regular crafter dropdowns. +---@field supportsCustomModifiers table? A table which describes which mod source IDs are applicable in the custom modifier menu. ---@type table -- Uniques which use the existing rare item crafting controls. data.rareLikeUniques = { @@ -1339,7 +1339,11 @@ data.rareLikeUniques = { affixes = data.itemMods.Explicit, prefixLimit = 3, suffixLimit = 3, - supportsCustomModifiers = true, + supportsCustomModifiers = { + ESSENCE = true, + VEILED = true, + CUSTOM = true, + }, } } -- Uniques (loaded after version-specific data because reasons) From 088aab13f9b02073f45f8056d8a1c414e76bb925 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Tue, 4 Aug 2026 18:33:54 +0300 Subject: [PATCH 4/8] Regen modcache --- src/Data/ModCache.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 81bd59d929..b7d020cc0a 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -7952,6 +7952,7 @@ c["Can Allocate Passives from the Templar's starting point"]={{},nil} c["Can Allocate Passives from the Witch's starting point"]={{},nil} c["Can Consume 4 Uncorrupted Support Gems"]={nil,"Can Consume 4 Uncorrupted Support Gems "} c["Can Consume 4 Uncorrupted Support Gems Has not Consumed any Gems"]={nil,"Can Consume 4 Uncorrupted Support Gems Has not Consumed any Gems "} +c["Can be Allflame Crafted as if Rare"]={{},nil} c["Can be Enchanted by a Kalguuran Runesmith"]={nil,"Can be Enchanted by a Kalguuran Runesmith "} c["Can be Enchanted by a Kalguuran Runesmith Can have 2 additional Runesmithing Enchantments"]={nil,"Can be Enchanted by a Kalguuran Runesmith Can have 2 additional Runesmithing Enchantments "} c["Can be Runesmithed as though it were all One Handed Melee Weapon Types"]={nil,"Can be Runesmithed as though it were all One Handed Melee Weapon Types "} @@ -8047,6 +8048,7 @@ c["Cannot deal non-Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="DealNoPhysi c["Cannot deal non-Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="DealNoPhysical",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="DealNoLightning",type="FLAG",value=true},[3]={flags=0,keywordFlags=0,name="DealNoCold",type="FLAG",value=true},[4]={flags=0,keywordFlags=0,name="DealNoChaos",type="FLAG",value=true}},nil} c["Cannot deal non-Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="DealNoPhysical",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="DealNoCold",type="FLAG",value=true},[3]={flags=0,keywordFlags=0,name="DealNoFire",type="FLAG",value=true},[4]={flags=0,keywordFlags=0,name="DealNoChaos",type="FLAG",value=true}},nil} c["Cannot gain Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="CannotGainEnergyShield",type="FLAG",value=true}},nil} +c["Cannot gain Intangibility"]={{},nil} c["Cannot gain Life during effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="CannotGainLife",type="FLAG",value=true}},nil} c["Cannot gain Mana during effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="CannotGainMana",type="FLAG",value=true}},nil} c["Cannot gain Power Charges"]={nil,"Cannot gain Power Charges "} From fe18293ad1b4673fc3e861528ca09c1bf2bd9330 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 5 Aug 2026 16:55:24 +1000 Subject: [PATCH 5/8] Fix Ghostly Artillery missing area and projectile flag --- src/Data/Skills/other.lua | 2 ++ src/Export/Skills/other.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index 2ef23a5729..3ccb7320d4 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -5892,6 +5892,8 @@ skills["GhostCannons"] = { fromItem = true, baseFlags = { attack = true, + projectile = true, + area = true, }, constantStats = { { "skill_physical_damage_%_to_convert_to_fire", 50 }, diff --git a/src/Export/Skills/other.txt b/src/Export/Skills/other.txt index 56510ea6d5..160940ddc3 100644 --- a/src/Export/Skills/other.txt +++ b/src/Export/Skills/other.txt @@ -1514,7 +1514,7 @@ local skills, mod, flag, skill = ... #mods #skill GhostCannons Ghostly Artillery -#flags attack +#flags attack projectile area fromItem = true, #mods From 8df13da1df3f0607cc199c00e99c107f88bb7c64 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 5 Aug 2026 17:46:45 +1000 Subject: [PATCH 6/8] Fix source weapon handling for triggered attacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow Ghostly Artillery to trigger from projectile attacks and calculate “when you Attack” triggers without chance to hit. Ensure Ghostly Artillery and Fiery Impact only trigger from and deal damage with the weapon that grants them, including correct trigger rates while dual wielding. --- spec/System/TestTriggers_spec.lua | 88 ++++++++++++++++++++++++++++++- src/Modules/CalcActiveSkill.lua | 11 +++- src/Modules/CalcTriggers.lua | 19 ++++--- 3 files changed, 107 insertions(+), 11 deletions(-) diff --git a/spec/System/TestTriggers_spec.lua b/spec/System/TestTriggers_spec.lua index 5769afa3b6..12e9a3ec10 100644 --- a/spec/System/TestTriggers_spec.lua +++ b/spec/System/TestTriggers_spec.lua @@ -1,4 +1,32 @@ describe("TestTriggers", function() + local function equipDreadCaptainsCutlass() + build.itemsTab:CreateDisplayItemFromRaw([[Dread Captain's Cutlass + Ghostflame Blade + League: Allflame + Crafted: true + Prefix: DeepwaterSwordGrantedSkillGhostCannons + Sockets: R-R-R + LevelReq: 68 + Implicits: 2 + Can be Allflame Crafted as if Rare + Cannot gain Intangibility + Trigger level 20 Ghostly Artillery when you Attack with this Weapon]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + end + + local function equipReviewSword() + build.itemsTab:CreateDisplayItemFromRaw([[Rarity: RARE + Review Sword + Rusted Sword + Crafted: true + Implicits: 0 + Adds 1000 to 1000 Physical Damage + Hits can't be Evaded]]) + build.itemsTab:AddDisplayItem() + runCallback("OnFrame") + end + before_each(function() newBuild() end) @@ -1437,7 +1465,7 @@ describe("TestTriggers", function() assert.are.not_equals(math.floor(build.calcsTab.mainOutput.SkillTriggerRate * 100), math.floor(baseRate * 100)) end) - it("skillId config search", function() + it("Trigger Fiery Impact with its source weapon", function() build.itemsTab:CreateDisplayItemFromRaw([[Rarity: RARE Physical 1H Mace Boom Mace @@ -1465,7 +1493,63 @@ describe("TestTriggers", function() build.skillsTab:PasteSocketGroup("Smite 20/0 1\n") runCallback("OnFrame") - local baseRate = build.calcsTab.mainOutput.SkillTriggerRate + local baseRate = build.calcsTab.mainOutput.EffectiveSourceRate assert.True(build.calcsTab.mainOutput.SkillTriggerRate ~= nil) + + equipReviewSword() + runCallback("OnFrame") + + assert.is_true(build.calcsTab.mainOutput.EffectiveSourceRate < baseRate) + assert.is_true(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon1Attack) + assert.is_falsy(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon2Attack) + end) + + it("Trigger Ghostly Artillery with a projectile attack", function() + equipDreadCaptainsCutlass() + build.skillsTab:PasteSocketGroup("Lancing Steel 20/0 1\n") + runCallback("OnFrame") + + assert.are.near(build.calcsTab.mainOutput.EffectiveSourceRate, build.calcsTab.mainOutput.SkillTriggerRate, 0.01) + end) + + it("Do not add socketed attacks to the Ghostly Artillery trigger rotation", function() + equipDreadCaptainsCutlass() + build.skillsTab:PasteSocketGroup("Smite 20/0 1\n") + runCallback("OnFrame") + local bodyArmourRate = build.calcsTab.mainOutput.SkillTriggerRate + + newBuild() + equipDreadCaptainsCutlass() + build.skillsTab:PasteSocketGroup("Slot: Weapon 1\nSmite 20/0 1\n") + runCallback("OnFrame") + + assert.are.near(bodyArmourRate, build.calcsTab.mainOutput.SkillTriggerRate, 10 ^ -9) + end) + + it("Use only the Cutlass when dual wielding", function() + equipDreadCaptainsCutlass() + build.skillsTab:PasteSocketGroup("Smite 20/0 1\n") + runCallback("OnFrame") + local singleWeaponRate = build.calcsTab.mainOutput.EffectiveSourceRate + + newBuild() + equipDreadCaptainsCutlass() + equipReviewSword() + build.skillsTab:PasteSocketGroup("Smite 20/0 1\n") + runCallback("OnFrame") + + assert.is_true(build.calcsTab.mainOutput.EffectiveSourceRate < singleWeaponRate) + assert.is_true(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon1Attack) + assert.is_falsy(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon2Attack) + assert.is_nil(build.calcsTab.mainOutput.OffHand and build.calcsTab.mainOutput.OffHand.AverageHit) + + newBuild() + equipReviewSword() + equipDreadCaptainsCutlass() + build.skillsTab:PasteSocketGroup("Smite 20/0 1\n") + runCallback("OnFrame") + + assert.is_falsy(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon1Attack) + assert.is_true(build.calcsTab.mainEnv.player.mainSkill.skillFlags.weapon2Attack) end) end) diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index 543bc6c616..1ff52a4b8b 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -278,13 +278,22 @@ function calcs.buildActiveSkillModList(env, activeSkill) activeSkill.weapon2Flags = 0 else -- Set weapon flags + if skillFlags.attack and activeSkill.socketGroup and activeSkill.socketGroup.sourceItem then + -- Item-granted attacks use the weapon that grants the skill + local sourceSlot = activeSkill.socketGroup.slot or "" + skillFlags.forceMainHand = sourceSlot:match("^Weapon 1") ~= nil + skillFlags.forceOffHand = sourceSlot:match("^Weapon 2") ~= nil + end local weaponTypes = { activeGrantedEffect.weaponTypes } for _, skillEffect in pairs(activeSkill.effectList) do if skillEffect.grantedEffect.support and skillEffect.grantedEffect.weaponTypes then t_insert(weaponTypes, skillEffect.grantedEffect.weaponTypes) end end - local weapon1Flags, weapon1Info = getWeaponFlags(env, activeSkill.actor.weaponData1, weaponTypes) + local weapon1Flags, weapon1Info + if not skillFlags.forceOffHand then + weapon1Flags, weapon1Info = getWeaponFlags(env, activeSkill.actor.weaponData1, weaponTypes) + end if not weapon1Flags and activeSkill.summonSkill then -- Minion skills seem to ignore weapon types weapon1Flags, weapon1Info = ModFlag[env.data.weaponTypeInfo["None"].flag], env.data.weaponTypeInfo["None"] diff --git a/src/Modules/CalcTriggers.lua b/src/Modules/CalcTriggers.lua index 4789587b33..ae3b4f3201 100644 --- a/src/Modules/CalcTriggers.lua +++ b/src/Modules/CalcTriggers.lua @@ -395,11 +395,14 @@ local function defaultTriggerHandler(env, config) local triggeredSkills = config.triggeredSkills or {} local trigRate = config.trigRate local uuid + local sourceWeapon = config.sourceWeapon + -- Only attacks using the granting weapon can activate source-weapon triggers + local sourceWeaponFlag = sourceWeapon and actor.mainSkill.socketGroup.slot and (actor.mainSkill.socketGroup.slot:match("^Weapon 2") and "weapon2Attack" or "weapon1Attack") -- Find trigger skill and triggered skills if config.triggeredSkillCond or config.triggerSkillCond then for _, skill in ipairs(env.player.activeSkillList) do - if config.triggerSkillCond and config.triggerSkillCond(env, skill) and (not isTriggered(skill) or actor.mainSkill.skillFlags.globalTrigger or config.allowTriggered) and skill ~= actor.mainSkill then + if config.triggerSkillCond and config.triggerSkillCond(env, skill) and (not sourceWeaponFlag or skill.skillFlags[sourceWeaponFlag]) and (not isTriggered(skill) or actor.mainSkill.skillFlags.globalTrigger or config.allowTriggered) and skill ~= actor.mainSkill then source, trigRate, uuid = findTriggerSkill(env, skill, source, trigRate, config.comparer) end if config.triggeredSkillCond and config.triggeredSkillCond(env,skill) then @@ -436,7 +439,9 @@ local function defaultTriggerHandler(env, config) end -- Dual wield triggers - if trigRate and source and env.player.weaponData1.type and env.player.weaponData2.type and not source.skillData.doubleHitsWhenDualWielding and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and actor.mainSkill.triggeredBy and actor.mainSkill.triggeredBy.grantedEffect.support and actor.mainSkill.triggeredBy.grantedEffect.fromItem then + local sourceWeaponTrigger = sourceWeapon and source and source.skillFlags.bothWeaponAttack + local itemSupportTrigger = actor.mainSkill.triggeredBy and actor.mainSkill.triggeredBy.grantedEffect.support and actor.mainSkill.triggeredBy.grantedEffect.fromItem + if trigRate and source and env.player.weaponData1.type and env.player.weaponData2.type and not source.skillData.doubleHitsWhenDualWielding and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and (sourceWeaponTrigger or itemSupportTrigger) then trigRate = trigRate / 2 if breakdown then t_insert(breakdown.EffectiveSourceRate, 2, s_format("/ 2 ^8(due to dual wielding)")) @@ -1523,13 +1528,11 @@ local configTable = { end} end, ["ghostly artillery"] = function(env) - -- Skill is triggered only when the weapon with the enchant on it hits return { + sourceWeapon = true, + triggerOnUse = true, triggerSkillCond = function(env, skill) - return skill.skillTypes[SkillType.Melee] - end, - triggeredSkillCond = function(env, skill) - return slotMatch(env, skill) + return skill.skillTypes[SkillType.Attack] end } end, @@ -1564,7 +1567,7 @@ local configTable = { return {triggerSkillCond = function(env, skill) return (skill.skillTypes[SkillType.Melee] or skill.skillTypes[SkillType.Attack]) end} end, ["FieryImpactHeistMaceImplicit"] = function(env) - return {triggerSkillCond = function(env, skill) return (skill.skillTypes[SkillType.Melee] or skill.skillTypes[SkillType.Attack]) end} + return {sourceWeapon = true, triggerSkillCond = function(env, skill) return (skill.skillTypes[SkillType.Melee] or skill.skillTypes[SkillType.Attack]) end} end, } From bcf166b2eadaa958dac9c1765c496040b996d76e Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 5 Aug 2026 18:10:16 +1000 Subject: [PATCH 7/8] Alphabetical unique sword order Ordering was not alphabetical --- src/Data/Uniques/sword.lua | 71 ++++++++++++++++++------------------ src/Export/Uniques/sword.lua | 69 +++++++++++++++++------------------ 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/src/Data/Uniques/sword.lua b/src/Data/Uniques/sword.lua index e7c882524d..70edcaf0b4 100644 --- a/src/Data/Uniques/sword.lua +++ b/src/Data/Uniques/sword.lua @@ -28,6 +28,15 @@ Implicits: 1 Skills fire 2 additional Projectiles if you've used a Movement Skill Recently Far Shot ]],[[ +Dread Captain's Cutlass +Ghostflame Blade +Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} +League: Allflame +Crafted: true +Implicits: 2 +Can be Allflame Crafted as if Rare +Cannot gain Intangibility +]],[[ Dreamfeather Eternal Sword Variant: Pre 2.0.0 @@ -804,6 +813,18 @@ Socketed Melee Gems have 15% increased Area of Effect {variant:4,5}Attack Skills gain 5% of Physical Damage as Extra Fire Damage per Socketed Red Gem {variant:4,5}You have Vaal Pact while all Socketed Gems are Red ]],[[ +Echoforge +Infernal Sword +Source: Drops from unique{The Maven} +Implicits: 1 +30% increased Chaos Damage +Adds (600-650) to (750-800) Chaos Damage +(-16-16)% reduced Attack Speed ++(-200-200) to maximum Life +Your Chaos Damage can Shock +(-40-40)% reduced Area of Effect for Attacks +Deal no Physical or Elemental Damage +]],[[ Edge of Madness Etched Greatsword League: Beyond @@ -824,6 +845,20 @@ Adds (60-68) to (90-102) Chaos Damage {variant:1,2,4}1% increased Chaos Damage per Level {variant:2,3,4}Adds 1 to 2 Physical Damage to Attacks per Level ]],[[ +The Golden Charlatan +Lion Sword +Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} +Requires Level 65, 104 Str, 122 Dex +Implicits: 1 ++50 to Strength and Dexterity ++200 Intelligence Requirement +(200-300)% increased Physical Damage +(10-16)% increased Attack Speed +(100-200)% increased Critical Strike Chance +Critical Strikes with this Weapon do not deal extra Damage +Gain a random Shrine Buff for 30 seconds when you Kill a Rare or Unique Enemy ++1 to maximum Mana per 2 Intelligence +]],[[ Hiltless Reaver Sword Variant: Pre 2.6.0 @@ -893,18 +928,6 @@ Adds (385-440) to (490-545) Cold Damage {variant:2}Culling Strike against Frozen Enemies Gain an Endurance Charge if an Attack Freezes an Enemy ]],[[ -Echoforge -Infernal Sword -Source: Drops from unique{The Maven} -Implicits: 1 -30% increased Chaos Damage -Adds (600-650) to (750-800) Chaos Damage -(-16-16)% reduced Attack Speed -+(-200-200) to maximum Life -Your Chaos Damage can Shock -(-40-40)% reduced Area of Effect for Attacks -Deal no Physical or Elemental Damage -]],[[ Queen's Decree Ornate Sword Variant: Pre 2.6.0 @@ -1048,29 +1071,5 @@ Your Elemental Damage can Shock {variant:3}Gain 700% of Weapon Physical Damage as Extra Damage of a random Element 20% increased Area of Effect for Attacks Deal no Non-Elemental Damage -]], - [[ -The Golden Charlatan -Lion Sword -Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} -Requires Level 65, 104 Str, 122 Dex -Implicits: 1 -+50 to Strength and Dexterity -+200 Intelligence Requirement -(200-300)% increased Physical Damage -(10-16)% increased Attack Speed -(100-200)% increased Critical Strike Chance -Critical Strikes with this Weapon do not deal extra Damage -Gain a random Shrine Buff for 30 seconds when you Kill a Rare or Unique Enemy -+1 to maximum Mana per 2 Intelligence -]], [[ -Dread Captain's Cutlass -Ghostflame Blade -Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} -League: Allflame -Crafted: true -Implicits: 2 -Can be Allflame Crafted as if Rare -Cannot gain Intangibility ]] } diff --git a/src/Export/Uniques/sword.lua b/src/Export/Uniques/sword.lua index 7cad56f573..d2ab4d412f 100644 --- a/src/Export/Uniques/sword.lua +++ b/src/Export/Uniques/sword.lua @@ -28,6 +28,14 @@ EvasionRatingWhileMovingUnique__1 NumberOfProjectilesIfUsedAMovementSkillRecentlyUnique__1 PlayerFarShotUnique__2 ]],[[ +Dread Captain's Cutlass +Ghostflame Blade +Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} +League: Allflame +Crafted: true +Implicits: 1 +CanBeGhostflameCraftedAsThoughRare +]],[[ Dreamfeather Eternal Sword Variant: Pre 2.0.0 @@ -795,6 +803,18 @@ LocalIncreasedAttackSpeedUniqueTwoHandSword8 {variant:4,5}AttackSkillsHavePhysToExtraFireDamagePerSocketedRedGemUniqueTwoHandSword8 {variant:4,5}VaalPactIfAllSocketedGemsAreRedUniqueTwoHandSword8 ]],[[ +Echoforge +Infernal Sword +Source: Drops from unique{The Maven} +Implicits: 1 +IncreasedChaosDamageImplicitUnique__1 +LocalAddedChaosDamageUnique__3 +LocalIncreasedAttackSpeedUnique__38 +IncreasedLifeUnique__117 +ChaosDamageCanShockUnique__1 +IncreasedAttackAreaOfEffectUnique__3 +DealNoElementalPhysicalDamageUnique__1 +]],[[ Edge of Madness Etched Greatsword League: Beyond @@ -815,6 +835,20 @@ LocalChaosDamageUniqueTwoHandSword7 {variant:1,2,4}IncreasedElementalDamagePerLevelUniqueTwoHandSword7 {variant:2,3,4}PhysicalDamageToAttacksPerLevelUnique__1_ ]],[[ +The Golden Charlatan +Lion Sword +Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} +Requires Level 65, 104 Str, 122 Dex +Implicits: 1 +StrengthDexterityImplicitSword_1 +IntelligenceRequirementsUnique_1 +LocalIncreasedPhysicalDamagePercentUnique__53 +IncreasedAttackSpeedUniqueGlovesDemigods1 +LocalCriticalStrikeChanceUnique__24 +LocalNoCriticalStrikeMultiplierUnique_1 +GainShrineOnRareOrUniqueKillUnique_1 +GainManaPer2IntelligenceUnique_1 +]],[[ Hiltless Reaver Sword Variant: Pre 2.6.0 @@ -884,18 +918,6 @@ ColdDamageTakenUnique__2 {variant:2}CullingAgainstFrozenEnemiesUnique__1 EnduranceChargeIfAttackFreezesUnique__1 ]],[[ -Echoforge -Infernal Sword -Source: Drops from unique{The Maven} -Implicits: 1 -IncreasedChaosDamageImplicitUnique__1 -LocalAddedChaosDamageUnique__3 -LocalIncreasedAttackSpeedUnique__38 -IncreasedLifeUnique__117 -ChaosDamageCanShockUnique__1 -IncreasedAttackAreaOfEffectUnique__3 -DealNoElementalPhysicalDamageUnique__1 -]],[[ Queen's Decree Ornate Sword Variant: Pre 2.6.0 @@ -1033,28 +1055,5 @@ ElementalDamageCanShockUnique__1__ {variant:3}WeaponPhysicalDamageAddedAsRandomElementUnique__1__ IncreasedAttackAreaOfEffectUnique__1_ DealNoNonElementalDamageUnique__1 -]], - [[ -The Golden Charlatan -Lion Sword -Source: Drops from unique{Uber Incarnation of Dread} in normal{Moment of Reverence} -Requires Level 65, 104 Str, 122 Dex -Implicits: 1 -StrengthDexterityImplicitSword_1 -IntelligenceRequirementsUnique_1 -LocalIncreasedPhysicalDamagePercentUnique__53 -IncreasedAttackSpeedUniqueGlovesDemigods1 -LocalCriticalStrikeChanceUnique__24 -LocalNoCriticalStrikeMultiplierUnique_1 -GainShrineOnRareOrUniqueKillUnique_1 -GainManaPer2IntelligenceUnique_1 -]], [[ -Dread Captain's Cutlass -Ghostflame Blade -Source: Drops from unique{Captainsbane} in normal{The Fathomless Depths} -League: Allflame -Crafted: true -Implicits: 1 -CanBeGhostflameCraftedAsThoughRare ]] } From 1a9db2402ffd16f3986216d0bab071c0d13a8271 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 5 Aug 2026 18:12:16 +1000 Subject: [PATCH 8/8] Fix extra mod I accidentally forgot to remove this when I copied the stat map --- src/Data/Skills/other.lua | 3 --- src/Export/Skills/other.txt | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/Data/Skills/other.lua b/src/Data/Skills/other.lua index 3ccb7320d4..33c503b2af 100644 --- a/src/Data/Skills/other.lua +++ b/src/Data/Skills/other.lua @@ -398,9 +398,6 @@ skills["BarnacleSnap"] = { skill("hitTimeOverride", nil), div = 1000, }, - ["spider_aspect_max_web_count"] = { - mod("Multiplier:SpiderWebApplyStackMax", "BASE", nil), - }, }, baseFlags = { attack = true, diff --git a/src/Export/Skills/other.txt b/src/Export/Skills/other.txt index 160940ddc3..ab103e85e7 100644 --- a/src/Export/Skills/other.txt +++ b/src/Export/Skills/other.txt @@ -151,9 +151,6 @@ local skills, mod, flag, skill = ... skill("hitTimeOverride", nil), div = 1000, }, - ["spider_aspect_max_web_count"] = { - mod("Multiplier:SpiderWebApplyStackMax", "BASE", nil), - }, }, #mods