Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Data/Skills/act_str.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6684,6 +6684,15 @@ skills["VaalRejuvenationTotem"] = {
statDescriptionScope = "skill_stat_descriptions",
skillTotemId = 21,
castTime = 0.1,
statMap = {
["base_life_regeneration_rate_per_minute"] = {
mod("LifeRegen", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Aura" }),
div = 60,
},
["vaal_rejuvenation_totem_%_damage_taken_applied_to_totem_instead"] = {
mod("takenFromVaalRejuvenationTotemsBeforeYou", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Aura" }),
},
},
baseFlags = {
spell = true,
aura = true,
Expand Down
9 changes: 9 additions & 0 deletions src/Export/Skills/act_str.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,15 @@ local skills, mod, flag, skill = ...

#skill VaalRejuvenationTotem
#flags spell aura totem area duration
statMap = {
["base_life_regeneration_rate_per_minute"] = {
mod("LifeRegen", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Aura" }),
div = 60,
},
["vaal_rejuvenation_totem_%_damage_taken_applied_to_totem_instead"] = {
mod("takenFromVaalRejuvenationTotemsBeforeYou", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Aura" }),
},
},
#baseMod skill("radius", 40)
#mods

Expand Down
108 changes: 88 additions & 20 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,27 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
local output = actor.output
local modDB = actor.modDB
local poolTbl = poolTable or { }
local frostShield = poolTbl.FrostShieldLife or output.FrostShieldLife or 0
local soulLink = poolTbl.SoulLink or output.SoulLink or 0

local alliesTakenBeforeYou = poolTbl.AlliesTakenBeforeYou
if not alliesTakenBeforeYou then
alliesTakenBeforeYou = {}
if output.FrostShieldLife then
Copy link
Contributor

@QuickStick123 QuickStick123 Apr 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should frost shield be grouped inside an allies take damage before you table?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frost shield is its own entity and doesnt count as you taking the damage, hence being grouped as a "non-you" entity

alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 }
end
if output.TotalSpectreLife then
alliesTakenBeforeYou["specters"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
end
if output.TotalTotemLife then
alliesTakenBeforeYou["totems"] = { remaining = output.TotalTotemLife, percent = output.TotemAllyDamageMitigation / 100 }
end
if output.TotalVaalRejuvenationTotemLife then
alliesTakenBeforeYou["vaalRejuvenationTotems"] = { remaining = output.TotalVaalRejuvenationTotemLife, percent = output.VaalRejuvenationTotemAllyDamageMitigation / 100 }
end
-- soul link is not implemented yet
if output.SoulLink then
alliesTakenBeforeYou["soulLink"] = { remaining = output.SoulLink, percent = output.SoulLinkMitigation / 100 }
end
end

local PoolsLost = poolTbl.PoolsLost or { }
local aegis = poolTbl.Aegis
Expand Down Expand Up @@ -122,18 +141,16 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)

for damageType, damage in pairs(damageTable) do
local damageRemainder = damage
if frostShield > 0 then
local tempDamage = m_min(damageRemainder * output.FrostShieldDamageMitigation / 100, frostShield)
frostShield = frostShield - tempDamage
damageRemainder = damageRemainder - tempDamage
end
-- soul link is not implemented for now
if soulLink > 0 then
local tempDamage = m_min(damageRemainder * output.SoulLinkMitigation / 100, soulLink)
soulLink = soulLink - tempDamage
damageRemainder = damageRemainder - tempDamage
for _, allyValues in pairs(alliesTakenBeforeYou) do
if not allyValues.damageType or allyValues.damageType == damageType then
if allyValues.remaining > 0 then
local tempDamage = m_min(damageRemainder * allyValues.percent, allyValues.remaining)
allyValues.remaining = allyValues.remaining - tempDamage
damageRemainder = damageRemainder - tempDamage
end
end
end
-- frost shield and soul link does not count as you taking damage
-- frost shield / soul link / other taken before you does not count as you taking damage
PoolsLost[damageType] = (PoolsLost[damageType] or 0) + damageRemainder
if aegis[damageType] > 0 then
local tempDamage = m_min(damageRemainder, aegis[damageType])
Expand Down Expand Up @@ -225,8 +242,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
end

return {
FrostShieldLife = frostShield,
SoulLink = soulLink,
AlliesTakenBeforeYou = alliesTakenBeforeYou,
Aegis = aegis,
Guard = guard,
PoolsLost = PoolsLost,
Expand Down Expand Up @@ -1894,8 +1910,9 @@ function calcs.buildDefenceEstimations(env, actor)
end
end

-- Frost Shield
-- taken from allies before you, eg. frost shield
do
-- frost shield
output["FrostShieldLife"] = modDB:Sum("BASE", nil, "FrostGlobeHealth")
output["FrostShieldDamageMitigation"] = modDB:Sum("BASE", nil, "FrostGlobeDamageMitigation")

Expand All @@ -1909,6 +1926,24 @@ function calcs.buildDefenceEstimations(env, actor)
s_format("= %d", lifeProtected),
}
end

-- from specters
output["SpectreAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromSpectresBeforeYou")
if output["SpectreAllyDamageMitigation"] ~= 0 then
output["TotalSpectreLife"] = modDB:Sum("BASE", nil, "TotalSpectreLife")
end

-- from totems
output["TotemAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromTotemsBeforeYou")
if output["TotemAllyDamageMitigation"] ~= 0 then
output["TotalTotemLife"] = modDB:Sum("BASE", nil, "TotalTotemLife")
end

-- from VaalRejuveTotem
output["VaalRejuvenationTotemAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromVaalRejuvenationTotemsBeforeYou") + output["TotemAllyDamageMitigation"]
if output["VaalRejuvenationTotemAllyDamageMitigation"] ~= output["TotemAllyDamageMitigation"] then
output["TotalVaalRejuvenationTotemLife"] = modDB:Sum("BASE", nil, "TotalVaalRejuvenationTotemLife")
end
end

-- Vaal Arctic Armour
Expand Down Expand Up @@ -1982,9 +2017,22 @@ function calcs.buildDefenceEstimations(env, actor)
aegis[damageType] = output[damageType.."Aegis"] or 0
guard[damageType] = output[damageType.."GuardAbsorb"] or 0
end
local alliesTakenBeforeYou = {}
if output.FrostShieldLife then
alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 }
end
if output.TotalSpectreLife then
alliesTakenBeforeYou["specters"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
end
if output.TotalTotemLife then
alliesTakenBeforeYou["totems"] = { remaining = output.TotalTotemLife, percent = output.TotemAllyDamageMitigation / 100 }
end
if output.TotalVaalRejuvenationTotemLife then
alliesTakenBeforeYou["vaalRejuvenationTotems"] = { remaining = output.TotalVaalRejuvenationTotemLife, percent = output.VaalRejuvenationTotemAllyDamageMitigation / 100 }
end

local poolTable = {
FrostShieldLife = output.FrostShieldLife or 0,
SoulLink = 0, -- soul link is not implemented for now
AlliesTakenBeforeYou = alliesTakenBeforeYou,
Aegis = aegis,
Guard = guard,
Ward = ward,
Expand Down Expand Up @@ -2031,7 +2079,9 @@ function calcs.buildDefenceEstimations(env, actor)
poolTable.EnergyShield = m_min(poolTable.EnergyShield + DamageIn.EnergyShieldWhenHit * (gainMult - 1), gainMult * output.EnergyShieldRecoveryCap)
end
poolTable = calcs.reducePoolsByDamage(poolTable, Damage, actor)
if poolTable.Life > 0 and damageTotal >= maxDamage then -- If still living and the amount of damage exceeds maximum threshold we survived infinite number of hits.

-- If still living and the amount of damage exceeds maximum threshold we survived infinite number of hits.
if poolTable.Life > 0 and damageTotal >= maxDamage then
return m_huge
end
if DamageIn.GainWhenHit and poolTable.Life > 0 then
Expand Down Expand Up @@ -2612,11 +2662,26 @@ function calcs.buildDefenceEstimations(env, actor)
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - GuardAbsorbRate / 100)
end
end
-- from allies before you
-- frost shield
if output["FrostShieldLife"] > 0 then
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
-- spectres
if output["TotalSpectreLife"] and output["TotalSpectreLife"] > 0 then
local poolProtected = output["TotalSpectreLife"] / (output["SpectreAllyDamageMitigation"] / 100) * (1 - output["SpectreAllyDamageMitigation"] / 100)
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["SpectreAllyDamageMitigation"] / 100)
end
-- totems
if output["TotalTotemLife"] and output["TotalTotemLife"] > 0 then
local poolProtected = output["TotalTotemLife"] / (output["TotemAllyDamageMitigation"] / 100) * (1 - output["TotemAllyDamageMitigation"] / 100)
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["TotemAllyDamageMitigation"] / 100)
end
if output["TotalVaalRejuvenationTotemLife"] and output["TotalVaalRejuvenationTotemLife"] > 0 then
local poolProtected = output["TotalVaalRejuvenationTotemLife"] / (output["VaalRejuvenationTotemAllyDamageMitigation"] / 100) * (1 - output["VaalRejuvenationTotemAllyDamageMitigation"] / 100)
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["VaalRejuvenationTotemAllyDamageMitigation"] / 100)
end
end

for _, damageType in ipairs(dmgTypeList) do
Expand Down Expand Up @@ -2753,7 +2818,10 @@ function calcs.buildDefenceEstimations(env, actor)

local poolsRemaining = calcs.reducePoolsByDamage(nil, takenDamages, actor)
local poolRemainingStrings = {
output.FrostShieldLife and output.FrostShieldLife > 0 and s_format("\t%d "..colorCodes.GEM.."Frost Shield Life ^7(%d remaining)", output.FrostShieldLife - poolsRemaining.FrostShieldLife, poolsRemaining.FrostShieldLife) or nil,
output.FrostShieldLife and output.FrostShieldLife > 0 and s_format("\t%d "..colorCodes.GEM.."Frost Shield Life ^7(%d remaining)", output.FrostShieldLife - poolsRemaining.AlliesTakenBeforeYou["frostShield"].remaining, poolsRemaining.AlliesTakenBeforeYou["frostShield"].remaining) or nil,
output.TotalSpectreLife and output.TotalSpectreLife > 0 and s_format("\t%d "..colorCodes.GEM.."Total Spectre Life ^7(%d remaining)", output.TotalSpectreLife - poolsRemaining.AlliesTakenBeforeYou["specters"].remaining, poolsRemaining.AlliesTakenBeforeYou["specters"].remaining) or nil,
output.TotalTotemLife and output.TotalTotemLife > 0 and s_format("\t%d "..colorCodes.GEM.."Total Totem Life ^7(%d remaining)", output.TotalTotemLife - poolsRemaining.AlliesTakenBeforeYou["totems"].remaining, poolsRemaining.AlliesTakenBeforeYou["totems"].remaining) or nil,
output.TotalVaalRejuvenationTotemLife and output.TotalVaalRejuvenationTotemLife > 0 and s_format("\t%d "..colorCodes.GEM.."Total Vaal Rejuvenation Totem Life ^7(%d remaining)", output.TotalVaalRejuvenationTotemLife - poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining, poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining) or nil,
output.sharedAegis and output.sharedAegis > 0 and s_format("\t%d "..colorCodes.GEM.."Shared Aegis charge ^7(%d remaining)", output.sharedAegis - poolsRemaining.Aegis.shared, poolsRemaining.Aegis.shared) or nil,
}
local receivedElemental = false
Expand Down
18 changes: 18 additions & 0 deletions src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,24 @@ return {
{ modName = { "FrostGlobeHealth", "FrostGlobeDamageMitigation" } },
},
},
{ label = "Spectre Ally", haveOutput = "TotalSpectreLife",
{ format = "{0:output:TotalSpectreLife}",
{ breakdown = "TotalSpectreLife" },
{ modName = { "TotalSpectreLife", "takenFromSpectresBeforeYou" } },
},
},
{ label = "Totem Ally", haveOutput = "TotalTotemLife",
{ format = "{0:output:TotalTotemLife}",
{ breakdown = "TotalTotemLife" },
{ modName = { "TotalTotemLife", "takenFromTotemsBeforeYou" } },
},
},
{ label = "Vaal Rejuv. Totem", haveOutput = "TotalVaalRejuvenationTotemLife",
{ format = "{0:output:TotalVaalRejuvenationTotemLife}",
{ breakdown = "TotalVaalRejuvenationTotemLife" },
{ modName = { "TotalVaalRejuvenationTotemLife", "takenFromVaalRejuvenationTotemsBeforeYou", "takenFromTotemsBeforeYou" } },
},
},
{ label = "Hits before death",{ format = "{2:output:NumberOfDamagingHits}", },
}
}, }, { defaultCollapsed = false, label = "Effective \"Health\" Pool", data = {
Expand Down
9 changes: 9 additions & 0 deletions src/Modules/ConfigOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,15 @@ Huge sets the radius to 11.
{ var = "enemyRadius", type = "integer", label = "Enemy radius:", ifSkill = { "Seismic Trap", "Lightning Spire Trap", "Explosive Trap" }, tooltip = "Configure the radius of an enemy hitbox to calculate some area overlapping (shotgunning) effects.", apply = function(val, modList, enemyModList)
modList:NewMod("EnemyRadius", "OVERRIDE", m_max(val, 1), "Config")
end },
{ var = "TotalSpectreLife", type = "integer", label = "Total Spectre Life:", ifMod = "takenFromSpectresBeforeYou", ifSkill = "Raise Spectre", tooltip = "The total life of your Spectres that can be taken before yours (used by jinxed juju)", apply = function(val, modList, enemyModList)
modList:NewMod("TotalSpectreLife", "BASE", val, "Config")
end },
{ var = "TotalTotemLife", type = "integer", label = "Total Totem Life:", ifOption = "conditionHaveTotem", ifMod = "takenFromTotemsBeforeYou", tooltip = "The total life of your Totems (excluding Vaal Rejuvenation Totem) that can be taken before yours (used by totem mastery)", apply = function(val, modList, enemyModList)
modList:NewMod("TotalTotemLife", "BASE", val, "Config")
end },
{ var = "TotalVaalRejuvenationTotemLife", type = "integer", label = "Total Vaal Rejuvenation Totem Life:", ifSkill = { "Vaal Rejuvenation Totem" }, ifMod = "takenFromVaalRejuvenationTotemsBeforeYou", tooltip = "The total life of your Vaal Rejuvenation Totems that can be taken before yours", apply = function(val, modList, enemyModList)
modList:NewMod("TotalVaalRejuvenationTotemLife", "BASE", val, "Config")
end },

-- Section: Map modifiers/curses
{ section = "Map Modifiers and Player Debuffs", col = 2 },
Expand Down
2 changes: 2 additions & 0 deletions src/Modules/ModParser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3972,6 +3972,8 @@ local specialModList = {
["(%d+)%% increased armour per second you've been stationary, up to a maximum of (%d+)%%"] = function(num, _, limit) return {
mod("Armour", "INC", num, { type = "Multiplier", var = "StationarySeconds", limit = tonumber(limit / num) }, { type = "Condition", var = "Stationary" }),
} end,
["(%d+)%% of damage from hits is taken from your spectres' life before you"] = function(num) return { mod("takenFromSpectresBeforeYou", "BASE", num) } end,
["(%d+)%% of damage from hits is taken from your nearest totem's life before you"] = function(num) return { mod("takenFromTotemsBeforeYou", "BASE", num, { type = "Condition", var = "HaveTotem" }) } end,
-- Knockback
["cannot knock enemies back"] = { flag("CannotKnockback") },
["knocks back enemies if you get a critical strike with a staff"] = { mod("EnemyKnockbackChance", "BASE", 100, nil, ModFlag.Staff, { type = "Condition", var = "CriticalStrike" }) },
Expand Down