Skip to content
Open
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
8 changes: 7 additions & 1 deletion src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,10 @@ function ImportTabClass:ImportItem(itemData, slotName)
end
end

local defaultDisabledGems = {
["Metadata/Items/Gems/SkillGemImmortalCall"] = true
}

function ImportTabClass:ImportSocketedItems(item, socketedItems, slotName)
-- Build socket group list
local itemSocketGroupList = { }
Expand All @@ -1039,6 +1043,8 @@ function ImportTabClass:ImportSocketedItems(item, socketedItems, slotName)
else
local normalizedBasename, qualityType = self.build.skillsTab:GetBaseNameAndQuality(socketedItem.typeLine, nil)
local gemId = self.build.data.gemForBaseName[normalizedBasename:lower()]
local enableGlobal1 = true
local enableGlobal2 = false
if socketedItem.hybrid then
-- Used by transfigured gems and dual-skill gems (currently just Stormbind)
normalizedBasename, qualityType = self.build.skillsTab:GetBaseNameAndQuality(socketedItem.hybrid.baseTypeName, nil)
Expand All @@ -1048,7 +1054,7 @@ function ImportTabClass:ImportSocketedItems(item, socketedItems, slotName)
end
end
if gemId then
local gemInstance = { level = 20, quality = 0, enabled = true, enableGlobal1 = true, gemId = gemId }
local gemInstance = { level = 20, quality = 0, enabled = not defaultDisabledGems[gemId], enableGlobal1 = enableGlobal1, enableGlobal2 = enableGlobal2, gemId = gemId }
gemInstance.nameSpec = self.build.data.gems[gemId].name
gemInstance.support = socketedItem.support
gemInstance.qualityId = qualityType
Expand Down
24 changes: 16 additions & 8 deletions src/Modules/BuildDisplayStats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,22 @@ local displayStats = {
{ },
{ stat = "Devotion", label = "Devotion", color = colorCodes.RARE, fmt = "d" },
{ },
{ stat = "TotalEHP", label = "Effective Hit Pool", fmt = ".0f", compPercent = true },
{ stat = "PvPTotalTakenHit", label = "PvP Hit Taken", fmt = ".1f", flag = "isPvP", lowerIsBetter = true },
{ stat = "PhysicalMaximumHitTaken", label = "Phys Max Hit", fmt = ".0f", color = colorCodes.PHYS, compPercent = true, },
{ stat = "LightningMaximumHitTaken", label = "Elemental Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken == o.ColdMaximumHitTaken and o.LightningMaximumHitTaken == o.FireMaximumHitTaken end },
{ stat = "FireMaximumHitTaken", label = "Fire Max Hit", fmt = ".0f", color = colorCodes.FIRE, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end },
{ stat = "ColdMaximumHitTaken", label = "Cold Max Hit", fmt = ".0f", color = colorCodes.COLD, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end },
{ stat = "LightningMaximumHitTaken", label = "Lightning Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken end },
{ stat = "ChaosMaximumHitTaken", label = "Chaos Max Hit", fmt = ".0f", color = colorCodes.CHAOS, compPercent = true },
{ stat = "TotalEHP", label = "Effective Hit Pool", fmt = ".0f", compPercent = true, condFunc = function(v,o) return not (o.AnyGuard or o.AnyScaledGuard or o.OnlySharedGuard or o.OnlyScaledSharedGuard) end },
{ stat = "TotalEHP", label = "Effective Hit Pool ^8(Guard)", fmt = ".0f", compPercent = true, condFunc = function(v,o) return o.AnyGuard or o.AnyScaledGuard or o.OnlySharedGuard or o.OnlyScaledSharedGuard end },
{ stat = "PvPTotalTakenHit", label = "PvP Hit Taken", fmt = ".1f", flag = "isPvP", lowerIsBetter = true, condFunc = function(v,o) return not (o.AnyGuard or o.AnyScaledGuard or o.OnlySharedGuard or o.OnlyScaledSharedGuard) end },
{ stat = "PvPTotalTakenHit", label = "PvP Hit Taken ^8(Guard)", fmt = ".1f", flag = "isPvP", lowerIsBetter = true, condFunc = function(v,o) return o.AnyGuard or o.AnyScaledGuard or o.OnlySharedGuard or o.OnlyScaledSharedGuard end },
{ stat = "PhysicalMaximumHitTaken", label = "Phys Max Hit", fmt = ".0f", color = colorCodes.PHYS, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard end, },
{ stat = "PhysicalMaximumHitTaken", label = "Phys Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.PHYS, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard end, },
{ stat = "LightningMaximumHitTaken", label = "Elemental Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard and o.LightningMaximumHitTaken == o.ColdMaximumHitTaken and o.LightningMaximumHitTaken == o.FireMaximumHitTaken end },
{ stat = "LightningMaximumHitTaken", label = "Elemental Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard and o.LightningMaximumHitTaken == o.ColdMaximumHitTaken and o.LightningMaximumHitTaken == o.FireMaximumHitTaken end },
{ stat = "FireMaximumHitTaken", label = "Fire Max Hit", fmt = ".0f", color = colorCodes.FIRE, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "FireMaximumHitTaken", label = "Fire Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.FIRE, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "ColdMaximumHitTaken", label = "Cold Max Hit", fmt = ".0f", color = colorCodes.COLD, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "ColdMaximumHitTaken", label = "Cold Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.COLD, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "LightningMaximumHitTaken", label = "Lightning Max Hit", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "LightningMaximumHitTaken", label = "Lightning Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.LIGHTNING, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard and (o.LightningMaximumHitTaken ~= o.ColdMaximumHitTaken or o.LightningMaximumHitTaken ~= o.FireMaximumHitTaken) end },
{ stat = "ChaosMaximumHitTaken", label = "Chaos Max Hit", fmt = ".0f", color = colorCodes.CHAOS, compPercent = true, condFunc = function(v,o) return not o.MaxHitGuard end },
{ stat = "ChaosMaximumHitTaken", label = "Chaos Max Hit ^8(Guard)", fmt = ".0f", color = colorCodes.CHAOS, compPercent = true, condFunc = function(v,o) return o.MaxHitGuard end },
{ },
{ stat = "MainHand", childStat = "Accuracy", label = "MH Accuracy", fmt = "d", condFunc = function(v,o) return o.PreciseTechnique end, warnFunc = function(v,o) return v < o.Life and "You do not have enough Accuracy for Precise Technique" end, warnColor = true },
{ stat = "OffHand", childStat = "Accuracy", label = "OH Accuracy", fmt = "d", condFunc = function(v,o) return o.PreciseTechnique end, warnFunc = function(v,o) return v < o.Life and "You do not have enough Accuracy for Precise Technique" end, warnColor = true },
Expand Down
154 changes: 122 additions & 32 deletions src/Modules/CalcDefence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,22 @@ function calcs.reducePoolsByDamage(poolTable, damageTable, actor)
end
local guard = poolTbl.Guard
if not guard then
guard = { shared = output.sharedGuardAbsorb or 0 }
for damageType in pairs(damageTable) do
guard[damageType] = output[damageType.."GuardAbsorb"] or 0
-- Assuming max hit guard mode ( EHP should set guard amount )
if output.maxHitGuardMode == "NONE" then
guard = { shared = 0 }
for damageType in pairs(damageTable) do
guard[damageType] = 0
end
elseif output.maxHitGuardMode == "MAX" then
guard = { shared = output.sharedGuardAbsorb or 0 }
for damageType in pairs(damageTable) do
guard[damageType] = output[damageType.."GuardAbsorb"] or 0
end
elseif output.maxHitGuardMode == "AVERAGE" then
guard = { shared = output.scaledSharedGuardAbsorb or 0 }
for damageType in pairs(damageTable) do
guard[damageType] = output["Scaled"..damageType.."GuardAbsorb"] or 0
end
end
end

Expand Down Expand Up @@ -2191,15 +2204,38 @@ function calcs.buildDefenceEstimations(env, actor)
if output["sharedGuardAbsorbRate"] > 0 then
output.OnlySharedGuard = true
output["sharedGuardAbsorb"] = calcLib.val(modDB, "GuardAbsorbLimit")
local lifeProtected = output["sharedGuardAbsorb"] / (output["sharedGuardAbsorbRate"] / 100) * (1 - output["sharedGuardAbsorbRate"] / 100)
if output.maxHitGuardMode ~= "NONE" then
output.MaxHitGuard = true
end
if (output.ehpGuardMode == "AVERAGE" or output.maxHitGuardMode == "AVERAGE") then
output["scaledSharedGuardAbsorb"] = calcLib.val(modDB, "ScaledGuardAbsorbLimit")
if output.ehpGuardMode == "AVERAGE" then
output.OnlySharedGuard = false
output.OnlyScaledSharedGuard = true
end
end
if breakdown then
breakdown["sharedGuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(guard limit)", output["sharedGuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output["sharedGuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output["sharedGuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected)
}
if output.OnlyScaledSharedGuard then
local lifeProtected = output["scaledSharedGuardAbsorb"] / (output["sharedGuardAbsorbRate"] / 100) * (1 - output["sharedGuardAbsorbRate"] / 100)
breakdown["scaledSharedGuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(normal guard limit)", output["sharedGuardAbsorb"]),
s_format("x %.2f%% ^8(guard uptime)", output["scaledSharedGuardAbsorb"] / output["sharedGuardAbsorb"] * 100),
s_format("= %d ^8(scaled guard limit)", output["scaledSharedGuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output["sharedGuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output["sharedGuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected)
}
else
local lifeProtected = output["sharedGuardAbsorb"] / (output["sharedGuardAbsorbRate"] / 100) * (1 - output["sharedGuardAbsorbRate"] / 100)
breakdown["sharedGuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(guard limit)", output["sharedGuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output["sharedGuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output["sharedGuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected)
}
end
end
end
for _, damageType in ipairs(dmgTypeList) do
Expand All @@ -2209,15 +2245,39 @@ function calcs.buildDefenceEstimations(env, actor)
output.AnyGuard = true
output.OnlySharedGuard = false
output[damageType.."GuardAbsorb"] = calcLib.val(modDB, damageType.."GuardAbsorbLimit")
local lifeProtected = output[damageType.."GuardAbsorb"] / (output[damageType.."GuardAbsorbRate"] / 100) * (1 - output[damageType.."GuardAbsorbRate"] / 100)
if output.maxHitGuardMode ~= "NONE" then
output.MaxHitGuard = true
end
if (output.ehpGuardMode == "AVERAGE" or output.maxHitGuardMode == "AVERAGE") then
output["Scaled"..damageType.."GuardAbsorb"] = calcLib.val(modDB, "Scaled"..damageType.."GuardAbsorbLimit")
if output.ehpGuardMode == "AVERAGE" then
output.OnlyScaledSharedGuard = false
output.AnyGuard = false
output.AnyScaledGuard = true
end
end
if breakdown then
breakdown[damageType.."GuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(guard limit)", output[damageType.."GuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output[damageType.."GuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output[damageType.."GuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected),
}
if output.AnyScaledGuard then
local lifeProtected = output["Scaled"..damageType.."GuardAbsorb"] / (output[damageType.."GuardAbsorbRate"] / 100) * (1 - output[damageType.."GuardAbsorbRate"] / 100)
breakdown["Scaled"..damageType.."GuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(normal guard limit)", output[damageType.."GuardAbsorb"]),
s_format("x %.2f%% ^8(guard uptime)", output["Scaled"..damageType.."GuardAbsorb"] / output[damageType.."GuardAbsorb"] * 100),
s_format("= %d ^8(scaled guard limit)", output["Scaled"..damageType.."GuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output[damageType.."GuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output[damageType.."GuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected),
}
else
local lifeProtected = output[damageType.."GuardAbsorb"] / (output[damageType.."GuardAbsorbRate"] / 100) * (1 - output[damageType.."GuardAbsorbRate"] / 100)
breakdown["Scaled"..damageType.."GuardAbsorb"] = {
s_format("Total life protected:"),
s_format("%d ^8(guard limit)", output["Scaled"..damageType.."GuardAbsorb"]),
s_format("/ %.2f ^8(portion taken from guard)", output[damageType.."GuardAbsorbRate"] / 100),
s_format("x %.2f ^8(portion taken from life and energy shield)", 1 - output[damageType.."GuardAbsorbRate"] / 100),
s_format("= %d", lifeProtected),
}
end
end
end
end
Expand Down Expand Up @@ -2366,10 +2426,18 @@ function calcs.buildDefenceEstimations(env, actor)
aegis["shared"] = output["sharedAegis"] or 0
aegis["sharedElemental"] = output["sharedElementalAegis"] or 0
local guard = { }
guard["shared"] = output.sharedGuardAbsorb or 0
for _, damageType in ipairs(dmgTypeList) do
aegis[damageType] = output[damageType.."Aegis"] or 0
guard[damageType] = output[damageType.."GuardAbsorb"] or 0
if output.ehpGuardMode == "AVERAGE" then
guard["shared"] = output.scaledSharedGuardAbsorb or 0
for _, damageType in ipairs(dmgTypeList) do
aegis[damageType] = output[damageType.."Aegis"] or 0
guard[damageType] = output["Scaled"..damageType.."GuardAbsorb"] or 0
end
else
guard["shared"] = output.sharedGuardAbsorb or 0
for _, damageType in ipairs(dmgTypeList) do
aegis[damageType] = output[damageType.."Aegis"] or 0
guard[damageType] = output[damageType.."GuardAbsorb"] or 0
end
end
local alliesTakenBeforeYou = {}
if output.FrostShieldLife then
Expand Down Expand Up @@ -2414,7 +2482,7 @@ function calcs.buildDefenceEstimations(env, actor)
DamageIn["WardBypass"] = DamageIn["WardBypass"] or modDB:Sum("BASE", nil, "WardBypass") or 0

local VaalArcticArmourHitsLeft = output.VaalArcticArmourLife
if DamageIn["cycles"] > 1 then
if (DamageIn["cycles"] > 1) or (output.ehpGuardMode == "AVERAGE") then
VaalArcticArmourHitsLeft = 0
end

Expand Down Expand Up @@ -2899,8 +2967,13 @@ function calcs.buildDefenceEstimations(env, actor)
output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + m_max(m_max(output[damageType.."Aegis"], output["sharedAegis"]), isElemental[damageType] and output[damageType.."AegisDisplay"] or 0)
-- guard skill
local GuardAbsorbRate = output["sharedGuardAbsorbRate"] or 0 + output[damageType.."GuardAbsorbRate"] or 0
if GuardAbsorbRate > 0 then
local GuardAbsorb = output["sharedGuardAbsorb"] or 0 + output[damageType.."GuardAbsorb"] or 0
if (GuardAbsorbRate > 0) and (output.maxHitGuardMode ~= "NONE") then
local GuardAbsorb = 0
if output.maxHitGuardMode == "MAX" then
GuardAbsorb = output["sharedGuardAbsorb"] or 0 + output[damageType.."GuardAbsorb"] or 0
elseif output.maxHitGuardMode == "AVERAGE" then
GuardAbsorb = output["scaledSharedGuardAbsorb"] or 0 + output["Scaled"..damageType.."GuardAbsorb"] or 0
end
if GuardAbsorbRate >= 100 then
output[damageType.."TotalHitPool"] = output[damageType.."TotalHitPool"] + GuardAbsorb
else
Expand Down Expand Up @@ -2938,6 +3011,12 @@ function calcs.buildDefenceEstimations(env, actor)
output[damageType.."TotalHitPool"] = m_max(output[damageType.."TotalHitPool"] - poolProtected, 0) + m_min(output[damageType.."TotalHitPool"], poolProtected) / (1 - output["SoulLinkMitigation"] / 100)
end
end

-- Disable Vaal Arctic Armour for max hit unless guard mode is max
if output.maxHitGuardMode ~= "MAX" then
output["VaalArcticArmourMitigation"] = 0
end


for _, damageType in ipairs(dmgTypeList) do
local partMin = m_huge
Expand Down Expand Up @@ -3107,12 +3186,23 @@ function calcs.buildDefenceEstimations(env, actor)
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]))
if output.maxHitGuardMode == "MAX" then
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
elseif output.maxHitGuardMode == "AVERAGE" then
if output.scaledSharedGuardAbsorb and output.scaledSharedGuardAbsorb > 0 then
t_insert(breakdown[maxHitCurType], s_format("\t%d "..colorCodes.SCOURGE.."Shared Guard charge ^7(%d remaining)", output.scaledSharedGuardAbsorb - poolsRemaining.Guard.shared, poolsRemaining.Guard.shared))
end
for takenType in pairs(takenDamages) do
if output["Scaled"..takenType.."GuardAbsorb"] and output["Scaled"..takenType.."GuardAbsorb"] > 0 then
t_insert(breakdown[maxHitCurType], s_format("\n\t%d "..colorCodes.SCOURGE.."%s Guard charge ^7(%d remaining)", output["Scaled"..takenType.."GuardAbsorb"] - poolsRemaining.Guard[takenType], takenType, poolsRemaining.Guard[takenType]))
end
end
end
if output.Ward and output.Ward > 0 then
Expand Down
Loading
Loading