From 15987b0e4342e3382219db551de358febeed18bc Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Tue, 5 May 2026 10:31:50 +1000 Subject: [PATCH] Add support for Companionship Support Uses the minion count code to see if more than one minion type exists and if it does then the support no longer grants it's affect to the minion Was unsure if we wanted to also then limit the max count for that minion in the sidebar too but I don't think it really matters --- src/Data/Skills/sup_dex.lua | 8 ++++++++ src/Export/Skills/sup_dex.txt | 8 ++++++++ src/Modules/CalcDefence.lua | 24 ++++++++++++++++++++++++ src/Modules/CalcPerform.lua | 5 +++++ 4 files changed, 45 insertions(+) diff --git a/src/Data/Skills/sup_dex.lua b/src/Data/Skills/sup_dex.lua index 591f5bb4d3..caf15b809f 100644 --- a/src/Data/Skills/sup_dex.lua +++ b/src/Data/Skills/sup_dex.lua @@ -1417,6 +1417,14 @@ skills["SupportCompanionship"] = { addSkillTypes = { }, excludeSkillTypes = { SkillType.MinionsAreUndamagable, SkillType.Triggered, }, statDescriptionScope = "gem_stat_descriptions", + statMap = { + ["support_companionship_minion_maximum_life_+%_final_if_at_most_one_minion"] = { + mod("MinionModifier", "LIST", { mod = mod("Life", "MORE", nil) }, 0, 0, { type = "Condition", var = "OnlyMinion" }), + }, + ["damage_removed_from_minions_before_life_or_es_%_if_only_one_minion"] = { + mod("takenFromMinionBeforeYou", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }), + }, + }, qualityStats = { { "minion_maximum_life_+%", 1 }, }, diff --git a/src/Export/Skills/sup_dex.txt b/src/Export/Skills/sup_dex.txt index 4daf604589..324de6c0fe 100644 --- a/src/Export/Skills/sup_dex.txt +++ b/src/Export/Skills/sup_dex.txt @@ -179,6 +179,14 @@ local skills, mod, flag, skill = ... #mods #skill SupportCompanionship + statMap = { + ["support_companionship_minion_maximum_life_+%_final_if_at_most_one_minion"] = { + mod("MinionModifier", "LIST", { mod = mod("Life", "MORE", nil) }, 0, 0, { type = "Condition", var = "OnlyMinion" }), + }, + ["damage_removed_from_minions_before_life_or_es_%_if_only_one_minion"] = { + mod("takenFromMinionBeforeYou", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff", unscalable = true }), + }, + }, #mods #skill SupportCriticalStrikeAffliction diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index cfb1699e22..dee263bc79 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -175,6 +175,9 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor) if output.FrostShieldLife then alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 } end + if output.TotalMinionLife then + alliesTakenBeforeYou["minion"] = { remaining = output.TotalMinionLife, percent = output.MinionAllyDamageMitigation / 100 } + end if output.TotalSpectreLife then alliesTakenBeforeYou["spectres"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 } end @@ -418,6 +421,9 @@ local function incomingDamageBreakdown(breakdownTable, poolsRemaining, output) if output.FrostShieldLife and output.FrostShieldLife > 0 then t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Frost Shield Life ^7(%d remaining)", output.FrostShieldLife - poolsRemaining.AlliesTakenBeforeYou["frostShield"].remaining, poolsRemaining.AlliesTakenBeforeYou["frostShield"].remaining)) end + if output.TotalMinionLife and output.TotalMinionLife > 0 then + t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Minion Life ^7(%d remaining)", output.TotalMinionLife - poolsRemaining.AlliesTakenBeforeYou["minion"].remaining, poolsRemaining.AlliesTakenBeforeYou["minion"].remaining)) + end if output.TotalSpectreLife and output.TotalSpectreLife > 0 then t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Spectre Life ^7(%d remaining)", output.TotalSpectreLife - poolsRemaining.AlliesTakenBeforeYou["spectres"].remaining, poolsRemaining.AlliesTakenBeforeYou["spectres"].remaining)) end @@ -2445,6 +2451,12 @@ function calcs.buildDefenceEstimations(env, actor) } end + -- from Minion + output["MinionAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromMinionBeforeYou") + if output["MinionAllyDamageMitigation"] ~= 0 then + output["TotalMinionLife"] = modDB:Sum("BASE", nil, "Multiplier:MinionLife") + end + -- from spectres output["SpectreAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromSpectresBeforeYou") if output["SpectreAllyDamageMitigation"] ~= 0 then @@ -2562,6 +2574,9 @@ function calcs.buildDefenceEstimations(env, actor) if output.FrostShieldLife then alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 } end + if output.TotalMinionLife then + alliesTakenBeforeYou["minion"] = { remaining = output.TotalMinionLife, percent = output.MinionAllyDamageMitigation / 100 } + end if output.TotalSpectreLife then alliesTakenBeforeYou["spectres"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 } end @@ -3123,6 +3138,11 @@ function calcs.buildDefenceEstimations(env, actor) local poolProtected = output["FrostShieldLife"] / (output["FrostShieldDamageMitigation"] / 100) * (1 - output["FrostShieldDamageMitigation"] / 100) output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["FrostShieldDamageMitigation"] / 100) end + -- minions + if output["TotalMinionLife"] and output["TotalMinionLife"] > 0 then + local poolProtected = output["TotalMinionLife"] / (output["MinionAllyDamageMitigation"] / 100) * (1 - output["MinionAllyDamageMitigation"] / 100) + output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["MinionAllyDamageMitigation"] / 100) + end -- spectres if output["TotalSpectreLife"] and output["TotalSpectreLife"] > 0 then local poolProtected = output["TotalSpectreLife"] / (output["SpectreAllyDamageMitigation"] / 100) * (1 - output["SpectreAllyDamageMitigation"] / 100) @@ -3764,6 +3784,10 @@ function calcs.buildDefenceEstimations(env, actor) resourcesLostSum = resourcesLostSum + resourcesLost.frostShield t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Frost Shield Life", resourcesLost.frostShield)) end + if resourcesLost.minion then + resourcesLostSum = resourcesLostSum + resourcesLost.minion + t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Minion Life", resourcesLost.minion)) + end if resourcesLost.spectres then resourcesLostSum = resourcesLostSum + resourcesLost.spectres t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Spectre Life", resourcesLost.spectres)) diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 513a245f26..5a5d7a0392 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -1338,6 +1338,7 @@ function calcs.perform(env, skipEHP) env.player.modDB:NewMod("Multiplier:NonVaalSummonedMinion", "BASE", output[activeSkill.minion.minionData.limit], "Config", { type = "Condition", var = "Combat" }) end minionCount[activeSkill.minion.minionData.limit] = true + t_insert(minionCount, activeSkill.minion.minionData.limit) end end if activeSkill.skillTypes[SkillType.CreatesMinion] and not activeSkill.skillTypes[SkillType.MinionsAreUndamagable] then @@ -1370,6 +1371,10 @@ function calcs.perform(env, skipEHP) end end + if #minionCount == 1 then + modDB.conditions["OnlyMinion"] = true + end + -- Special Rarity / Quantity Calc for Bisco's local lootQuantityNormalEnemies = modDB:Sum("INC", nil, "LootQuantityNormalEnemies") output.LootQuantityNormalEnemies = (lootQuantityNormalEnemies > 0) and lootQuantityNormalEnemies + modDB:Sum("INC", nil, "LootQuantity") or 0