diff --git a/Classes/ConfigTab.lua b/Classes/ConfigTab.lua index 311673b9..0e4c1c90 100644 --- a/Classes/ConfigTab.lua +++ b/Classes/ConfigTab.lua @@ -55,6 +55,9 @@ local varList = { { var = "conditionEnemyPoisoned", type = "check", label = "Is the enemy Poisoned?", apply = function(val, modList, enemyModList) modList:NewMod("Misc", "LIST", { type = "Condition", var = "EnemyPoisoned" }, "Config", { type = "Condition", var = "Effective" }) end }, + { var = "conditionEnemyMaimed", type = "check", label = "Is the enemy Maimed?", apply = function(val, modList, enemyModList) + modList:NewMod("Misc", "LIST", { type = "Condition", var = "EnemyMaimed" }, "Config", { type = "Condition", var = "Effective" }) + end }, { var = "conditionEnemyBurning", type = "check", label = "Is the enemy Burning?", apply = function(val, modList, enemyModList) modList:NewMod("Misc", "LIST", { type = "Condition", var = "EnemyBurning" }, "Config", { type = "Condition", var = "Effective" }) end }, diff --git a/Data/Gems/act_int.lua b/Data/Gems/act_int.lua index 8cfb3c9d..c7a6223a 100644 --- a/Data/Gems/act_int.lua +++ b/Data/Gems/act_int.lua @@ -208,7 +208,7 @@ gems["Assassin's Mark"] = { skillTypes = { [2] = true, [11] = true, [12] = true, [17] = true, [18] = true, [19] = true, [26] = true, [32] = true, [36] = true, }, baseMods = { skill("castTime", 0.5), - --"base_self_critical_strike_multiplier_-%" = -20 + mod("SelfCritMultiplier", "INC", 20, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), --"base_self_critical_strike_multiplier_-%" = -20 --"base_deal_no_damage" = ? skill("debuff", true), }, diff --git a/Modules/CalcSections.lua b/Modules/CalcSections.lua index 65e75996..a978fdae 100644 --- a/Modules/CalcSections.lua +++ b/Modules/CalcSections.lua @@ -157,8 +157,8 @@ return { 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" }, { modName = "CritChance", cfg = "skill" }, }, }, - { label = "Crit Multiplier", { format = "x {2:output:CritMultiplier}", { modName = "CritMultiplier", 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" }, }, }, } }, { 1, "HitChance", 1, "Accuracy", data.colorCodes.OFFENCE, { diff --git a/Modules/Calcs.lua b/Modules/Calcs.lua index 24ead98b..44419cd3 100644 --- a/Modules/Calcs.lua +++ b/Modules/Calcs.lua @@ -1793,14 +1793,51 @@ local function performCalcs(env) if baseCrit > 0 then output.CritChance = m_max(output.CritChance, 5) end - if breakdown then - simpleBreakdown(baseCrit, skillCfg, "CritChance") + if breakdown and output.CritChance ~= baseCrit then + local base = modDB:Sum("BASE", cfg, "CritChance") + local inc = modDB:Sum("INC", cfg, "CritChance") + local more = modDB:Sum("MORE", cfg, "CritChance") + local enemyExtra = enemyDB:Sum("BASE", nil, "SelfExtraCritChance") + breakdown.CritChance = { } + if base ~= 0 then + t_insert(breakdown.CritChance, s_format("(%g + %g) ^8(base)", baseCrit, base)) + else + t_insert(breakdown.CritChance, s_format("%g ^8(base)", baseCrit + base)) + end + if inc ~= 0 then + t_insert(breakdown.CritChance, s_format("x %.2f", 1 + inc/100).." ^8(increased/reduced)") + end + if more ~= 1 then + t_insert(breakdown.CritChance, s_format("x %.2f", more).." ^8(more/less)") + end + if env.mode_effective and enemyExtra ~= 0 then + t_insert(breakdown.CritChance, s_format("+ %g ^8(extra chance for enemy to be crit)", enemyExtra)) + end + t_insert(breakdown.CritChance, s_format("= %g", output.CritChance)) end end if modDB:Sum("FLAG", skillCfg, "NoCritMultiplier") then output.CritMultiplier = 1 else - output.CritMultiplier = 1.5 + modDB:Sum("BASE", skillCfg, "CritMultiplier") / 100 + local extraDamage = 0.5 + modDB:Sum("BASE", skillCfg, "CritMultiplier") / 100 + if env.mode_effective then + extraDamage = round(extraDamage * (1 + enemyDB:Sum("INC", nil, "SelfCritMultiplier") / 100), 2) + end + output.CritMultiplier = 1 + m_max(0, extraDamage) + if breakdown and output.CritMultiplier ~= 1.5 then + breakdown.CritMultiplier = { + "50% ^8(base)", + } + local base = modDB:Sum("BASE", skillCfg, "CritMultiplier") + if base ~= 0 then + t_insert(breakdown.CritMultiplier, s_format("+ %d%% ^8(additional extra damage)", base)) + end + local enemyInc = 1 + enemyDB:Sum("INC", nil, "SelfCritMultiplier") / 100 + if env.mode_effective and enemyInc ~= 1 then + t_insert(breakdown.CritMultiplier, s_format("x %.2f ^8(increased/reduced extra crit damage taken by enemy)", enemyInc)) + end + t_insert(breakdown.CritMultiplier, s_format("= %d%% ^8(extra crit damage)", extraDamage * 100)) + end end output.CritEffect = 1 - output.CritChance / 100 + output.CritChance / 100 * output.CritMultiplier if breakdown and output.CritEffect ~= 1 then @@ -2066,7 +2103,8 @@ local function performCalcs(env) keywordFlags = bor(skillCfg.keywordFlags, KeywordFlag.Poison) } env.mainSkill.poisonCfg = dotCfg - local baseVal = (output.PhysicalAverage + output.ChaosAverage) * output.CritEffect * 0.08 + local poisonCritEffect = 1 - output.CritChance / 100 + output.CritChance / 100 * output.CritMultiplier * modDB:Sum("MORE", skillCfg, "PoisonDamageOnCrit") + local baseVal = (output.PhysicalAverage + output.ChaosAverage) * poisonCritEffect * 0.08 local effMult = 1 if env.mode_effective then local resist = output["EnemyChaosResist"] @@ -2089,12 +2127,17 @@ local function performCalcs(env) output.PoisonDuration = durationBase * calcMod(modDB, dotCfg, "Duration") * debuffDurationMult output.PoisonDamage = output.PoisonDPS * output.PoisonDuration if breakdown then - breakdown.PoisonDPS = { - "Base damage:", - s_format("%.1f ^8(average physical + chaos non-crit damage)", output.PhysicalAverage + output.ChaosAverage) - } + breakdown.PoisonDPS = { } + if poisonCritEffect ~= output.CritEffect then + t_insert(breakdown.PoisonDPS, "Crit effect modifier for poison base damage:") + t_insert(breakdown.PoisonDPS, s_format("(1 - %g) ^8(portion of damage from non-crits)", output.CritChance/100)) + t_insert(breakdown.PoisonDPS, s_format("+ (%g x %g x %g) ^8(portion of damage from crits)", output.CritChance/100, output.CritMultiplier, modDB:Sum("MORE", skillCfg, "PoisonDamageOnCrit"))) + t_insert(breakdown.PoisonDPS, s_format("= %.3f", poisonCritEffect)) + end + t_insert(breakdown.PoisonDPS, "Base damage:") + t_insert(breakdown.PoisonDPS, s_format("%.1f ^8(average physical + chaos non-crit damage)", output.PhysicalAverage + output.ChaosAverage)) if output.CritEffect ~= 1 then - t_insert(breakdown.PoisonDPS, s_format("x %.3f ^8(crit effect modifier)", output.CritEffect)) + t_insert(breakdown.PoisonDPS, s_format("x %.3f ^8(crit effect modifier)", poisonCritEffect)) end t_insert(breakdown.PoisonDPS, "x 0.08 ^8(poison deals 8% per second)") t_insert(breakdown.PoisonDPS, s_format("= %.1f", baseVal, 1)) diff --git a/Modules/ModParser.lua b/Modules/ModParser.lua index 9a163ff5..cc6305e8 100644 --- a/Modules/ModParser.lua +++ b/Modules/ModParser.lua @@ -418,6 +418,8 @@ local specialModList = { ["skills from your helmet penetrate (%d+)%% elemental resistances"] = function(num) return { mod("ElementalPenetration", "BASE", num, { type = "SocketedIn", slotName = "Helmet" }) } end, ["skills from your gloves have (%d+)%% increased area of effect"] = function(num) return { mod("AreaRadius", "INC", num, { type = "SocketedIn", slotName = "Gloves" }) } end, ["(%d+)%% less totem damage per totem"] = function(num) return { mod("Damage", "MORE", -num, nil, 0, KeywordFlag.Totem, { type = "PerStat", stat = "ActiveTotemLimit", div = 1 }) } end, + ["poison you inflict with critical strikes deals (%d+)%% more damage"] = function(num) return { mod("PoisonDamageOnCrit", "MORE", 100) } end, + ["bleeding you inflict on maimed enemies deals (%d+)%% more damage"] = function(num) return { mod("Damage", "MORE", num, nil, 0, KeywordFlag.Bleed, { type = "Condition", var = "EnemyMaimed"}) } end, -- Special node types ["(%d+)%% of block chance applied to spells"] = function(num) return { mod("BlockChanceConv", "BASE", num) } end, ["(%d+)%% additional block chance with staves"] = function(num) return { mod("BlockChance", "BASE", num, { type = "Condition", var = "UsingStaff" }) } end, @@ -517,12 +519,16 @@ end local convTypes = { ["as extra lightning damage"] = "GainAsLightning", ["added as lightning damage"] = "GainAsLightning", + ["gained as extra lightning damage"] = "GainAsLightning", ["as extra cold damage"] = "GainAsCold", ["added as cold damage"] = "GainAsCold", + ["gained as extra cold damage"] = "GainAsCold", ["as extra fire damage"] = "GainAsFire", ["added as fire damage"] = "GainAsFire", + ["gained as extra fire damage"] = "GainAsFire", ["as extra chaos damage"] = "GainAsChaos", ["added as chaos damage"] = "GainAsChaos", + ["gained as extra chaos damage"] = "GainAsChaos", ["converted to lightning damage"] = "ConvertToLightning", ["converted to cold damage"] = "ConvertToCold", ["converted to fire damage"] = "ConvertToFire", @@ -668,7 +674,7 @@ local function scan(line, patternList, plain) return bestMatch[1], bestMatch[2], bestMatch[3] end -return function(line) +local function parseMod(line) -- Check if this is a special modifier local specialMod, specialLine, cap = scan(line, specialModList) if specialMod and #specialLine == 0 then @@ -812,4 +818,12 @@ return function(line) } end return modList, line:match("%S") and line +end + +local cache = { } +return function(line) + if not cache[line] then + cache[line] = { parseMod(line) } + end + return unpack(copyTable(cache[line])) end \ No newline at end of file diff --git a/README.md b/README.md index f1aa9042..1a3c2cd2 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,13 @@ 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.13 - 2016/11/22 + * The breakdown for crit chance now includes the "additional chance to receive a Critical Strike" from Assassin's Mark + * Added support for the "increased extra damage from Critical Strikes" modifier on Assassin's Mark + * Added support for Toxic Delivery + * The extra chaos and bleed damage modifiers require their respective conditions to be enabled in the Configuration tab + * Improved the program's startup time + ### 1.2.12 - 2016/11/22 * Hovering over the character level input will now show the experience penalties for relevant area levels * Fixed the "not Killed Recently" condition on "Rite of Ruin" diff --git a/changelog.txt b/changelog.txt index 726c7236..40ccbbf1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +VERSION[1.2.13][2016/11/22] + * The breakdown for crit chance now includes the "additional chance to receive a Critical Strike" from Assassin's Mark + * Added support for the "increased extra damage from Critical Strikes" modifier on Assassin's Mark + * Added support for Toxic Delivery + * The extra chaos and bleed damage modifiers require their respective conditions to be enabled in the Configuration tab + * Improved the program's startup time VERSION[1.2.12][2016/11/22] * Hovering over the character level input will now show the experience penalties for relevant area levels * Fixed the "not Killed Recently" condition on "Rite of Ruin" diff --git a/manifest.xml b/manifest.xml index d4e6db14..3c7852e4 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,20 +1,20 @@ - + - + - + @@ -43,20 +43,20 @@ - - + + - + - +