From 03092170ee9e37d5d24e6168861ed0aa886da19b Mon Sep 17 00:00:00 2001 From: Paul O'Day Date: Sat, 25 Jan 2025 18:18:03 -0800 Subject: [PATCH] New culling strike logic, add rarity dropdown Replace the "CullPercent" mod with "CullingStrike" flag. Add rarity dropdown to config tab, hidden when boss is selected. Add "CullThreshold" mod. Use all of these to implement new 30/20/10/5 cull logic. --- src/Data/ModCache.lua | 12 ++++++------ src/Data/Skills/sup_dex.lua | 5 ++--- src/Export/Skills/sup_dex.txt | 8 ++++---- src/Modules/CalcOffence.lua | 16 +++++++++++++--- src/Modules/CalcSections.lua | 2 +- src/Modules/ConfigOptions.lua | 8 ++++++++ src/Modules/ModParser.lua | 34 +++++++++++++++++----------------- 7 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 30d5b7fbe6..854917a064 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -739,7 +739,7 @@ c["100% increased Cold Damage"]={{[1]={flags=0,keywordFlags=0,name="ColdDamage", c["100% increased Critical Damage Bonus against Enemies that are on Full Life"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="FullLife"},flags=0,keywordFlags=0,name="CritMultiplier",type="INC",value=100}},nil} c["100% increased Critical Hit Chance"]={{[1]={flags=0,keywordFlags=0,name="CritChance",type="INC",value=100}},nil} c["100% increased Critical Hit Chance against Enemies on Full Life"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="FullLife"},flags=0,keywordFlags=0,name="CritChance",type="INC",value=100}},nil} -c["100% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} +c["100% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullThreshold",type="INC",value=100}},nil} c["100% increased Defences from Equipped Shield"]={{[1]={[1]={slotName="Weapon 2",type="SlotName"},flags=0,keywordFlags=0,name="Defences",type="INC",value=100}},nil} c["100% increased Effect of Jewel Socket Passive Skills"]={{[1]={flags=0,keywordFlags=0,name="LocalEffect",type="INC",value=100}}," of Jewel Socket Passive Skills "} c["100% increased Effect of Jewel Socket Passive Skills containing Corrupted Magic Jewels"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="corruptedMagicJewelIncEffect",value=100}}},nil} @@ -1300,7 +1300,7 @@ c["25% increased Critical Hit Chance against Shocked Enemies"]={{[1]={[1]={actor c["25% increased Critical Hit Chance for Attacks"]={{[1]={flags=1,keywordFlags=0,name="CritChance",type="INC",value=25}},nil} c["25% increased Critical Hit Chance for Spells"]={{[1]={flags=2,keywordFlags=0,name="CritChance",type="INC",value=25}},nil} c["25% increased Critical Hit Chance with Traps"]={{[1]={flags=0,keywordFlags=4096,name="CritChance",type="INC",value=25}},nil} -c["25% increased Culling Strike Threshold"]={{}," Culling Strike Threshold "} +c["25% increased Culling Strike Threshold"]={{[1]={flags=0,keywordFlags=0,name="CullThreshold",type="INC",value=25}},nil} c["25% increased Damage against Dazed Enemies"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=25}}," against Dazed Enemies "} c["25% increased Damage against Dazed Enemies 25% increased Daze Buildup"]={{[1]={flags=0,keywordFlags=0,name="Damage",type="INC",value=25}}," against Dazed Enemies 25% increased Daze Buildup "} c["25% increased Damage while you have a Totem"]={{[1]={[1]={type="Condition",var="HaveTotem"},flags=0,keywordFlags=0,name="Damage",type="INC",value=25}},nil} @@ -2294,9 +2294,9 @@ c["Critical Hits do not deal extra Damage"]={{[1]={flags=0,keywordFlags=0,name=" c["Critical Hits ignore Enemy Monster Elemental Resistances"]={{[1]={[1]={type="Condition",var="CriticalStrike"},flags=0,keywordFlags=0,name="IgnoreElementalResistances",type="FLAG",value=true}},nil} c["Critical Hits ignore non-negative Enemy Monster Elemental Resistances"]={nil,"Critical Hits ignore non-negative Enemy Monster Elemental Resistances "} c["Critical Hits with Daggers have a 25% chance to Poison the Enemy"]={{[1]={[1]={type="Condition",var="CriticalStrike"},flags=524288,keywordFlags=0,name="PoisonChance",type="BASE",value=25}},nil} -c["Culling Strike"]={{[1]={[1]={effectType="Global",type="GlobalEffect",unscalable=true},flags=0,keywordFlags=0,name="CullPercent",type="MAX",value=10}},nil} -c["Culling Strike against Enemies you Mark"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Marked"},flags=0,keywordFlags=0,name="CullPercent",type="MAX",value=10}},nil} -c["Culling Strike against Frozen Enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Frozen"},flags=0,keywordFlags=0,name="CullPercent",type="MAX",value=10}},nil} +c["Culling Strike"]={{[1]={[1]={effectType="Global",type="GlobalEffect"},flags=0,keywordFlags=0,name="CullingStrike",type="FLAG",value=true}},nil} +c["Culling Strike against Enemies you Mark"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Marked"},flags=0,keywordFlags=0,name="CullingStrike",type="FLAG",value=true}},nil} +c["Culling Strike against Frozen Enemies"]={{[1]={[1]={actor="enemy",type="ActorCondition",var="Frozen"},flags=0,keywordFlags=0,name="CullingStrike",type="FLAG",value=true}},nil} c["Curse Skills have 15% increased Cast Speed"]={{[1]={flags=16,keywordFlags=2,name="Speed",type="INC",value=15}},nil} c["Curse Skills have 20% increased Cast Speed"]={{[1]={flags=16,keywordFlags=2,name="Speed",type="INC",value=20}},nil} c["Curses have no Activation Delay"]={nil,"Curses have no Activation Delay "} @@ -2606,7 +2606,7 @@ c["Hits against you have 20% reduced Critical Damage Bonus"]={{[1]={flags=0,keyw c["Hits against you have 25% reduced Critical Damage Bonus"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=4,keywordFlags=0,name="CritMultiplier",type="INC",value=-25}}}},nil} c["Hits have 25% reduced Critical Hit Chance against you"]={nil,"Hits have 25% reduced Critical Hit Chance "} c["Hits ignore non-negative Elemental Resistances of Frozen Enemies"]={nil,"Hits ignore non-negative Elemental Resistances of Frozen Enemies "} -c["Hits that Heavy Stun Enemies have Culling Strike"]={{[1]={[1]={type="Condition",var="AlwaysHeavyStunning"},flags=0,keywordFlags=0,name="CullPercent",type="MAX",value=10}},nil} +c["Hits that Heavy Stun Enemies have Culling Strike"]={{[1]={[1]={type="Condition",var="AlwaysHeavyStunning"},flags=0,keywordFlags=0,name="CullingStrike",type="FLAG",value=true}},nil} c["Hits that Heavy Stun inflict Fire Exposure"]={nil,"Hits that Heavy Stun inflict Fire Exposure "} c["Hits that deal Cold Damage remove Cold Exposure and inflict Fire Exposure"]={nil,"Hits that deal Cold Damage remove Cold Exposure and inflict Fire Exposure "} c["Hits that deal Cold Damage remove Cold Exposure and inflict Fire Exposure Hits that deal Lightning Damage remove Lightning Exposure and inflict Cold Exposure"]={nil,"Hits that deal Cold Damage remove Cold Exposure and inflict Fire Exposure Hits that deal Lightning Damage remove Lightning Exposure and inflict Cold Exposure "} diff --git a/src/Data/Skills/sup_dex.lua b/src/Data/Skills/sup_dex.lua index 2e271dc2f4..0c0432ce72 100644 --- a/src/Data/Skills/sup_dex.lua +++ b/src/Data/Skills/sup_dex.lua @@ -495,8 +495,7 @@ skills["SupportCullingStrikePlayer"] = { statDescriptionScope = "gem_stat_descriptions", statMap = { ["support_culling_strike_vs_rare_or_unique_enemy"] = { - mod("CullPercent", "MAX", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }), - value = 10 + flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }) }, }, baseFlags = { @@ -1940,4 +1939,4 @@ skills["SupportWindowOfOpportunityPlayer"] = { }, }, } -} \ No newline at end of file +} diff --git a/src/Export/Skills/sup_dex.txt b/src/Export/Skills/sup_dex.txt index d137e5752a..8c38df6fc5 100644 --- a/src/Export/Skills/sup_dex.txt +++ b/src/Export/Skills/sup_dex.txt @@ -129,10 +129,10 @@ statMap = { #skill SupportCullingStrikePlayer #startSets #set SupportCullingStrikePlayer -statMap = { - ["support_culling_strike_vs_rare_or_unique_enemy"] = { - mod("CullPercent", "MAX", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }), - value = 10 + statMap = { + ["support_culling_strike_vs_rare_or_unique_enemy"] = { + flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "RareOrUnique" }) + }, }, }, #mods diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index a30e31d078..60a7e83c6f 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -2992,12 +2992,22 @@ function calcs.offence(env, actor, activeSkill) local hitRate = output.HitChance / 100 * (globalOutput.HitSpeed or globalOutput.Speed) * skillData.dpsMultiplier -- Calculate culling DPS - local criticalCull = skillModList:Max(cfg, "CriticalCullPercent") or 0 - if criticalCull > 0 then + local enemyRarity = env.configInput["enemyIsBoss"] ~= "None" and "Unique" or env.configInput["enemyRarity"] or "Normal" + local cullThresholds = { Normal = 30, Magic = 20, Rare = 10, Unique = 5 } + local enemyCullThreshold = cullThresholds[enemyRarity] + local criticalCull = 0 + if skillModList:Flag(cfg, "CriticalCullingStrike") then + local critCullThresholdInc = skillModList:Sum("INC", cfg, "CriticalCullThreshold") or 0 + criticalCull = enemyCullThreshold * (1 + critCullThresholdInc / 100) criticalCull = m_min(criticalCull, criticalCull * (1 - (1 - output.CritChance / 100) ^ hitRate)) end - local regularCull = skillModList:Max(cfg, "CullPercent") or 0 + local regularCull = 0 + if skillModList:Flag(cfg, "CullingStrike") then + local cullThresholdInc = skillModList:Sum("INC", cfg, "CullThreshold") or 1 + regularCull = enemyCullThreshold * (1 + cullThresholdInc / 100) + end local maxCullPercent = m_max(criticalCull, regularCull) + globalOutput.CullPercent = maxCullPercent globalOutput.CullMultiplier = 100 / (100 - globalOutput.CullPercent) diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index 25b10630b5..17323937a8 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -1369,7 +1369,7 @@ return { { label = "IIQ for Normal Mobs", haveOutput = "LootQuantityNormalEnemies", { format = "{0:output:LootQuantityNormalEnemies}%", { modName = { "LootQuantityNormalEnemies", "LootQuantity" } }, }, }, { label = "Inc. Item Rarity", { format = "{0:mod:1}%", { modName = "LootRarity", modType = "INC", cfg = "skill" }, }, }, { label = "IIR for Magic Mobs", haveOutput = "LootRarityMagicEnemies", { format = "{0:output:LootRarityMagicEnemies}%", { modName = { "LootRarityMagicEnemies", "LootRarity" } }, }, }, - { label = "Culling Strike", haveOutput = "CullPercent", { format = "{0:output:CullPercent}%", { modName = { "CullPercent", "CriticalCullPercent" }, cfg = "skill" } } }, + { label = "Culling Strike", haveOutput = "CullPercent", { format = "{2:output:CullPercent}%", { modName = { "CullPercent", "CriticalCullPercent" }, cfg = "skill" } } }, { label = "Enemy Life Recovery", haveOutput = "EnemyLifeRegen", { format = "{0:output:EnemyLifeRegen}%", { modName = "LifeRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy Mana Recovery", haveOutput = "EnemyManaRegen", { format = "{0:output:EnemyManaRegen}%", { modName = "ManaRegen", modType = "INC", enemy = true }, }, }, { label = "Enemy ES Recovery", haveOutput = "EnemyEnergyShieldRegen", { format = "{0:output:EnemyEnergyShieldRegen}%", { modName = "EnergyShieldRegen", modType = "INC", enemy = true }, }, }, diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 29055cceb0..5dcd9aab2d 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -1684,12 +1684,20 @@ Huge sets the radius to 11. { var = "conditionEnemyRareOrUnique", type = "check", label = "Is the enemy Rare or Unique?", ifEnemyCond = "EnemyRareOrUnique", tooltip = "The enemy will automatically be considered to be Unique if they are a Boss,\nbut you can use this option to force it if necessary.", apply = function(val, modList, enemyModList) enemyModList:NewMod("Condition:RareOrUnique", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) end }, + { var = "enemyRarity", type = "list", label = "Enemy Rarity", ifFlag = "NotABoss", list = {{val="Normal",label="Normal"},{val="Magic",label="Magic"},{val="Rare",label="Rare"},{val="Unique",label="Unique"}}, tooltip = "Used for calculating culling strike damage. Ignored if enemy is a boss.", apply = function(val, mdoList, enemyModList) + if val == "Rare" then + enemyModList:NewMod("Condition:RareOrUnique", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) + elseif val == "Unique" then + enemyModList:NewMod("Condition:RareOrUnique", "FLAG", true, "Config", { type = "Condition", var = "Effective" }) + end + end }, { var = "enemyIsBoss", type = "list", label = "Is the enemy a Boss?", defaultIndex = 3, tooltip = data.enemyIsBossTooltip, list = {{val="None",label="No"},{val="Boss",label="Standard Boss"},{val="Pinnacle",label="Guardian/Pinnacle Boss"},{val="Uber",label="Uber Pinnacle Boss"}}, apply = function(val, modList, enemyModList, build) -- These defaults are here so that the placeholders get reset correctly build.configTab.varControls['enemySpeed']:SetPlaceholder(700, true) build.configTab.varControls['enemyCritChance']:SetPlaceholder(5, true) build.configTab.varControls['enemyCritDamage']:SetPlaceholder(30, true) if val == "None" then + modList:NewMod("NotABoss", "FLAG", true, "Config") local defaultResist = "" build.configTab.varControls['enemyLightningResist']:SetPlaceholder(defaultResist, true) build.configTab.varControls['enemyColdResist']:SetPlaceholder(defaultResist, true) diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 3c615b1f70..67cc153d44 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -785,6 +785,7 @@ local modNameList = { ["to ignore enemy physical damage reduction"] = "ChanceToIgnoreEnemyPhysicalDamageReduction", ["weapon swap speed"] = "WeaponSwapSpeed", ["to chain an additional time from terrain"] = "TerrainChainChance", + ["culling strike threshold"] = "CullThreshold", -- Flask and Charm modifiers ["effect"] = "LocalEffect", ["effect of flasks"] = "FlaskEffect", @@ -2783,7 +2784,6 @@ local specialModList = { ["cannot take reflected physical damage"] = { mod("PhysicalReflectedDamageTaken", "MORE", -100, { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, ["gain (%d+)%% increased movement speed for 20 seconds when you kill an enemy"] = function(num) return { mod("MovementSpeed", "INC", num, { type = "Condition", var = "KilledRecently" }) } end, ["gain (%d+)%% increased attack speed for 20 seconds when you kill a rare or unique enemy"] = function(num) return { mod("Speed", "INC", num, nil, ModFlag.Attack, 0, { type = "Condition", var = "KilledUniqueEnemy" }) } end, - ["kill enemies that have (%d+)%% or lower life when hit by your skills"] = function(num) return { mod("CullPercent", "MAX", num) } end, ["you are unaffected by bleeding while leeching"] = { mod("SelfBleedEffect", "MORE", -100, { type = "Condition", var = "Leeching" }) }, -- Titan ["(%d+)%% increased effect of small passive skills"] = function(num) return { mod("SmallPassiveSkillEffect", "INC", num) } end, @@ -4505,22 +4505,22 @@ local specialModList = { ["adds knockback to melee attacks during f?l?a?s?k? ?effect"] = { mod("EnemyKnockbackChance", "BASE", 100, nil, ModFlag.Melee, { type = "Condition", var = "UsingFlask" }) }, ["knockback direction is reversed"] = { mod("EnemyKnockbackDistance", "MORE", -200) }, -- Culling - ["culling strike"] = { mod("CullPercent", "MAX", 10, { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, - ["culling strike with melee weapons"] = { mod("CullPercent", "MAX", 10, nil, ModFlag.WeaponMelee, { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, - ["melee weapon attacks have culling strike"] = { mod("CullPercent", "MAX", 10, nil, bor(ModFlag.Attack, ModFlag.WeaponMelee), { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, - ["culling strike during f?l?a?s?k? ?effect"] = { mod("CullPercent", "MAX", 10, { type = "Condition", var = "UsingFlask" }, { type = "GlobalEffect", effectType = "Global", unscalable = true }) }, - ["hits with this weapon have culling strike against bleeding enemies"] = { mod("CullPercent", "MAX", 10, { type = "ActorCondition", actor = "enemy", var = "Bleeding" }) }, - ["you have culling strike against cursed enemies"] = { mod("CullPercent", "MAX", 10, { type = "ActorCondition", actor = "enemy", var = "Cursed" }) }, - ["critical hits have culling strike"] = { mod("CriticalCullPercent", "MAX", 10) }, - ["your critical hits have culling strike"] = { mod("CriticalCullPercent", "MAX", 10) }, - ["your spells have culling strike"] = { mod("CullPercent", "MAX", 10, nil, ModFlag.Spell) }, - ["bow attacks have culling strike"] = { mod("CullPercent", "MAX", 10, nil, bor(ModFlag.Attack, ModFlag.Bow)) }, - ["culling strike against burning enemies"] = { mod("CullPercent", "MAX", 10, { type = "ActorCondition", actor = "enemy", var = "Burning" }) }, - ["culling strike against frozen enemies"] = { mod("CullPercent", "MAX", 10, { type = "ActorCondition", actor = "enemy", var = "Frozen" }) }, - ["culling strike against enemies you mark"] = { mod("CullPercent", "MAX", 10, { type = "ActorCondition", actor = "enemy", var = "Marked" }) }, - ["nearby allies have culling strike"] = { mod("ExtraAura", "LIST", {onlyAllies = true, mod = mod("CullPercent", "MAX", 10) }) }, - ["hits that stun enemies have culling strike"] = { mod("CullPercent", "MAX", 10, { type = "Condition", var = "AlwaysStunning" }) }, - ["hits that heavy stun enemies have culling strike"] = { mod("CullPercent", "MAX", 10, { type = "Condition", var = "AlwaysHeavyStunning" }) }, + ["culling strike"] = { flag("CullingStrike", { type = "GlobalEffect", effectType = "Global" }) }, + ["culling strike with melee weapons"] = { flag("CullingStrike", nil, ModFlag.WeaponMelee, { type = "GlobalEffect", effectType = "Global" }) }, + ["melee weapon attacks have culling strike"] = { flag("CullingStrike", nil, bor(ModFlag.Attack, ModFlag.WeaponMelee), { type = "GlobalEffect", effectType = "Global" }) }, + ["culling strike during f?l?a?s?k? ?effect"] = { flag("CullingStrike", { type = "Condition", var = "UsingFlask" }, { type = "GlobalEffect", effectType = "Global" }) }, + ["hits with this weapon have culling strike against bleeding enemies"] = { flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "Bleeding" }) }, + ["you have culling strike against cursed enemies"] = { flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "Cursed" }) }, + ["critical hits have culling strike"] = { flag("CriticalCullingStrike") }, + ["your critical hits have culling strike"] = { flag("CriticalCullingStrike") }, + ["your spells have culling strike"] = { flag("CullingStrike", nil, ModFlag.Spell) }, + ["bow attacks have culling strike"] = { flag("CullingStrike", nil, bor(ModFlag.Attack, ModFlag.Bow)) }, + ["culling strike against burning enemies"] = { flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "Burning" }) }, + ["culling strike against frozen enemies"] = { flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "Frozen" }) }, + ["culling strike against enemies you mark"] = { flag("CullingStrike", { type = "ActorCondition", actor = "enemy", var = "Marked" }) }, + ["nearby allies have culling strike"] = { flag("ExtraAura", "LIST", {onlyAllies = true, mod = mod("CullingStrike") }) }, + ["hits that stun enemies have culling strike"] = { flag("CullingStrike", { type = "Condition", var = "AlwaysStunning" }) }, + ["hits that heavy stun enemies have culling strike"] = { flag("CullingStrike", { type = "Condition", var = "AlwaysHeavyStunning" }) }, -- Intimidate ["permanently intimidate enemies on block"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Intimidated") }, { type = "Condition", var = "BlockedRecently" }) }, ["with a murderous eye jewel socketed, intimidate enemies for (%d) seconds on hit with attacks"] = { mod("EnemyModifier", "LIST", { mod = flag("Condition:Intimidated") }, { type = "Condition", var = "HaveMurderousEyeJewelIn{SlotName}" }) },