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
3 changes: 3 additions & 0 deletions src/Modules/Build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild)
self.displayStats = {
{ stat = "ActiveMinionLimit", label = "Active Minion Limit", fmt = "d" },
{ stat = "AverageHit", label = "Average Hit", fmt = ".1f", compPercent = true },
{ stat = "PvpAverageHit", label = "PvP Average Hit", fmt = ".1f", compPercent = true, flag = "isPvP" },
{ stat = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true, flag = "attack" },
{ stat = "PvpAverageDamage", label = "PvP Average Damage", fmt = ".1f", compPercent = true, flag = "attackPvP" },
{ stat = "Speed", label = "Attack Rate", fmt = ".2f", compPercent = true, flag = "attack", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end },
{ stat = "Speed", label = "Cast Rate", fmt = ".2f", compPercent = true, flag = "spell", condFunc = function(v,o) return v > 0 and (o.TriggerTime or 0) == 0 end },
{ stat = "ServerTriggerRate", label = "Trigger Rate", fmt = ".2f", compPercent = true, condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end },
Expand All @@ -282,6 +284,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild)
{ stat = "CritMultiplier", label = "Crit Multiplier", fmt = "d%%", pc = true, condFunc = function(v,o) return (o.CritChance or 0) > 0 end },
{ stat = "HitChance", label = "Hit Chance", fmt = ".0f%%", flag = "attack" },
{ stat = "TotalDPS", label = "Total DPS", fmt = ".1f", compPercent = true, flag = "notAverage" },
{ stat = "PvpTotalDPS", label = "PvP Total DPS", fmt = ".1f", compPercent = true, flag = "notAveragePvP" },
{ stat = "TotalDPS", label = "Total DPS", fmt = ".1f", compPercent = true, flag = "showAverage", condFunc = function(v,o) return (o.TriggerTime or 0) ~= 0 end },
{ stat = "TotalDot", label = "DoT DPS", fmt = ".1f", compPercent = true },
{ stat = "WithDotDPS", label = "Total DPS inc. DoT", fmt = ".1f", compPercent = true, flag = "notAverage", condFunc = function(v,o) return v ~= o.TotalDPS and (o.PoisonDPS or 0) == 0 and (o.IgniteDPS or 0) == 0 and (o.ImpaleDPS or 0) == 0 and (o.BleedDPS or 0) == 0 end },
Expand Down
110 changes: 110 additions & 0 deletions src/Modules/CalcOffence.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2549,6 +2549,85 @@ function calcs.offence(env, actor, activeSkill)
t_insert(breakdown.AverageDamage, s_format("= %.1f", output.AverageDamage))
end
end


-- Calculate PvP values

--setup flags
skillFlags.isPvP = false
skillFlags.notAttackPvP = false
skillFlags.attackPvP = false
skillFlags.weapon1AttackPvP = false
skillFlags.weapon2AttackPvP = false
skillFlags.notAveragePvP = false

if env.configInput.PvpScaling then
skillFlags.isPvP = true
skillFlags.attackPvP = skillFlags.attack
skillFlags.notAttackPvP = not skillFlags.attack
skillFlags.weapon1AttackPvP = skillFlags.weapon1Attack
skillFlags.weapon2AttackPvP = skillFlags.weapon2Attack
skillFlags.notAveragePvP = skillFlags.notAverage
local PvpTvalue = env.configInput.multiplierPvpTvalueOverride or nil
if PvpTvalue then
PvpTvalue = PvpTvalue / 1000
else
if skillFlags.mine then
PvpTvalue = output.MineLayingTime*globalOutput.ActionSpeedMod
elseif skillFlags.trap then
PvpTvalue = output.TrapThrowingTime*globalOutput.ActionSpeedMod
else
PvpTvalue = 1/((globalOutput.HitSpeed or globalOutput.Speed)/globalOutput.ActionSpeedMod)
end
if PvpTvalue > 2147483647 then
PvpTvalue = 1
end
end
local PvpMultiplier = (env.configInput.multiplierPvpDamage or 100) / 100

local PvpNonElemental1 = data.misc.PvpNonElemental1
local PvpNonElemental2 = data.misc.PvpNonElemental2
local PvpElemental1 = data.misc.PvpElemental1
local PvpElemental2 = data.misc.PvpElemental2

local percentageNonElemental = ((output["PhysicalHitAverage"] + output["ChaosHitAverage"]) / (totalHitMin + totalHitMax) * 2)
local percentageElemental = 1 - percentageNonElemental
local portionNonElemental = (output.AverageHit / PvpTvalue / PvpNonElemental2 ) ^ PvpNonElemental1 * PvpTvalue * PvpNonElemental2 * percentageNonElemental
local portionElemental = (output.AverageHit / PvpTvalue / PvpElemental2 ) ^ PvpElemental1 * PvpTvalue * PvpElemental2 * percentageElemental
output.PvpAverageHit = (portionNonElemental + portionElemental) * PvpMultiplier
output.PvpAverageDamage = output.PvpAverageHit * output.HitChance / 100
output.PvpTotalDPS = output.PvpAverageDamage * (globalOutput.HitSpeed or globalOutput.Speed) * (skillData.dpsMultiplier or 1)

-- fix for these being nan
if output.PvpAverageHit ~= output.PvpAverageHit then
output.PvpAverageHit = 0
end
if output.PvpAverageDamage ~= output.PvpAverageDamage then
output.PvpAverageDamage = 0
end
if output.PvpTotalDPS ~= output.PvpTotalDPS then
output.PvpTotalDPS = 0
end

if breakdown then
breakdown.PvpAverageHit = { }
t_insert(breakdown.PvpAverageHit, s_format("Pvp Formula is (D/(T*M))^E*T*M*P, where D is the damage, T is the time taken," ))
t_insert(breakdown.PvpAverageHit, s_format("M is the multiplier, E is the exponent and P is the percentage of that type (ele or non ele)"))
t_insert(breakdown.PvpAverageHit, s_format("(M=%.1f for ele and %.1f for non-ele)(E=%.2f for ele and %.2f for non-ele)", PvpElemental2, PvpNonElemental2, PvpElemental1, PvpNonElemental1))
t_insert(breakdown.PvpAverageHit, s_format("(%.1f / (%.2f * %.1f)) ^ %.2f * %.2f * %.1f * %.2f = %.1f", output.AverageHit, PvpTvalue, PvpNonElemental2, PvpNonElemental1, PvpTvalue, PvpNonElemental2, percentageNonElemental, portionNonElemental))
t_insert(breakdown.PvpAverageHit, s_format("(%.1f / (%.2f * %.1f)) ^ %.2f * %.2f * %.1f * %.2f = %.1f", output.AverageHit, PvpTvalue, PvpElemental2, PvpElemental1, PvpTvalue, PvpElemental2, percentageElemental, portionElemental))
t_insert(breakdown.PvpAverageHit, s_format("(portionNonElemental + portionElemental) * PvP multiplier"))
t_insert(breakdown.PvpAverageHit, s_format("(%.1f + %.1f) * %.1f", portionNonElemental, portionElemental, PvpMultiplier))
t_insert(breakdown.PvpAverageHit, s_format("= %.1f", output.PvpAverageHit))
if isAttack then
breakdown.PvpAverageDamage = { }
t_insert(breakdown.PvpAverageDamage, s_format("%s:", pass.label))
t_insert(breakdown.PvpAverageDamage, s_format("%.1f ^8(average pvp hit)", output.PvpAverageHit))
t_insert(breakdown.PvpAverageDamage, s_format("x %.2f ^8(chance to hit)", output.HitChance / 100))
t_insert(breakdown.PvpAverageDamage, s_format("= %.1f", output.PvpAverageDamage))
end
end
end
end

if isAttack then
Expand All @@ -2557,7 +2636,9 @@ function calcs.offence(env, actor, activeSkill)
combineStat("CritChance", "AVERAGE")
combineStat("CritMultiplier", "AVERAGE")
combineStat("AverageDamage", "DPS")
combineStat("PvpAverageDamage", "DPS")
combineStat("TotalDPS", "DPS")
combineStat("PvpTotalDPS", "DPS")
combineStat("LifeLeechDuration", "DPS")
combineStat("LifeLeechInstances", "DPS")
combineStat("LifeLeechInstant", "DPS")
Expand Down Expand Up @@ -2586,6 +2667,16 @@ function calcs.offence(env, actor, activeSkill)
t_insert(breakdown.AverageDamage, s_format("(%.1f + %.1f) / 2 ^8(skill alternates weapons)", output.MainHand.AverageDamage, output.OffHand.AverageDamage))
end
t_insert(breakdown.AverageDamage, s_format("= %.1f", output.AverageDamage))
if skillFlags.isPvP then
breakdown.PvpAverageDamage = { }
t_insert(breakdown.PvpAverageDamage, "Both weapons:")
if skillData.doubleHitsWhenDualWielding then
t_insert(breakdown.PvpAverageDamage, s_format("%.1f + %.1f ^8(skill hits with both weapons at once)", output.MainHand.PvpAverageDamage, output.OffHand.PvpAverageDamage))
else
t_insert(breakdown.PvpAverageDamage, s_format("(%.1f + %.1f) / 2 ^8(skill alternates weapons)", output.MainHand.PvpAverageDamage, output.OffHand.PvpAverageDamage))
end
t_insert(breakdown.PvpAverageDamage, s_format("= %.1f", output.PvpAverageDamage))
end
end
end
end
Expand Down Expand Up @@ -2620,6 +2711,25 @@ function calcs.offence(env, actor, activeSkill)
t_insert(breakdown.TotalDPS, s_format("x %g ^8(quantity multiplier for this skill)", quantityMultiplier))
end
t_insert(breakdown.TotalDPS, s_format("= %.1f", output.TotalDPS))
if skillFlags.isPvP then
local rateType = "cast"
if isAttack then
rateType = "attack"
elseif isTriggered then
rateType = "trigger"
end
breakdown.PvpTotalDPS = {
s_format("%.1f ^8(average pvp hit)", output.PvpAverageDamage),
output.HitSpeed and s_format("x %.2f ^8(hit rate)", output.HitSpeed) or s_format("x %.2f ^8(%s rate)", output.Speed, rateType),
}
if skillData.dpsMultiplier then
t_insert(breakdown.PvpTotalDPS, s_format("x %g ^8(DPS multiplier for this skill)", skillData.dpsMultiplier))
end
if quantityMultiplier > 1 then
t_insert(breakdown.PvpTotalDPS, s_format("x %g ^8(quantity multiplier for this skill)", quantityMultiplier))
end
t_insert(breakdown.PvpTotalDPS, s_format("= %.1f", output.PvpTotalDPS))
end
end

-- Calculate leech rates
Expand Down
9 changes: 9 additions & 0 deletions src/Modules/CalcSections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ return {
},
},
{ label = "Skill Average Hit", notFlag = "attack", { format = "{1:output:AverageHit}", { breakdown = "AverageHit" }, }, },
{ label = "Skill PvP Average Hit", flag = "notAttackPvP", { format = "{1:output:PvpAverageHit}", { breakdown = "PvpAverageHit" }, }, },
-- Main Hand Hit Damage
{ label = "MH Total Increased", bgCol = colorCodes.MAINHANDBG, flag = "weapon1Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "INC", cfg = "weapon1" }, },
Expand Down Expand Up @@ -235,6 +236,7 @@ return {
},
},
{ label = "MH Average Hit", bgCol = colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{1:output:MainHand.AverageHit}", { breakdown = "MainHand.AverageHit" }, }, },
{ label = "MH PvP Average Hit", bgCol = colorCodes.MAINHANDBG, flag = "weapon1AttackPvP", { format = "{1:output:MainHand.PvpAverageHit}", { breakdown = "MainHand.PvpAverageHit" }, }, },
-- Off Hand Hit Damage
{ label = "OH Total Increased", bgCol = colorCodes.OFFHANDBG, flag = "weapon2Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "INC", cfg = "weapon2" }, },
Expand Down Expand Up @@ -302,12 +304,19 @@ return {
},
},
{ label = "OH Average Hit", bgCol = colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{1:output:OffHand.AverageHit}", { breakdown = "OffHand.AverageHit" }, }, },
{ label = "OH PvP Average Hit", bgCol = colorCodes.OFFHANDBG, flag = "weapon2AttackPvP", { format = "{1:output:OffHand.PvpAverageHit}", { breakdown = "OffHand.PvpAverageHit" }, }, },
{ label = "Average Damage", flag = "attack", { format = "{1:output:AverageDamage}",
{ breakdown = "MainHand.AverageDamage" },
{ breakdown = "OffHand.AverageDamage" },
{ breakdown = "AverageDamage" },
}, },
{ label = "PvP Average Dmg", flag = "attackPvP", { format = "{1:output:PvpAverageDamage}",
{ breakdown = "MainHand.PvpAverageDamage" },
{ breakdown = "OffHand.PvpAverageDamage" },
{ breakdown = "PvpAverageDamage" },
}, },
{ label = "Skill DPS", flag = "notAverage", notFlag = "triggered", { format = "{1:output:TotalDPS}", { breakdown = "TotalDPS" }, }, },
{ label = "Skill PvP DPS", flag = "notAveragePvP", { format = "{1:output:PvpTotalDPS}", { breakdown = "PvpTotalDPS" }, }, },
{ label = "Skill DPS", flag = "triggered", { format = "{1:output:TotalDPS}", { breakdown = "TotalDPS" }, }, },
} }
} },
Expand Down
10 changes: 10 additions & 0 deletions src/Modules/ConfigOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,10 @@ return {
{ var = "multiplierSextant", type = "count", label = "# of Sextants affecting the area", ifMult = "Sextant", apply = function(val, modList, enemyModList)
modList:NewMod("Multiplier:Sextant", "BASE", m_min(val, 5), "Config")
end },
{ label = "Unique Map Modifiers:" },
{ var = "PvpScaling", type = "check", label = "PvP damage scaling in effect", tooltip = "'Hall of Grandmasters'", apply = function(val, modList, enemyModList)
modList:NewMod("HasPvpScaling", "FLAG", true, "Config")
end },
{ label = "Player is cursed by:" },
{ var = "playerCursedWithAssassinsMark", type = "count", label = "Assassin's Mark:", tooltip = "Sets the level of Assassin's Mark to apply to the player.", apply = function(val, modList, enemyModList)
modList:NewMod("ExtraCurse", "LIST", { skillId = "AssassinsMark", level = val, applyToPlayer = true })
Expand Down Expand Up @@ -1163,6 +1167,12 @@ return {
{ var = "buffFanaticism", type = "check", label = "Do you have Fanaticism?", ifFlag = "Condition:CanGainFanaticism", tooltip = "This will enable the Fanaticism buff itself. (Grants 75% more cast speed, reduced ^x7070FFmana ^7cost, and increased area of effect)", apply = function(val, modList, enemyModList)
modList:NewMod("Condition:Fanaticism", "FLAG", true, "Config", { type = "Condition", var = "Combat" }, { type = "Condition", var = "CanGainFanaticism" })
end },
{ var = "multiplierPvpTvalueOverride", type = "count", label = "PvP Tvalue override (ms):", ifFlag = "isPvP", tooltip = "Tvalue in milliseconds. This overrides the Tvalue of a given skill, for instance any with fixed tvalues or for traps/mines until those are supported", apply = function(val, modList, enemyModList)
modList:NewMod("Multiplier:PvpTvalueOverride", "BASE", val, "Config", { type = "Condition", var = "Combat" })
end },
{ var = "multiplierPvpDamage", type = "count", label = "Custom PvP Damage multiplier percent:", ifFlag = "isPvP", tooltip = "This multiplies the damage of a given skill in pvp, for instance any with damage multiplier specific to pvp (from skill or support or item like sire of shards)", apply = function(val, modList, enemyModList)
modList:NewMod("Multiplier:PvpDamage", "BASE", val, "Config", { type = "Condition", var = "Combat" })
end },
-- Section: Effective DPS options
{ section = "For Effective DPS", col = 1 },
{ var = "critChanceLucky", type = "check", label = "Is your Crit Chance Lucky?", apply = function(val, modList, enemyModList)
Expand Down
6 changes: 6 additions & 0 deletions src/Modules/Data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,12 @@ data.misc = { -- magic numbers
ehpCalcMaxDepth = 512,
-- max hits is currently depth + speedup - 1 to give as much accuracy with as few cycles as possible, but can be increased for more accuracy
ehpCalcMaxHitsToCalc = 519,
-- PvP scaling used for hogm
PvpElemental1 = 0.55,
PvpElemental2 = 150,
PvpNonElemental1 = 0.57,
PvpNonElemental2 = 90,

}

data.bossSkills = {
Expand Down