Add resource lost information to enemy damage breakdown (#8594)
This commit is contained in:
@@ -134,7 +134,8 @@ function calcs.takenHitFromDamage(rawDamage, damageType, actor)
|
||||
local takenFlat = output[damageConvertedType.."takenFlat"]
|
||||
if convertPercent > 0 or takenFlat ~= 0 then
|
||||
local convertedDamage = rawDamage * convertPercent / 100
|
||||
local reducedDamage = round(m_max(convertedDamage * damageMitigationMultiplierForType(convertedDamage, damageConvertedType) + takenFlat, 0) * output[damageConvertedType .."AfterReductionTakenHitMulti"]) * (1 - output["VaalArcticArmourMitigation"])
|
||||
local vaalArctic = m_min(-modDB:Sum("MORE", nil, "VaalArcticArmourMitigation") / 100, 1)
|
||||
local reducedDamage = round(m_max(convertedDamage * damageMitigationMultiplierForType(convertedDamage, damageConvertedType) + takenFlat, 0) * output[damageConvertedType .."AfterReductionTakenHitMulti"]) * (1 - vaalArctic)
|
||||
receivedDamageSum = receivedDamageSum + reducedDamage
|
||||
damages[damageConvertedType] = (reducedDamage > 0 or convertPercent > 0) and reducedDamage or nil
|
||||
end
|
||||
@@ -169,7 +170,7 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
|
||||
alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 }
|
||||
end
|
||||
if output.TotalSpectreLife then
|
||||
alliesTakenBeforeYou["specters"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
|
||||
alliesTakenBeforeYou["spectres"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
|
||||
end
|
||||
if output.TotalTotemLife then
|
||||
alliesTakenBeforeYou["totems"] = { remaining = output.TotalTotemLife, percent = output.TotemAllyDamageMitigation / 100 }
|
||||
@@ -214,121 +215,141 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
|
||||
local LifeLossLostOverTime = poolTbl.LifeLossLostOverTime or 0
|
||||
local LifeBelowHalfLossLostOverTime = poolTbl.LifeBelowHalfLossLostOverTime or 0
|
||||
local overkillDamage = 0
|
||||
local resourcesLostToTypeDamage = { Physical = { }, Lightning = { }, Cold = { }, Fire = { }, Chaos = { } }
|
||||
local MoMPoolRemaining = m_huge
|
||||
local esPoolRemaining = m_huge
|
||||
|
||||
for damageType, damage in pairs(damageTable) do
|
||||
local damageRemainder = damage
|
||||
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 = m_floor(allyValues.remaining - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
for _, damageType in ipairs(dmgTypeList) do
|
||||
local damageRemainder = damageTable[damageType]
|
||||
if damageRemainder then
|
||||
for ally, 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 = m_floor(allyValues.remaining - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType][ally] = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- frost shield / soul link / other taken before you does not count as you taking damage
|
||||
damageTakenThatCanBeRecouped[damageType] = (damageTakenThatCanBeRecouped[damageType] or 0) + damageRemainder
|
||||
if aegis[damageType] > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis[damageType])
|
||||
aegis[damageType] = aegis[damageType] - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
if isElemental[damageType] and aegis.sharedElemental > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis.sharedElemental)
|
||||
aegis.sharedElemental = aegis.sharedElemental - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
if aegis.shared > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis.shared)
|
||||
aegis.shared = aegis.shared - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
if guard[damageType] > 0 then
|
||||
local tempDamage = m_min(damageRemainder * output[damageType.."GuardAbsorbRate"] / 100, guard[damageType])
|
||||
guard[damageType] = m_floor(guard[damageType] - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
if guard.shared > 0 then
|
||||
local tempDamage = m_min(damageRemainder * output.sharedGuardAbsorbRate / 100, guard.shared)
|
||||
guard.shared = m_floor(guard.shared - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
if ward > 0 then
|
||||
local tempDamage = m_min(damageRemainder * (1 - (modDB:Sum("BASE", nil, "WardBypass") or 0) / 100), ward)
|
||||
ward = ward - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
local esBypass = output[damageType.."EnergyShieldBypass"] / 100 or 0
|
||||
local lifeHitPool = calcLifeHitPoolWithLossPrevention(life, output.Life, output.preventedLifeLoss, lifeLossBelowHalfPrevented)
|
||||
local MoMEffect = m_min(output.sharedMindOverMatter + output[damageType.."MindOverMatter"], 100) / 100
|
||||
local MoMPool = MoMEffect < 1 and m_min(lifeHitPool / (1 - MoMEffect) - lifeHitPool, mana) or mana
|
||||
local lifePlusMoMHitPool = lifeHitPool + MoMPool
|
||||
if energyShield > 0 and not modDB:Flag(nil, "EnergyShieldProtectsMana") and esBypass < 1 then
|
||||
local esPool = esBypass > 0 and m_min(lifePlusMoMHitPool / esBypass - lifePlusMoMHitPool, energyShield) or energyShield
|
||||
local tempDamage = m_min(damageRemainder * (1 - esBypass), esPool)
|
||||
esPoolRemaining = m_min(esPoolRemaining, esPool - tempDamage)
|
||||
energyShield = energyShield - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
elseif esBypass == 1 then
|
||||
esPoolRemaining = 0
|
||||
end
|
||||
if MoMEffect > 0 and mana > 0 then
|
||||
local MoMDamage = damageRemainder * MoMEffect
|
||||
if modDB:Flag(nil, "EnergyShieldProtectsMana") and energyShield > 0 and esBypass < 1 then
|
||||
local MoMEBPool = esBypass > 0 and m_min(MoMPool / esBypass - MoMPool, energyShield) or energyShield
|
||||
local tempDamage = m_min(MoMDamage * (1 - esBypass), MoMEBPool)
|
||||
esPoolRemaining = m_min(esPoolRemaining, MoMEBPool - tempDamage)
|
||||
-- frost shield / soul link / other taken before you does not count as you taking damage
|
||||
damageTakenThatCanBeRecouped[damageType] = (damageTakenThatCanBeRecouped[damageType] or 0) + damageRemainder
|
||||
if aegis[damageType] > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis[damageType])
|
||||
aegis[damageType] = aegis[damageType] - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].aegis = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
if isElemental[damageType] and aegis.sharedElemental > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis.sharedElemental)
|
||||
aegis.sharedElemental = aegis.sharedElemental - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].sharedElementalAegis = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
if aegis.shared > 0 then
|
||||
local tempDamage = m_min(damageRemainder, aegis.shared)
|
||||
aegis.shared = aegis.shared - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].sharedAegis = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
if guard[damageType] > 0 then
|
||||
local tempDamage = m_min(damageRemainder * output[damageType.."GuardAbsorbRate"] / 100, guard[damageType])
|
||||
guard[damageType] = m_floor(guard[damageType] - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].guard = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
if guard.shared > 0 then
|
||||
local tempDamage = m_min(damageRemainder * output.sharedGuardAbsorbRate / 100, guard.shared)
|
||||
guard.shared = m_floor(guard.shared - tempDamage)
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].sharedGuard = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
if ward > 0 then
|
||||
local tempDamage = m_min(damageRemainder * (1 - (modDB:Sum("BASE", nil, "WardBypass") or 0) / 100), ward)
|
||||
ward = ward - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].ward = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
local esBypass = output[damageType.."EnergyShieldBypass"] / 100 or 0
|
||||
local lifeHitPool = calcLifeHitPoolWithLossPrevention(life, output.Life, output.preventedLifeLoss, lifeLossBelowHalfPrevented)
|
||||
local MoMEffect = m_min(output.sharedMindOverMatter + output[damageType.."MindOverMatter"], 100) / 100
|
||||
local MoMPool = MoMEffect < 1 and m_min(lifeHitPool / (1 - MoMEffect) - lifeHitPool, mana) or mana
|
||||
local lifePlusMoMHitPool = lifeHitPool + MoMPool
|
||||
if energyShield > 0 and not modDB:Flag(nil, "EnergyShieldProtectsMana") and esBypass < 1 then
|
||||
local esPool = esBypass > 0 and m_min(lifePlusMoMHitPool / esBypass - lifePlusMoMHitPool, energyShield) or energyShield
|
||||
local tempDamage = m_min(damageRemainder * (1 - esBypass), esPool)
|
||||
esPoolRemaining = m_min(esPoolRemaining, esPool - tempDamage)
|
||||
energyShield = energyShield - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
MoMDamage = MoMDamage - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].energyShield = tempDamage >= 1 and tempDamage or nil
|
||||
elseif esBypass == 1 then
|
||||
esPoolRemaining = 0
|
||||
end
|
||||
local tempDamage = m_min(MoMDamage, MoMPool)
|
||||
MoMPoolRemaining = m_min(MoMPoolRemaining, MoMPool - tempDamage)
|
||||
mana = mana - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
else
|
||||
MoMPoolRemaining = 0
|
||||
end
|
||||
if output.preventedLifeLossTotal > 0 then
|
||||
local halfLife = output.Life * 0.5
|
||||
local lifeOverHalfLife = m_max(life - halfLife, 0)
|
||||
local preventPercent = output.preventedLifeLoss / 100
|
||||
local poolAboveLow = lifeOverHalfLife / (1 - preventPercent)
|
||||
local preventBelowHalfPercent = lifeLossBelowHalfPrevented / 100
|
||||
local damageThatLifeCanStillTake = poolAboveLow + m_max(m_min(life, halfLife), 0) / (1 - preventBelowHalfPercent) / (1 - output.preventedLifeLoss / 100)
|
||||
if damageThatLifeCanStillTake < damageRemainder then
|
||||
overkillDamage = overkillDamage + damageRemainder - damageThatLifeCanStillTake
|
||||
damageRemainder = damageThatLifeCanStillTake
|
||||
end
|
||||
if output.preventedLifeLossBelowHalf ~= 0 then
|
||||
local damageToSplit = m_min(damageRemainder, poolAboveLow)
|
||||
local lostLife = damageToSplit * (1 - preventPercent)
|
||||
local preventedLoss = damageToSplit * preventPercent
|
||||
damageRemainder = damageRemainder - damageToSplit
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + preventedLoss
|
||||
life = life - lostLife
|
||||
if life <= halfLife then
|
||||
local unspecificallyLowLifePreventedDamage = damageRemainder * preventPercent
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + unspecificallyLowLifePreventedDamage
|
||||
damageRemainder = damageRemainder - unspecificallyLowLifePreventedDamage
|
||||
local specificallyLowLifePreventedDamage = damageRemainder * preventBelowHalfPercent
|
||||
LifeBelowHalfLossLostOverTime = LifeBelowHalfLossLostOverTime + specificallyLowLifePreventedDamage
|
||||
damageRemainder = damageRemainder - specificallyLowLifePreventedDamage
|
||||
if MoMEffect > 0 and mana > 0 then
|
||||
local MoMDamage = damageRemainder * MoMEffect
|
||||
if modDB:Flag(nil, "EnergyShieldProtectsMana") and energyShield > 0 and esBypass < 1 then
|
||||
local MoMEBPool = esBypass > 0 and m_min(MoMPool / esBypass - MoMPool, energyShield) or energyShield
|
||||
local tempDamage = m_min(MoMDamage * (1 - esBypass), MoMEBPool)
|
||||
esPoolRemaining = m_min(esPoolRemaining, MoMEBPool - tempDamage)
|
||||
energyShield = energyShield - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
MoMDamage = MoMDamage - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].energyShield = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
else
|
||||
local tempDamage = damageRemainder * output.preventedLifeLoss / 100
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + tempDamage
|
||||
local tempDamage = m_min(MoMDamage, MoMPool)
|
||||
MoMPoolRemaining = m_min(MoMPoolRemaining, MoMPool - tempDamage)
|
||||
mana = mana - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].mana = tempDamage >= 1 and tempDamage or nil
|
||||
else
|
||||
MoMPoolRemaining = 0
|
||||
end
|
||||
if output.preventedLifeLossTotal > 0 then
|
||||
local halfLife = output.Life * 0.5
|
||||
local lifeOverHalfLife = m_max(life - halfLife, 0)
|
||||
local preventPercent = output.preventedLifeLoss / 100
|
||||
local poolAboveLow = lifeOverHalfLife / (1 - preventPercent)
|
||||
local preventBelowHalfPercent = lifeLossBelowHalfPrevented / 100
|
||||
local damageThatLifeCanStillTake = poolAboveLow + m_max(m_min(life, halfLife), 0) / (1 - preventBelowHalfPercent) / (1 - output.preventedLifeLoss / 100)
|
||||
if damageThatLifeCanStillTake < damageRemainder then
|
||||
overkillDamage = overkillDamage + damageRemainder - damageThatLifeCanStillTake
|
||||
damageRemainder = damageThatLifeCanStillTake
|
||||
end
|
||||
if output.preventedLifeLossBelowHalf ~= 0 then
|
||||
local damageToSplit = m_min(damageRemainder, poolAboveLow)
|
||||
local lostLife = damageToSplit * (1 - preventPercent)
|
||||
local preventedLoss = damageToSplit * preventPercent
|
||||
damageRemainder = damageRemainder - damageToSplit
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + preventedLoss
|
||||
life = life - lostLife
|
||||
resourcesLostToTypeDamage[damageType].life = lostLife
|
||||
resourcesLostToTypeDamage[damageType].lifeLossPrevented = preventedLoss
|
||||
if life <= halfLife then
|
||||
local unspecificallyLowLifePreventedDamage = damageRemainder * preventPercent
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + unspecificallyLowLifePreventedDamage
|
||||
damageRemainder = damageRemainder - unspecificallyLowLifePreventedDamage
|
||||
local specificallyLowLifePreventedDamage = damageRemainder * preventBelowHalfPercent
|
||||
LifeBelowHalfLossLostOverTime = LifeBelowHalfLossLostOverTime + specificallyLowLifePreventedDamage
|
||||
damageRemainder = damageRemainder - specificallyLowLifePreventedDamage
|
||||
resourcesLostToTypeDamage[damageType].lifeLossPrevented = resourcesLostToTypeDamage[damageType].lifeLossPrevented + unspecificallyLowLifePreventedDamage + specificallyLowLifePreventedDamage
|
||||
end
|
||||
resourcesLostToTypeDamage[damageType].lifeLossPrevented = resourcesLostToTypeDamage[damageType].lifeLossPrevented >= 1 and resourcesLostToTypeDamage[damageType].lifeLossPrevented or nil
|
||||
else
|
||||
local tempDamage = damageRemainder * output.preventedLifeLoss / 100
|
||||
LifeLossLostOverTime = LifeLossLostOverTime + tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].lifeLossPrevented = tempDamage >= 1 and tempDamage or nil
|
||||
end
|
||||
end
|
||||
if life > 0 then
|
||||
local tempDamage = m_min(damageRemainder, life)
|
||||
life = life - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
resourcesLostToTypeDamage[damageType].life = (resourcesLostToTypeDamage[damageType].life or 0) + (tempDamage > 0 and tempDamage or 0)
|
||||
end
|
||||
overkillDamage = overkillDamage + damageRemainder
|
||||
resourcesLostToTypeDamage[damageType].overkill = damageRemainder >= 1 and damageRemainder or nil
|
||||
end
|
||||
if life > 0 then
|
||||
local tempDamage = m_min(damageRemainder, life)
|
||||
life = life - tempDamage
|
||||
damageRemainder = damageRemainder - tempDamage
|
||||
end
|
||||
overkillDamage = overkillDamage + damageRemainder
|
||||
end
|
||||
local hitPoolRemaining = calcLifeHitPoolWithLossPrevention(life, output.Life, output.preventedLifeLoss, lifeLossBelowHalfPrevented) +
|
||||
(MoMPoolRemaining ~= m_huge and MoMPoolRemaining or 0) + (esPoolRemaining ~= m_huge and esPoolRemaining or 0)
|
||||
@@ -345,10 +366,76 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
|
||||
LifeLossLostOverTime = m_ceil(LifeLossLostOverTime),
|
||||
LifeBelowHalfLossLostOverTime = m_ceil(LifeBelowHalfLossLostOverTime),
|
||||
OverkillDamage = m_ceil(overkillDamage),
|
||||
hitPoolRemaining = m_floor(hitPoolRemaining)
|
||||
hitPoolRemaining = m_floor(hitPoolRemaining),
|
||||
resourcesLostToTypeDamage = resourcesLostToTypeDamage
|
||||
}
|
||||
end
|
||||
|
||||
---Inserts breakdown of resources drained by a hit
|
||||
---@param breakdownTable table table to insert items to
|
||||
---@param poolsRemaining table remaining pools after running reducePoolsByDamage on damage to beak down
|
||||
---@param output table must already contain things like guard, aegis, ally life...
|
||||
---@return table breakdownTable with drained resource list
|
||||
local function incomingDamageBreakdown(breakdownTable, poolsRemaining, output)
|
||||
--region Breakdown inserts
|
||||
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.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
|
||||
if output.TotalTotemLife and output.TotalTotemLife > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Totem Life ^7(%d remaining)", output.TotalTotemLife - poolsRemaining.AlliesTakenBeforeYou["totems"].remaining, poolsRemaining.AlliesTakenBeforeYou["totems"].remaining))
|
||||
end
|
||||
if output.TotalVaalRejuvenationTotemLife and output.TotalVaalRejuvenationTotemLife > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Vaal Rejuvenation Totem Life ^7(%d remaining)", output.TotalVaalRejuvenationTotemLife - poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining, poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining))
|
||||
end
|
||||
if output.TotalRadianceSentinelLife and output.TotalRadianceSentinelLife > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Sentinel of Radiance Life ^7(%d remaining)", output.TotalRadianceSentinelLife - poolsRemaining.AlliesTakenBeforeYou["radianceSentinel"].remaining, poolsRemaining.AlliesTakenBeforeYou["radianceSentinel"].remaining))
|
||||
end
|
||||
if output.AlliedEnergyShield and output.AlliedEnergyShield > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Allied Energy shield ^7(%d remaining)", output.AlliedEnergyShield - poolsRemaining.AlliesTakenBeforeYou["soulLink"].remaining, poolsRemaining.AlliesTakenBeforeYou["soulLink"].remaining))
|
||||
end
|
||||
for _, damageType in ipairs(dmgTypeList) do
|
||||
if poolsRemaining.resourcesLostToTypeDamage[damageType].aegis then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."%s Aegis charge ^7(%d remaining)", poolsRemaining.resourcesLostToTypeDamage[damageType].aegis, damageType, poolsRemaining.Aegis[damageType]))
|
||||
end
|
||||
end
|
||||
if output.sharedElementalAegis and output.sharedElementalAegis ~= poolsRemaining.Aegis.sharedElemental then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Elemental Aegis charge ^7(%d remaining)", output.sharedElementalAegis - poolsRemaining.Aegis.sharedElemental, poolsRemaining.Aegis.sharedElemental))
|
||||
end
|
||||
if output.sharedAegis and output.sharedAegis > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Shared Aegis charge ^7(%d remaining)", output.sharedAegis - poolsRemaining.Aegis.shared, poolsRemaining.Aegis.shared))
|
||||
end
|
||||
for _, damageType in ipairs(dmgTypeList) do
|
||||
if poolsRemaining.resourcesLostToTypeDamage[damageType].guard then
|
||||
t_insert(breakdownTable, s_format("\n\t%d "..colorCodes.SCOURGE.."%s Guard charge ^7(%d remaining)", poolsRemaining.resourcesLostToTypeDamage[damageType].guard, damageType, poolsRemaining.Guard[damageType]))
|
||||
end
|
||||
end
|
||||
if output.sharedGuardAbsorb and output.sharedGuardAbsorb > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.SCOURGE.."Shared Guard charge ^7(%d remaining)", output.sharedGuardAbsorb - poolsRemaining.Guard.shared, poolsRemaining.Guard.shared))
|
||||
end
|
||||
if output.Ward and output.Ward > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.WARD.."Ward", output.Ward))
|
||||
end
|
||||
if output.EnergyShieldRecoveryCap ~= poolsRemaining.EnergyShield and output.EnergyShieldRecoveryCap and output.EnergyShieldRecoveryCap > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.ES.."Energy Shield ^7(%d remaining)", output.EnergyShieldRecoveryCap - poolsRemaining.EnergyShield, poolsRemaining.EnergyShield))
|
||||
end
|
||||
if output.ManaUnreserved ~= poolsRemaining.Mana and output.ManaUnreserved and output.ManaUnreserved > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.MANA.."Mana ^7(%d remaining)", output.ManaUnreserved - poolsRemaining.Mana, poolsRemaining.Mana))
|
||||
end
|
||||
if poolsRemaining.LifeLossLostOverTime + poolsRemaining.LifeBelowHalfLossLostOverTime > 0 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.LIFE.."Life ^7Loss Prevented", poolsRemaining.LifeLossLostOverTime + poolsRemaining.LifeBelowHalfLossLostOverTime))
|
||||
end
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.LIFE.."Life ^7(%d remaining)", output.LifeRecoverable - poolsRemaining.Life, poolsRemaining.Life))
|
||||
if poolsRemaining.OverkillDamage >= 1 then
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.NEGATIVE.."Overkill damage", poolsRemaining.OverkillDamage))
|
||||
end
|
||||
--endregion
|
||||
|
||||
return breakdownTable
|
||||
end
|
||||
|
||||
-- Performs all ingame and related defensive calculations
|
||||
function calcs.defence(env, actor)
|
||||
local modDB = actor.modDB
|
||||
@@ -1905,18 +1992,6 @@ function calcs.buildDefenceEstimations(env, actor)
|
||||
if takenMult ~= 1 or takenFlat ~= 0 or spellSuppressMult ~= 1 or impaleDamage ~= 0 then
|
||||
t_insert(breakdown[damageType.."TakenHitMult"], s_format("= %.3f", output[damageType.."TakenHitMult"]))
|
||||
end
|
||||
breakdown[damageType.."TakenHit"] = {
|
||||
s_format("Final %s Damage taken:", damageType),
|
||||
s_format("%.1f incoming damage", damage),
|
||||
s_format("x %.3f damage mult", output[damageType.."TakenHitMult"]),
|
||||
s_format("= %.1f", output[damageType.."TakenHit"]),
|
||||
}
|
||||
t_insert(breakdown["totalTakenHit"].rowList, {
|
||||
type = s_format("%s", damageType),
|
||||
incoming = s_format("%.1f incoming damage", damage),
|
||||
mult = s_format("x %.3f damage mult", output[damageType.."TakenHitMult"] ),
|
||||
value = s_format("%d", output[damageType.."TakenHit"]),
|
||||
})
|
||||
if output.AnyTakenReflect then
|
||||
breakdown[damageType.."TakenReflectMult"] = {
|
||||
s_format("Resistance: %.3f", 1 - resist / 100),
|
||||
@@ -2299,7 +2374,7 @@ function calcs.buildDefenceEstimations(env, actor)
|
||||
}
|
||||
end
|
||||
|
||||
-- from specters
|
||||
-- from spectres
|
||||
output["SpectreAllyDamageMitigation"] = modDB:Sum("BASE", nil, "takenFromSpectresBeforeYou")
|
||||
if output["SpectreAllyDamageMitigation"] ~= 0 then
|
||||
output["TotalSpectreLife"] = modDB:Sum("BASE", nil, "TotalSpectreLife")
|
||||
@@ -2411,7 +2486,7 @@ function calcs.buildDefenceEstimations(env, actor)
|
||||
alliesTakenBeforeYou["frostShield"] = { remaining = output.FrostShieldLife, percent = output.FrostShieldDamageMitigation / 100 }
|
||||
end
|
||||
if output.TotalSpectreLife then
|
||||
alliesTakenBeforeYou["specters"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
|
||||
alliesTakenBeforeYou["spectres"] = { remaining = output.TotalSpectreLife, percent = output.SpectreAllyDamageMitigation / 100 }
|
||||
end
|
||||
if output.TotalTotemLife then
|
||||
alliesTakenBeforeYou["totems"] = { remaining = output.TotalTotemLife, percent = output.TotemAllyDamageMitigation / 100 }
|
||||
@@ -3103,65 +3178,9 @@ function calcs.buildDefenceEstimations(env, actor)
|
||||
t_insert(breakdown[maxHitCurType], s_format("/ %.2f ^8(modifiers to enemy damage)", enemyDamageMult))
|
||||
end
|
||||
t_insert(breakdown[maxHitCurType], s_format("= %.0f ^8maximum survivable enemy damage%s", finalMaxHit, useConversionSmoothing and " (approximate)" or ""))
|
||||
|
||||
local poolsRemaining = calcs.reducePoolsByDamage(nil, takenDamages, actor)
|
||||
|
||||
t_insert(breakdown[maxHitCurType], s_format("^8Such a hit would drain the following:"))
|
||||
if output.FrostShieldLife and output.FrostShieldLife > 0 then
|
||||
t_insert(breakdown[maxHitCurType], 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.TotalSpectreLife and output.TotalSpectreLife > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Total Spectre Life ^7(%d remaining)", output.TotalSpectreLife - poolsRemaining.AlliesTakenBeforeYou["specters"].remaining, poolsRemaining.AlliesTakenBeforeYou["specters"].remaining))
|
||||
end
|
||||
if output.TotalTotemLife and output.TotalTotemLife > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Total Totem Life ^7(%d remaining)", output.TotalTotemLife - poolsRemaining.AlliesTakenBeforeYou["totems"].remaining, poolsRemaining.AlliesTakenBeforeYou["totems"].remaining))
|
||||
end
|
||||
if output.TotalVaalRejuvenationTotemLife and output.TotalVaalRejuvenationTotemLife > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Total Vaal Rejuvenation Totem Life ^7(%d remaining)", output.TotalVaalRejuvenationTotemLife - poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining, poolsRemaining.AlliesTakenBeforeYou["vaalRejuvenationTotems"].remaining))
|
||||
end
|
||||
if output.TotalRadianceSentinelLife and output.TotalRadianceSentinelLife > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Total Sentinel of Radiance Life ^7(%d remaining)", output.TotalRadianceSentinelLife - poolsRemaining.AlliesTakenBeforeYou["radianceSentinel"].remaining, poolsRemaining.AlliesTakenBeforeYou["radianceSentinel"].remaining))
|
||||
end
|
||||
if output.AlliedEnergyShield and output.AlliedEnergyShield > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Total Allied Energy shield ^7(%d remaining)", output.AlliedEnergyShield - poolsRemaining.AlliesTakenBeforeYou["soulLink"].remaining, poolsRemaining.AlliesTakenBeforeYou["soulLink"].remaining))
|
||||
end
|
||||
if output.sharedAegis and output.sharedAegis > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Shared Aegis charge ^7(%d remaining)", output.sharedAegis - poolsRemaining.Aegis.shared, poolsRemaining.Aegis.shared))
|
||||
end
|
||||
local receivedElemental = false
|
||||
for takenType in pairs(takenDamages) do
|
||||
receivedElemental = receivedElemental or isElemental[takenType]
|
||||
if output[takenType.."Aegis"] and output[takenType.."Aegis"] > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."%s Aegis charge ^7(%d remaining)", output[takenType.."Aegis"] - poolsRemaining.Aegis[takenType], takenType, poolsRemaining.Aegis[takenType]))
|
||||
end
|
||||
end
|
||||
if receivedElemental and output.sharedElementalAegis and output.sharedElementalAegis > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.GEM.."Elemental Aegis charge ^7(%d remaining)", output.sharedElementalAegis - poolsRemaining.Aegis.sharedElemental, poolsRemaining.Aegis.sharedElemental))
|
||||
end
|
||||
if output.sharedGuardAbsorb and output.sharedGuardAbsorb > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.SCOURGE.."Shared Guard charge ^7(%d remaining)", output.sharedGuardAbsorb - poolsRemaining.Guard.shared, poolsRemaining.Guard.shared))
|
||||
end
|
||||
for takenType in pairs(takenDamages) do
|
||||
if output[takenType.."GuardAbsorb"] and output[takenType.."GuardAbsorb"] > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\n\t%d "..colorCodes.SCOURGE.."%s Guard charge ^7(%d remaining)", output[takenType.."GuardAbsorb"] - poolsRemaining.Guard[takenType], takenType, poolsRemaining.Guard[takenType]))
|
||||
end
|
||||
end
|
||||
if output.Ward and output.Ward > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.WARD.."Ward", output.Ward))
|
||||
end
|
||||
if output.EnergyShieldRecoveryCap ~= poolsRemaining.EnergyShield and output.EnergyShieldRecoveryCap and output.EnergyShieldRecoveryCap > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.ES.."Energy Shield ^7(%d remaining)", output.EnergyShieldRecoveryCap - poolsRemaining.EnergyShield, poolsRemaining.EnergyShield))
|
||||
end
|
||||
if output.ManaUnreserved ~= poolsRemaining.Mana and output.ManaUnreserved and output.ManaUnreserved > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.MANA.."Mana ^7(%d remaining)", output.ManaUnreserved - poolsRemaining.Mana, poolsRemaining.Mana))
|
||||
end
|
||||
if poolsRemaining.LifeLossLostOverTime + poolsRemaining.LifeBelowHalfLossLostOverTime > 0 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.LIFE.."Life ^7Loss Prevented", poolsRemaining.LifeLossLostOverTime + poolsRemaining.LifeBelowHalfLossLostOverTime))
|
||||
end
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.LIFE.."Life ^7(%d remaining)", output.LifeRecoverable - poolsRemaining.Life, poolsRemaining.Life))
|
||||
if poolsRemaining.OverkillDamage >= 1 then
|
||||
t_insert(breakdown[maxHitCurType], s_format("\t%d Overkill damage", poolsRemaining.OverkillDamage))
|
||||
end
|
||||
|
||||
t_insert(breakdown[maxHitCurType], "^8Such a hit would drain the following resources:")
|
||||
breakdown[maxHitCurType] = incomingDamageBreakdown(breakdown[maxHitCurType], calcs.reducePoolsByDamage(nil, takenDamages, actor), output)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3595,4 +3614,106 @@ function calcs.buildDefenceEstimations(env, actor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--region Add breakdown to enemy incoming damage
|
||||
if breakdown then
|
||||
local takenHit = { }
|
||||
for _, damageType in ipairs(dmgTypeList) do
|
||||
takenHit[damageType] = output[damageType.."TakenHit"] > 0 and output[damageType.."TakenHit"] or nil
|
||||
t_insert(breakdown["totalTakenHit"].rowList, {
|
||||
type = s_format("%s", damageType),
|
||||
incoming = s_format("%.1f incoming damage", output[damageType.."TakenDamage"]),
|
||||
mult = s_format("x %.3f damage mult", output[damageType.."TakenHitMult"] ),
|
||||
value = s_format("%d", m_ceil(output[damageType.."TakenHit"])),
|
||||
})
|
||||
end
|
||||
local poolsRemaining = calcs.reducePoolsByDamage(nil, takenHit, actor)
|
||||
|
||||
t_insert(breakdown["totalTakenHit"], "Such a hit would drain the following resources:")
|
||||
breakdown["totalTakenHit"] = incomingDamageBreakdown(breakdown["totalTakenHit"], poolsRemaining, output)
|
||||
|
||||
for _, damageType in ipairs(dmgTypeList) do
|
||||
local breakdownTable = {}
|
||||
local resourcesLost = poolsRemaining.resourcesLostToTypeDamage[damageType]
|
||||
local resourcesLostSum = 0
|
||||
|
||||
t_insert(breakdownTable, s_format("Final %s Damage taken:", damageType))
|
||||
t_insert(breakdownTable, s_format("%.1f incoming damage", output[damageType.."TakenDamage"]))
|
||||
t_insert(breakdownTable, s_format("x %.3f damage mult", output[damageType.."TakenHitMult"]))
|
||||
t_insert(breakdownTable, s_format("= %.1f", output[damageType.."TakenHit"]))
|
||||
|
||||
t_insert(breakdownTable, "This part of the hit drains the following resources:")
|
||||
if resourcesLost.frostShield then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.frostShield
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Frost Shield Life", resourcesLost.frostShield))
|
||||
end
|
||||
if resourcesLost.spectres then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.spectres
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Spectre Life", resourcesLost.spectres))
|
||||
end
|
||||
if resourcesLost.totems then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.totems
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Totem Life", resourcesLost.totems))
|
||||
end
|
||||
if resourcesLost.vaalRejuvenationTotems then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.vaalRejuvenationTotems
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Vaal Rejuvenation Totem Life", resourcesLost.vaalRejuvenationTotems))
|
||||
end
|
||||
if resourcesLost.radianceSentinel then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.radianceSentinel
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Sentinel of Radiance Life", resourcesLost.radianceSentinel))
|
||||
end
|
||||
if resourcesLost.soulLink then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.soulLink
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Total Allied Energy shield", resourcesLost.soulLink))
|
||||
end
|
||||
if resourcesLost.aegis then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.aegis
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."%s Aegis charge", resourcesLost.aegis, damageType))
|
||||
end
|
||||
if resourcesLost.sharedElementalAegis then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.sharedElementalAegis
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Elemental Aegis charge", resourcesLost.sharedElementalAegis))
|
||||
end
|
||||
if resourcesLost.sharedAegis then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.sharedAegis
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.GEM.."Shared Aegis charge", resourcesLost.sharedAegis))
|
||||
end
|
||||
if resourcesLost.guard then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.guard
|
||||
t_insert(breakdownTable, s_format("\n\t%d "..colorCodes.SCOURGE.."%s Guard charge", resourcesLost.guard, damageType))
|
||||
end
|
||||
if resourcesLost.sharedGuard then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.sharedGuard
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.SCOURGE.."Shared Guard charge", resourcesLost.sharedGuard))
|
||||
end
|
||||
if resourcesLost.ward then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.ward
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.WARD.."Ward", resourcesLost.ward))
|
||||
end
|
||||
if resourcesLost.energyShield then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.energyShield
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.ES.."Energy Shield", resourcesLost.energyShield))
|
||||
end
|
||||
if resourcesLost.mana then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.mana
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.MANA.."Mana", resourcesLost.mana))
|
||||
end
|
||||
if resourcesLost.lifeLossPrevented and resourcesLost.lifeLossPrevented > 0 then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.lifeLossPrevented
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.LIFE.."Life ^7Loss Prevented", resourcesLost.lifeLossPrevented))
|
||||
end
|
||||
if resourcesLost.life and resourcesLost.life > 0 then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.life
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.LIFE.."Life", resourcesLost.life))
|
||||
end
|
||||
if resourcesLost.overkill then
|
||||
resourcesLostSum = resourcesLostSum + resourcesLost.overkill
|
||||
t_insert(breakdownTable, s_format("\t%d "..colorCodes.NEGATIVE.."Overkill damage", resourcesLost.overkill))
|
||||
end
|
||||
t_insert(breakdownTable, s_format("\t^8(%d total)", resourcesLostSum))
|
||||
breakdown[damageType.."TakenHit"] = breakdownTable
|
||||
end
|
||||
end
|
||||
--endregion
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user