Release 1.2.39

- Added full dual wielding support
- Added Dual Strike support
- Fixed PoEPlanner link import
This commit is contained in:
Openarl
2017-02-08 02:42:33 +10:00
parent ff7a1a3b48
commit 41693c28d0
17 changed files with 1385 additions and 739 deletions

View File

@@ -40,10 +40,12 @@ function CalcBreakdownClass:SetBreakdownData(displayData, pinned)
-- Build list of sections
self.sectionList = wipeTable(self.sectionList)
for _, sectionData in ipairs(displayData) do
if sectionData.breakdown then
self:AddBreakdownSection(sectionData)
elseif sectionData.modName then
self:AddModSection(sectionData)
if self.calcsTab:CheckFlag(sectionData) then
if sectionData.breakdown then
self:AddBreakdownSection(sectionData)
elseif sectionData.modName then
self:AddModSection(sectionData)
end
end
end
if #self.sectionList == 0 then
@@ -76,6 +78,9 @@ function CalcBreakdownClass:SetBreakdownData(displayData, pinned)
section.width = section.width + col.width
end
end
if section.label then
section.width = m_max(section.width, 6 + DrawStringWidth(16, "VAR", section.label..":"))
end
section.height = #section.rowList * 14 + 20
if section.label then
section.height = section.height + 16
@@ -90,7 +95,13 @@ end
-- Add sections based on the breakdown data generated by the Calcs module
function CalcBreakdownClass:AddBreakdownSection(sectionData)
local breakdown = self.calcsTab.calcsEnv.breakdown[sectionData.breakdown]
local breakdown
local ns, name = sectionData.breakdown:match("^(%a+)%.(%a+)$")
if ns then
breakdown = self.calcsTab.calcsEnv.breakdown[ns] and self.calcsTab.calcsEnv.breakdown[ns][name]
else
breakdown = self.calcsTab.calcsEnv.breakdown[sectionData.breakdown]
end
if not breakdown then
return
end

View File

@@ -74,8 +74,7 @@ function CalcSectionClass:IsMouseOver()
end
function CalcSectionClass:UpdateSize()
local skillFlags = self.calcsTab.calcsEnv.mainSkill.skillFlags
self.enabled = (not self.flag or skillFlags[self.flag]) and (not self.notFlag or not skillFlags[self.notFlag])
self.enabled = self.calcsTab:CheckFlag(self)
if not self.enabled then
self.height = 22
return
@@ -86,7 +85,7 @@ function CalcSectionClass:UpdateSize()
self.enabled = false
local yOffset = 22
for _, rowData in ipairs(self.data) do
rowData.enabled = (not rowData.flag or skillFlags[rowData.flag]) and (not rowData.notFlag or not skillFlags[rowData.notFlag])
rowData.enabled = self.calcsTab:CheckFlag(rowData)
if rowData.enabled then
self.enabled = true
local xOffset = 134
@@ -208,15 +207,15 @@ function CalcSectionClass:Draw(viewPort)
if rowData.enabled then
if rowData.label then
-- Draw row label with background
SetDrawColor(0, 0, 0)
SetDrawColor(rowData.bgCol or "^0")
DrawImage(nil, x + 2, lineY, 130, 18)
DrawString(x + 132, lineY + 1, "RIGHT_X", 16, "VAR", "^7"..rowData.label..":")
DrawString(x + 132, lineY + 1, "RIGHT_X", 16, "VAR", "^7"..rowData.label.."^7:")
end
for col, colData in ipairs(rowData) do
-- Draw column separator at the left end of the cell
SetDrawColor(self.col)
DrawImage(nil, colData.x, lineY, 2, colData.height)
if colData.format then
if colData.format and self.calcsTab:CheckFlag(colData) then
if cursorY >= viewPort.y and cursorY < viewPort.y + viewPort.height and cursorX >= colData.x and cursorY >= colData.y and cursorX < colData.x + colData.width and cursorY < colData.y + colData.height then
self.calcsTab:SetDisplayStat(colData)
end
@@ -224,10 +223,10 @@ function CalcSectionClass:Draw(viewPort)
-- This is the display stat, draw a green border around this cell
SetDrawColor(0.25, 1, 0.25)
DrawImage(nil, colData.x + 2, colData.y, colData.width - 2, colData.height)
SetDrawColor(0, 0, 0)
SetDrawColor(rowData.bgCol or "^0")
DrawImage(nil, colData.x + 3, colData.y + 1, colData.width - 4, colData.height - 2)
else
SetDrawColor(0, 0, 0)
SetDrawColor(rowData.bgCol or "^0")
DrawImage(nil, colData.x + 2, colData.y, colData.width - 2, colData.height)
end
local textSize = rowData.textSize or 14

View File

@@ -319,6 +319,31 @@ function CalcsTabClass:SetDisplayStat(displayData, pin)
self.controls.breakdown:SetBreakdownData(displayData, pin)
end
function CalcsTabClass:CheckFlag(obj)
local skillFlags = self.calcsEnv.mainSkill.skillFlags
if obj.flag and not skillFlags[obj.flag] then
return
end
if obj.flagList then
for _, flag in ipairs(obj.flagList) do
if not skillFlags[flag] then
return
end
end
end
if obj.notFlag and skillFlags[obj.notFlag] then
return
end
if obj.notFlagList then
for _, flag in ipairs(obj.notFlagList) do
if skillFlags[flag] then
return
end
end
end
return true
end
-- Build the calculation output tables
function CalcsTabClass:BuildOutput()
self.powerBuildFlag = true
@@ -358,7 +383,10 @@ function CalcsTabClass:BuildPower()
end
if self.powerBuilder then
collectgarbage("stop") -- This is necessary to work around a bug in the JIT
coroutine.resume(self.powerBuilder, self)
local res, errMsg = coroutine.resume(self.powerBuilder, self)
if launch.devMode and not res then
error(errMsg)
end
if coroutine.status(self.powerBuilder) == "dead" then
self.powerBuilder = nil
end
@@ -377,6 +405,9 @@ function CalcsTabClass:PowerBuilder()
if not self.powerMax then
self.powerMax = newPowerMax
end
if coroutine.running() then
coroutine.yield()
end
local start = GetTime()
for _, node in pairs(self.build.spec.nodes) do
wipeTable(node.power)

View File

@@ -82,7 +82,7 @@ end
function ModDBClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
local flags, keywordFlags = 0, 0
local skillName, skillGem, skillPart, skillTypes, slotName, source, tabulate
local skillName, skillGem, skillPart, skillTypes, skillStats, skillCond, slotName, source, tabulate
if cfg then
flags = cfg.flags or 0
keywordFlags = cfg.keywordFlags or 0
@@ -90,6 +90,8 @@ function ModDBClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
skillGem = cfg.skillGem
skillPart = cfg.skillPart
skillTypes = cfg.skillTypes
skillStats = cfg.skillStats
skillCond = cfg.skillCond
slotName = cfg.slotName
source = cfg.source
tabulate = cfg.tabulate
@@ -159,7 +161,7 @@ function ModDBClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
value = value * mult + (tag.base or 0)
end
elseif tag.type == "PerStat" then
local mult = m_floor((self.stats[tag.stat] or 0) / tag.div + 0.0001)
local mult = m_floor((self.stats[tag.stat] or (skillStats and skillStats[tag.stat]) or 0) / tag.div + 0.0001)
if type(value) == "table" then
value = copyTable(value)
value.value = value.value * mult + (tag.base or 0)
@@ -170,13 +172,13 @@ function ModDBClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
local match = false
if tag.varList then
for _, var in pairs(tag.varList) do
if self.conditions[var] then
if self.conditions[var] or (skillCond and skillCond[var]) then
match = true
break
end
end
else
match = self.conditions[tag.var]
match = self.conditions[tag.var] or (skillCond and skillCond[tag.var])
end
if tag.neg then
match = not match

View File

@@ -54,7 +54,7 @@ end
function ModListClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
local flags, keywordFlags = 0, 0
local skillName, skillGem, skillPart, skillTypes, slotName, source, tabulate
local skillName, skillGem, skillPart, skillTypes, skillStats, skillCond, slotName, source, tabulate
if cfg then
flags = cfg.flags or 0
keywordFlags = cfg.keywordFlags or 0
@@ -62,6 +62,8 @@ function ModListClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7
skillGem = cfg.skillGem
skillPart = cfg.skillPart
skillTypes = cfg.skillTypes
skillStats = cfg.skillStats
skillCond = cfg.skillCond
slotName = cfg.slotName
source = cfg.source
tabulate = cfg.tabulate
@@ -129,7 +131,7 @@ function ModListClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7
value = value * mult + (tag.base or 0)
end
elseif tag.type == "PerStat" then
local mult = m_floor((self.stats[tag.stat] or 0) / tag.div + 0.0001)
local mult = m_floor((self.stats[tag.stat] or (skillStats and skillStats[tag.stat]) or 0) / tag.div + 0.0001)
if type(value) == "table" then
value = copyTable(value)
value.value = value.value * mult + (tag.base or 0)
@@ -140,13 +142,13 @@ function ModListClass:Sum(modType, cfg, arg1, arg2, arg3, arg4, arg5, arg6, arg7
local match = false
if tag.varList then
for _, var in pairs(tag.varList) do
if self.conditions[var] then
if self.conditions[var] or (skillCond and skillCond[var]) then
match = true
break
end
end
else
match = self.conditions[tag.var]
match = self.conditions[tag.var] or (skillCond and skillCond[tag.var])
end
if tag.neg then
match = not match

View File

@@ -99,6 +99,14 @@ function PassiveSpecClass:DecodeURL(url)
ascendClassId = b:byte(4)
bandits = b:byte(5)
nodes = b:sub(8, -1)
elseif b:byte(1) == 0 and b:byte(2) == 4 then
-- PoE Planner version 4
-- Now with 50% fewer layers of base 64 encoding
classId = b:byte(6) % 16
ascendClassId = m_floor(b:byte(6) / 16)
bandits = b:byte(7)
local numNodes = b:byte(8) * 256 + b:byte(9)
nodes = b:sub(10, 10 + numNodes * 2 - 1)
else
local ver = b:byte(1) * 16777216 + b:byte(2) * 65536 + b:byte(3) * 256 + b:byte(4)
if ver > 4 then

View File

@@ -1150,7 +1150,63 @@ gems["Dual Strike"] = {
active_skill = true,
attack = true,
melee = true,
unsupported = true,
color = 2,
baseFlags = {
attack = true,
melee = true,
},
skillTypes = { [1] = true, [4] = true, [25] = true, [28] = true, [24] = true, },
weaponTypes = {
["One Handed Mace"] = true,
["Two Handed Axe"] = true,
["Claw"] = true,
["One Handed Axe"] = true,
["Dagger"] = true,
["One Handed Sword"] = true,
},
baseMods = {
skill("castTime", 1),
skill("manaCost", 5),
skill("doubleHitsWhenDualWielding", true), --"skill_double_hits_when_dual_wielding" = ?
},
qualityMods = {
mod("Speed", "INC", 0.5, ModFlag.Attack, 0, nil), --"attack_speed_+%" = 0.5
},
levelMods = {
[1] = mod("Damage", "MORE", nil, ModFlag.Attack),
},
levels = {
[1] = { -15, },
[2] = { -14, },
[3] = { -13, },
[4] = { -12, },
[5] = { -11, },
[6] = { -10, },
[7] = { -9, },
[8] = { -8, },
[9] = { -7, },
[10] = { -6, },
[11] = { -5, },
[12] = { -4, },
[13] = { -3, },
[14] = { -2, },
[15] = { -1, },
[16] = { nil, },
[17] = { 1, },
[18] = { 2, },
[19] = { 3, },
[20] = { 4, },
[21] = { 5, },
[22] = { 6, },
[23] = { 7, },
[24] = { 8, },
[25] = { 9, },
[26] = { 10, },
[27] = { 11, },
[28] = { 12, },
[29] = { 13, },
[30] = { 14, },
},
}
gems["Elemental Hit"] = {
dexterity = true,
@@ -3171,7 +3227,7 @@ gems["Riposte"] = {
--"melee_counterattack_trigger_on_block_%" = 100
--"attack_unusable_if_triggerable" = ?
skill("showAverage", true), --"base_skill_show_average_damage_instead_of_dps" = ?
--"skill_double_hits_when_dual_wielding" = ?
skill("doubleHitsWhenDualWielding", true), --"skill_double_hits_when_dual_wielding" = ?
},
qualityMods = {
mod("Damage", "INC", 1, 0, 0, nil), --"damage_+%" = 1

View File

@@ -328,9 +328,9 @@ gems["Cleave"] = {
baseMods = {
skill("castTime", 1),
skill("manaCost", 6),
--"cleave_damage_+%_final_while_dual_wielding" = -40
mod("Damage", "MORE", -40, 0, 0, { type = "Condition", var = "DualWielding" }), --"cleave_damage_+%_final_while_dual_wielding" = -40
--"is_area_damage" = ?
--"skill_double_hits_when_dual_wielding" = ?
skill("doubleHitsWhenDualWielding", true), --"skill_double_hits_when_dual_wielding" = ?
},
qualityMods = {
mod("Speed", "INC", 0.5, ModFlag.Attack, 0, nil), --"attack_speed_+%" = 0.5

View File

@@ -226,12 +226,13 @@ function buildMode:Init(dbFileName, buildName)
-- This may be user-customisable in the future
self.displayStats = {
{ mod = "AverageHit", label = "Average Hit", fmt = ".1f", compPercent = true },
{ mod = "AverageDamage", label = "Average Damage", fmt = ".1f", compPercent = true, flag = "attack" },
{ mod = "Speed", label = "Attack Rate", fmt = ".2f", compPercent = true, flag = "attack" },
{ mod = "Speed", label = "Cast Rate", fmt = ".2f", compPercent = true, flag = "spell" },
{ mod = "HitSpeed", label = "Hit Rate", fmt = ".2f" },
{ mod = "CritChance", label = "Crit Chance", fmt = ".2f%%" },
{ mod = "CritMultiplier", label = "Crit Multiplier", fmt = "d%%", pc = true, condFunc = function(v,o) return o.CritChance > 0 end },
{ mod = "HitChance", label = "Hit Chance", fmt = "d%%", flag = "attack" },
{ mod = "HitChance", label = "Hit Chance", fmt = ".0f%%", flag = "attack" },
{ mod = "TotalDPS", label = "Total DPS", fmt = ".1f", compPercent = true, flag = "notAverage" },
{ mod = "TotalDot", label = "DoT DPS", fmt = ".1f", compPercent = true },
{ mod = "BleedDPS", label = "Bleed DPS", fmt = ".1f", compPercent = true },

View File

@@ -33,7 +33,8 @@ return {
{ format = "{0:mod:1}", { modName = "FireMax", cfg = "skill" }, },
{ format = "{0:mod:1}", { modName = "ChaosMax", cfg = "skill" }, },
},
{ label = "Total Increased",
-- Skill Hit Damage
{ label = "Total Increased", notFlag = "attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "INC", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "INC", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "INC", cfg = "skill" }, },
@@ -41,7 +42,7 @@ return {
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "INC", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "INC", cfg = "skill" }, },
},
{ label = "Total More",
{ label = "Total More", notFlag = "attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "MORE", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "MORE", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "MORE", cfg = "skill" }, },
@@ -49,7 +50,7 @@ return {
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "MORE", cfg = "skill" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "MORE", cfg = "skill" }, },
},
{ label = "Effective DPS Mod", flag = "effective",
{ label = "Effective DPS Mod", notFlag = "attack", flag = "effective",
{ },
{ format = "x {3:output:PhysicalEffMult}",
{ breakdown = "PhysicalEffMult" },
@@ -75,16 +76,166 @@ return {
{ label = "Enemy modifiers", modName = { "DamageTaken", "ChaosDamageTaken", "ChaosResist" }, enemy = true },
},
},
{ label = "Hit Damage", textSize = 12,
{ label = "Skill Hit Damage", textSize = 12, notFlag = "attack",
{ format = "{0:output:TotalMin} to {0:output:TotalMax}", },
{ format = "{0:output:PhysicalMin} to {0:output:PhysicalMax}", { breakdown = "Physical" }, { label = "Conversions", modName = { "SkillPhysicalDamageConvertToLightning", "SkillPhysicalDamageConvertToCold", "SkillPhysicalDamageConvertToFire", "SkillPhysicalDamageConvertToChaos", "PhysicalDamageConvertToLightning", "PhysicalDamageConvertToCold", "PhysicalDamageConvertToFire", "PhysicalDamageConvertToChaos", "PhysicalDamageGainAsLightning", "PhysicalDamageGainAsCold", "PhysicalDamageGainAsFire", "PhysicalDamageGainAsChaos" }, modType = "BASE", cfg = "skill" }, },
{ format = "{0:output:LightningMin} to {0:output:LightningMax}", { breakdown = "Lightning" }, { label = "Conversions", modName = { "LightningDamageConvertToCold", "LightningDamageConvertToFire", "LightningDamageConvertToChaos", "LightningDamageGainAsCold", "LightningDamageGainAsFire", "LightningDamageGainAsChaos" }, modType = "BASE", cfg = "skill" }, },
{ format = "{0:output:ColdMin} to {0:output:ColdMax}", { breakdown = "Cold" }, { label = "Conversions", modName = { "SkillColdDamageConvertToFire", "ColdDamageConvertToFire", "ColdDamageConvertToChaos", "ColdDamageGainAsFire", "ColdDamageGainAsChaos" }, modType = "BASE", cfg = "skill" }, },
{ format = "{0:output:FireMin} to {0:output:FireMax}", { breakdown = "Fire" }, { label = "Conversions", modName = { "FireDamageConvertToChaos", "FireDamageGainAsChaos" }, modType = "BASE", cfg = "skill" }, },
{ format = "{0:output:ChaosMin} to {0:output:ChaosMax}", { breakdown = "Chaos" }, },
{ format = "{0:output:PhysicalMin} to {0:output:PhysicalMax}",
{ breakdown = "Physical" },
{ label = "Conversions", modType = "BASE", cfg = "skill", modName = { "SkillPhysicalDamageConvertToLightning", "SkillPhysicalDamageConvertToCold", "SkillPhysicalDamageConvertToFire", "SkillPhysicalDamageConvertToChaos", "PhysicalDamageConvertToLightning", "PhysicalDamageConvertToCold", "PhysicalDamageConvertToFire", "PhysicalDamageConvertToChaos", "PhysicalDamageGainAsLightning", "PhysicalDamageGainAsCold", "PhysicalDamageGainAsFire", "PhysicalDamageGainAsChaos" } },
},
{ format = "{0:output:LightningMin} to {0:output:LightningMax}",
{ breakdown = "Lightning" },
{ label = "Conversions", modType = "BASE", cfg = "skill", modName = { "LightningDamageConvertToCold", "LightningDamageConvertToFire", "LightningDamageConvertToChaos", "LightningDamageGainAsCold", "LightningDamageGainAsFire", "LightningDamageGainAsChaos" } },
},
{ format = "{0:output:ColdMin} to {0:output:ColdMax}",
{ breakdown = "Cold" },
{ label = "Conversions", modType = "BASE", cfg = "skill", modName = { "SkillColdDamageConvertToFire", "ColdDamageConvertToFire", "ColdDamageConvertToChaos", "ColdDamageGainAsFire", "ColdDamageGainAsChaos" } },
},
{ format = "{0:output:FireMin} to {0:output:FireMax}",
{ breakdown = "Fire" },
{ label = "Conversions", modType = "BASE", cfg = "skill", modName = { "FireDamageConvertToChaos", "FireDamageGainAsChaos" } },
},
{ format = "{0:output:ChaosMin} to {0:output:ChaosMax}",
{ breakdown = "Chaos" },
},
},
{ label = "Average Hit", { format = "{1:output:AverageHit}", { breakdown = "AverageHit" }, }, },
{ label = "Average Damage", flag = "attack", { format = "{1:output:AverageDamage}", { breakdown = "AverageDamage" }, }, },
{ label = "Skill Average Hit", notFlag = "attack", { format = "{1:output:AverageHit}", { breakdown = "AverageHit" }, }, },
-- Main Hand Hit Damage
{ label = "MH Total Increased", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "INC", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "INC", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "ColdDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "INC", cfg = "weapon1" }, },
},
{ label = "MH Total More", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "MORE", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "MORE", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "ColdDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon1" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "MORE", cfg = "weapon1" }, },
},
{ label = "MH Eff. DPS Mod", bgCol = data.colorCodes.MAINHANDBG, flagList = {"weapon1Attack","effective"},
{ },
{ format = "x {3:output:MainHand.PhysicalEffMult}",
{ breakdown = "MainHand.PhysicalEffMult" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "PhysicalDamageTaken" }, enemy = true },
},
{ format = "x {3:output:MainHand.LightningEffMult}",
{ breakdown = "MainHand.LightningEffMult" },
{ label = "Player modifiers", modName = { "LightningPenetration", "ElementalPenetration" }, cfg = "weapon1" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "LightningDamageTaken", "ElementalDamageTaken", "LightningResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:MainHand.ColdEffMult}",
{ breakdown = "MainHand.ColdEffMult" },
{ label = "Player modifiers", modName = { "ColdPenetration", "ElementalPenetration" }, cfg = "weapon1" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "ColdDamageTaken", "ElementalDamageTaken", "ColdResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:MainHand.FireEffMult}",
{ breakdown = "MainHand.FireEffMult" },
{ label = "Player modifiers", modName = { "FirePenetration", "ElementalPenetration" }, cfg = "weapon1" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "FireDamageTaken", "ElementalDamageTaken", "FireResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:MainHand.ChaosEffMult}",
{ breakdown = "MainHand.ChaosEffMult" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "ChaosDamageTaken", "ChaosResist" }, enemy = true },
},
},
{ label = "MH Hit Damage", bgCol = data.colorCodes.MAINHANDBG, textSize = 12, flag = "weapon1Attack",
{ format = "{0:output:MainHand.TotalMin} to {0:output:MainHand.TotalMax}", },
{ format = "{0:output:MainHand.PhysicalMin} to {0:output:MainHand.PhysicalMax}",
{ breakdown = "MainHand.Physical" },
{ label = "Conversions", modType = "BASE", cfg = "weapon1", modName = { "SkillPhysicalDamageConvertToLightning", "SkillPhysicalDamageConvertToCold", "SkillPhysicalDamageConvertToFire", "SkillPhysicalDamageConvertToChaos", "PhysicalDamageConvertToLightning", "PhysicalDamageConvertToCold", "PhysicalDamageConvertToFire", "PhysicalDamageConvertToChaos", "PhysicalDamageGainAsLightning", "PhysicalDamageGainAsCold", "PhysicalDamageGainAsFire", "PhysicalDamageGainAsChaos" } },
},
{ format = "{0:output:MainHand.LightningMin} to {0:output:MainHand.LightningMax}",
{ breakdown = "MainHand.Lightning" },
{ label = "Conversions", modType = "BASE", cfg = "weapon1", modName = { "LightningDamageConvertToCold", "LightningDamageConvertToFire", "LightningDamageConvertToChaos", "LightningDamageGainAsCold", "LightningDamageGainAsFire", "LightningDamageGainAsChaos" } },
},
{ format = "{0:output:MainHand.ColdMin} to {0:output:MainHand.ColdMax}",
{ breakdown = "MainHand.Cold" },
{ label = "Conversions", modType = "BASE", cfg = "weapon1", modName = { "SkillColdDamageConvertToFire", "ColdDamageConvertToFire", "ColdDamageConvertToChaos", "ColdDamageGainAsFire", "ColdDamageGainAsChaos" } },
},
{ format = "{0:output:MainHand.FireMin} to {0:output:MainHand.FireMax}",
{ breakdown = "MainHand.Fire" },
{ label = "Conversions", modType = "BASE", cfg = "weapon1", modName = { "FireDamageConvertToChaos", "FireDamageGainAsChaos" } },
},
{ format = "{0:output:MainHand.ChaosMin} to {0:output:MainHand.ChaosMax}",
{ breakdown = "MainHand.Chaos" },
},
},
{ label = "MH Average Hit", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{1:output:MainHand.AverageHit}", { breakdown = "MainHand.AverageHit" }, }, },
-- Off Hand Hit Damage
{ label = "OH Total Increased", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "INC", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "INC", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "ColdDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "INC", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "INC", cfg = "weapon2" }, },
},
{ label = "OH Total More", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack",
{ format = "{0:mod:1}%", { modName = "Damage", modType = "MORE", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = "PhysicalDamage", modType = "MORE", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "LightningDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "ColdDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = { "FireDamage", "ElementalDamage" }, modType = "MORE", cfg = "weapon2" }, },
{ format = "{0:mod:1}%", { modName = "ChaosDamage", modType = "MORE", cfg = "weapon2" }, },
},
{ label = "OH Eff. DPS Mod", bgCol = data.colorCodes.OFFHANDBG, flagList = {"weapon2Attack","effective"},
{ },
{ format = "x {3:output:OffHand.PhysicalEffMult}",
{ breakdown = "OffHand.PhysicalEffMult" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "PhysicalDamageTaken" }, enemy = true },
},
{ format = "x {3:output:OffHand.LightningEffMult}",
{ breakdown = "OffHand.LightningEffMult" },
{ label = "Player modifiers", modName = { "LightningPenetration", "ElementalPenetration" }, cfg = "weapon2" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "LightningDamageTaken", "ElementalDamageTaken", "LightningResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:OffHand.ColdEffMult}",
{ breakdown = "OffHand.ColdEffMult" },
{ label = "Player modifiers", modName = { "ColdPenetration", "ElementalPenetration" }, cfg = "weapon2" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "ColdDamageTaken", "ElementalDamageTaken", "ColdResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:OffHand.FireEffMult}",
{ breakdown = "OffHand.FireEffMult" },
{ label = "Player modifiers", modName = { "FirePenetration", "ElementalPenetration" }, cfg = "weapon2" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "FireDamageTaken", "ElementalDamageTaken", "FireResist", "ElementalResist" }, enemy = true },
},
{ format = "x {3:output:OffHand.ChaosEffMult}",
{ breakdown = "OffHand.ChaosEffMult" },
{ label = "Enemy modifiers", modName = { "DamageTaken", "ChaosDamageTaken", "ChaosResist" }, enemy = true },
},
},
{ label = "OH Hit Damage", bgCol = data.colorCodes.OFFHANDBG, textSize = 12, flag = "weapon2Attack",
{ format = "{0:output:OffHand.TotalMin} to {0:output:OffHand.TotalMax}", },
{ format = "{0:output:OffHand.PhysicalMin} to {0:output:OffHand.PhysicalMax}",
{ breakdown = "OffHand.Physical" },
{ label = "Conversions", modType = "BASE", cfg = "weapon2", modName = { "SkillPhysicalDamageConvertToLightning", "SkillPhysicalDamageConvertToCold", "SkillPhysicalDamageConvertToFire", "SkillPhysicalDamageConvertToChaos", "PhysicalDamageConvertToLightning", "PhysicalDamageConvertToCold", "PhysicalDamageConvertToFire", "PhysicalDamageConvertToChaos", "PhysicalDamageGainAsLightning", "PhysicalDamageGainAsCold", "PhysicalDamageGainAsFire", "PhysicalDamageGainAsChaos" } },
},
{ format = "{0:output:OffHand.LightningMin} to {0:output:OffHand.LightningMax}",
{ breakdown = "OffHand.Lightning" },
{ label = "Conversions", modType = "BASE", cfg = "weapon2", modName = { "LightningDamageConvertToCold", "LightningDamageConvertToFire", "LightningDamageConvertToChaos", "LightningDamageGainAsCold", "LightningDamageGainAsFire", "LightningDamageGainAsChaos" } },
},
{ format = "{0:output:OffHand.ColdMin} to {0:output:OffHand.ColdMax}",
{ breakdown = "OffHand.Cold" },
{ label = "Conversions", modType = "BASE", cfg = "weapon2", modName = { "SkillColdDamageConvertToFire", "ColdDamageConvertToFire", "ColdDamageConvertToChaos", "ColdDamageGainAsFire", "ColdDamageGainAsChaos" } },
},
{ format = "{0:output:OffHand.FireMin} to {0:output:OffHand.FireMax}",
{ breakdown = "OffHand.Fire" },
{ label = "Conversions", modType = "BASE", cfg = "weapon2", modName = { "FireDamageConvertToChaos", "FireDamageGainAsChaos" } },
},
{ format = "{0:output:OffHand.ChaosMin} to {0:output:OffHand.ChaosMax}",
{ breakdown = "OffHand.Chaos" },
},
},
{ label = "OH Average Hit", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{1:output:OffHand.AverageHit}", { breakdown = "OffHand.AverageHit" }, }, },
{ label = "Average Damage", flag = "attack", { format = "{1:output:AverageDamage}",
{ breakdown = "MainHand.AverageDamage" },
{ breakdown = "OffHand.AverageDamage" },
{ breakdown = "AverageDamage" },
}, },
{ label = "Skill DPS", flag = "notAverage", { format = "{1:output:TotalDPS}", { breakdown = "TotalDPS" }, }, },
{ label = "Mana Cost", { format = "{0:output:ManaCost}", { breakdown = "ManaCost" }, { modName = "ManaCost", cfg = "skill" }, }, },
} },
@@ -144,82 +295,239 @@ return {
} },
{ 1, "Speed", 1, "Attack/Cast Rate", data.colorCodes.OFFENCE, {
extra = "{2:output:Speed}/s",
{ label = "Inc. Attack Speed", flag = "attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "INC", cfg = "skill", }, }, },
{ label = "More Attack Speed", flag = "attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "MORE", cfg = "skill", }, }, },
{ label = "MH Inc. Att. Speed", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "INC", cfg = "weapon1", }, }, },
{ label = "MH More Att. Speed", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "MORE", cfg = "weapon1", }, }, },
{ label = "MH Att. per second", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{2:output:MainHand.Speed}", { breakdown = "MainHand.Speed" }, }, },
{ label = "OH Inc. Att. Speed", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "INC", cfg = "weapon2", }, }, },
{ label = "OH More Att. Speed", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{0:mod:1}%", { modName = "Speed", modType = "MORE", cfg = "weapon2", }, }, },
{ label = "OH Att. per second", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{2:output:OffHand.Speed}", { breakdown = "OffHand.Speed" }, }, },
{ label = "Attacks per second", flag = "bothWeaponAttack", { format = "{2:output:Speed}", { breakdown = "Speed" }, }, },
{ label = "Attack time", flag = "attack", { format = "{2:output:Time}s", }, },
{ label = "Inc. Cast Speed", flag = "spell", { format = "{0:mod:1}%", { modName = "Speed", modType = "INC", cfg = "skill", }, }, },
{ label = "More Cast Speed", flag = "spell", { format = "{0:mod:1}%", { modName = "Speed", modType = "MORE", cfg = "skill", }, }, },
{ label = "Casts per second", flag = "spell", { format = "{2:output:Speed}", { breakdown = "Speed" }, }, },
{ label = "Attacks per second", flag = "attack", { format = "{2:output:Speed}", { breakdown = "Speed" }, }, },
{ label = "Cast time", flag = "spell", { format = "{2:output:Time}s", }, },
{ label = "Attack time", flag = "attack", { format = "{2:output:Time}s", }, },
} },
{ 1, "Crit", 1, "Crits", data.colorCodes.OFFENCE, {
extra = "{2:output:CritChance}% x{2:output:CritMultiplier}",
flag = "hit",
{ label = "Inc. Crit Chance", { format = "{0:mod:1}%", { modName = "CritChance", modType = "INC", cfg = "skill" }, }, },
{ label = "Crit Chance", { format = "{2:output:CritChance}%", { breakdown = "CritChance" }, { label = "Player modifiers", modName = "CritChance", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfExtraCritChance", enemy = true }, }, },
{ label = "Crit Multiplier", { format = "x {2:output:CritMultiplier}", { breakdown = "CritMultiplier" }, { label = "Player modifiers", modName = "CritMultiplier", cfg = "skill"}, { label = "Enemy modifiers", modName = "SelfCritMultiplier", enemy = true }, }, },
{ label = "Crit Effect Mod", { format = "x {3:output:CritEffect}", { breakdown = "CritEffect" }, }, },
-- Skill
{ label = "Inc. Crit Chance", notFlag = "attack", { format = "{0:mod:1}%", { modName = "CritChance", modType = "INC", cfg = "skill" }, }, },
{ label = "Crit Chance", notFlag = "attack", { format = "{2:output:CritChance}%",
{ breakdown = "CritChance" },
{ label = "Player modifiers", modName = "CritChance", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfExtraCritChance", enemy = true },
}, },
{ label = "Crit Multiplier", notFlag = "attack", { format = "x {2:output:CritMultiplier}",
{ breakdown = "CritMultiplier" },
{ label = "Player modifiers", modName = "CritMultiplier", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfCritMultiplier", enemy = true },
}, },
{ label = "Crit Effect Mod", notFlag = "attack", { format = "x {3:output:CritEffect}", { breakdown = "CritEffect" }, }, },
-- Main Hand
{ label = "MH Inc. Crit Chance", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{0:mod:1}%", { modName = "CritChance", modType = "INC", cfg = "weapon1" }, }, },
{ label = "MH Crit Chance", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{2:output:MainHand.CritChance}%",
{ breakdown = "MainHand.CritChance" },
{ label = "Player modifiers", modName = "CritChance", cfg = "weapon1" },
{ label = "Enemy modifiers", modName = "SelfExtraCritChance", enemy = true },
}, },
{ label = "MH Crit Multiplier", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "x {2:output:MainHand.CritMultiplier}",
{ breakdown = "MainHand.CritMultiplier" },
{ label = "Player modifiers", modName = "CritMultiplier", cfg = "weapon1" },
{ label = "Enemy modifiers", modName = "SelfCritMultiplier", enemy = true },
}, },
{ label = "MH Crit Effect Mod", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "x {3:output:MainHand.CritEffect}", { breakdown = "MainHand.CritEffect" }, }, },
-- Off Hand
{ label = "OH Inc. Crit Chance", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{0:mod:1}%", { modName = "CritChance", modType = "INC", cfg = "weapon2" }, }, },
{ label = "OH Crit Chance", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{2:output:OffHand.CritChance}%",
{ breakdown = "OffHand.CritChance" },
{ label = "Player modifiers", modName = "CritChance", cfg = "weapon2" },
{ label = "Enemy modifiers", modName = "SelfExtraCritChance", enemy = true },
}, },
{ label = "OH Crit Multiplier", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "x {2:output:OffHand.CritMultiplier}",
{ breakdown = "OffHand.CritMultiplier" },
{ label = "Player modifiers", modName = "CritMultiplier", cfg = "weapon2" },
{ label = "Enemy modifiers", modName = "SelfCritMultiplier", enemy = true },
}, },
{ label = "OH Crit Effect Mod", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "x {3:output:OffHand.CritEffect}", { breakdown = "OffHand.CritEffect" }, }, },
} },
{ 1, "HitChance", 1, "Accuracy", data.colorCodes.OFFENCE, {
extra = "{0:output:HitChance}%",
flag = "attack",
{ label = "Accuracy", { format = "{0:output:Accuracy}", { breakdown = "Accuracy" }, { modName = "Accuracy", cfg = "skill" }, }, },
{ label = "Chance to Hit", { format = "{0:output:HitChance}%", { breakdown = "HitChance" }, { label = "Enemy Evasion modifiers", modName = "Evasion", enemy = true }, }, },
{ label = "MH Accuracy", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{0:output:MainHand.Accuracy}",
{ breakdown = "MainHand.Accuracy" },
{ modName = "Accuracy", cfg = "weapon1" },
}, },
{ label = "MH Chance to Hit", bgCol = data.colorCodes.MAINHANDBG, flag = "weapon1Attack", { format = "{0:output:MainHand.HitChance}%",
{ breakdown = "MainHand.HitChance" },
{ label = "Enemy Evasion modifiers", modName = "Evasion", enemy = true },
}, },
{ label = "OH Accuracy", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{0:output:OffHand.Accuracy}",
{ breakdown = "OffHand.Accuracy" },
{ modName = "Accuracy", cfg = "weapon2" },
}, },
{ label = "OH Chance to Hit", bgCol = data.colorCodes.OFFHANDBG, flag = "weapon2Attack", { format = "{0:output:OffHand.HitChance}%",
{ breakdown = "OffHand.HitChance" },
{ label = "Enemy Evasion modifiers", modName = "Evasion", enemy = true },
}, },
} },
{ 1, "SkillTypeStats", 1, "Skill type-specific Stats", data.colorCodes.OFFENCE, {
{ label = "Duration Mod", flag = "duration", { format = "x {2:output:DurationMod}", { breakdown = "DurationMod"}, { modName = "Duration", cfg = "skill" }, }, },
{ label = "Duration Mod", flag = "duration", { format = "x {2:output:DurationMod}",
{ breakdown = "DurationMod"},
{ modName = "Duration", cfg = "skill" },
}, },
{ label = "Skill Duration", flag = "duration", { format = "{2:output:Duration}s", { breakdown = "Duration" }, }, },
{ label = "Projectile Count", flag = "projectile", { format = "{0:output:ProjectileCount}", { modName = "ProjectileCount", cfg = "skill" }, }, },
{ label = "Pierce Chance", flag = "projectile", { format = "{0:output:PierceChance}%", { modName = "PierceChance", cfg = "skill" }, }, },
{ label = "Proj. Speed Mod", flag = "projectile", { format = "x {2:output:ProjectileSpeedMod}", { breakdown = "ProjectileSpeedMod" }, { modName = "ProjectileSpeed", cfg = "skill" }, }, },
{ label = "Area Radius Mod", flag = "area", { format = "x {2:output:AreaRadiusMod}", { breakdown = "AreaRadiusMod" }, { modName = "AreaRadius", cfg = "skill" }, }, },
{ label = "Proj. Speed Mod", flag = "projectile", { format = "x {2:output:ProjectileSpeedMod}",
{ breakdown = "ProjectileSpeedMod" },
{ modName = "ProjectileSpeed", cfg = "skill" },
}, },
{ label = "Area Radius Mod", flag = "area", { format = "x {2:output:AreaRadiusMod}",
{ breakdown = "AreaRadiusMod" },
{ modName = "AreaRadius", cfg = "skill" },
}, },
{ label = "Active Trap Limit", flag = "trap", { format = "{0:output:ActiveTrapLimit}", { modName = "ActiveTrapLimit", cfg = "skill" }, }, },
{ label = "Trap Cooldown", flag = "trap", { format = "{2:output:TrapCooldown}s", { breakdown = "TrapCooldown" }, { modName = "TrapCooldownRecovery", cfg = "skill" }, }, },
{ label = "Trap Cooldown", flag = "trap", { format = "{2:output:TrapCooldown}s",
{ breakdown = "TrapCooldown" },
{ modName = "TrapCooldownRecovery", cfg = "skill" },
}, },
{ label = "Active Mine Limit", flag = "mine", { format = "{0:output:ActiveMineLimit}", { modName = "ActiveMineLimit", cfg = "skill" }, }, },
{ label = "Active Totem Limit", flag = "totem", { format = "{0:output:ActiveTotemLimit}", { modName = "ActiveTotemLimit", cfg = "skill" }, }, },
{ label = "Totem Life Mod", flag = "totem", { format = "x {2:output:TotemLifeMod}", { breakdown = "TotemLifeMod" }, { modName = "TotemLife", cfg = "skill" }, }, },
{ label = "Totem Life Mod", flag = "totem", { format = "x {2:output:TotemLifeMod}",
{ breakdown = "TotemLifeMod" },
{ modName = "TotemLife", cfg = "skill" },
}, },
{ label = "Totem Life", flag = "totem", { format = "{0:output:TotemLife}", { breakdown = "TotemLife" }, }, },
} },
{ 1, "Bleed", 1, "Bleed", data.colorCodes.OFFENCE, {
extra = "{0:output:BleedChance}% {1:output:BleedDPS} {2:output:BleedDuration}s",
flag = "bleed",
{ label = "Chance to Bleed", { format = "{0:output:BleedChance}%", { breakdown = "BleedChance" }, { modName = "BleedChance", cfg = "skill" }, }, },
{ label = "Chance to Bleed", { format = "{0:output:BleedChance}%",
{ breakdown = "MainHand.BleedChance" },
{ breakdown = "OffHand.BleedChance" },
{ breakdown = "BleedChance" },
{ label = "Main Hand", flag = "weapon1Attack", modName = "BleedChance", modType = "BASE", cfg = "weapon1" },
{ label = "Off Hand", flag = "weapon2Attack", modName = "BleedChance", modType = "BASE", cfg = "weapon2" },
}, },
{ label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Damage", "PhysicalDamage" }, modType = "INC", cfg = "bleed" }, }, },
{ label = "Total More", { format = "{0:mod:1}%", { modName = { "Damage", "PhysicalDamage" }, modType = "MORE", cfg = "bleed" }, }, },
{ label = "Effective DPS Mod", flag = "effective", { format = "x {3:output:BleedEffMult}", { breakdown = "BleedEffMult" }, { label = "Enemy modifiers", modName = { "DamageTaken", "DotTaken", "PhysicalDamageTaken", "PhysicalDamageReduction" }, enemy = true }, }, },
{ label = "Bleed DPS", { format = "{1:output:BleedDPS}", { breakdown = "BleedDPS" }, }, },
{ label = "Bleed Duration", { format = "{2:output:BleedDuration}s", { breakdown = "BleedDuration" }, }, },
{ label = "Bleed DPS", { format = "{1:output:BleedDPS}", { breakdown = "BleedDPS" }, { breakdown = "MainHand.BleedDPS" }, { breakdown = "OffHand.BleedDPS" }, }, },
{ label = "Bleed Duration", { format = "{2:output:BleedDuration}s", { breakdown = "BleedDuration" }, { modName = "Duration", cfg = "bleed" }, }, },
} },
{ 1, "Poison", 1, "Poison", data.colorCodes.OFFENCE, {
extra = "{0:output:PoisonChance}% {1:output:PoisonDPS} {2:output:PoisonDuration}s",
flag = "poison",
{ label = "Chance to Poison", { format = "{0:output:PoisonChance}%", { breakdown = "PoisonChance" }, { modName = "PoisonChance", cfg = "skill" }, }, },
{ label = "Chance to Poison", { format = "{0:output:PoisonChance}%",
{ breakdown = "MainHand.PoisonChance" },
{ breakdown = "OffHand.PoisonChance" },
{ breakdown = "PoisonChance" },
{ notFlag = "attack", modName = "PoisonChance", modType = "BASE", cfg = "skill" },
{ label = "Main Hand", flag = "weapon1Attack", modName = "PoisonChance", modType = "BASE", cfg = "weapon1" },
{ label = "Off Hand", flag = "weapon2Attack", modName = "PoisonChance", modType = "BASE", cfg = "weapon2" },
}, },
{ label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Damage", "ChaosDamage" }, modType = "INC", cfg = "poison" }, }, },
{ label = "Total More", { format = "{0:mod:1}%", { modName = { "Damage", "ChaosDamage" }, modType = "MORE", cfg = "poison" }, }, },
{ label = "Effective DPS Mod", flag = "effective", { format = "x {3:output:PoisonEffMult}", { breakdown = "PoisonEffMult" }, { label = "Enemy modifiers", modName = { "ChaosResist", "DamageTaken", "DotTaken", "ChaosDamageTaken" }, enemy = true }, }, },
{ label = "Poison DPS", { format = "{1:output:PoisonDPS}", { breakdown = "PoisonDPS" }, }, },
{ label = "Poison Duration", { format = "{2:output:PoisonDuration}s", { breakdown = "PoisonDuration" }, }, },
{ label = "Dmg. per Poison", { format = "{1:output:PoisonDamage}", { breakdown = "PoisonDamage" }, }, },
{ label = "Effective DPS Mod", flag = "effective", { format = "x {3:output:PoisonEffMult}",
{ breakdown = "PoisonEffMult" },
{ label = "Enemy modifiers", modName = { "ChaosResist", "DamageTaken", "DotTaken", "ChaosDamageTaken" }, enemy = true },
}, },
{ label = "Poison DPS", { format = "{1:output:PoisonDPS}",
{ breakdown = "PoisonDPS" },
{ breakdown = "MainHand.PoisonDPS" },
{ breakdown = "OffHand.PoisonDPS" },
}, },
{ label = "Poison Duration", { format = "{2:output:PoisonDuration}s",
{ breakdown = "PoisonDuration" },
{ modName = "Duration", cfg = "poison" },
}, },
{ label = "Dmg. per Poison", { format = "{1:output:PoisonDamage}",
{ breakdown = "MainHand.PoisonDamage" },
{ breakdown = "OffHand.PoisonDamage" },
{ breakdown = "PoisonDamage" },
}, },
} },
{ 1, "Ignite", 1, "Ignite", data.colorCodes.OFFENCE, {
extra = "{0:output:IgniteChance}% {1:output:IgniteDPS} {2:output:IgniteDuration}s",
flag = "ignite",
{ label = "Chance to Ignite", { format = "{0:output:IgniteChance}%", { breakdown = "IgniteChance" }, { label = "Player modifiers", modName = "EnemyIgniteChance", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfIgniteChance", enemy = true }, }, },
{ label = "Chance to Ignite", { format = "{0:output:IgniteChance}%",
{ breakdown = "MainHand.IgniteChance" },
{ breakdown = "OffHand.IgniteChance" },
{ breakdown = "IgniteChance" },
{ label = "Player modifiers", modName = "EnemyIgniteChance", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfIgniteChance", enemy = true },
}, },
{ label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Damage", "FireDamage", "ElementalDamage" }, modType = "INC", cfg = "ignite" }, }, },
{ label = "Total More", { format = "{0:mod:1}%", { modName = { "Damage", "FireDamage", "ElementalDamage" }, modType = "MORE", cfg = "ignite" }, }, },
{ label = "Effective DPS Mod", flag = "effective", { format = "x {3:output:IgniteEffMult}", { breakdown = "IgniteEffMult" }, { label = "Enemy modifiers", modName = { "FireResist", "ElementalResist", "DamageTaken", "DotTaken", "FireDamageTaken", "BurningDamageTaken", "ElementalDamageTaken" }, enemy = true }, }, },
{ label = "Ignite DPS", { format = "{1:output:IgniteDPS}", { breakdown = "IgniteDPS" }, { modName = { "IgniteBurnRate" }, cfg = "skill" }, }, },
{ label = "Ignite Duration", { format = "{2:output:IgniteDuration}s", { breakdown = "IgniteDuration" }, { label = "Player modifiers", modName = "EnemyIgniteDuration", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfIgniteDuration", enemy = true }, }, },
{ label = "Dmg. per Ignite", flag = "igniteCanStack", { format = "{1:output:IgniteDamage}", { breakdown = "IgniteDamage" }, }, },
{ label = "Effective DPS Mod", flag = "effective", { format = "x {3:output:IgniteEffMult}",
{ breakdown = "IgniteEffMult" },
{ label = "Enemy modifiers", modName = { "FireResist", "ElementalResist", "DamageTaken", "DotTaken", "FireDamageTaken", "BurningDamageTaken", "ElementalDamageTaken" }, enemy = true },
}, },
{ label = "Ignite DPS", { format = "{1:output:IgniteDPS}",
{ breakdown = "IgniteDPS" },
{ breakdown = "MainHand.IgniteDPS" },
{ breakdown = "OffHand.IgniteDPS" },
{ modName = { "IgniteBurnRate" }, cfg = "skill" },
}, },
{ label = "Ignite Duration", { format = "{2:output:IgniteDuration}s",
{ breakdown = "IgniteDuration" },
{ label = "Player modifiers", modName = "EnemyIgniteDuration", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfIgniteDuration", enemy = true },
}, },
{ label = "Dmg. per Ignite", flag = "igniteCanStack", { format = "{1:output:IgniteDamage}",
{ breakdown = "MainHand.IgniteDamage" },
{ breakdown = "OffHand.IgniteDamage" },
{ breakdown = "IgniteDamage" },
}, },
} },
{ 1, "MiscEffects", 1, "Other Effects", data.colorCodes.OFFENCE, {
{ label = "Chance to Shock", flag = "shock", { format = "{0:output:ShockChance}%", { breakdown = "ShockChance" }, { label = "Player modifiers", modName = "EnemyShockChance", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfShockChance", enemy = true }, }, },
{ label = "Shock Dur. Mod", flag = "shock", { format = "x {2:output:ShockDurationMod}", { breakdown = "ShockDPS" }, { label = "Player modifiers", modName = "EnemyShockDuration", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfShockDuration", enemy = true }, }, },
{ label = "Chance to Freeze", flag = "freeze", { format = "{0:output:FreezeChance}%", { breakdown = "FreezeChance" }, { label = "Player modifiers", modName = "EnemyFreezeChance", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfFreezeChance", enemy = true }, }, },
{ label = "Freeze Dur. Mod", flag = "freeze", { format = "x {2:output:FreezeDurationMod}", { breakdown = "FreezeDPS" }, { label = "Player modifiers", modName = "EnemyFreezeDuration", cfg = "skill" }, { label = "Enemy modifiers", modName = "SelfFreezeDuration", enemy = true }, }, },
{ label = "Stun Thresh. Mod", flag = "hit", { format = "x {2:output:EnemyStunThresholdMod}", { modName = "EnemyStunThreshold", cfg = "skill" }, }, },
{ label = "Stun Duration", flag = "hit", { format = "{2:output:EnemyStunDuration}s", { breakdown = "EnemyStunDuration" }, { label = "Player modifiers", modName = { "EnemyStunDuration" }, cfg = "skill" }, { label = "Enemy modifiers", modName = { "StunRecovery" }, enemy = true }, }, },
{ label = "Chance to Shock", flag = "shock", { format = "{0:output:ShockChance}%",
{ breakdown = "MainHand.ShockChance" },
{ breakdown = "OffHand.ShockChance" },
{ breakdown = "ShockChance" },
{ label = "Player modifiers", modName = "EnemyShockChance", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfShockChance", enemy = true },
}, },
{ label = "Shock Dur. Mod", flag = "shock", { format = "x {2:output:ShockDurationMod}",
{ breakdown = "MainHand.ShockDPS" },
{ breakdown = "OffHand.ShockDPS" },
{ breakdown = "ShockDPS" },
{ label = "Player modifiers", modName = "EnemyShockDuration", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfShockDuration", enemy = true },
}, },
{ label = "Chance to Freeze", flag = "freeze", { format = "{0:output:FreezeChance}%",
{ breakdown = "MainHand.FreezeChance" },
{ breakdown = "OffHand.FreezeChance" },
{ breakdown = "FreezeChance" },
{ label = "Player modifiers", modName = "EnemyFreezeChance", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfFreezeChance", enemy = true },
}, },
{ label = "Freeze Dur. Mod", flag = "freeze", { format = "x {2:output:FreezeDurationMod}",
{ breakdown = "MainHand.FreezeDPS" },
{ breakdown = "OffHand.FreezeDPS" },
{ breakdown = "FreezeDPS" },
{ label = "Player modifiers", modName = "EnemyFreezeDuration", cfg = "skill" },
{ label = "Enemy modifiers", modName = "SelfFreezeDuration", enemy = true },
}, },
{ label = "Stun Threshold", flag = "hit", notFlag = "attack", { format = "x {2:output:EnemyStunThresholdMod}", { modName = "EnemyStunThreshold", cfg = "skill" }, }, },
{ label = "Stun Duration", flag = "hit", notFlag = "attack", { format = "{2:output:EnemyStunDuration}s",
{ breakdown = "EnemyStunDuration" },
{ label = "Player modifiers", modName = { "EnemyStunDuration" }, cfg = "skill" },
{ label = "Enemy modifiers", modName = { "StunRecovery" }, enemy = true },
}, },
{ label = "MH Stun Threshold", bgCol = data.colorCodes.MAINHANDBG, flagList = {"hit","weapon1Attack"}, { format = "x {2:output:MainHand.EnemyStunThresholdMod}", { modName = "EnemyStunThreshold", cfg = "weapon1" }, }, },
{ label = "MH Stun Duration", bgCol = data.colorCodes.MAINHANDBG, flagList = {"hit","weapon1Attack"}, { format = "{2:output:MainHand.EnemyStunDuration}s",
{ breakdown = "MainHand.EnemyStunDuration" },
{ label = "Player modifiers", modName = { "EnemyStunDuration" }, cfg = "weapon1" },
{ label = "Enemy modifiers", modName = { "StunRecovery" }, enemy = true },
}, },
{ label = "OH Stun Threshold", bgCol = data.colorCodes.OFFHANDBG, flagList = {"hit","weapon2Attack"}, { format = "x {2:output:OffHand.EnemyStunThresholdMod}", { modName = "EnemyStunThreshold", cfg = "weapon2" }, }, },
{ label = "OH Stun Duration", bgCol = data.colorCodes.OFFHANDBG, flagList = {"hit","weapon2Attack"}, { format = "{2:output:OffHand.EnemyStunDuration}s",
{ breakdown = "OffHand.EnemyStunDuration" },
{ label = "Player modifiers", modName = { "EnemyStunDuration" }, cfg = "weapon2" },
{ label = "Enemy modifiers", modName = { "StunRecovery" }, enemy = true },
}, },
{ label = "Inc. Item Quantity", { format = "{0:mod:1}%", { modName = "LootQuantity", modType = "INC", cfg = "skill" }, }, },
{ label = "Inc. Item Rarity", { format = "{0:mod:1}%", { modName = "LootRarity", modType = "INC", cfg = "skill" }, }, },
} },
@@ -261,8 +569,14 @@ return {
{ label = "Total Increased", { format = "{0:mod:1}%", { modName = { "EnergyShield", "Defences" }, modType = "INC" }, }, },
{ label = "Total More", { format = "{0:mod:1}%", { modName = { "EnergyShield", "Defences" }, modType = "MORE" }, }, },
{ label = "Total", { format = "{0:output:EnergyShield}", { breakdown = "EnergyShield" }, }, },
{ label = "Recharge Rate", { format = "{1:output:EnergyShieldRecharge}", { breakdown = "EnergyShieldRecharge" }, { modName = { "EnergyShieldRecharge", "EnergyShieldRecovery" }, }, }, },
{ label = "Recharge Delay", { format = "{2:output:EnergyShieldRechargeDelay}s", { breakdown = "EnergyShieldRechargeDelay" }, { modName = "EnergyShieldRechargeFaster" }, }, },
{ label = "Recharge Rate", { format = "{1:output:EnergyShieldRecharge}",
{ breakdown = "EnergyShieldRecharge" },
{ modName = { "EnergyShieldRecharge", "EnergyShieldRecovery" }, },
}, },
{ label = "Recharge Delay", { format = "{2:output:EnergyShieldRechargeDelay}s",
{ breakdown = "EnergyShieldRechargeDelay" },
{ modName = "EnergyShieldRechargeFaster" },
}, },
{ label = "Regen", { format = "{1:output:EnergyShieldRegen} ({1:output:EnergyShieldRegenPercent}%)", { modName = { "EnergyShieldRegen", "EnergyShieldRegenPercent", "EnergyShieldRecovery" }, modType = "BASE" }, }, },
} },
{ 1, "Armour", 3, "Armour", data.colorCodes.DEFENCE, {
@@ -282,22 +596,50 @@ return {
{ label = "Total Increased", { format = "{0:mod:1}%", { modName = { "Evasion", "ArmourAndEvasion", "Defences" }, modType = "INC" }, }, },
{ label = "Total More", { format = "{0:mod:1}%", { modName = { "Evasion", "ArmourAndEvasion", "Defences" }, modType = "MORE" }, }, },
{ label = "Total", { format = "{0:output:Evasion}", { breakdown = "Evasion" }, }, },
{ label = "Evade Chance", { format = "{0:output:EvadeChance}%", { breakdown = "EvadeChance" }, { modName = { "CannotEvade" } }, { label = "Enemy Accuracy modifiers", modName = "Accuracy", enemy = true }, }, },
{ label = "Evade Chance", { format = "{0:output:EvadeChance}%",
{ breakdown = "EvadeChance" },
{ modName = { "CannotEvade" } },
{ label = "Enemy Accuracy modifiers", modName = "Accuracy", enemy = true },
}, },
} },
{ 1, "Resist", 3, "Resists", data.colorCodes.DEFENCE, {
extra = data.colorCodes.FIRE.."{0:output:FireResist}+{0:output:FireResistOverCap}^7/"..data.colorCodes.COLD.."{0:output:ColdResist}+{0:output:ColdResistOverCap}^7/"..data.colorCodes.LIGHTNING.."{0:output:LightningResist}+{0:output:LightningResistOverCap}",
{ label = "Fire Resist", { format = "{0:output:FireResist}% (+{0:output:FireResistOverCap}%)", { breakdown = "FireResist" }, { modName = { "FireResistMax", "FireResist", "ElementalResist" }, }, }, },
{ label = "Cold Resist", { format = "{0:output:ColdResist}% (+{0:output:ColdResistOverCap}%)", { breakdown = "ColdResist" }, { modName = { "ColdResistMax", "ColdResist", "ElementalResist" }, }, }, },
{ label = "Lightning Resist", { format = "{0:output:LightningResist}% (+{0:output:LightningResistOverCap}%)", { breakdown = "LightningResist" }, { modName = { "LightningResistMax", "LightningResist", "ElementalResist" }, }, }, },
{ label = "Chaos Resist", { format = "{0:output:ChaosResist}% (+{0:output:ChaosResistOverCap}%)", { breakdown = "ChaosResist" }, { modName = { "ChaosResistMax", "ChaosResist" }, }, }, },
{ label = "Fire Resist", { format = "{0:output:FireResist}% (+{0:output:FireResistOverCap}%)",
{ breakdown = "FireResist" },
{ modName = { "FireResistMax", "FireResist", "ElementalResist" }, },
}, },
{ label = "Cold Resist", { format = "{0:output:ColdResist}% (+{0:output:ColdResistOverCap}%)",
{ breakdown = "ColdResist" },
{ modName = { "ColdResistMax", "ColdResist", "ElementalResist" }, },
}, },
{ label = "Lightning Resist", { format = "{0:output:LightningResist}% (+{0:output:LightningResistOverCap}%)",
{ breakdown = "LightningResist" },
{ modName = { "LightningResistMax", "LightningResist", "ElementalResist" }, },
}, },
{ label = "Chaos Resist", { format = "{0:output:ChaosResist}% (+{0:output:ChaosResistOverCap}%)",
{ breakdown = "ChaosResist" },
{ modName = { "ChaosResistMax", "ChaosResist" }, },
}, },
} },
{ 1, "MiscDefences", 3, "Other Defences", data.colorCodes.DEFENCE, {
{ label = "Dodge Chance", { format = "{0:output:AttackDodgeChance}%", { modName = "AttackDodgeChance" }, }, },
{ label = "Spell Ddg. Chance", { format = "{0:output:SpellDodgeChance}%", { modName = "SpellDodgeChance" }, }, },
{ label = "Block Chance", { format = "{0:output:BlockChance}%", { breakdown = "BlockChance" }, { modName = "BlockChance" }, }, },
{ label = "Spell Block Chance", { format = "{0:output:SpellBlockChance}%", { breakdown = "SpellBlockChance" }, { modName = { "SpellBlockChance", "BlockChanceConv" }, }, }, },
{ label = "Block Chance", { format = "{0:output:BlockChance}%",
{ breakdown = "BlockChance" },
{ modName = "BlockChance" },
}, },
{ label = "Spell Block Chance", { format = "{0:output:SpellBlockChance}%",
{ breakdown = "SpellBlockChance" },
{ modName = { "SpellBlockChance", "BlockChanceConv" }, },
}, },
{ label = "Stun Avoid Chance", { format = "{0:output:StunAvoidChance}%", { modName = "AvoidStun" }, }, },
{ label = "Stun Duration", { format = "{2:output:StunDuration}s", { breakdown = "StunDuration" }, { modName = "StunRecovery" }, }, },
{ label = "Block Duration", { format = "{2:output:BlockDuration}s", { breakdown = "BlockDuration" }, { modName = { "StunRecovery", "BlockRecovery" }, }, }, },
{ label = "Stun Duration", { format = "{2:output:StunDuration}s",
{ breakdown = "StunDuration" },
{ modName = "StunRecovery" },
}, },
{ label = "Block Duration", { format = "{2:output:BlockDuration}s",
{ breakdown = "BlockDuration" },
{ modName = { "StunRecovery", "BlockRecovery" }, },
}, },
} },
}

File diff suppressed because it is too large Load Diff

View File

@@ -181,6 +181,10 @@ data.colorCodes = {
DUELIST = "^xE0E070",
TEMPLAR = "^xC040FF",
SHADOW = "^x30C0D0",
MAINHAND = "^x50FF50",
MAINHANDBG = "^x071907",
OFFHAND = "^xB7B7FF",
OFFHANDBG = "^x070719",
}
data.colorCodes.STRENGTH = data.colorCodes.MARAUDER
data.colorCodes.DEXTERITY = data.colorCodes.RANGER

View File

@@ -323,12 +323,13 @@ end
-- Add up local modifiers, and removes them from the modifier list
-- To be considered local, a modifier must be an exact flag match, and cannot have any tags (e.g conditions, multipliers)
-- Only the InSlot tag is allowed (for Adds x to x X Damage in X Hand modifiers)
local function sumLocal(modList, name, type, flags)
local result = 0
local i = 1
while modList[i] do
local mod = modList[i]
if mod.name == name and mod.type == type and mod.flags == flags and mod.keywordFlags == 0 and not mod.tagList[1] then
if mod.name == name and mod.type == type and mod.flags == flags and mod.keywordFlags == 0 and (not mod.tagList[1] or mod.tagList[1].type == "InSlot") then
result = result + mod.value
t_remove(modList, i)
else
@@ -349,7 +350,7 @@ function itemLib.buildItemModListForSlotNum(item, baseList, slotNum)
local mod = copyTable(baseMod)
local add = true
for _, tag in pairs(mod.tagList) do
if tag.type == "SlotNumber" then
if tag.type == "SlotNumber" or tag.type == "InSlot" then
if tag.num ~= slotNum then
add = false
break
@@ -371,14 +372,14 @@ function itemLib.buildItemModListForSlotNum(item, baseList, slotNum)
weaponData.type = item.base.type
weaponData.name = item.name
weaponData.AttackSpeedInc = sumLocal(modList, "Speed", "INC", ModFlag.Attack)
weaponData.attackRate = m_floor(item.base.weapon.attackRateBase * (1 + weaponData.AttackSpeedInc / 100) * 100 + 0.5) / 100
weaponData.attackRate = round(item.base.weapon.attackRateBase * (1 + weaponData.AttackSpeedInc / 100), 2)
for _, dmgType in pairs(dmgTypeList) do
local min = (item.base.weapon[dmgType.."Min"] or 0) + sumLocal(modList, dmgType.."Min", "BASE", ModFlag.Attack)
local max = (item.base.weapon[dmgType.."Max"] or 0) + sumLocal(modList, dmgType.."Max", "BASE", ModFlag.Attack)
local min = (item.base.weapon[dmgType.."Min"] or 0) + sumLocal(modList, dmgType.."Min", "BASE", 0)
local max = (item.base.weapon[dmgType.."Max"] or 0) + sumLocal(modList, dmgType.."Max", "BASE", 0)
if dmgType == "Physical" then
local physInc = sumLocal(modList, "PhysicalDamage", "INC", 0)
min = m_floor(min * (1 + (physInc + item.quality) / 100) + 0.5)
max = m_floor(max * (1 + (physInc + item.quality) / 100) + 0.5)
min = round(min * (1 + (physInc + item.quality) / 100))
max = round(max * (1 + (physInc + item.quality) / 100))
end
if min > 0 and max > 0 then
weaponData[dmgType.."Min"] = min
@@ -390,12 +391,18 @@ function itemLib.buildItemModListForSlotNum(item, baseList, slotNum)
end
end
end
weaponData.critChance = m_floor(item.base.weapon.critChanceBase * (1 + sumLocal(modList, "CritChance", "INC", 0) / 100) * 100 + 0.5) / 100
weaponData.critChance = round(item.base.weapon.critChanceBase * (1 + sumLocal(modList, "CritChance", "INC", 0) / 100), 2)
for _, value in ipairs(modList:Sum("LIST", nil, "Misc")) do
if value.type == "WeaponData" then
weaponData[value.key] = value.value
end
end
for _, mod in ipairs(modList) do
-- Convert accuracy modifiers to local
if mod.name == "Accuracy" and mod.flags == 0 and mod.keywordFlags == 0 and not mod.tagList[1] then
mod.tagList[1] = { type = "Condition", var = (slotNum == 1) and "MainHandAttack" or "OffHandAttack" }
end
end
weaponData.TotalDPS = 0
for _, dmgType in pairs(dmgTypeList) do
weaponData.TotalDPS = weaponData.TotalDPS + (weaponData[dmgType.."DPS"] or 0)
@@ -412,9 +419,9 @@ function itemLib.buildItemModListForSlotNum(item, baseList, slotNum)
local energyShieldInc = sumLocal(modList, "EnergyShield", "INC", 0)
local armourEnergyShieldInc = sumLocal(modList, "ArmourAndEnergyShield", "INC", 0)
local defencesInc = sumLocal(modList, "Defences", "INC", 0)
armourData.Armour = m_floor(armourBase * (1 + (armourInc + armourEvasionInc + armourEnergyShieldInc + defencesInc + item.quality) / 100) + 0.5)
armourData.Evasion = m_floor(evasionBase * (1 + (evasionInc + armourEvasionInc + evasionEnergyShieldInc + defencesInc + item.quality) / 100) + 0.5)
armourData.EnergyShield = m_floor(energyShieldBase * (1 + (energyShieldInc + armourEnergyShieldInc + evasionEnergyShieldInc + defencesInc + item.quality) / 100) + 0.5)
armourData.Armour = round(armourBase * (1 + (armourInc + armourEvasionInc + armourEnergyShieldInc + defencesInc + item.quality) / 100))
armourData.Evasion = round(evasionBase * (1 + (evasionInc + armourEvasionInc + evasionEnergyShieldInc + defencesInc + item.quality) / 100))
armourData.EnergyShield = round(energyShieldBase * (1 + (energyShieldInc + armourEnergyShieldInc + evasionEnergyShieldInc + defencesInc + item.quality) / 100))
if item.base.armour.blockChance then
armourData.BlockChance = item.base.armour.blockChance + sumLocal(modList, "BlockChance", "BASE", 0)
end

View File

@@ -33,8 +33,8 @@ local formList = {
["^([%d%.]+) (.+) regenerated per second"] = "REGENFLAT",
["^regenerate ([%d%.]+) (.+) per second"] = "REGENFLAT",
["(%d+) to (%d+) additional (%a+) damage"] = "DMG",
["adds (%d+)%-(%d+) (%a+) damage"] = "DMGATTACKS",
["adds (%d+) to (%d+) (%a+) damage"] = "DMGATTACKS",
["adds (%d+)%-(%d+) (%a+) damage"] = "DMG",
["adds (%d+) to (%d+) (%a+) damage"] = "DMG",
["adds (%d+)%-(%d+) (%a+) damage to attacks"] = "DMGATTACKS",
["adds (%d+) to (%d+) (%a+) damage to attacks"] = "DMGATTACKS",
["adds (%d+)%-(%d+) (%a+) damage to spells"] = "DMGSPELLS",
@@ -114,6 +114,7 @@ local modNameList = {
["block recovery"] = "BlockRecovery",
["enemy stun threshold"] = "EnemyStunThreshold",
["stun duration on enemies"] = "EnemyStunDuration",
["stun duration"] = "EnemyStunDuration",
-- Auras/curses
["effect of non-curse auras you cast"] = "AuraEffect",
["effect of your curses"] = "CurseEffect",
@@ -310,6 +311,7 @@ local preFlagList = {
-- List of modifier tags
local modTagList = {
["on enemies"] = { },
-- Multipliers
["per power charge"] = { tag = { type = "Multiplier", var = "PowerCharge" } },
["per frenzy charge"] = { tag = { type = "Multiplier", var = "FrenzyCharge" } },
@@ -329,10 +331,10 @@ local modTagList = {
["per (%d+)%% block chance"] = function(num) return { tag = { type = "PerStat", stat = "BlockChance", div = num } } end,
["per (%d+) of the lowest of armour and evasion rating"] = function(num) return { tag = { type = "PerStat", stat = "LowestOfArmourAndEvasion", div = num } } end,
-- Slot conditions
["in main hand"] = { tag = { type = "SlotNumber", num = 1 } },
["when in main hand"] = { tag = { type = "SlotNumber", num = 1 } },
["in off hand"] = { tag = { type = "SlotNumber", num = 2 } },
["when in off hand"] = { tag = { type = "SlotNumber", num = 2 } },
["in main hand"] = { tag = { type = "InSlot", num = 1 } },
["in off hand"] = { tag = { type = "InSlot", num = 2 } },
-- Equipment conditions
["while holding a shield"] = { tag = { type = "Condition", var = "UsingShield" } },
["with shields"] = { tag = { type = "Condition", var = "UsingShield" } },
@@ -376,9 +378,9 @@ local modTagList = {
["if you have hit recently"] = { tag = { type = "Condition", var = "HitRecently" } },
["if you've crit recently"] = { tag = { type = "Condition", var = "CritRecently" } },
["if you've dealt a critical strike recently"] = { tag = { type = "Condition", var = "CritRecently" } },
["if you haven't crit recently"] = { tag = { type = "Condition", var = "NotCritRecently" } },
["if you haven't crit recently"] = { tag = { type = "Condition", var = "CritRecently", neg = true } },
["if you've killed recently"] = { tag = { type = "Condition", var = "KilledRecently" } },
["if you haven't killed recently"] = { tag = { type = "Condition", var = "NotKilledRecently" } },
["if you haven't killed recently"] = { tag = { type = "Condition", var = "KilledRecently", neg = true } },
["if you or your totems have killed recently"] = { tag = { type = "Condition", varList = {"KilledRecently","TotemsKilledRecently"} } },
["if you've killed a maimed enemy recently"] = { tagList = { { type = "Condition", var = "KilledRecently" }, { type = "Condition", var = "EnemyMaimed" } } },
["if you've been hit recently"] = { tag = { type = "Condition", var = "BeenHitRecently" } },
@@ -386,8 +388,8 @@ local modTagList = {
["if you were damaged by a hit recently"] = { tag = { type = "Condition", var = "BeenHitRecently" } },
["if you've taken a savage hit recently"] = { tag = { type = "Condition", var = "BeenSavageHitRecently" } },
["if you've blocked recently"] = { tag = { type = "Condition", var = "BlockedRecently" } },
["if you haven't been hit recently"] = { tag = { type = "Condition", var = "NotBeenHitRecently" } },
["if you've taken no damage from hits recently"] = { tag = { type = "Condition", var = "NotBeenHitRecently" } },
["if you haven't been hit recently"] = { tag = { type = "Condition", var = "BeenHitRecently", neg = true } },
["if you've taken no damage from hits recently"] = { tag = { type = "Condition", var = "BeenHitRecently", neg = true } },
["if you've blocked a hit from a unique enemy recently"] = { tag = { type = "Condition", var = "BlockedHitFromUniqueEnemyRecently" } },
["if you've attacked recently"] = { tag = { type = "Condition", var = "AttackedRecently" } },
["if you've cast a spell recently"] = { tag = { type = "Condition", var = "CastSpellRecently" } },
@@ -555,7 +557,7 @@ local specialModList = {
["melee critical strikes cause bleeding"] = { mod("BleedChance", "BASE", 100, nil, ModFlag.Melee, { type = "Condition", var = "CriticalStrike" }) },
["melee critical strikes have (%d+)%% chance to cause bleeding"] = function(num) return { mod("BleedChance", "BASE", num, nil, ModFlag.Melee, { type = "Condition", var = "CriticalStrike" }) } end,
["melee critical strikes have (%d+)%% chance to poison the enemy"] = function(num) return { mod("PoisonChance", "BASE", num, nil, ModFlag.Melee, { type = "Condition", var = "CriticalStrike" }) } end,
["causes bleeding on melee critical strike"] = { mod("BleedChance", "BASE", num, nil, ModFlag.Melee, { type = "Condition", var = "CriticalStrike" }) },
["causes bleeding on melee critical strike"] = { mod("BleedChance", "BASE", 100, nil, ModFlag.Melee, { type = "Condition", var = "CriticalStrike" }) },
["traps and mines deal (%d+)%-(%d+) additional physical damage"] = function(_, min, max) return { mod("PhysicalMin", "BASE", tonumber(min), nil, 0, bor(KeywordFlag.Trap, KeywordFlag.Mine)), mod("PhysicalMax", "BASE", tonumber(max), nil, 0, bor(KeywordFlag.Trap, KeywordFlag.Mine)) } end,
["traps and mines deal (%d+) to (%d+) additional physical damage"] = function(_, min, max) return { mod("PhysicalMin", "BASE", tonumber(min), nil, 0, bor(KeywordFlag.Trap, KeywordFlag.Mine)), mod("PhysicalMax", "BASE", tonumber(max), nil, 0, bor(KeywordFlag.Trap, KeywordFlag.Mine)) } end,
["traps and mines have a (%d+)%% chance to poison on hit"] = function(num) return { mod("PoisonChance", "BASE", num, nil, 0, bor(KeywordFlag.Trap, KeywordFlag.Mine)) } end,
@@ -564,7 +566,7 @@ local specialModList = {
["gain (%d+) armour per grand spectrum"] = function(num) return { mod("Armour", "BASE", num, { type = "Multiplier", var = "GrandSpectrum" }), mod("Misc", "LIST", { type = "Multiplier", var = "GrandSpectrum", value = 1}) } end,
["gain (%d+) mana per grand spectrum"] = function(num) return { mod("Mana", "BASE", num, { type = "Multiplier", var = "GrandSpectrum" }), mod("Misc", "LIST", { type = "Multiplier", var = "GrandSpectrum", value = 1}) } end,
["(%d+)%% increased elemental damage per grand spectrum"] = function(num) return { mod("ElementalDamage", "INC", num, { type = "Multiplier", var = "GrandSpectrum" }), mod("Misc", "LIST", { type = "Multiplier", var = "GrandSpectrum", value = 1}) } end,
["counts as dual wielding"] = { mod("Misc", "LIST", { type = "Condition", var = "DualWielding"}) },
["counts as dual wielding"] = { mod("Misc", "LIST", { type = "WeaponData", key = "countsAsDualWielding", value = true}) },
["counts as all one handed melee weapon types"] = { mod("Misc", "LIST", { type = "WeaponData", key = "countsAsAll1H", value = true }) },
["gain (%d+)%% of bow physical damage as extra damage of each element"] = function(num) return { mod("PhysicalDamageGainAsLightning", "BASE", num, nil, ModFlag.Bow), mod("PhysicalDamageGainAsCold", "BASE", num, nil, ModFlag.Bow), mod("PhysicalDamageGainAsFire", "BASE", num, nil, ModFlag.Bow) } end,
["totems fire (%d+) additional projectiles"] = function(num) return { mod("ProjectileCount", "BASE", num, nil, 0, KeywordFlag.Totem) } end,

View File

@@ -48,6 +48,16 @@ Head over to the [Releases](https://github.com/Openarl/PathOfBuilding/releases)
![ss3](https://cloud.githubusercontent.com/assets/19189971/18089780/f0ff234a-6f04-11e6-8c88-6193fe59a5c4.png)
## Changelog
### 1.2.39 - 2017/02/08
This update adds full support for Dual Wielding:
* DPS calculations for dual wield skills will now use both weapons if they are usable with the skill
* Calculations for bleed, poison and ignite will correctly factor in both weapons
* Dual Strike is now supported
Other changes:
* Importing the passive tree from PoEPlanner links will now work with links created by the latest version of the site
* Fixed error when showing the tooltip for Kondo's Pride
* Various minor tweaks and fixes
### 1.2.38 - 2017/02/05
* Fixed error when hovering over a passive node with a main skill that isn't compatible with the equipped weapons

View File

@@ -1,3 +1,12 @@
VERSION[1.2.39][2017/02/08]
This update adds full support for Dual Wielding:
* DPS calculations for dual wield skills will now use both weapons if they are usable with the skill
* Calculations for bleed, poison and ignite will correctly factor in both weapons
* Dual Strike is now supported
Other changes:
* Importing the passive tree from PoEPlanner links will now work with links created by the latest version of the site
* Fixed error when showing the tooltip for Kondo's Pride
* Various minor tweaks and fixes
VERSION[1.2.38][2017/02/05]
* Fixed error when hovering over a passive node with a main skill that isn't compatible with the equipped weapons
VERSION[1.2.37][2017/02/05]

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<PoBVersion>
<Version number="1.2.38"/>
<Version number="1.2.39"/>
<Source part="program" url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/"/>
<Source part="tree" url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/tree.zip"/>
<Source url="https://raw.githubusercontent.com/Openarl/PathOfBuilding/{branch}/runtime-win32.zip" part="runtime" platform="win32"/>
<File sha1="5ffc5d4ad59c4a165657132a8a3ddb206a64d99f" name="Launch.lua" part="program"/>
<File sha1="d8e42beeb38baabcc197d658e4c0af33419eeff3" name="UpdateCheck.lua" part="program"/>
<File sha1="4f17937f2b37784e169a3792b235f2a0a3961e61" name="UpdateApply.lua" part="program"/>
<File sha1="2914cedd3f105928fa455dc06d0f9f26cd7168ef" name="changelog.txt" part="program"/>
<File sha1="2309363102b712213f31e1eca1af723b0dbd25bf" name="changelog.txt" part="program"/>
<File sha1="231a4fe264d84294427edacbf3e29ec4b301712e" name="Classes/BuildListControl.lua" part="program"/>
<File sha1="47c28993f5653955c9e76714775d87ac22b077da" name="Classes/ButtonControl.lua" part="program"/>
<File sha1="5a4b4930533a97f4d87231a6024b7f48ff0bad89" name="Classes/CalcBreakdownControl.lua" part="program"/>
<File sha1="df7435047e1eb3adf8fd4ee657595229869e30f4" name="Classes/CalcSectionControl.lua" part="program"/>
<File sha1="4d64a07ee57737d4ab0c34958c3205f463417dd7" name="Classes/CalcsTab.lua" part="program"/>
<File sha1="412639a254d0e275d9cc2286c5d76d3b0a9a0e8e" name="Classes/CalcBreakdownControl.lua" part="program"/>
<File sha1="e30db9887e852afc1b149e2ee34cc124bc6d7a0a" name="Classes/CalcSectionControl.lua" part="program"/>
<File sha1="f3ae212fbec31f042c781f9d4b328903548d804b" name="Classes/CalcsTab.lua" part="program"/>
<File sha1="1e0a9766951fb193018c0c12f2da240157571388" name="Classes/CheckBoxControl.lua" part="program"/>
<File sha1="e2686d4209c8a788534fe0ec5edb599f2ed9c917" name="Classes/ConfigTab.lua" part="program"/>
<File sha1="bbb08f183746d6ec023e2bd08fb7a89d365381da" name="Classes/Control.lua" part="program"/>
@@ -26,10 +26,10 @@
<File sha1="dc4977d3ac5655af1c0f6c56bc0b6c3318b19426" name="Classes/ItemSlotControl.lua" part="program"/>
<File sha1="43a66bcb4705c2bd3fb36d35e4b54a4386adcdc0" name="Classes/ItemsTab.lua" part="program"/>
<File sha1="62138c7db82d57d638a16610a26acd0de75d3486" name="Classes/LabelControl.lua" part="program"/>
<File sha1="708d326ee584cc865649b45df3786113553a09e9" name="Classes/ModDB.lua" part="program"/>
<File sha1="c09bb45d6cbfd02497cb280736c06cadcfe84951" name="Classes/ModList.lua" part="program"/>
<File sha1="62a5a9ce8e3bc3000c9c0445e2fca60c0b2e9e8d" name="Classes/ModDB.lua" part="program"/>
<File sha1="c2cc7ad12754df03ec5401df02bce45894bbe3bd" name="Classes/ModList.lua" part="program"/>
<File sha1="9bc0d8791e7825e52070e96e7894d29fad70cf98" name="Classes/NotesTab.lua" part="program"/>
<File sha1="fa28afb94a37bb847a924322d4dd28dff7c7c5df" name="Classes/PassiveSpec.lua" part="program"/>
<File sha1="b6630ae993e53bf220f15ec258f9255c1d5ec897" name="Classes/PassiveSpec.lua" part="program"/>
<File sha1="9a6bce38a62d9c07851cdd095e91f088e37cea4e" name="Classes/PassiveTree.lua" part="program"/>
<File sha1="74a461e57c49d731d8ba61f03bc76d11a2ff599d" name="Classes/PassiveTreeView.lua" part="program"/>
<File sha1="fd75c7a6a55b13163ac4068bbef9cb49a898eb24" name="Classes/PopupDialog.lua" part="program"/>
@@ -42,23 +42,23 @@
<File sha1="a4f9cc96ba474d0a75c768a0eabec92837e027cf" name="Classes/TextListControl.lua" part="program"/>
<File sha1="74e2261bb0803451c80e4eeef83834a7c3930b92" name="Classes/TreeTab.lua" part="program"/>
<File sha1="4b7675c8b4fe71cade7dd3d70793df1ed8022d01" name="Classes/UndoHandler.lua" part="program"/>
<File sha1="53965f8a13b8498b35fd4a33f26fa2b9fbdcb033" name="Modules/Build.lua" part="program"/>
<File sha1="1defc0cee128843fb95dca41a68747780ed41144" name="Modules/Build.lua" part="program"/>
<File sha1="8a07fe01c53b785ebb6256236e781fbaabd36c0e" name="Modules/BuildList.lua" part="program"/>
<File sha1="89daff2cd9c72b5c38b08a9cc27aacf7b7c143be" name="Modules/Calcs.lua" part="program"/>
<File sha1="1655b03fb16360ab85f817b5ac1c48751cccb113" name="Modules/CalcSections.lua" part="program"/>
<File sha1="5bdbf2ef8347e76c7136c398d4caff2abcaf840e" name="Modules/Calcs.lua" part="program"/>
<File sha1="2fb2a3151af2a47765c03b41d543ae834ff36ced" name="Modules/CalcSections.lua" part="program"/>
<File sha1="761af85f3e1c5601fdb790356a09aefe2f5a64e3" name="Modules/Common.lua" part="program"/>
<File sha1="65bf4efe167b1df2f26443936c654f55f76c1708" name="Modules/Data.lua" part="program"/>
<File sha1="786d2dfd1fde410d5319d55b04878c44c26307cf" name="Modules/ItemTools.lua" part="program"/>
<File sha1="0c8db1ddd9ef1e787af243afa3f31911cb7ec72a" name="Modules/Data.lua" part="program"/>
<File sha1="ab3be945b8fcb09b8104b8c6aa7554dff90af94b" name="Modules/ItemTools.lua" part="program"/>
<File sha1="6165a0baf0c7d1cb6adf9bef68bfa9d9d3ad67ec" name="Modules/Main.lua" part="program"/>
<File sha1="c44ac05f704d2129107939d27b53b0237debfcb0" name="Modules/ModParser.lua" part="program"/>
<File sha1="2e53801d2ee00519e0874afe1d43b76ad686fb00" name="Modules/ModParser.lua" part="program"/>
<File sha1="5f93a9d8f58e0d5990a1f84e1ab1d53fbd35fb56" name="Modules/ModTools.lua" part="program"/>
<File sha1="e7ee7e5b6388facb7bf568517ecc401590757df7" name="Assets/ring.png" part="program"/>
<File sha1="9a320bfe629b1cf3f14fc77fbbf2508d0a5b2841" name="Assets/small_ring.png" part="program"/>
<File sha1="24596d013ecc9170990670c4e02f1b38c326db9e" name="Data/New.lua" part="program"/>
<File sha1="0623dabce4ba730d770abfbb0087dc5c9bbce501" name="Data/Rares.lua" part="program"/>
<File sha1="d97ce11bba97c69f0e3db7cf8cbb57d69c38e144" name="Data/Gems/act_dex.lua" part="program"/>
<File sha1="cbbe3cbcc79cdf568c634dbb1e3760322b66315b" name="Data/Gems/act_dex.lua" part="program"/>
<File sha1="ca8311c31a667bab3fb7fbb8803073d5121d1b2b" name="Data/Gems/act_int.lua" part="program"/>
<File sha1="a8a37f6fe29080ebb27e293c0d8d4f605c9114b6" name="Data/Gems/act_str.lua" part="program"/>
<File sha1="967c7ba3c51c6d13f90b8410925ff16bc65be74b" name="Data/Gems/act_str.lua" part="program"/>
<File sha1="fb08097a2a2d5065d98e70a080e1025e85eb3e4c" name="Data/Gems/other.lua" part="program"/>
<File sha1="56d472af3b6da1de572670c06530be247d29d61a" name="Data/Gems/sup_dex.lua" part="program"/>
<File sha1="f7eb18bfadfc93937b42cf57fc1f293190ae3006" name="Data/Gems/sup_int.lua" part="program"/>