From 58eb6e46fb9c6d5a73666b32ab64e7486284827f Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 9 Nov 2025 14:16:59 +1100 Subject: [PATCH 1/2] Fix Spiritblade conversion and Moonbenders Wing gain mods We previously only calculated conversion at the skill level with no handling for local weapon mods so we applied them globally with some hacky condition checks that still had issues Now we use the cfg passes to build tables for each weapon hand and a global skill table The random gain/convert mods require a cache of the processed mods so that a global skill mod doesn't end up in each cfg and counting 3 times. --- src/Data/ModCache.lua | 8 +- src/Modules/CalcOffence.lua | 203 ++++++++++++++++++++---------------- src/Modules/ModParser.lua | 5 +- 3 files changed, 120 insertions(+), 96 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 06e0e46d92..bd1d348b1d 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2859,7 +2859,7 @@ c["100% of Lightning Damage from Hits taken as Cold Damage"]={{[1]={flags=0,keyw c["100% of Lightning Damage from Hits taken as Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="LightningDamageFromHitsTakenAsFire",type="BASE",value=100}},nil} c["100% of Physical Damage Converted to Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToCold",type="BASE",value=100}},nil} c["100% of Physical Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToFire",type="BASE",value=100}},nil} -c["100% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=100}},nil} +c["100% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="MainHandAttack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=100}},nil} c["100% reduced Global Accuracy Rating"]={{[1]={[1]={type="Global"},flags=0,keywordFlags=0,name="Accuracy",type="INC",value=-100}},nil} c["1000% increased Armour and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEnergyShield",type="INC",value=1000}},nil} c["1000% increased Stun and Block Recovery"]={{[1]={flags=0,keywordFlags=0,name="StunRecovery",type="INC",value=1000}},nil} @@ -5825,7 +5825,7 @@ c["50% of Physical Damage Converted to Fire while you have Avatar of Fire"]={{[1 c["50% of Physical Damage Converted to Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToLightning",type="BASE",value=50}},nil} c["50% of Physical Damage Converted to Lightning during Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToLightning",type="BASE",value=50}},nil} c["50% of Physical Damage from Hits taken as Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageFromHitsTakenAsLightning",type="BASE",value=50}},nil} -c["50% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=50}},nil} +c["50% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="MainHandAttack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=50}},nil} c["50% of Physical, Cold and Lightning Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToFire",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="LightningDamageConvertToFire",type="BASE",value=50},[3]={flags=0,keywordFlags=0,name="ColdDamageConvertToFire",type="BASE",value=50}},nil} c["50% of your Energy Shield is added to your Stun Threshold"]={{[1]={flags=0,keywordFlags=0,name="AddESToStunThreshold",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ESToStunThresholdPercent",type="BASE",value=50}},nil} c["50% reduced Area of Effect of Hex Skills"]={{[1]={[1]={skillType=108,type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=-50}},nil} @@ -9203,8 +9203,8 @@ c["Hits with this Weapon deal 45% increased Damage to Shocked Enemies"]={{[1]={[ c["Hits with this Weapon deal 60% increased Damage to Frozen Enemies"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Frozen"},flags=4,keywordFlags=0,name="Damage",type="INC",value=60}},nil} c["Hits with this Weapon deal 60% increased Damage to Ignited Enemies"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Ignited"},flags=4,keywordFlags=0,name="Damage",type="INC",value=60}},nil} c["Hits with this Weapon deal 60% increased Damage to Shocked Enemies"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={actor="enemy",type="ActorCondition",var="Shocked"},flags=4,keywordFlags=0,name="Damage",type="INC",value=60}},nil} -c["Hits with this Weapon gain 100% of Physical Damage as Extra Cold or Lightning Damage"]={{[1]={[1]={type="Condition",var="DualWielding"},[2]={skillType=1,type="SkillType"},[3]={neg=true,skillType=13,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=50},[2]={[1]={neg=true,type="Condition",var="DualWielding"},[2]={skillType=1,type="SkillType"},[3]={neg=true,skillType=13,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=100}},nil} -c["Hits with this Weapon gain 88% of Physical Damage as Extra Cold or Lightning Damage"]={{[1]={[1]={type="Condition",var="DualWielding"},[2]={skillType=1,type="SkillType"},[3]={neg=true,skillType=13,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=44},[2]={[1]={neg=true,type="Condition",var="DualWielding"},[2]={skillType=1,type="SkillType"},[3]={neg=true,skillType=13,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=88}},nil} +c["Hits with this Weapon gain 100% of Physical Damage as Extra Cold or Lightning Damage"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=100}},nil} +c["Hits with this Weapon gain 88% of Physical Damage as Extra Cold or Lightning Damage"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=4,keywordFlags=0,name="PhysicalDamageGainAsColdOrLightning",type="BASE",value=88}},nil} c["Hits with this Weapon have +10% to Critical Strike Multiplier per Enemy Power"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},[3]={type="Multiplier",var="EnemyPower"},flags=4,keywordFlags=0,name="CritMultiplier",type="BASE",value=10}},nil} c["Hits with this Weapon ignore Enemy Physical Damage Reduction"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},[2]={skillType=1,type="SkillType"},flags=4,keywordFlags=0,name="ChanceToIgnoreEnemyPhysicalDamageReduction",type="BASE",value=100}},nil} c["Hollow Palm Technique"]={{[1]={flags=0,keywordFlags=0,name="Keystone",type="LIST",value="Hollow Palm Technique"}},nil} diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index ef3293bdb0..712c39e917 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -72,7 +72,7 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF -- Calculate conversions local addMin, addMax = 0, 0 - local conversionTable = activeSkill.conversionTable + local conversionTable = (cfg and cfg.conversionTable) or activeSkill.conversionTable for _, otherType in ipairs(dmgTypeList) do if otherType == damageType then -- Damage can only be converted from damage types that precede this one in the conversion sequence, so stop here @@ -140,7 +140,8 @@ end local function calcAilmentSourceDamage(activeSkill, output, cfg, breakdown, damageType, typeFlags) local min, max = calcDamage(activeSkill, output, cfg, breakdown, damageType, typeFlags) - local convMult = activeSkill.conversionTable[damageType].mult + local conversionTable = (cfg and cfg.conversionTable) or activeSkill.conversionTable + local convMult = conversionTable[damageType].mult if breakdown and convMult ~= 1 then t_insert(breakdown, "Source damage:") t_insert(breakdown, s_format("%d to %d ^8(total damage)", min, max)) @@ -916,49 +917,61 @@ function calcs.offence(env, actor, activeSkill) }) end end - if skillModList:Sum("BASE", skillCfg, "PhysicalDamageGainAsRandom", "PhysicalDamageConvertToRandom", "PhysicalDamageGainAsColdOrLightning") > 0 then - skillFlags.randomPhys = true - local physMode = env.configInput.physMode or "AVERAGE" - for i, value in ipairs(skillModList:Tabulate("BASE", skillCfg, "PhysicalDamageGainAsRandom")) do - local mod = value.mod - local effVal = mod.value / 3 - if physMode == "AVERAGE" then - skillModList:NewMod("PhysicalDamageGainAsFire", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "FIRE" then - skillModList:NewMod("PhysicalDamageGainAsFire", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "COLD" then - skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "LIGHTNING" then - skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - end - end - for i, value in ipairs(skillModList:Tabulate("BASE", skillCfg, "PhysicalDamageConvertToRandom")) do - local mod = value.mod - local effVal = mod.value / 3 - if physMode == "AVERAGE" then - skillModList:NewMod("PhysicalDamageConvertToFire", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - skillModList:NewMod("PhysicalDamageConvertToCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - skillModList:NewMod("PhysicalDamageConvertToLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "FIRE" then - skillModList:NewMod("PhysicalDamageConvertToFire", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "COLD" then - skillModList:NewMod("PhysicalDamageConvertToCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "LIGHTNING" then - skillModList:NewMod("PhysicalDamageConvertToLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - end - end - for i, value in ipairs(skillModList:Tabulate("BASE", skillCfg, "PhysicalDamageGainAsColdOrLightning")) do - local mod = value.mod - local effVal = mod.value / 2 - if physMode == "AVERAGE" or physMode == "FIRE" then - skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "COLD" then - skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) - elseif physMode == "LIGHTNING" then - skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + local physMode = env.configInput.physMode or "AVERAGE" + local processedRandomMods = { } + for _, cfg in ipairs({ skillCfg, activeSkill.weapon1Cfg, activeSkill.weapon2Cfg }) do + if cfg and skillModList:Sum("BASE", cfg, "PhysicalDamageGainAsRandom", "PhysicalDamageConvertToRandom", "PhysicalDamageGainAsColdOrLightning") > 0 then + skillFlags.randomPhys = true + for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "PhysicalDamageGainAsRandom")) do + local mod = value.mod + if not processedRandomMods[mod] then + processedRandomMods[mod] = true + local effVal = mod.value / 3 + if physMode == "AVERAGE" then + skillModList:NewMod("PhysicalDamageGainAsFire", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "FIRE" then + skillModList:NewMod("PhysicalDamageGainAsFire", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "COLD" then + skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "LIGHTNING" then + skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + end + end + end + for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "PhysicalDamageConvertToRandom")) do + local mod = value.mod + if not processedRandomMods[mod] then + processedRandomMods[mod] = true + local effVal = mod.value / 3 + if physMode == "AVERAGE" then + skillModList:NewMod("PhysicalDamageConvertToFire", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + skillModList:NewMod("PhysicalDamageConvertToCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + skillModList:NewMod("PhysicalDamageConvertToLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "FIRE" then + skillModList:NewMod("PhysicalDamageConvertToFire", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "COLD" then + skillModList:NewMod("PhysicalDamageConvertToCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "LIGHTNING" then + skillModList:NewMod("PhysicalDamageConvertToLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + end + end + end + for _, value in ipairs(skillModList:Tabulate("BASE", cfg, "PhysicalDamageGainAsColdOrLightning")) do + local mod = value.mod + if not processedRandomMods[mod] then + processedRandomMods[mod] = true + local effVal = mod.value / 2 + if physMode == "AVERAGE" or physMode == "FIRE" then + skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", effVal, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "COLD" then + skillModList:NewMod("PhysicalDamageGainAsCold", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + elseif physMode == "LIGHTNING" then + skillModList:NewMod("PhysicalDamageGainAsLightning", "BASE", mod.value, mod.source, mod.flags, mod.keywordFlags, unpack(mod)) + end + end end end end @@ -1801,49 +1814,60 @@ function calcs.offence(env, actor, activeSkill) end -- Calculate damage conversion percentages - activeSkill.conversionTable = wipeTable(activeSkill.conversionTable) - for damageTypeIndex = 1, 4 do - local damageType = dmgTypeList[damageTypeIndex] - local globalConv = wipeTable(tempTable1) - local skillConv = wipeTable(tempTable2) - local add = wipeTable(tempTable3) - local globalTotal, skillTotal = 0, 0 - for otherTypeIndex = damageTypeIndex + 1, 5 do - -- For all possible destination types, check for global and skill conversions - local otherType = dmgTypeList[otherTypeIndex] - globalConv[otherType] = m_max(skillModList:Sum("BASE", skillCfg, damageType.."DamageConvertTo"..otherType, isElemental[damageType] and "ElementalDamageConvertTo"..otherType or nil, damageType ~= "Chaos" and "NonChaosDamageConvertTo"..otherType or nil), 0) - globalTotal = globalTotal + globalConv[otherType] - skillConv[otherType] = m_max(skillModList:Sum("BASE", skillCfg, "Skill"..damageType.."DamageConvertTo"..otherType), 0) - skillTotal = skillTotal + skillConv[otherType] - add[otherType] = m_max(skillModList:Sum("BASE", skillCfg, damageType.."DamageGainAs"..otherType, isElemental[damageType] and "ElementalDamageGainAs"..otherType or nil, damageType ~= "Chaos" and "NonChaosDamageGainAs"..otherType or nil), 0) - end - if skillTotal > 100 then - -- Skill conversion exceeds 100%, scale it down and remove non-skill conversions - local factor = 100 / skillTotal - for type, val in pairs(skillConv) do - skillConv[type] = val * factor - end - for type, val in pairs(globalConv) do - globalConv[type] = 0 - end - elseif globalTotal + skillTotal > 100 then - -- Conversion exceeds 100%, scale down non-skill conversions - local factor = (100 - skillTotal) / globalTotal - for type, val in pairs(globalConv) do - globalConv[type] = val * factor - end - globalTotal = globalTotal * factor - end - local dmgTable = { conversion = { }, gain = { } } - for type in pairs(globalConv) do - dmgTable.conversion[type] = (globalConv[type] + skillConv[type]) / 100 - dmgTable.gain[type] = add[type] / 100 - dmgTable[type] = (globalConv[type] + skillConv[type] + add[type]) / 100 - end - dmgTable.mult = 1 - m_min((globalTotal + skillTotal) / 100, 1) - activeSkill.conversionTable[damageType] = dmgTable - end - activeSkill.conversionTable["Chaos"] = { mult = 1 } + local function buildConversionTable(cfg) + local conversionTable = { } + for damageTypeIndex = 1, 4 do + local damageType = dmgTypeList[damageTypeIndex] + local globalConv = wipeTable(tempTable1) + local skillConv = wipeTable(tempTable2) + local add = wipeTable(tempTable3) + local globalTotal, skillTotal = 0, 0 + for otherTypeIndex = damageTypeIndex + 1, 5 do + -- For all possible destination types, check for global and skill conversions + local otherType = dmgTypeList[otherTypeIndex] + globalConv[otherType] = m_max(skillModList:Sum("BASE", cfg, damageType.."DamageConvertTo"..otherType, isElemental[damageType] and "ElementalDamageConvertTo"..otherType or nil, damageType ~= "Chaos" and "NonChaosDamageConvertTo"..otherType or nil), 0) + globalTotal = globalTotal + globalConv[otherType] + skillConv[otherType] = m_max(skillModList:Sum("BASE", cfg, "Skill"..damageType.."DamageConvertTo"..otherType), 0) + skillTotal = skillTotal + skillConv[otherType] + add[otherType] = m_max(skillModList:Sum("BASE", cfg, damageType.."DamageGainAs"..otherType, isElemental[damageType] and "ElementalDamageGainAs"..otherType or nil, damageType ~= "Chaos" and "NonChaosDamageGainAs"..otherType or nil), 0) + end + if skillTotal > 100 then + -- Skill conversion exceeds 100%, scale it down and remove non-skill conversions + local factor = 100 / skillTotal + for type, val in pairs(skillConv) do + skillConv[type] = val * factor + end + for type, val in pairs(globalConv) do + globalConv[type] = 0 + end + elseif globalTotal + skillTotal > 100 then + -- Conversion exceeds 100%, scale down non-skill conversions + local factor = (100 - skillTotal) / globalTotal + for type, val in pairs(globalConv) do + globalConv[type] = val * factor + end + globalTotal = globalTotal * factor + end + local dmgTable = { conversion = { }, gain = { } } + for type in pairs(globalConv) do + dmgTable.conversion[type] = (globalConv[type] + skillConv[type]) / 100 + dmgTable.gain[type] = add[type] / 100 + dmgTable[type] = (globalConv[type] + skillConv[type] + add[type]) / 100 + end + dmgTable.mult = 1 - m_min((globalTotal + skillTotal) / 100, 1) + conversionTable[damageType] = dmgTable + end + conversionTable["Chaos"] = { mult = 1 } + return conversionTable + end + + activeSkill.conversionTable = buildConversionTable(skillCfg) + if activeSkill.weapon1Cfg then + activeSkill.weapon1Cfg.conversionTable = buildConversionTable(activeSkill.weapon1Cfg) + end + if activeSkill.weapon2Cfg then + activeSkill.weapon2Cfg.conversionTable = buildConversionTable(activeSkill.weapon2Cfg) + end -- Configure damage passes local passList = { } @@ -3057,7 +3081,8 @@ function calcs.offence(env, actor, activeSkill) local damageTypeHitMin, damageTypeHitMax, damageTypeHitAvg, damageTypeLuckyChance, damageTypeHitAvgLucky, damageTypeUnluckyChance, damageTypeHitAvgUnlucky, damageTypeHitAvgNotLucky = 0, 0, 0, 0, 0, 0, 0 if skillFlags.hit and canDeal[damageType] then damageTypeHitMin, damageTypeHitMax = calcDamage(activeSkill, output, cfg, pass == 2 and breakdown and breakdown[damageType], damageType, 0) - local convMult = activeSkill.conversionTable[damageType].mult + local conversionTable = (cfg and cfg.conversionTable) or activeSkill.conversionTable + local convMult = conversionTable[damageType].mult if pass == 2 and breakdown then t_insert(breakdown[damageType], "Hit damage:") t_insert(breakdown[damageType], s_format("%d to %d ^8(total damage)", damageTypeHitMin, damageTypeHitMax)) diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index a3334f825e..4965ddd880 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2886,8 +2886,7 @@ local specialModList = { ["poisonous hit"] = { mod("PoisonChance", "BASE", 100, { type = "Condition", var = "{Hand}Attack" }) }, ["attacks with this weapon deal double damage"] = { mod("DoubleDamageChance", "BASE", 100, nil, ModFlag.Hit, { type = "Condition", var = "{Hand}Attack" }, { type = "SkillType", skillType = SkillType.Attack }) }, ["hits with this weapon gain (%d+)%% of physical damage as extra cold or lightning damage"] = function(num) return { - mod("PhysicalDamageGainAsColdOrLightning", "BASE", num / 2, nil, ModFlag.Hit, { type = "Condition", var = "DualWielding" }, { type = "SkillType", skillType = SkillType.Attack }, { type = "SkillType", skillType = SkillType.RequiresShield, neg = true }), - mod("PhysicalDamageGainAsColdOrLightning", "BASE", num, nil, ModFlag.Hit, { type = "Condition", var = "DualWielding", neg = true}, { type = "SkillType", skillType = SkillType.Attack }, { type = "SkillType", skillType = SkillType.RequiresShield, neg = true }) + mod("PhysicalDamageGainAsColdOrLightning", "BASE", num, nil, ModFlag.Hit, { type = "Condition", var = "{Hand}Attack" }, { type = "SkillType", skillType = SkillType.Attack }), } end, ["hits with this weapon shock enemies as though dealing (%d+)%% more damage"] = function(num) return { mod("ShockAsThoughDealing", "MORE", num, nil, ModFlag.Hit, { type = "Condition", var = "{Hand}Attack" }, { type = "SkillType", skillType = SkillType.Attack }) } end, ["hits with this weapon freeze enemies as though dealing (%d+)%% more damage"] = function(num) return { mod("FreezeAsThoughDealing", "MORE", num, nil, ModFlag.Hit, { type = "Condition", var = "{Hand}Attack" }, { type = "SkillType", skillType = SkillType.Attack }) } end, @@ -3212,7 +3211,7 @@ local specialModList = { ["(%d+)%% chance for hits to deal (%d+)%% of physical damage as extra damage of a random element"] = function(num, _, physPercent) return { mod("PhysicalDamageGainAsRandom", "BASE", (num*physPercent/100) ) } end, ["gain (%d+)%% of physical damage as a random element if you've cast (.-) in the past (%d+) seconds"] = function(num, _, curse) return { mod("PhysicalDamageGainAsRandom", "BASE", num, { type = "Condition", var = "SelfCast"..curse:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", "") }) } end, ["gain (%d+)%% of physical damage as extra damage of a random element while you are ignited"] = function(num) return { mod("PhysicalDamageGainAsRandom", "BASE", num, { type = "Condition", var = "Ignited" }) } end, - ["(%d+)%% of physical damage from hits with this weapon is converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num ) } end, + ["(%d+)%% of physical damage from hits with this weapon is converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num, { type = "Condition", var = "MainHandAttack" }) } end, ["(%d+)%% of physical damage converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num ) } end, ["nearby enemies convert (%d+)%% of their (%a+) damage to (%a+)"] = function(num, _, damageFrom, damageTo) return { mod("EnemyModifier", "LIST", { mod = mod((damageFrom:gsub("^%l", string.upper)).."DamageConvertTo"..(damageTo:gsub("^%l", string.upper)), "BASE", num ) }), } end, ["enemies ignited by you have (%d+)%% of (%a+) damage they deal converted to (%a+)"] = function(num, _, damageFrom, damageTo) return { mod("EnemyModifier", "LIST", { mod = mod((damageFrom:gsub("^%l", string.upper)).."DamageConvertTo"..(damageTo:gsub("^%l", string.upper)), "BASE", num, { type = "Condition", var = "Ignited" }) }), } end, From 30120d08beb3e33f1a6459004801d54963ab562a Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 9 Nov 2025 14:39:48 +1100 Subject: [PATCH 2/2] Fix override to main hand --- src/Data/ModCache.lua | 4 ++-- src/Modules/ModParser.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index bd1d348b1d..15866ac8fb 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2859,7 +2859,7 @@ c["100% of Lightning Damage from Hits taken as Cold Damage"]={{[1]={flags=0,keyw c["100% of Lightning Damage from Hits taken as Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="LightningDamageFromHitsTakenAsFire",type="BASE",value=100}},nil} c["100% of Physical Damage Converted to Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToCold",type="BASE",value=100}},nil} c["100% of Physical Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToFire",type="BASE",value=100}},nil} -c["100% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="MainHandAttack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=100}},nil} +c["100% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=100}},nil} c["100% reduced Global Accuracy Rating"]={{[1]={[1]={type="Global"},flags=0,keywordFlags=0,name="Accuracy",type="INC",value=-100}},nil} c["1000% increased Armour and Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="ArmourAndEnergyShield",type="INC",value=1000}},nil} c["1000% increased Stun and Block Recovery"]={{[1]={flags=0,keywordFlags=0,name="StunRecovery",type="INC",value=1000}},nil} @@ -5825,7 +5825,7 @@ c["50% of Physical Damage Converted to Fire while you have Avatar of Fire"]={{[1 c["50% of Physical Damage Converted to Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToLightning",type="BASE",value=50}},nil} c["50% of Physical Damage Converted to Lightning during Effect"]={{[1]={[1]={type="Condition",var="UsingFlask"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToLightning",type="BASE",value=50}},nil} c["50% of Physical Damage from Hits taken as Lightning Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageFromHitsTakenAsLightning",type="BASE",value=50}},nil} -c["50% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="MainHandAttack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=50}},nil} +c["50% of Physical Damage from Hits with this Weapon is Converted to a random Element"]={{[1]={[1]={type="Condition",var="{Hand}Attack"},flags=0,keywordFlags=0,name="PhysicalDamageConvertToRandom",type="BASE",value=50}},nil} c["50% of Physical, Cold and Lightning Damage Converted to Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamageConvertToFire",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="LightningDamageConvertToFire",type="BASE",value=50},[3]={flags=0,keywordFlags=0,name="ColdDamageConvertToFire",type="BASE",value=50}},nil} c["50% of your Energy Shield is added to your Stun Threshold"]={{[1]={flags=0,keywordFlags=0,name="AddESToStunThreshold",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="ESToStunThresholdPercent",type="BASE",value=50}},nil} c["50% reduced Area of Effect of Hex Skills"]={{[1]={[1]={skillType=108,type="SkillType"},flags=0,keywordFlags=0,name="AreaOfEffect",type="INC",value=-50}},nil} diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 4965ddd880..6c30f833dc 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -3211,7 +3211,7 @@ local specialModList = { ["(%d+)%% chance for hits to deal (%d+)%% of physical damage as extra damage of a random element"] = function(num, _, physPercent) return { mod("PhysicalDamageGainAsRandom", "BASE", (num*physPercent/100) ) } end, ["gain (%d+)%% of physical damage as a random element if you've cast (.-) in the past (%d+) seconds"] = function(num, _, curse) return { mod("PhysicalDamageGainAsRandom", "BASE", num, { type = "Condition", var = "SelfCast"..curse:gsub("^%l", string.upper):gsub(" %l", string.upper):gsub(" ", "") }) } end, ["gain (%d+)%% of physical damage as extra damage of a random element while you are ignited"] = function(num) return { mod("PhysicalDamageGainAsRandom", "BASE", num, { type = "Condition", var = "Ignited" }) } end, - ["(%d+)%% of physical damage from hits with this weapon is converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num, { type = "Condition", var = "MainHandAttack" }) } end, + ["(%d+)%% of physical damage from hits with this weapon is converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num, { type = "Condition", var = "{Hand}Attack" }) } end, ["(%d+)%% of physical damage converted to a random element"] = function(num) return { mod("PhysicalDamageConvertToRandom", "BASE", num ) } end, ["nearby enemies convert (%d+)%% of their (%a+) damage to (%a+)"] = function(num, _, damageFrom, damageTo) return { mod("EnemyModifier", "LIST", { mod = mod((damageFrom:gsub("^%l", string.upper)).."DamageConvertTo"..(damageTo:gsub("^%l", string.upper)), "BASE", num ) }), } end, ["enemies ignited by you have (%d+)%% of (%a+) damage they deal converted to (%a+)"] = function(num, _, damageFrom, damageTo) return { mod("EnemyModifier", "LIST", { mod = mod((damageFrom:gsub("^%l", string.upper)).."DamageConvertTo"..(damageTo:gsub("^%l", string.upper)), "BASE", num, { type = "Condition", var = "Ignited" }) }), } end,