Skip to content

Commit

Permalink
Improve support for minions applying auras (#6745)
Browse files Browse the repository at this point in the history
* initial support for minions applying auras

* merge in the spectre buffs into main buff loop

* add dummy relic to apply all auras

* add support for exporting minion buffs to party tab

* fix merge issue

* Remove other relics from skill dropdown

---------

Co-authored-by: LocalIdentity <[email protected]>
  • Loading branch information
Regisle and LocalIdentity authored Dec 5, 2023
1 parent 33a107f commit a3317a5
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/Classes/PartyTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
else
if line:find("|") and currentName ~= "SKIP" and not line:find("MinionModifier|LIST") then
if currentModType == "otherEffects" then
currentName, currentEffect, line = line:match("([%w ]-%w+)|(%w+)|(.+)")
currentName, currentEffect, line = line:match("([%w ']-%w+)|(%w+)|(.+)")
end
local mod = modLib.parseFormattedSourceMod(line)
if mod then
Expand Down
25 changes: 25 additions & 0 deletions src/Data/Minions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,31 @@ minions["GuardianSentinel"] = {
},
}

-- This is a fake Minion to apply all 3 auras
minions["GuardianRelicAll"] = {
name = "All Relics",
life = 4,
energyShield = 0.6,
fireResist = 40,
coldResist = 40,
lightningResist = 40,
chaosResist = 20,
damage = 1,
damageSpread = 0,
attackTime = 1,
attackRange = 6,
accuracy = 1,
skillList = {
"RelicTeleport",
"Anger",
"Hatred",
"Wrath",
},
modList = {
-- EmergeSpeedHigh [emerge_speed_+% = 0]
},
}

minions["GuardianRelicFire"] = {
name = "Fire Relic",
life = 4,
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Skills/minion.lua
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ skills["MonsterProjectileSpellLightningGolemSummoned"] = {
},
}
skills["LightningGolemWrath"] = {
name = "Wrath",
name = "Lightning Golem Wrath",
hidden = true,
color = 3,
baseEffectiveness = 0.16249999403954,
Expand Down
4 changes: 1 addition & 3 deletions src/Data/Skills/other.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2652,9 +2652,7 @@ skills["SummonGuardianRelic"] = {
castTime = 1,
fromTree = true,
minionList = {
"GuardianRelicFire",
"GuardianRelicCold",
"GuardianRelicLightning",
"GuardianRelicAll",
},
statMap = {
["minion_actor_level_is_user_level_up_to_maximum"] = {
Expand Down
25 changes: 25 additions & 0 deletions src/Export/Minions/Minions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,31 @@ local minions, mod = ...
#monster Metadata/Monsters/Axis/AxisEliteSoldierRadiance GuardianSentinel
#emit

-- This is a fake Minion to apply all 3 auras
minions["GuardianRelicAll"] = {
name = "All Relics",
life = 4,
energyShield = 0.6,
fireResist = 40,
coldResist = 40,
lightningResist = 40,
chaosResist = 20,
damage = 1,
damageSpread = 0,
attackTime = 1,
attackRange = 6,
accuracy = 1,
skillList = {
"RelicTeleport",
"Anger",
"Hatred",
"Wrath",
},
modList = {
-- EmergeSpeedHigh [emerge_speed_+% = 0]
},
}

#monster Metadata/Monsters/AnimatedItem/ElementalLivingRelicFire GuardianRelicFire
#emit

Expand Down
2 changes: 1 addition & 1 deletion src/Export/Skills/minion.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ local skills, mod, flag, skill = ...
#flags spell projectile
#mods

#skill LightningGolemWrath Wrath
#skill LightningGolemWrath Lightning Golem Wrath
#flags spell aura area duration
statMap = {
["attack_minimum_added_lightning_damage"] = {
Expand Down
4 changes: 1 addition & 3 deletions src/Export/Skills/other.txt
Original file line number Diff line number Diff line change
Expand Up @@ -737,9 +737,7 @@ local skills, mod, flag, skill = ...
#flags spell minion duration
fromTree = true,
minionList = {
"GuardianRelicFire",
"GuardianRelicCold",
"GuardianRelicLightning",
"GuardianRelicAll",
},
statMap = {
["minion_actor_level_is_user_level_up_to_maximum"] = {
Expand Down
197 changes: 125 additions & 72 deletions src/Modules/CalcPerform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2030,53 +2030,148 @@ function calcs.perform(env, fullDPSSkipEHP)
end
if activeSkill.minion and activeSkill.minion.activeSkillList then
local castingMinion = activeSkill.minion
for _, activeSkill in ipairs(activeSkill.minion.activeSkillList) do
local skillModList = activeSkill.skillModList
local skillCfg = activeSkill.skillCfg
for _, buff in ipairs(activeSkill.buffList) do
for _, activeMinionSkill in ipairs(activeSkill.minion.activeSkillList) do
local skillModList = activeMinionSkill.skillModList
local skillCfg = activeMinionSkill.skillCfg
for _, buff in ipairs(activeMinionSkill.buffList) do
if buff.type == "Buff" then
if env.mode_buffs and activeSkill.skillData.enable then
if env.mode_buffs and activeMinionSkill.skillData.enable then
local skillCfg = buff.activeSkillBuff and skillCfg
local modStore = buff.activeSkillBuff and skillModList or castingMinion.modDB
if buff.applyAllies then
activeMinionSkill.buffSkill = true
modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
local srcList = new("ModList")
local inc = modStore:Sum("INC", skillCfg, "BuffEffect") + modDB:Sum("INC", nil, "BuffEffectOnSelf")
local more = modStore:More(skillCfg, "BuffEffect") * modDB:More(nil, "BuffEffectOnSelf")
local inc = modStore:Sum("INC", skillCfg, "BuffEffect", "BuffEffectOnPlayer") + modDB:Sum("INC", nil, "BuffEffectOnSelf")
local more = modStore:More(skillCfg, "BuffEffect", "BuffEffectOnPlayer") * modDB:More(nil, "BuffEffectOnSelf")
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, buffs, buff.name)
mergeBuff(buff.modList, buffs, buff.name)
if activeMinionSkill.skillData.thisIsNotABuff then
buffs[buff.name].notBuff = true
end
if partyTabEnableExportBuffs then
local inc = modStore:Sum("INC", skillCfg, "BuffEffect")
local more = modStore:More(skillCfg, "BuffEffect")
buffExports["Aura"]["otherEffects"] = buffExports["Aura"]["otherEffects"] or { }
buffExports["Aura"]["otherEffects"][buff.name] = { effectMult = (1 + inc / 100) * more, modList = buff.modList }
end
end
if env.minion and (env.minion == castingMinion or buff.applyAllies) then
env.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
local envMinionCheck = (env.minion and (env.minion == castingMinion or buff.applyAllies))
if buff.applyMinions or envMinionCheck then
activeMinionSkill.minionBuffSkill = true
if envMinionCheck then
env.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
else
activeSkill.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
end
local srcList = new("ModList")
local inc = modStore:Sum("INC", skillCfg, "BuffEffect", "BuffEffectOnSelf")
local more = modStore:More(skillCfg, "BuffEffect", "BuffEffectOnSelf")
local inc = modStore:Sum("INC", skillCfg, "BuffEffect", (env.minion == castingMinion) and "BuffEffectOnSelf" or nil)
local more = modStore:More(skillCfg, "BuffEffect", (env.minion == castingMinion) and "BuffEffectOnSelf" or nil)
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, minionBuffs, buff.name)
mergeBuff(buff.modList, minionBuffs, buff.name)
if activeMinionSkill.skillData.thisIsNotABuff then
buffs[buff.name].notBuff = true
end
end
end
elseif buff.type == "Aura" then
if env.mode_buffs and activeSkill.skillData.enable then
if not modDB:Flag(nil, "AlliesAurasCannotAffectSelf") then
local srcList = new("ModList")
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect") + modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect") * modDB:More(nil, "BuffEffectOnSelf", "AuraEffectOnSelf")
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, buffs, buff.name)
if env.mode_buffs and activeMinionSkill.skillData.enable then
-- Check for extra modifiers to apply to aura skills
local extraAuraModList = { }
for _, value in ipairs(activeSkill.minion.modDB:List(skillCfg, "ExtraAuraEffect")) do
local add = true
for _, mod in ipairs(extraAuraModList) do
if modLib.compareModParams(mod, value.mod) then
mod.value = mod.value + value.mod.value
add = false
break
end
end
if add then
t_insert(extraAuraModList, copyTable(value.mod, true))
end
end
if env.minion and (env.minion ~= activeSkill.minion or not activeSkill.skillData.auraCannotAffectSelf) then
local srcList = new("ModList")
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect") + env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect") * env.minion.modDB:More(nil, "BuffEffectOnSelf", "AuraEffectOnSelf")
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, minionBuffs, buff.name)
if not (activeSkill.minion.modDB:Flag(nil, "SelfAurasCannotAffectAllies") or activeSkill.minion.modDB:Flag(nil, "SelfAurasOnlyAffectYou") or activeSkill.minion.modDB:Flag(nil, "SelfAuraSkillsCannotAffectAllies")) then
if not modDB:Flag(nil, "AlliesAurasCannotAffectSelf") and not modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] then
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect", "BuffEffectOnPlayer", "AuraBuffEffect") + modDB:Sum("INC", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect", "AuraBuffEffect") * modDB:More(skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf")
local mult = (1 + inc / 100) * more
if not allyBuffs["Aura"] or not allyBuffs["Aura"][buff.name] or allyBuffs["Aura"][buff.name].effectMult / 100 <= mult then
activeMinionSkill.buffSkill = true
modDB.conditions["AffectedByAura"] = true
if buff.name:sub(1,4) == "Vaal" then
modDB.conditions["AffectedBy"..buff.name:sub(6):gsub(" ","")] = true
end
modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
local srcList = new("ModList")
srcList:ScaleAddList(buff.modList, mult)
srcList:ScaleAddList(extraAuraModList, mult)
mergeBuff(srcList, buffs, buff.name)
end
end
if env.minion and not env.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] and (env.minion ~= activeSkill.minion or not activeSkill.skillData.auraCannotAffectSelf) then
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect") + env.minion.modDB:Sum("INC", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect") * env.minion.modDB:More(skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf")
local mult = (1 + inc / 100) * more
if not allyBuffs["Aura"] or not allyBuffs["Aura"][buff.name] or allyBuffs["Aura"][buff.name].effectMult / 100 <= mult then
activeMinionSkill.minionBuffSkill = true
env.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
env.minion.modDB.conditions["AffectedByAura"] = true
local srcList = new("ModList")
srcList:ScaleAddList(buff.modList, mult)
srcList:ScaleAddList(extraAuraModList, mult)
mergeBuff(srcList, minionBuffs, buff.name)
end
end
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect")
local mult = (1 + inc / 100) * more
local newModList = new("ModList")
newModList:AddList(buff.modList)
newModList:AddList(extraAuraModList)
if buffExports["Aura"][buff.name] then
buffExports["Aura"][buff.name.."_Debuff"] = buffExports["Aura"][buff.name]
end
buffExports["Aura"][buff.name] = { effectMult = mult, modList = newModList }
if env.player.mainSkill.skillFlags.totem and not env.player.mainSkill.skillModList.conditions["AffectedBy"..buff.name:gsub(" ","")] then
activeMinionSkill.totemBuffSkill = true
env.player.mainSkill.skillModList.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
env.player.mainSkill.skillModList.conditions["AffectedByAura"] = true

local srcList = new("ModList")
local inc = skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect", "AuraBuffEffect")
local more = skillModList:More(skillCfg, "AuraEffect", "BuffEffect", "AuraBuffEffect")
local lists = {extraAuraModList, buff.modList}
local scale = (1 + inc / 100) * more
scale = m_max(scale, 0)

for _, modList in ipairs(lists) do
for _, mod in ipairs(modList) do
if mod.name == "EnergyShield" or mod.name == "Armour" or mod.name == "Evasion" or mod.name:match("Resist?M?a?x?$") then
local totemMod = copyTable(mod)
totemMod.name = "Totem"..totemMod.name
if scale ~= 1 then
if type(totemMod.value) == "number" then
totemMod.value = (m_floor(totemMod.value) == totemMod.value) and m_modf(round(totemMod.value * scale, 2)) or totemMod.value * scale
elseif type(totemMod.value) == "table" and totemMod.value.mod then
totemMod.value.mod.value = (m_floor(totemMod.value.mod.value) == totemMod.value.mod.value) and m_modf(round(totemMod.value.mod.value * scale, 2)) or totemMod.value.mod.value * scale
end
end
srcList:AddMod(totemMod)
end
end
end
mergeBuff(srcList, buffs, "Totem "..buff.name)
end
end
end
elseif buff.type == "Curse" then
if env.mode_effective and activeSkill.skillData.enable and (not enemyDB:Flag(nil, "Hexproof") or activeSkill.skillTypes[SkillType.Mark]) then
if env.mode_effective and activeMinionSkill.skillData.enable and (not enemyDB:Flag(nil, "Hexproof") or activeMinionSkill.skillTypes[SkillType.Mark]) then
local curse = {
name = buff.name,
priority = determineCursePriority(buff.name, activeSkill),
priority = determineCursePriority(buff.name, activeMinionSkill),
}
local inc = skillModList:Sum("INC", skillCfg, "CurseEffect") + enemyDB:Sum("INC", nil, "CurseEffectOnSelf")
local more = skillModList:More(skillCfg, "CurseEffect") * enemyDB:More(nil, "CurseEffectOnSelf")
Expand All @@ -2094,14 +2189,14 @@ function calcs.perform(env, fullDPSSkipEHP)
stackCount = m_min(stackCount, modDB:Sum("BASE", skillCfg, "Multiplier:"..buff.stackLimitVar))
end
else
stackCount = activeSkill.skillData.stackCount or 1
stackCount = activeMinionSkill.skillData.stackCount or 1
end
if env.mode_effective and stackCount > 0 then
activeSkill.debuffSkill = true
activeMinionSkill.debuffSkill = true
local srcList = new("ModList")
srcList:ScaleAddList(buff.modList, stackCount)
if activeSkill.skillData.stackCount then
srcList:NewMod("Multiplier:"..buff.name.."Stack", "BASE", activeSkill.skillData.stackCount, buff.name)
if activeMinionSkill.skillData.stackCount then
srcList:NewMod("Multiplier:"..buff.name.."Stack", "BASE", activeMinionSkill.skillData.stackCount, buff.name)
end
mergeBuff(srcList, debuffs, buff.name)
end
Expand Down Expand Up @@ -2208,48 +2303,6 @@ function calcs.perform(env, fullDPSSkipEHP)
end
end

-- Limited support for handling buffs originating from Spectres
for _, activeSkill in ipairs(env.player.activeSkillList) do
if activeSkill.minion then
for _, activeMinionSkill in ipairs(activeSkill.minion.activeSkillList) do
if activeMinionSkill.skillData.enable then
local skillModList = activeMinionSkill.skillModList
local skillCfg = activeMinionSkill.skillCfg
for _, buff in ipairs(activeMinionSkill.buffList) do
if buff.type == "Buff" then
if buff.applyAllies then
activeMinionSkill.buffSkill = true
modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
local srcList = new("ModList")
local inc = skillModList:Sum("INC", skillCfg, "BuffEffect", "BuffEffectOnPlayer")
local more = skillModList:More(skillCfg, "BuffEffect", "BuffEffectOnPlayer")
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, buffs, buff.name)
mergeBuff(buff.modList, buffs, buff.name)
if activeMinionSkill.skillData.thisIsNotABuff then
buffs[buff.name].notBuff = true
end
end
if buff.applyMinions then
activeMinionSkill.minionBuffSkill = true
activeSkill.minion.modDB.conditions["AffectedBy"..buff.name:gsub(" ","")] = true
local srcList = new("ModList")
local inc = skillModList:Sum("INC", skillCfg, "BuffEffect")
local more = skillModList:More(skillCfg, "BuffEffect")
srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more)
mergeBuff(srcList, minionBuffs, buff.name)
mergeBuff(buff.modList, minionBuffs, buff.name)
if activeMinionSkill.skillData.thisIsNotABuff then
buffs[buff.name].notBuff = true
end
end
end
end
end
end
end
end

if env.mode_combat then
-- This needs to be done in 2 steps to account for effects affecting life recovery from flasks
-- For example Sorrow of the Divine and buffs (like flask recovery watchers eye)
Expand Down
10 changes: 10 additions & 0 deletions src/Modules/ConfigOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,16 @@ return {
{ var = "stormRainBeamOverlap", type = "count", label = "# of Overlapping Beams:", ifSkill = "Storm Rain", apply = function(val, modList, enemyModList)
modList:NewMod("SkillData", "LIST", { key = "beamOverlapMultiplier", value = val }, "Config", { type = "SkillName", skillName = "Storm Rain" })
end },
{ label = "Summon Elemental Relic:", ifSkill = "Summon Elemental Relic" },
{ var = "summonElementalRelicEnableAngerAura", type = "check", defaultState = true, label = "Enable Anger Aura:", ifSkill = "Summon Elemental Relic", apply = function(val, modList, enemyModList)
modList:NewMod("SkillData", "LIST", { key = "enable", value = true }, "Config", { type = "SkillId", skillId = "Anger" }, { type = "SkillName", skillName = "Summon Elemental Relic", summonSkill = true })
end },
{ var = "summonElementalRelicEnableHatredAura", type = "check", defaultState = true, label = "Enable Hatred Aura:", ifSkill = "Summon Elemental Relic", apply = function(val, modList, enemyModList)
modList:NewMod("SkillData", "LIST", { key = "enable", value = true }, "Config", { type = "SkillId", skillId = "Hatred" }, { type = "SkillName", skillName = "Summon Elemental Relic", summonSkill = true })
end },
{ var = "summonElementalRelicEnableWrathAura", type = "check", defaultState = true, label = "Enable Wrath Aura:", ifSkill = "Summon Elemental Relic", apply = function(val, modList, enemyModList)
modList:NewMod("SkillData", "LIST", { key = "enable", value = true }, "Config", { type = "SkillId", skillId = "Wrath" }, { type = "SkillName", skillName = "Summon Elemental Relic", summonSkill = true })
end },
{ label = "Summon Holy Relic:", ifSkill = "Summon Holy Relic" },
{ var = "summonHolyRelicEnableHolyRelicBoon", type = "check", label = "Enable Holy Relic's Boon Aura:", ifSkill = "Summon Holy Relic", apply = function(val, modList, enemyModList)
modList:NewMod("Condition:HolyRelicBoonActive", "FLAG", true, "Config")
Expand Down

0 comments on commit a3317a5

Please sign in to comment.