From c9a5e7fc9a0bf3d745ffcf6727c2f9d53cbbd45f Mon Sep 17 00:00:00 2001 From: Openarl Date: Mon, 20 Mar 2017 21:06:47 +1000 Subject: [PATCH] Release 1.3.21 - Overhauled buff/debuff and curse handling - Added support for Punishment, Generosity and Block Chance Reduction - Minor corrections to unique stat wording --- Data/Gems/act_str.lua | 55 ++++++++++- Data/Gems/sup_dex.lua | 46 ++++++++- Data/Gems/sup_str.lua | 46 ++++++++- Data/Uniques/boots.lua | 2 +- Data/Uniques/claw.lua | 4 +- Data/Uniques/gloves.lua | 4 +- Data/Uniques/ring.lua | 8 +- Data/Uniques/shield.lua | 2 +- Data/Uniques/sword.lua | 2 +- Modules/Calcs.lua | 212 +++++++++++++++++++++++++++++++--------- Modules/ItemTools.lua | 25 +++-- Modules/ModParser.lua | 7 +- Modules/ModTools.lua | 8 +- README.md | 14 +++ changelog.txt | 13 +++ manifest.xml | 30 +++--- 16 files changed, 390 insertions(+), 88 deletions(-) diff --git a/Data/Gems/act_str.lua b/Data/Gems/act_str.lua index 3695c036..7efbb2ce 100644 --- a/Data/Gems/act_str.lua +++ b/Data/Gems/act_str.lua @@ -1753,7 +1753,60 @@ gems["Punishment"] = { spell = true, area = true, duration = true, - unsupported = true, + color = 1, + baseFlags = { + spell = true, + curse = true, + area = true, + duration = true, + }, + skillTypes = { [2] = true, [11] = true, [12] = true, [17] = true, [18] = true, [19] = true, [26] = true, [32] = true, [36] = true, }, + baseMods = { + skill("castTime", 0.5), + --"newpunishment_applied_buff_duration_ms" = 4000 + }, + qualityMods = { + mod("Speed", "INC", 0.25, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_attack_speed_+%" = 0.25 + }, + levelMods = { + [1] = skill("manaCost", nil), + [2] = skill("duration", nil), --"base_skill_effect_duration" + [3] = mod("Damage", "MORE", nil, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_melee_damage_+%_final" + [4] = mod("Speed", "INC", nil, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_attack_speed_+%" + [5] = mod("AreaOfEffect", "INC", nil), --"base_skill_area_of_effect_+%" + }, + levels = { + [1] = { 24, 9, 25, 10, 0, }, + [2] = { 26, 9.1, 26, 10, 4, }, + [3] = { 27, 9.2, 26, 11, 8, }, + [4] = { 29, 9.3, 27, 11, 12, }, + [5] = { 30, 9.4, 27, 12, 16, }, + [6] = { 32, 9.5, 28, 12, 20, }, + [7] = { 34, 9.6, 28, 13, 24, }, + [8] = { 35, 9.7, 29, 13, 28, }, + [9] = { 37, 9.8, 29, 14, 32, }, + [10] = { 38, 9.9, 30, 14, 36, }, + [11] = { 39, 10, 30, 15, 40, }, + [12] = { 40, 10.1, 31, 15, 44, }, + [13] = { 42, 10.2, 31, 16, 48, }, + [14] = { 43, 10.3, 32, 16, 52, }, + [15] = { 44, 10.4, 32, 17, 56, }, + [16] = { 45, 10.5, 33, 17, 60, }, + [17] = { 46, 10.6, 33, 18, 64, }, + [18] = { 47, 10.7, 34, 18, 68, }, + [19] = { 48, 10.8, 34, 19, 72, }, + [20] = { 50, 10.9, 35, 19, 76, }, + [21] = { 51, 11, 35, 20, 80, }, + [22] = { 52, 11.1, 36, 20, 84, }, + [23] = { 53, 11.2, 36, 21, 88, }, + [24] = { 54, 11.3, 37, 21, 92, }, + [25] = { 56, 11.4, 37, 22, 96, }, + [26] = { 57, 11.5, 38, 22, 100, }, + [27] = { 58, 11.6, 38, 23, 104, }, + [28] = { 59, 11.7, 39, 23, 108, }, + [29] = { 60, 11.8, 39, 24, 112, }, + [30] = { 61, 11.9, 40, 24, 116, }, + }, } gems["Purity of Fire"] = { aura = true, diff --git a/Data/Gems/sup_dex.lua b/Data/Gems/sup_dex.lua index 41efe6bb..f92eb2e1 100644 --- a/Data/Gems/sup_dex.lua +++ b/Data/Gems/sup_dex.lua @@ -157,7 +157,51 @@ gems["Blind"] = { gems["Block Chance Reduction"] = { dexterity = true, support = true, - unsupported = true, + color = 2, + requireSkillTypes = { 10, 1, }, + addSkillTypes = { }, + excludeSkillTypes = { }, + baseMods = { + }, + qualityMods = { + --"global_reduce_enemy_block_%" = 0.25 + }, + levelMods = { + --[1] = "global_reduce_enemy_block_%" + --[2] = "reduce_enemy_dodge_%" + }, + levels = { + [1] = { 20, 20, }, + [2] = { 21, 20, }, + [3] = { 21, 21, }, + [4] = { 22, 21, }, + [5] = { 22, 22, }, + [6] = { 23, 22, }, + [7] = { 23, 23, }, + [8] = { 24, 23, }, + [9] = { 24, 24, }, + [10] = { 25, 24, }, + [11] = { 25, 25, }, + [12] = { 26, 25, }, + [13] = { 26, 26, }, + [14] = { 27, 26, }, + [15] = { 27, 27, }, + [16] = { 28, 27, }, + [17] = { 28, 28, }, + [18] = { 29, 28, }, + [19] = { 29, 29, }, + [20] = { 30, 29, }, + [21] = { 30, 30, }, + [22] = { 31, 30, }, + [23] = { 31, 31, }, + [24] = { 32, 31, }, + [25] = { 32, 32, }, + [26] = { 33, 32, }, + [27] = { 33, 33, }, + [28] = { 34, 33, }, + [29] = { 34, 34, }, + [30] = { 35, 34, }, + }, } gems["Cast On Critical Strike"] = { dexterity = true, diff --git a/Data/Gems/sup_str.lua b/Data/Gems/sup_str.lua index 27893966..b0798305 100644 --- a/Data/Gems/sup_str.lua +++ b/Data/Gems/sup_str.lua @@ -508,7 +508,51 @@ gems["Generosity"] = { strength = true, support = true, aura = true, - unsupported = true, + color = 1, + requireSkillTypes = { 44, }, + addSkillTypes = { }, + excludeSkillTypes = { 30, 32, }, + baseMods = { + skill("auraCannotAffectSelf", true), --"aura_cannot_affect_self" = ? + }, + qualityMods = { + mod("AreaOfEffect", "INC", 2, 0, KeywordFlag.Aura), --"base_aura_area_of_effect_+%" = 2 + }, + levelMods = { + [1] = mod("AuraEffect", "INC", nil), --"non_curse_aura_effect_+%" + }, + levels = { + [1] = { 20, }, + [2] = { 21, }, + [3] = { 22, }, + [4] = { 23, }, + [5] = { 24, }, + [6] = { 25, }, + [7] = { 26, }, + [8] = { 27, }, + [9] = { 28, }, + [10] = { 29, }, + [11] = { 30, }, + [12] = { 31, }, + [13] = { 32, }, + [14] = { 33, }, + [15] = { 34, }, + [16] = { 35, }, + [17] = { 36, }, + [18] = { 37, }, + [19] = { 38, }, + [20] = { 39, }, + [21] = { 40, }, + [22] = { 41, }, + [23] = { 42, }, + [24] = { 43, }, + [25] = { 44, }, + [26] = { 45, }, + [27] = { 46, }, + [28] = { 47, }, + [29] = { 48, }, + [30] = { 49, }, + }, } gems["Increased Burning Damage"] = { fire = true, diff --git a/Data/Uniques/boots.lua b/Data/Uniques/boots.lua index 08a0f00f..e50f986c 100644 --- a/Data/Uniques/boots.lua +++ b/Data/Uniques/boots.lua @@ -294,7 +294,7 @@ Requires Level 18 15% increased Movement Speed 50% increased Stun Recovery 20% reduced Light Radius -{variant:2}Adds (15-20) to (25-30) Chaos Damage while using a Flask +{variant:2}Adds (15-20) to (25-30) Chaos Damage to Spells and Attacks while using a Flask +50% to Chaos Resistance while using a Flask ]],[[ Dusktoe diff --git a/Data/Uniques/claw.lua b/Data/Uniques/claw.lua index d12acc0f..c65a4a91 100644 --- a/Data/Uniques/claw.lua +++ b/Data/Uniques/claw.lua @@ -205,8 +205,8 @@ Requires Level 70, 113 Dex, 113 Int Adds (35-50) to (100-125) Physical Damage (10-15)% increased Attack Speed Minions have (10-15)% increased Attack Speed -10% Chance to summon a Spectral Wolf on Kill -Increases and reductions to Minion Damage also affects you +10% Chance to Cast level 18 Summon Spectral Wolf on Kill +Increases and Reductions to Minion Damage also affect you 70% increased Minion Damage if you have Hit Recently ]],[[ Touch of Anguish diff --git a/Data/Uniques/gloves.lua b/Data/Uniques/gloves.lua index 5ba9b478..b7eb1717 100644 --- a/Data/Uniques/gloves.lua +++ b/Data/Uniques/gloves.lua @@ -86,7 +86,7 @@ Requires Level 24, 17 Dex {variant:2}+(40-50) to Evasion Rating {variant:1}+(10-20)% to Cold Resistance {variant:2}+(20-30)% to Cold Resistance -{variant:2}Adds (5-7) to (13-15) Cold Damage +{variant:2}Adds (5-7) to (13-15) Cold Damage to Spells and Attacks {variant:1}25% of Physical Damage Converted to Cold Damage {variant:2}50% of Physical Damage Converted to Cold Damage Reflects 10 Cold Damage to Melee Attackers @@ -102,7 +102,7 @@ Requires Level 9, 17 Dex {variant:2}+(40-50) to Evasion Rating {variant:1}+(10-20)% to Cold Resistance {variant:2}+(20-30)% to Cold Resistance -{variant:2}Adds (5-7) to (13-15) Cold Damage +{variant:2}Adds (5-7) to (13-15) Cold Damage to Spells and Attacks {variant:1}25% of Physical Damage Converted to Cold Damage {variant:2}50% of Physical Damage Converted to Cold Damage Reflects 10 Cold Damage to Melee Attackers diff --git a/Data/Uniques/ring.lua b/Data/Uniques/ring.lua index 62a28732..1b83fe74 100644 --- a/Data/Uniques/ring.lua +++ b/Data/Uniques/ring.lua @@ -21,7 +21,7 @@ Requires Level 20 {variant:1}(10-15)% increased Cold Damage {variant:2}(25-30)% increased Cold Damage {variant:1}Adds 1 to (1-50) Lightning Damage to Attacks -{variant:2}Adds 1 to (50-70) Lightning Damage +{variant:2}Adds 1 to (50-70) Lightning Damage to Spells and Attacks +(30-40) to maximum Life {variant:1}1% of Damage against Frozen Enemies Leeched as Life {variant:2}1% of Damage against Shocked Enemies Leeched as Life @@ -38,7 +38,7 @@ Requires Level 20 {variant:1}(10-15)% increased Fire Damage {variant:1}(25-30)% increased Fire Damage {variant:1}Adds 1 to (10-30) Cold Damage to Attacks -{variant:2}Adds (20-25) to (30-50) Cold Damage +{variant:2}Adds (20-25) to (30-50) Cold Damage to Spells and Attacks +(30-40) to maximum Energy Shield 30% increased Damage while Ignited +5000 to Armour while Frozen @@ -51,7 +51,7 @@ League: Domination, Nemesis Requires Level 20 +(12-16)% to Fire and Lightning Resistances {variant:1}Adds 1 to (10-30) Fire Damage to Attacks -{variant:2}Adds (20-25) to (30-50) Fire Damage +{variant:2}Adds (20-25) to (30-50) Fire Damage to Spells and Attacks {variant:1}(10-15)% increased Lightning Damage {variant:2}(25-30)% increased Lightning Damage +(30-40) to maximum Mana @@ -486,7 +486,7 @@ Requires Level 20 {variant:1}Adds 10 to 15 Physical Damage to Attacks against Frozen Enemies {variant:2}Adds 40 to 60 Cold Damage against Chilled Enemies {variant:1}Adds (5-6) to (7-9) Cold Damage to Attacks -{variant:2}Adds (7-10) to (15-20) Cold Damage +{variant:2}Adds (7-10) to (15-20) Cold Damage to Spells and Attacks +(200-300) to Evasion Rating {variant:1}20% reduced Chill Duration on You {variant:2}50% chance to Avoid being Chilled diff --git a/Data/Uniques/shield.lua b/Data/Uniques/shield.lua index 00b70eca..34de38e5 100644 --- a/Data/Uniques/shield.lua +++ b/Data/Uniques/shield.lua @@ -31,7 +31,7 @@ Variant: Pre 2.6.0 Variant: Current Requires Level 61, 159 Str {variant:2}Adds (7-10) to (15-25) Fire Damage to Attacks -{variant:3}Adds (12-15) to (30-35) Fire Damage +{variant:3}Adds (12-15) to (30-35) Fire Damage to Spells and Attacks (120-150)% increased Armour {variant:3}+(60-80) to maximum Life +(35-50)% to Fire Resistance diff --git a/Data/Uniques/sword.lua b/Data/Uniques/sword.lua index b5d4c37b..7bf285d4 100644 --- a/Data/Uniques/sword.lua +++ b/Data/Uniques/sword.lua @@ -467,7 +467,7 @@ Implicits: 2 +1 to Level of Active Socketed Skill Gems (60-80)% increased Physical Damage Adds (60-65) to (90-105) Chaos Damage -{variant:2}Adds 1 to 2 Physical Damage per Level +{variant:2}Adds 1 to 2 Physical Damage to Attacks per Level {variant:1}+1 Life gained on Kill per Level {variant:1}1% increased Elemental Damage per Level 1% increased Chaos Damage per Level diff --git a/Modules/Calcs.lua b/Modules/Calcs.lua index e619738c..8f739c12 100644 --- a/Modules/Calcs.lua +++ b/Modules/Calcs.lua @@ -3,7 +3,7 @@ -- Module: Calcs -- Performs all the offense and defense calculations. -- Here be dragons! --- This file is 3300 lines long, over half of which is in one function... +-- This file is 3400 lines long, over half of which is in one function... -- local pairs = pairs @@ -474,6 +474,29 @@ local function buildNodeModList(env, nodeList, finishJewels) return modList end +-- Merge an instance of a buff, taking the highest value of each modifier +local function mergeBuff(src, destTable, destKey) + if not destTable[destKey] then + destTable[destKey] = { } + end + local dest = destTable[destKey] + for _, mod in ipairs(src) do + local param = modLib.formatModParams(mod) + for index, destMod in ipairs(dest) do + if param == modLib.formatModParams(destMod) then + if type(destMod.value) == "number" and mod.value > destMod.value then + dest[index] = mod + end + param = nil + break + end + end + if param then + t_insert(dest, mod) + end + end +end + -- Calculate min/max damage of a hit for the given damage type local function calcHitDamage(env, source, cfg, breakdown, damageType, ...) local modDB = env.modDB @@ -1002,7 +1025,7 @@ local function initEnv(build, mode, override) end -- Finalise environment and perform the calculations --- This function is 1900 lines long. Enjoy! +-- This function is 2100 lines long. Enjoy! local function performCalcs(env) local modDB = env.modDB local enemyDB = env.enemyDB @@ -1049,9 +1072,35 @@ local function performCalcs(env) -- Merge flask modifiers if env.mode_combat then local effectInc = modDB:Sum("INC", nil, "FlaskEffect") + local flaskBuffs = { } for item in pairs(env.flasks) do modDB.conditions["UsingFlask"] = true - modDB:ScaleAddList(item.modList, 1 + (effectInc + item.flaskData.effectInc) / 100) + -- Avert thine eyes, lest they be forever scarred + -- I have no idea how to determine which buff is applied by a given flask, + -- so utility flasks are grouped by base, unique flasks are grouped by name, and magic flasks by their modifiers + local effectMod = 1 + (effectInc + item.flaskData.effectInc) / 100 + if item.buffModList[1] then + local srcList = common.New("ModList") + srcList:ScaleAddList(item.buffModList, effectMod) + mergeBuff(srcList, flaskBuffs, item.baseName) + end + if item.modList[1] then + local srcList = common.New("ModList") + srcList:ScaleAddList(item.modList, effectMod) + local key + if item.rarity == "UNIQUE" then + key = item.title + else + key = "" + for _, mod in ipairs(item.modList) do + key = key .. modLib.formatModParams(mod) .. "&" + end + end + mergeBuff(srcList, flaskBuffs, key) + end + end + for _, buffModList in pairs(flaskBuffs) do + modDB:AddList(buffModList) end end @@ -1124,27 +1173,6 @@ local function performCalcs(env) if env.mode_effective then condList["Effective"] = true end - - -- Check for extra curses - for _, value in ipairs(modDB:Sum("LIST", nil, "ExtraCurse")) do - local modList = common.New("ModList") - mergeGemMods(modList, { - level = value.level, - quality = 0, - data = data.gems[value.name], - }) - modDB.multipliers["CurseOnEnemy"] = (modDB.multipliers["CurseOnEnemy"] or 0) + 1 - local curseModList = { } - for _, mod in ipairs(modList) do - for _, tag in ipairs(mod.tagList) do - if tag.type == "GlobalEffect" and tag.effectType == "Curse" then - t_insert(curseModList, mod) - break - end - end - end - enemyDB:ScaleAddList(curseModList, (1 + enemyDB:Sum("INC", nil, "CurseEffect") / 100) * enemyDB:Sum("MORE", nil, "CurseEffect")) - end -- Check for extra modifiers to apply to aura skills local extraAuraModList = { } @@ -1155,7 +1183,10 @@ local function performCalcs(env) end end - -- Merge auxillary skill modifiers and calculate skill life and mana reservations + -- Combine buffs/debuffs and calculate skill life and mana reservations + local buffs = { } + local debuffs = { } + local curses = { } env.reserved_LifeBase = 0 env.reserved_LifePercent = 0 env.reserved_ManaBase = 0 @@ -1168,37 +1199,58 @@ local function performCalcs(env) local skillModList = activeSkill.skillModList local skillCfg = activeSkill.skillCfg - -- Merge auxillary modifiers + -- Combine buffs/debuffs if env.mode_buffs then - if activeSkill.buffModList and (not activeSkill.skillFlags.totem or activeSkill.skillData.allowTotemBuff) and (not activeSkill.skillData.offering or modDB:Sum("FLAG", nil, "OfferingsAffectPlayer")) then + if activeSkill.buffModList and + not activeSkill.skillFlags.curse and + (not activeSkill.skillFlags.totem or activeSkill.skillData.allowTotemBuff) and + (not activeSkill.skillData.offering or modDB:Sum("FLAG", nil, "OfferingsAffectPlayer")) then activeSkill.buffSkill = true + local srcList = common.New("ModList") local inc = modDB:Sum("INC", skillCfg, "BuffEffect") - if activeSkill.activeGem.data.golem and modDB:Sum("FLAG", skillCfg, "LiegeOfThePrimordial") and (activeSkill.activeGem.data.fire or activeSkill.activeGem.data.cold or activeSkill.activeGem.data.lightning) then - inc = inc + 100 - end - modDB:ScaleAddList(activeSkill.buffModList, 1 + inc / 100) + local more = modDB:Sum("MORE", skillCfg, "BuffEffect") + srcList:ScaleAddList(activeSkill.buffModList, (1 + inc / 100) * more) + mergeBuff(srcList, buffs, activeSkill.activeGem.name) end - if activeSkill.auraModList then + if activeSkill.auraModList and not activeSkill.skillData.auraCannotAffectSelf then activeSkill.buffSkill = true - local inc = modDB:Sum("INC", skillCfg, "AuraEffect") + skillModList:Sum("INC", skillCfg, "AuraEffect") + modDB:Sum("INC", skillCfg, "BuffEffect") - local more = modDB:Sum("MORE", skillCfg, "AuraEffect") * skillModList:Sum("MORE", skillCfg, "AuraEffect") - modDB:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) - modDB:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "AuraEffect", "BuffEffect") + skillModList:Sum("INC", skillCfg, "AuraEffect", "BuffEffect") + local more = modDB:Sum("MORE", skillCfg, "AuraEffect", "BuffEffect") * skillModList:Sum("MORE", skillCfg, "AuraEffect", "BuffEffect") + srcList:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) + srcList:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) + mergeBuff(srcList, buffs, activeSkill.activeGem.name) condList["HaveAuraActive"] = true end end if env.mode_effective then if activeSkill.debuffModList then activeSkill.debuffSkill = true - enemyDB:ScaleAddList(activeSkill.debuffModList, activeSkill.skillData.stackCount or 1) + local srcList = common.New("ModList") + srcList:ScaleAddList(activeSkill.debuffModList, activeSkill.skillData.stackCount or 1) + mergeBuff(srcList, debuffs, activeSkill.activeGem.name) end - if activeSkill.curseModList then - activeSkill.debuffSkill = true - condList["EnemyCursed"] = true - modDB.multipliers["CurseOnEnemy"] = (modDB.multipliers["CurseOnEnemy"] or 0) + 1 + if activeSkill.curseModList or (activeSkill.skillFlags.curse and activeSkill.buffModList) then + local curse = { + name = activeSkill.activeGem.name, + priority = activeSkill.skillTypes[SkillType.Aura] and 3 or 1, + } local inc = modDB:Sum("INC", skillCfg, "CurseEffect") + enemyDB:Sum("INC", nil, "CurseEffect") + skillModList:Sum("INC", skillCfg, "CurseEffect") local more = modDB:Sum("MORE", skillCfg, "CurseEffect") * enemyDB:Sum("MORE", nil, "CurseEffect") * skillModList:Sum("MORE", skillCfg, "CurseEffect") - enemyDB:ScaleAddList(activeSkill.curseModList, (1 + inc / 100) * more) + if activeSkill.curseModList then + curse.modList = common.New("ModList") + curse.modList:ScaleAddList(activeSkill.curseModList, (1 + inc / 100) * more) + end + if activeSkill.buffModList then + -- Curse applies a buff; scale by curse effect, then buff effect + local temp = common.New("ModList") + temp:ScaleAddList(activeSkill.buffModList, (1 + inc / 100) * more) + curse.buffModList = common.New("ModList") + local buffInc = modDB:Sum("INC", skillCfg, "BuffEffect") + local buffMore = modDB:Sum("MORE", skillCfg, "BuffEffect") + curse.buffModList:ScaleAddList(temp, (1 + buffInc / 100) * buffMore) + end + t_insert(curses, curse) end end @@ -1231,6 +1283,76 @@ local function performCalcs(env) end end + -- Check for extra curses + for _, value in ipairs(modDB:Sum("LIST", nil, "ExtraCurse")) do + local curse = { + name = value.name, + priority = 2, + modList = common.New("ModList") + } + local gemModList = common.New("ModList") + mergeGemMods(gemModList, { + level = value.level, + quality = 0, + data = data.gems[value.name], + }) + local curseModList = { } + for _, mod in ipairs(gemModList) do + for _, tag in ipairs(mod.tagList) do + if tag.type == "GlobalEffect" and tag.effectType == "Curse" then + t_insert(curseModList, mod) + break + end + end + end + curse.modList:ScaleAddList(curseModList, (1 + enemyDB:Sum("INC", nil, "CurseEffect") / 100) * enemyDB:Sum("MORE", nil, "CurseEffect")) + t_insert(curses, curse) + end + + -- Assign curses to slots + local curseSlots = { } + env.curseSlots = curseSlots + output.EnemyCurseLimit = modDB:Sum("BASE", nil, "EnemyCurseLimit") + for _, curse in ipairs(curses) do + local slot + for i = 1, output.EnemyCurseLimit do + if not curseSlots[i] then + slot = i + break + elseif curseSlots[i].name == curse.name then + if curseSlots[i].priority < curse.priority then + slot = i + else + slot = nil + end + break + elseif curseSlots[i].priority < curse.priority then + slot = i + end + end + if slot then + curseSlots[slot] = curse + end + end + + -- Merge buff/debuff modifiers + for _, modList in pairs(buffs) do + modDB:AddList(modList) + end + for _, modList in pairs(debuffs) do + enemyDB:AddList(modList) + end + modDB.multipliers["CurseOnEnemy"] = #curseSlots + for _, slot in ipairs(curseSlots) do + condList["EnemyCursed"] = true + if slot.modList then + enemyDB:AddList(slot.modList) + end + if slot.buffModList then + modDB:AddList(slot.buffModList) + end + end + -- Process misc modifiers for _, value in ipairs(modDB:Sum("LIST", nil, "Misc")) do if value.type == "Condition" then @@ -2538,7 +2660,7 @@ local function performCalcs(env) skillFlags.bleed = false skillFlags.poison = false skillFlags.ignite = false - skillFlags.igniteCanStack = modDB:Sum("FLAG", nil, "IgniteCanStack") + skillFlags.igniteCanStack = modDB:Sum("FLAG", skillCfg, "IgniteCanStack") skillFlags.shock = false skillFlags.freeze = false for _, pass in ipairs(passList) do @@ -3263,8 +3385,8 @@ function calcs.buildOutput(build, mode) end end end - for _, value in ipairs(env.modDB:Sum("LIST", nil, "ExtraCurse")) do - t_insert(curseList, value.name) + for _, slot in ipairs(env.curseSlots) do + t_insert(curseList, slot.name) end output.BuffList = table.concat(buffList, ", ") output.CombatList = table.concat(combatList, ", ") diff --git a/Modules/ItemTools.lua b/Modules/ItemTools.lua index ef4c51fe..e9e90b4f 100644 --- a/Modules/ItemTools.lua +++ b/Modules/ItemTools.lua @@ -620,6 +620,16 @@ function itemLib.buildItemModList(item) return end local baseList = { } + if item.base.weapon then + item.weaponData = { } + elseif item.base.armour then + item.armourData = { } + elseif item.base.flask then + item.flaskData = { } + item.buffModList = { } + elseif item.type == "Jewel" then + item.jewelData = { } + end item.baseModList = baseList item.rangeLineList = { } item.modSource = "Item:"..(item.id or -1)..":"..item.name @@ -638,7 +648,11 @@ function itemLib.buildItemModList(item) if type(mod.value) == "table" and mod.value.mod then mod.value.mod.source = mod.source end - t_insert(baseList, mod) + if modLine.buff then + t_insert(item.buffModList, mod) + else + t_insert(baseList, mod) + end end end end @@ -646,15 +660,6 @@ function itemLib.buildItemModList(item) -- Hack to remove the energy shield t_insert(baseList, { name = "Misc", type = "LIST", value = { type = "ArmourData", key = "EnergyShield" }, flags = 0, keywordFlags = 0, tagList = { } }) end - if item.base.weapon then - item.weaponData = { } - elseif item.base.armour then - item.armourData = { } - elseif item.base.flask then - item.flaskData = { } - elseif item.type == "Jewel" then - item.jewelData = { } - end if item.base.weapon or item.type == "Ring" then item.slotModList = { } for i = 1, 2 do diff --git a/Modules/ModParser.lua b/Modules/ModParser.lua index 371a3633..1d5f47d2 100644 --- a/Modules/ModParser.lua +++ b/Modules/ModParser.lua @@ -546,7 +546,11 @@ local specialModList = { mod("FireDamage", "INC", num, { type = "Condition", var = "HaveFireGolem"}), mod("ChaosDamage", "INC", num, { type = "Condition", var = "HaveChaosGolem"}) } end, - ["100%% increased effect of buffs granted by your elemental golems"] = { flag("LiegeOfThePrimordial") }, + ["(%d+)%% increased effect of buffs granted by your elemental golems"] = function(num) return { + mod("BuffEffect", "INC", num, { type = "SkillType", skillType = SkillType.Golem }, { type = "SkillType", skillType = SkillType.FireSkill }), + mod("BuffEffect", "INC", num, { type = "SkillType", skillType = SkillType.Golem }, { type = "SkillType", skillType = SkillType.ColdSkill }), + mod("BuffEffect", "INC", num, { type = "SkillType", skillType = SkillType.Golem }, { type = "SkillType", skillType = SkillType.LightningSkill }), + } end, ["every 10 seconds, gain (%d+)%% increased elemental damage for 4 seconds"] = function(num) return { mod("ElementalDamage", "INC", num, { type = "Condition", var = "PendulumOfDestruction" }) } end, ["every 10 seconds, gain (%d+)%% increased area of effect of area skills for 4 seconds"] = function(num) return { mod("AreaOfEffect", "INC", num, { type = "Condition", var = "PendulumOfDestruction" }) } end, ["enemies you curse take (%d+)%% increased damage"] = function(num) return { mod("Misc", "LIST", { type = "EnemyModifier", mod = mod("DamageTaken", "INC", num) }, { type = "Condition", var = "EnemyCursed" }) } end, @@ -1081,7 +1085,6 @@ local function parseMod(line, order) end modValue = { tonumber(formCap[1]), tonumber(formCap[2]) } modName = { damageType.."Min", damageType.."Max" } - modFlag = modFlag or { flags = bor(ModFlag.Attack, ModFlag.Spell) } end -- Combine flags and tags diff --git a/Modules/ModTools.lua b/Modules/ModTools.lua index 79690ff6..029e6521 100644 --- a/Modules/ModTools.lua +++ b/Modules/ModTools.lua @@ -113,6 +113,10 @@ function modLib.formatValue(value) return "{"..ret.."}" end -function modLib.formatMod(mod) - return string.format("%s = %s|%s|%s|%s|%s", modLib.formatValue(mod.value), mod.name, mod.type, modLib.formatFlags(mod.flags, ModFlag), modLib.formatFlags(mod.keywordFlags, KeywordFlag), modLib.formatTags(mod.tagList)) +function modLib.formatModParams(mod) + return string.format("%s|%s|%s|%s|%s", mod.name, mod.type, modLib.formatFlags(mod.flags, ModFlag), modLib.formatFlags(mod.keywordFlags, KeywordFlag), modLib.formatTags(mod.tagList)) +end + +function modLib.formatMod(mod) + return modLib.formatValue(mod.value) .. " = " .. modLib.formatModParams(mod) end diff --git a/README.md b/README.md index 1ddc89b8..0ce0775e 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,20 @@ 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.3.21 - 2017/03/20 +With this update, the handling of buffs and debuffs has been improved: + * Having multiple copies of the same flask or buff/debuff skill active is now handled correctly + * When multiple copies are present, the highest value of each stat is used + * The enemy curse limit is now calculated and respected; when the limit is exceeded: + * Blasphemy curses take priority over other curses + * The Vulnerability aura from Witchfire Brew takes priority over non-Blasphemy curses + * Otherwise, curses are prioritised according to their ordering in the Skills tab +Other changes: + * Punishment is now supported (this was mostly made possible by the buff overhaul) + * Generosity is now supported + * Block Chance Reduction is now supported (although it has no effect) + * Several uniques have received minor corrections to the wording of stats + ### 1.3.20 - 2017/03/17 * Added skill parts to Vaal Fireball that match those on Fireball * Reverted the rounding change from the previous update, as the change in the game has been reverted also diff --git a/changelog.txt b/changelog.txt index 4dfcc057..e61dc9ff 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,16 @@ +VERSION[1.3.21][2017/03/20] +With this update, the handling of buffs and debuffs has been improved: + * Having multiple copies of the same flask or buff/debuff skill active is now handled correctly + * When multiple copies are present, the highest value of each stat is used + * The enemy curse limit is now calculated and respected; when the limit is exceeded: + * Blasphemy curses take priority over other curses + * The Vulnerability aura from Witchfire Brew takes priority over non-Blasphemy curses + * Otherwise, curses are prioritised according to their ordering in the Skills tab +Other changes: + * Punishment is now supported (this was mostly made possible by the buff overhaul) + * Generosity is now supported + * Block Chance Reduction is now supported (although it has no effect) + * Several uniques have received minor corrections to the wording of stats VERSION[1.3.20][2017/03/17] * Added skill parts to Vaal Fireball that match those on Fireball * Reverted the rounding change from the previous update, as the change in the game has been reverted also diff --git a/manifest.xml b/manifest.xml index d8bb957f..46829ff0 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,13 +1,13 @@ - + - + @@ -44,14 +44,14 @@ - + - + - - + + @@ -60,11 +60,11 @@ - + - + - + @@ -88,20 +88,20 @@ - + - + - + - - + + - +