diff --git a/Classes/CalcBreakdownControl.lua b/Classes/CalcBreakdownControl.lua index 3ea5ea60..5218668b 100644 --- a/Classes/CalcBreakdownControl.lua +++ b/Classes/CalcBreakdownControl.lua @@ -190,10 +190,15 @@ function CalcBreakdownClass:AddBreakdownSection(sectionData) end end end + + if breakdown.modList and #breakdown.modList > 0 then + -- Provided mod list + self:AddModSection(sectionData, breakdown.modList) + end end -- Add a table section showing a list of modifiers -function CalcBreakdownClass:AddModSection(sectionData) +function CalcBreakdownClass:AddModSection(sectionData, modList) local actor = self.calcsTab.input.showMinion and self.calcsTab.calcsEnv.minion or self.calcsTab.calcsEnv.player local build = self.calcsTab.build @@ -203,10 +208,14 @@ function CalcBreakdownClass:AddModSection(sectionData) cfg.tabulate = true local rowList local modDB = sectionData.enemy and actor.enemy.modDB or actor.modDB - if type(sectionData.modName) == "table" then - rowList = modDB:Sum(sectionData.modType, cfg, unpack(sectionData.modName)) + if modList then + rowList = modList else - rowList = modDB:Sum(sectionData.modType, cfg, sectionData.modName) + if type(sectionData.modName) == "table" then + rowList = modDB:Sum(sectionData.modType, cfg, unpack(sectionData.modName)) + else + rowList = modDB:Sum(sectionData.modType, cfg, sectionData.modName) + end end if #rowList == 0 then return @@ -218,7 +227,7 @@ function CalcBreakdownClass:AddModSection(sectionData) label = sectionData.label, rowList = rowList, colList = { - { label = "Value", key = "value" }, + { label = "Value", key = "displayValue" }, { label = "Stat", key = "name" }, { label = "Skill types", key = "flags" }, { label = "Notes", key = "tags" }, @@ -228,9 +237,9 @@ function CalcBreakdownClass:AddModSection(sectionData) } t_insert(self.sectionList, section) - if not sectionData.modType then + if not modList and not sectionData.modType then -- Sort modifiers by type - for i, row in pairs(rowList) do + for i, row in ipairs(rowList) do row.index = i end table.sort(rowList, function(a, b) @@ -243,11 +252,11 @@ function CalcBreakdownClass:AddModSection(sectionData) end local sourceTotals = { } - if not sectionData.modSource then + if not modList and not sectionData.modSource then -- Build list of totals from each modifier source local types = { } local typeList = { } - for i, row in pairs(rowList) do + for i, row in ipairs(rowList) do -- Find all the modifier types and source types that are present in the modifier lsit if not types[row.mod.type] then types[row.mod.type] = true @@ -287,20 +296,20 @@ function CalcBreakdownClass:AddModSection(sectionData) end -- Process modifier data - for _, row in pairs(rowList) do + for _, row in ipairs(rowList) do if not sectionData.modType then -- No modifier type specified, so format the value to convey type - row.value = self:FormatModValue(row.value, row.mod.type) + row.displayValue = self:FormatModValue(row.value, row.mod.type) else section.colList[1].right = true - row.value = formatRound(row.value, 2) + row.displayValue = formatRound(row.value, 2) end - if type(sectionData.modName) == "table" then + if modList or type(sectionData.modName) == "table" then -- Multiple stat names specified, add this modifier's stat to the table row.name = self:FormatModName(row.mod.name) end local sourceType = row.mod.source:match("[^:]+") - if not sectionData.modSource then + if not modList and not sectionData.modSource then -- No modifier source specified, add the source type to the table row.source = sourceType row.sourceTooltip = function() @@ -349,9 +358,10 @@ function CalcBreakdownClass:AddModSection(sectionData) table.sort(flagNames) row.flags = table.concat(flagNames, ", ") end + row.tags = nil if row.mod.tagList[1] then -- Format modifier tags - local baseVal = (row.mod.type == "BASE" and string.format("%+g", math.abs(row.mod.value)) or math.abs(row.mod.value).."%") + local baseVal = type(row.mod.value) == "number" and (row.mod.type == "BASE" and string.format("%+g", math.abs(row.mod.value)) or math.abs(row.mod.value).."%") for _, tag in ipairs(row.mod.tagList) do local desc if tag.type == "Condition" then diff --git a/Classes/CalcsTab.lua b/Classes/CalcsTab.lua index ba52c42f..2744329b 100644 --- a/Classes/CalcsTab.lua +++ b/Classes/CalcsTab.lua @@ -110,9 +110,9 @@ Buffed: Aura and buff skills apply. This is equivelant to standing in your hideo In Combat: Charges and combat buffs such as Onslaught will also apply. This will show your character sheet stats in combat. Effective DPS: Curses and enemy properties (such as resistances and status conditions) will also apply. This estimates your true DPS.]]) }, }, - { label = "Aura and Buff Skills", flag = "buffs", textSize = 12, { format = "{output:BuffList}" }, }, + { label = "Aura and Buff Skills", flag = "buffs", textSize = 12, { format = "{output:BuffList}", { breakdown = "SkillBuffs" } }, }, { label = "Combat Buffs", flag = "combat", textSize = 12, { format = "{output:CombatList}" }, }, - { label = "Curses and Debuffs", flag = "effective", textSize = 12, { format = "{output:CurseList}" }, }, + { label = "Curses and Debuffs", flag = "effective", textSize = 12, { format = "{output:CurseList}", { breakdown = "SkillDebuffs" } }, }, }, function(section) self.build:RefreshSkillSelectControls(section.controls, self.input.skill_number, "Calcs") section.controls.showMinion.state = self.input.showMinion diff --git a/Classes/ConfigTab.lua b/Classes/ConfigTab.lua index 8ec30ec4..23eeb83d 100644 --- a/Classes/ConfigTab.lua +++ b/Classes/ConfigTab.lua @@ -24,7 +24,7 @@ local varList = { { var = "conditionFullLife", type = "check", label = "Are you always on Full Life?", ifCond = "FullLife", tooltip = "You will automatically be considered to be on Full Life if you have Chaos Innoculation,\nbut you can use this option to force it if necessary.", apply = function(val, modList, enemyModList) modList:NewMod("Condition:FullLife", "FLAG", true, "Config") end }, - { var = "conditionFullEnergyShield", type = "check", label = "Are you always on Full Energy Shield?", ifCond = "FullES", apply = function(val, modList, enemyModList) + { var = "conditionFullEnergyShield", type = "check", label = "Are you always on Full Energy Shield?", ifCond = "FullEnergyShield", apply = function(val, modList, enemyModList) modList:NewMod("Condition:FullEnergyShield", "FLAG", true, "Config") end }, { var = "igniteMode", type = "list", label = "Ignite calculation mode:", tooltip = "Controls how the base damage for ignite is calculated:\nAverage Damage: Ignite is based on the average damage dealt, factoring in crits and non-crits.\nCrit Damage: Ignite is based on crit damage only.", list = {{val="AVERAGE",label="Average Damage"},{val="CRIT",label="Crit Damage"}} }, diff --git a/Classes/ModDB.lua b/Classes/ModDB.lua index 8a51721c..888bf416 100644 --- a/Classes/ModDB.lua +++ b/Classes/ModDB.lua @@ -88,6 +88,160 @@ function ModDBClass:NewMod(...) self:AddMod(mod_createMod(...)) end +function ModDBClass:EvalMod(mod, cfg) + local value = mod.value + for _, tag in pairs(mod.tagList) do + if tag.type == "Multiplier" then + local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) + if type(value) == "table" then + value = copyTable(value) + if value.mod then + value.mod.value = value.mod.value * mult + (tag.base or 0) + else + value.value = value.value * mult + (tag.base or 0) + end + else + value = value * mult + (tag.base or 0) + end + elseif tag.type == "MultiplierThreshold" then + local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) + if mult < tag.threshold then + return + end + elseif tag.type == "PerStat" then + local mult = m_floor((self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) / tag.div + 0.0001) + if type(value) == "table" then + value = copyTable(value) + if value.mod then + value.mod.value = value.mod.value * mult + (tag.base or 0) + else + value.value = value.value * mult + (tag.base or 0) + end + else + value = value * mult + (tag.base or 0) + end + elseif tag.type == "StatThreshold" then + if (self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) < tag.threshold then + return + end + elseif tag.type == "DistanceRamp" then + if not cfg or not cfg.skillDist then + return + end + if cfg.skillDist <= tag.ramp[1][1] then + value = value * tag.ramp[1][2] + elseif cfg.skillDist >= tag.ramp[#tag.ramp][1] then + value = value * tag.ramp[#tag.ramp][2] + else + for i, dat in ipairs(tag.ramp) do + local next = tag.ramp[i+1] + if cfg.skillDist <= next[1] then + value = value * (dat[2] + (next[2] - dat[2]) * (cfg.skillDist - dat[1]) / (next[1] - dat[1])) + break + end + end + end + elseif tag.type == "Condition" then + local match = false + if tag.varList then + for _, var in pairs(tag.varList) do + if self.conditions[var] or (cfg and cfg.skillCond and cfg.skillCond[var]) or self:Sum("FLAG", cfg, conditionName[var]) then + match = true + break + end + end + else + match = self.conditions[tag.var] or (cfg and cfg.skillCond and cfg.skillCond[tag.var]) or self:Sum("FLAG", cfg, conditionName[tag.var]) + end + if tag.neg then + match = not match + end + if not match then + return + end + elseif tag.type == "EnemyCondition" then + local match = false + local enemy = self.actor.enemy + if enemy then + if tag.varList then + for _, var in pairs(tag.varList) do + if enemy.modDB.conditions[var] or enemy.modDB:Sum("FLAG", nil, conditionName[var]) then + match = true + break + end + end + else + match = enemy.modDB.conditions[tag.var] or enemy.modDB:Sum("FLAG", nil, conditionName[tag.var]) + end + if tag.neg then + match = not match + end + end + if not match then + return + end + elseif tag.type == "ParentCondition" then + local match = false + local parent = self.actor.parent + if parent then + if tag.varList then + for _, var in pairs(tag.varList) do + if parent.modDB.conditions[var] or parent.modDB:Sum("FLAG", nil, conditionName[var]) then + match = true + break + end + end + else + match = parent.modDB.conditions[tag.var] or parent.modDB:Sum("FLAG", nil, conditionName[tag.var]) + end + end + if tag.neg then + match = not match + end + if not match then + return + end + elseif tag.type == "SocketedIn" then + if not cfg or tag.slotName ~= cfg.slotName or (tag.keyword and (not cfg or not cfg.skillGem or not calcLib.gemIsType(cfg.skillGem, tag.keyword))) then + return + end + elseif tag.type == "SkillName" then + local match = false + local matchName = tag.summonSkill and (cfg and cfg.summonSkillName or "") or (cfg and cfg.skillName) + if tag.skillNameList then + for _, name in pairs(tag.skillNameList) do + if name == matchName then + match = true + break + end + end + else + match = (tag.skillName == matchName) + end + if not match then + return + end + elseif tag.type == "SkillId" then + if not cfg or not cfg.skillGem or cfg.skillGem.grantedEffect.id ~= tag.skillId then + return + end + elseif tag.type == "SkillPart" then + if not cfg or tag.skillPart ~= cfg.skillPart then + return + end + elseif tag.type == "SkillType" then + if not cfg or not cfg.skillTypes or not cfg.skillTypes[tag.skillType] then + return + end + elseif tag.type == "SlotName" then + if not cfg or tag.slotName ~= cfg.slotName then + return + end + end + end + return value +end + function ModDBClass:Sum(modType, cfg, ...) local flags, keywordFlags = 0, 0 local source, tabulate @@ -121,168 +275,12 @@ function ModDBClass:Sum(modType, cfg, ...) for i = 1, #modList do local mod = modList[i] if (not modType or mod.type == modType) and (mod.flags == 0 or band(flags, mod.flags) == mod.flags) and (mod.keywordFlags == 0 or band(keywordFlags, mod.keywordFlags) ~= 0) and (not source or mod.source:match("[^:]+") == source) then - local value = mod.value - for _, tag in pairs(mod.tagList) do - if tag.type == "Multiplier" then - local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) - if type(value) == "table" then - value = copyTable(value) - if value.mod then - value.mod.value = value.mod.value * mult + (tag.base or 0) - else - value.value = value.value * mult + (tag.base or 0) - end - else - value = value * mult + (tag.base or 0) - end - elseif tag.type == "MultiplierThreshold" then - local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) - if mult < tag.threshold then - value = nullValue - break - end - elseif tag.type == "PerStat" then - local mult = m_floor((self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) / tag.div + 0.0001) - if type(value) == "table" then - value = copyTable(value) - if value.mod then - value.mod.value = value.mod.value * mult + (tag.base or 0) - else - value.value = value.value * mult + (tag.base or 0) - end - else - value = value * mult + (tag.base or 0) - end - elseif tag.type == "StatThreshold" then - if (self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) < tag.threshold then - value = nullValue - break - end - elseif tag.type == "DistanceRamp" then - if not cfg or not cfg.skillDist then - value = nullValue - break - end - if cfg.skillDist <= tag.ramp[1][1] then - value = value * tag.ramp[1][2] - elseif cfg.skillDist >= tag.ramp[#tag.ramp][1] then - value = value * tag.ramp[#tag.ramp][2] - else - for i, dat in ipairs(tag.ramp) do - local next = tag.ramp[i+1] - if cfg.skillDist <= next[1] then - value = value * (dat[2] + (next[2] - dat[2]) * (cfg.skillDist - dat[1]) / (next[1] - dat[1])) - break - end - end - end - elseif tag.type == "Condition" then - local match = false - if tag.varList then - for _, var in pairs(tag.varList) do - if self.conditions[var] or (cfg and cfg.skillCond and cfg.skillCond[var]) or self:Sum("FLAG", cfg, conditionName[var]) then - match = true - break - end - end - else - match = self.conditions[tag.var] or (cfg and cfg.skillCond and cfg.skillCond[tag.var]) or self:Sum("FLAG", cfg, conditionName[tag.var]) - end - if tag.neg then - match = not match - end - if not match then - value = nullValue - break - end - elseif tag.type == "EnemyCondition" then - local match = false - local enemy = self.actor.enemy - if enemy then - if tag.varList then - for _, var in pairs(tag.varList) do - if enemy.modDB.conditions[var] or enemy.modDB:Sum("FLAG", nil, conditionName[var]) then - match = true - break - end - end - else - match = enemy.modDB.conditions[tag.var] or enemy.modDB:Sum("FLAG", nil, conditionName[tag.var]) - end - if tag.neg then - match = not match - end - end - if not match then - value = nullValue - break - end - elseif tag.type == "ParentCondition" then - local match = false - local parent = self.actor.parent - if parent then - if tag.varList then - for _, var in pairs(tag.varList) do - if parent.modDB.conditions[var] or parent.modDB:Sum("FLAG", nil, conditionName[var]) then - match = true - break - end - end - else - match = parent.modDB.conditions[tag.var] or parent.modDB:Sum("FLAG", nil, conditionName[tag.var]) - end - end - if tag.neg then - match = not match - end - if not match then - value = nullValue - break - end - elseif tag.type == "SocketedIn" then - if not cfg or tag.slotName ~= cfg.slotName or (tag.keyword and (not cfg or not cfg.skillGem or not calcLib.gemIsType(cfg.skillGem, tag.keyword))) then - value = nullValue - break - end - elseif tag.type == "SkillName" then - local match = false - local matchName = tag.summonSkill and (cfg and cfg.summonSkillName or "") or (cfg and cfg.skillName) - if tag.skillNameList then - for _, name in pairs(tag.skillNameList) do - if name == matchName then - match = true - break - end - end - else - match = (tag.skillName == matchName) - end - if not match then - value = nullValue - break - end - elseif tag.type == "SkillId" then - if not cfg or not cfg.skillGem or cfg.skillGem.grantedEffect.id ~= tag.skillId then - value = nullValue - break - end - elseif tag.type == "SkillPart" then - if not cfg or tag.skillPart ~= cfg.skillPart then - value = nullValue - break - end - elseif tag.type == "SkillType" then - if not cfg or not cfg.skillTypes or not cfg.skillTypes[tag.skillType] then - value = nullValue - break - end - elseif tag.type == "SlotName" then - if not cfg or tag.slotName ~= cfg.slotName then - value = nullValue - break - end - end - end + local value + if mod.tagList[1] then + value = self:EvalMod(mod, cfg) or nullValue + else + value = mod.value + end if tabulate then if value and value ~= 0 then t_insert(result, { value = value, mod = mod }) diff --git a/Classes/ModList.lua b/Classes/ModList.lua index c20ccae2..acbe3841 100644 --- a/Classes/ModList.lua +++ b/Classes/ModList.lua @@ -64,6 +64,160 @@ function ModListClass:NewMod(...) self:AddMod(mod_createMod(...)) end +function ModListClass:EvalMod(mod, cfg) + local value = mod.value + for _, tag in pairs(mod.tagList) do + if tag.type == "Multiplier" then + local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) + if type(value) == "table" then + value = copyTable(value) + if value.mod then + value.mod.value = value.mod.value * mult + (tag.base or 0) + else + value.value = value.value * mult + (tag.base or 0) + end + else + value = value * mult + (tag.base or 0) + end + elseif tag.type == "MultiplierThreshold" then + local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) + if mult < tag.threshold then + return + end + elseif tag.type == "PerStat" then + local mult = m_floor((self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) / tag.div + 0.0001) + if type(value) == "table" then + value = copyTable(value) + if value.mod then + value.mod.value = value.mod.value * mult + (tag.base or 0) + else + value.value = value.value * mult + (tag.base or 0) + end + else + value = value * mult + (tag.base or 0) + end + elseif tag.type == "StatThreshold" then + if (self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) < tag.threshold then + return + end + elseif tag.type == "DistanceRamp" then + if not cfg or not cfg.skillDist then + return + end + if cfg.skillDist <= tag.ramp[1][1] then + value = value * tag.ramp[1][2] + elseif cfg.skillDist >= tag.ramp[#tag.ramp][1] then + value = value * tag.ramp[#tag.ramp][2] + else + for i, dat in ipairs(tag.ramp) do + local next = tag.ramp[i+1] + if cfg.skillDist <= next[1] then + value = value * (dat[2] + (next[2] - dat[2]) * (cfg.skillDist - dat[1]) / (next[1] - dat[1])) + break + end + end + end + elseif tag.type == "Condition" then + local match = false + if tag.varList then + for _, var in pairs(tag.varList) do + if self.conditions[var] or (cfg and cfg.skillCond and cfg.skillCond[var]) or self:Sum("FLAG", cfg, conditionName[var]) then + match = true + break + end + end + else + match = self.conditions[tag.var] or (cfg and cfg.skillCond and cfg.skillCond[tag.var]) or self:Sum("FLAG", cfg, conditionName[tag.var]) + end + if tag.neg then + match = not match + end + if not match then + return + end + elseif tag.type == "EnemyCondition" then + local match = false + local enemy = self.actor.enemy + if enemy then + if tag.varList then + for _, var in pairs(tag.varList) do + if enemy.modDB.conditions[var] or enemy.modDB:Sum("FLAG", nil, conditionName[var]) then + match = true + break + end + end + else + match = enemy.modDB.conditions[tag.var] or enemy.modDB:Sum("FLAG", nil, conditionName[tag.var]) + end + if tag.neg then + match = not match + end + end + if not match then + return + end + elseif tag.type == "ParentCondition" then + local match = false + local parent = self.actor.parent + if parent then + if tag.varList then + for _, var in pairs(tag.varList) do + if parent.modDB.conditions[var] or parent.modDB:Sum("FLAG", nil, conditionName[var]) then + match = true + break + end + end + else + match = parent.modDB.conditions[tag.var] or parent.modDB:Sum("FLAG", nil, conditionName[tag.var]) + end + end + if tag.neg then + match = not match + end + if not match then + return + end + elseif tag.type == "SocketedIn" then + if not cfg or tag.slotName ~= cfg.slotName or (tag.keyword and (not cfg or not cfg.skillGem or not calcLib.gemIsType(cfg.skillGem, tag.keyword))) then + return + end + elseif tag.type == "SkillName" then + local match = false + local matchName = tag.summonSkill and (cfg and cfg.summonSkillName or "") or (cfg and cfg.skillName) + if tag.skillNameList then + for _, name in pairs(tag.skillNameList) do + if name == matchName then + match = true + break + end + end + else + match = (tag.skillName == matchName) + end + if not match then + return + end + elseif tag.type == "SkillId" then + if not cfg or not cfg.skillGem or cfg.skillGem.grantedEffect.id ~= tag.skillId then + return + end + elseif tag.type == "SkillPart" then + if not cfg or tag.skillPart ~= cfg.skillPart then + return + end + elseif tag.type == "SkillType" then + if not cfg or not cfg.skillTypes or not cfg.skillTypes[tag.skillType] then + return + end + elseif tag.type == "SlotName" then + if not cfg or tag.slotName ~= cfg.slotName then + return + end + end + end + return value +end + function ModListClass:Sum(modType, cfg, ...) local flags, keywordFlags = 0, 0 local source, tabulate @@ -95,167 +249,11 @@ function ModListClass:Sum(modType, cfg, ...) for i = 1, #self do local mod = self[i] if mod.name == modName and (not modType or mod.type == modType) and band(flags, mod.flags) == mod.flags and (mod.keywordFlags == 0 or band(keywordFlags, mod.keywordFlags) ~= 0) and (not source or mod.source:match("[^:]+") == source) then - local value = mod.value - for _, tag in pairs(mod.tagList) do - if tag.type == "Multiplier" then - local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) - if type(value) == "table" then - value = copyTable(value) - if value.mod then - value.mod.value = value.mod.value * mult + (tag.base or 0) - else - value.value = value.value * mult + (tag.base or 0) - end - else - value = value * mult + (tag.base or 0) - end - elseif tag.type == "MultiplierThreshold" then - local mult = (self.multipliers[tag.var] or 0) + self:Sum("BASE", cfg, multiplierName[tag.var]) - if mult < tag.threshold then - value = nullValue - break - end - elseif tag.type == "PerStat" then - local mult = m_floor((self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) / tag.div + 0.0001) - if type(value) == "table" then - value = copyTable(value) - if value.mod then - value.mod.value = value.mod.value * mult + (tag.base or 0) - else - value.value = value.value * mult + (tag.base or 0) - end - else - value = value * mult + (tag.base or 0) - end - elseif tag.type == "StatThreshold" then - if (self.actor.output[tag.stat] or (cfg and cfg.skillStats and cfg.skillStats[tag.stat]) or 0) < tag.threshold then - value = nullValue - break - end - elseif tag.type == "DistanceRamp" then - if not cfg or not cfg.skillDist then - value = nullValue - break - end - if cfg.skillDist <= tag.ramp[1][1] then - value = value * tag.ramp[1][2] - elseif cfg.skillDist >= tag.ramp[#tag.ramp][1] then - value = value * tag.ramp[#tag.ramp][2] - else - for i, dat in ipairs(tag.ramp) do - local next = tag.ramp[i+1] - if cfg.skillDist <= next[1] then - value = value * (dat[2] + (next[2] - dat[2]) * (cfg.skillDist - dat[1]) / (next[1] - dat[1])) - break - end - end - end - elseif tag.type == "Condition" then - local match = false - if tag.varList then - for _, var in pairs(tag.varList) do - if self.conditions[var] or (cfg and cfg.skillCond and cfg.skillCond[var]) or self:Sum("FLAG", cfg, conditionName[var]) then - match = true - break - end - end - else - match = self.conditions[tag.var] or (cfg and cfg.skillCond and cfg.skillCond[tag.var]) or self:Sum("FLAG", cfg, conditionName[tag.var]) - end - if tag.neg then - match = not match - end - if not match then - value = nullValue - break - end - elseif tag.type == "EnemyCondition" then - local match = false - local enemy = self.actor.enemy - if enemy then - if tag.varList then - for _, var in pairs(tag.varList) do - if enemy.modDB.conditions[var] or enemy.modDB:Sum("FLAG", nil, conditionName[var]) then - match = true - break - end - end - else - match = enemy.modDB.conditions[tag.var] or enemy.modDB:Sum("FLAG", nil, conditionName[tag.var]) - end - if tag.neg then - match = not match - end - end - if not match then - value = nullValue - break - end - elseif tag.type == "ParentCondition" then - local match = false - local parent = self.actor.parent - if parent then - if tag.varList then - for _, var in pairs(tag.varList) do - if parent.modDB.conditions[var] or parent.modDB:Sum("FLAG", nil, conditionName[var]) then - match = true - break - end - end - else - match = parent.modDB.conditions[tag.var] or parent.modDB:Sum("FLAG", nil, conditionName[tag.var]) - end - end - if tag.neg then - match = not match - end - if not match then - value = nullValue - break - end - elseif tag.type == "SocketedIn" then - if not cfg or tag.slotName ~= cfg.slotName or (tag.keyword and (not cfg or not cfg.skillGem or not calcLib.gemIsType(cfg.skillGem, tag.keyword))) then - value = nullValue - break - end - elseif tag.type == "SkillName" then - local match = false - local matchName = tag.summonSkill and (cfg and cfg.summonSkillName or "") or (cfg and cfg.skillName) - if tag.skillNameList then - for _, name in pairs(tag.skillNameList) do - if name == matchName then - match = true - break - end - end - else - match = (tag.skillName == matchName) - end - if not match then - value = nullValue - break - end - elseif tag.type == "SkillId" then - if not cfg or not cfg.skillGem or cfg.skillGem.grantedEffect.id ~= tag.skillId then - value = nullValue - break - end - elseif tag.type == "SkillPart" then - if not cfg or tag.skillPart ~= cfg.skillPart then - value = nullValue - break - end - elseif tag.type == "SkillType" then - if not cfg or not cfg.skillTypes or not cfg.skillTypes[tag.skillType] then - value = nullValue - break - end - elseif tag.type == "SlotName" then - if not cfg or tag.slotName ~= cfg.slotName then - value = nullValue - break - end - end + local value + if mod.tagList[1] then + value = self:EvalMod(mod, cfg) or nullValue + else + value = mod.value end if tabulate then if value and value ~= 0 then diff --git a/Classes/SkillsTab.lua b/Classes/SkillsTab.lua index 26c8fdb6..6bceb07a 100644 --- a/Classes/SkillsTab.lua +++ b/Classes/SkillsTab.lua @@ -481,7 +481,7 @@ function SkillsTabClass:SetDisplayGroup(socketGroup) -- Update the main controls self.controls.groupLabel:SetText(socketGroup.label) - self.controls.groupSlot:SelByValue(socketGroup.slot or "None", "slotName") + self.controls.groupSlot:SelByValue(socketGroup.slot, "slotName") self.controls.groupEnabled.state = socketGroup.enabled -- Update the gem slot controls diff --git a/Data/3_0/Skills/act_dex.lua b/Data/3_0/Skills/act_dex.lua index e5aa1048..ac7967da 100644 --- a/Data/3_0/Skills/act_dex.lua +++ b/Data/3_0/Skills/act_dex.lua @@ -355,7 +355,7 @@ skills["ChargedAttack"] = { --"base_skill_show_average_damage_instead_of_dps" = ? --"skill_can_add_multiple_charges_per_action" = ? skill("radius", 14), - mod("Damage", "MORE", 120, 0, 0, { type = "SkillPart", skillPart = 2 }), + mod("Damage", "MORE", 120, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }), skill("dpsMultiplier", 3, { type = "SkillPart", skillPart = 3 }), }, qualityMods = { @@ -448,9 +448,9 @@ skills["BladeVortex"] = { --"action_ignores_crit_tracking" = ? --"base_skill_show_average_damage_instead_of_dps" = ? skill("radius", 15), - mod("Damage", "MORE", 150, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 2 }), - mod("Damage", "MORE", 300, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 3 }), - mod("Damage", "MORE", 600, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 4 }), + mod("Damage", "MORE", 150, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }), + mod("Damage", "MORE", 300, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 3 }), + mod("Damage", "MORE", 600, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 4 }), skill("hitTimeOverride", 0.6, { type = "SkillPart", skillPart = 1 }), skill("hitTimeOverride", 0.4, { type = "SkillPart", skillPart = 2 }), skill("hitTimeOverride", 0.3, { type = "SkillPart", skillPart = 3 }), @@ -584,7 +584,7 @@ skills["BlastRain"] = { gemInt = 0, color = 2, description = "Fires an arrow up in the air, which splits and rains down in a series of explosions over an area. The explosions will always overlap on the targeted area.", - skillTypes = { [1] = true, [11] = true, [14] = true, [22] = true, [17] = true, [19] = true, [33] = true, [48] = true, }, + skillTypes = { [1] = true, [11] = true, [14] = true, [22] = true, [17] = true, [19] = true, [33] = true, [48] = true, [57] = true, }, weaponTypes = { ["Bow"] = true, }, @@ -3176,6 +3176,7 @@ skills["LightningStrike"] = { mod("SkillPhysicalDamageConvertToLightning", "BASE", 50), --"skill_physical_damage_%_to_convert_to_lightning" = 50 mod("Damage", "MORE", -25, ModFlag.Projectile), --"active_skill_projectile_damage_+%_final" = -25 --"total_projectile_spread_angle_override" = 70 + mod("Damage", "MORE", -25, ModFlag.Dot, 0, { type = "SkillPart", skillPart = 2 }), --"active_skill_damage_over_time_from_projectile_hits_+%_final" = -25 --"show_number_of_projectiles" = ? }, qualityMods = { @@ -3508,7 +3509,7 @@ skills["PoachersMark"] = { [2] = skill("manaCost", nil), [3] = skill("duration", nil), --"base_skill_effect_duration" [4] = mod("AreaOfEffect", "INC", nil), --"base_skill_area_of_effect_+%" - [5] = mod("Evasion", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse"}), --"evasion_rating_+%_final_from_poachers_mark" + [5] = mod("Evasion", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }), --"evasion_rating_+%_final_from_poachers_mark" [6] = mod("SelfLifeOnHit", "BASE", nil, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Curse" }), --"life_granted_when_hit_by_attacks" [7] = mod("SelfManaOnHit", "BASE", nil, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Curse" }), --"mana_granted_when_hit_by_attacks" --[8] = "chance_to_grant_frenzy_charge_on_death_%" @@ -3654,8 +3655,10 @@ skills["Puncture"] = { baseMods = { skill("castTime", 1), skill("manaCost", 6), + skill("duration", 8), --"base_skill_effect_duration" = 8000 --"skill_can_fire_arrows" = ? mod("BleedChance", "BASE", 100), --"global_bleed_on_hit" = ? + skill("bleedDurationIsSkillDuration", true), --"bleed_duration_is_skill_duration" = ? skill("bleedIsSkillEffect", true), }, qualityMods = { diff --git a/Data/3_0/Skills/act_int.lua b/Data/3_0/Skills/act_int.lua index 76a79776..56943d09 100644 --- a/Data/3_0/Skills/act_int.lua +++ b/Data/3_0/Skills/act_int.lua @@ -1199,7 +1199,7 @@ skills["Discipline"] = { skill("castTime", 1.2), skill("manaCost", 35), skill("cooldown", 1.2), - --"energy_shield_recharge_rate_+%" = 30 + mod("EnergyShieldRecharge", "INC", 30, 0, 0, { type = "GlobalEffect", effectType = "Aura" }), --"energy_shield_recharge_rate_+%" = 30 --"base_deal_no_damage" = ? skill("radius", 36), }, @@ -1966,7 +1966,7 @@ skills["FlameWhip"] = { baseMods = { skill("castTime", 0.5), skill("CritChance", 6), - mod("Damage", "MORE", 50, bit.bor(ModFlag.Spell, ModFlag.Hit), 0, { type = "EnemyCondition", var = "Burning" }), --"flame_whip_damage_+%_final_vs_burning_enemies" = 50 + mod("Damage", "MORE", 50, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }), --"flame_whip_damage_+%_final_vs_burning_enemies" = 50 flag("CannotIgnite"), --"never_ignite" = ? --"is_area_damage" = ? skill("radius", 30), @@ -2050,7 +2050,7 @@ skills["Flameblast"] = { --"charged_blast_spell_damage_+%_final_per_stack" = 110 --"is_area_damage" = ? --"base_skill_show_average_damage_instead_of_dps" = ? - mod("Damage", "MORE", 990, 0, 0, { type = "SkillPart", skillPart = 2 }), + mod("Damage", "MORE", 990, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }), skill("dpsMultiplier", 0.1, { type = "SkillPart", skillPart = 2 }), }, qualityMods = { @@ -3094,7 +3094,7 @@ skills["Incinerate"] = { --"base_is_projectile" = ? mod("PierceChance", "BASE", 100), --"always_pierce" = ? --"skill_can_add_multiple_charges_per_action" = ? - mod("Damage", "MORE", 150, 0, 0, { type = "SkillPart", skillPart = 2 }), + mod("Damage", "MORE", 150, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }), }, qualityMods = { mod("ProjectileSpeed", "INC", 2), --"base_projectile_speed_+%" = 2 @@ -4446,7 +4446,7 @@ skills["ShockNova"] = { gemInt = 100, color = 3, description = "Casts a ring of Lightning around you, followed by a larger Lightning nova. Each effect hits enemies caught in their area with Lightning Damage.", - skillTypes = { [2] = true, [10] = true, [11] = true, [17] = true, [18] = true, [19] = true, [26] = true, [36] = true, [45] = true, [35] = true, [43] = true, }, + skillTypes = { [2] = true, [10] = true, [11] = true, [17] = true, [18] = true, [19] = true, [26] = true, [36] = true, [45] = true, [35] = true, }, parts = { { name = "Ring", diff --git a/Data/3_0/Skills/act_str.lua b/Data/3_0/Skills/act_str.lua index 5109bb0f..f008c696 100644 --- a/Data/3_0/Skills/act_str.lua +++ b/Data/3_0/Skills/act_str.lua @@ -2115,6 +2115,7 @@ skills["MoltenStrike"] = { mod("SkillPhysicalDamageConvertToFire", "BASE", 60), --"skill_physical_damage_%_to_convert_to_fire" = 60 mod("ProjectileCount", "BASE", 2), --"number_of_additional_projectiles" = 2 mod("Damage", "MORE", -40, ModFlag.Projectile), --"active_skill_projectile_damage_+%_final" = -40 + mod("Damage", "MORE", -40, ModFlag.Dot, 0, { type = "SkillPart", skillPart = 2 }), --"active_skill_damage_over_time_from_projectile_hits_+%_final" = -40 --"show_number_of_projectiles" = ? }, qualityMods = { @@ -2188,14 +2189,14 @@ skills["Punishment"] = { skill("radius", 22), }, qualityMods = { - mod("Speed", "INC", 0.25, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_attack_speed_+%" = 0.25 + mod("Speed", "INC", 0.25, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "CurseBuff" }), --"newpunishment_attack_speed_+%" = 0.25 }, levelMods = { [1] = skill("levelRequirement", nil), [2] = skill("manaCost", nil), [3] = skill("duration", nil), --"base_skill_effect_duration" - [4] = mod("Damage", "MORE", nil, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_melee_damage_+%_final" - [5] = mod("Speed", "INC", nil, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Buff"}), --"newpunishment_attack_speed_+%" + [4] = mod("Damage", "MORE", nil, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "CurseBuff" }), --"newpunishment_melee_damage_+%_final" + [5] = mod("Speed", "INC", nil, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "CurseBuff" }), --"newpunishment_attack_speed_+%" [6] = mod("AreaOfEffect", "INC", nil), --"base_skill_area_of_effect_+%" }, levels = { diff --git a/Data/3_0/Skills/sup_dex.lua b/Data/3_0/Skills/sup_dex.lua index 0993f63d..15113517 100644 --- a/Data/3_0/Skills/sup_dex.lua +++ b/Data/3_0/Skills/sup_dex.lua @@ -1033,7 +1033,7 @@ skills["SupportDamageAgainstChilled"] = { }, levelMods = { [1] = nil, - [2] = mod("Damage", "MORE", nil, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Chilled" }), --"support_hypothermia_damage_+%_vs_chilled_enemies_final" + [2] = mod("Damage", "MORE", nil, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "EnemyCondition", var = "Chilled" }), --"support_hypothermia_damage_+%_vs_chilled_enemies_final" }, levels = { [1] = { 31, 20, }, @@ -1193,10 +1193,11 @@ skills["SupportLesserMultipleProjectiles"] = { skills["SupportLesserPoison"] = { name = "Lesser Poison", gemTags = { + chaos = true, dexterity = true, support = true, }, - gemTagString = "Support", + gemTagString = "Chaos, Support", gemStr = 0, gemDex = 100, gemInt = 0, @@ -1926,14 +1927,14 @@ skills["SupportTrapAndMineDamage"] = { skills["SupportDebilitate"] = { name = "Vile Toxins", gemTags = { - strength = true, + dexterity = true, support = true, }, gemTagString = "Support", gemStr = 0, gemDex = 100, gemInt = 0, - color = 1, + color = 2, support = true, requireSkillTypes = { 10, 1, }, addSkillTypes = { }, diff --git a/Data/3_0/Skills/sup_int.lua b/Data/3_0/Skills/sup_int.lua index 422c3ea0..80951963 100644 --- a/Data/3_0/Skills/sup_int.lua +++ b/Data/3_0/Skills/sup_int.lua @@ -556,10 +556,11 @@ skills["SupportCurseOnHit"] = { skills["SupportDecay"] = { name = "Decay", gemTags = { + chaos = true, intelligence = true, support = true, }, - gemTagString = "Support", + gemTagString = "Chaos, Support", gemStr = 0, gemDex = 40, gemInt = 60, @@ -579,36 +580,36 @@ skills["SupportDecay"] = { [2] = mod("SkillData", "LIST", { key = "decay", value = nil, merge = "MAX" }), --"deal_chaos_damage_per_second_for_10_seconds_on_hit" }, levels = { - [1] = { 38, 234, }, - [2] = { 40, 266, }, - [3] = { 42, 302, }, - [4] = { 44, 343, }, - [5] = { 46, 388, }, - [6] = { 48, 439, }, - [7] = { 50, 496, }, - [8] = { 52, 560, }, - [9] = { 54, 632, }, - [10] = { 56, 711, }, - [11] = { 58, 800, }, - [12] = { 60, 900, }, - [13] = { 62, 1011, }, - [14] = { 64, 1135, }, - [15] = { 65, 1202, }, - [16] = { 66, 1273, }, - [17] = { 67, 1347, }, - [18] = { 68, 1426, }, - [19] = { 69, 1510, }, - [20] = { 70, 1598, }, - [21] = { 72, 1789, }, - [22] = { 74, 2001, }, - [23] = { 76, 2237, }, - [24] = { 78, 2500, }, - [25] = { 80, 2792, }, - [26] = { 82, 3117, }, - [27] = { 84, 3478, }, - [28] = { 86, 3879, }, - [29] = { 88, 4325, }, - [30] = { 90, 4819, }, + [1] = { 38, 195, }, + [2] = { 40, 223, }, + [3] = { 42, 255, }, + [4] = { 44, 291, }, + [5] = { 46, 331, }, + [6] = { 48, 377, }, + [7] = { 50, 428, }, + [8] = { 52, 486, }, + [9] = { 54, 551, }, + [10] = { 56, 625, }, + [11] = { 58, 707, }, + [12] = { 60, 799, }, + [13] = { 62, 903, }, + [14] = { 64, 1019, }, + [15] = { 65, 1083, }, + [16] = { 66, 1150, }, + [17] = { 67, 1221, }, + [18] = { 68, 1296, }, + [19] = { 69, 1376, }, + [20] = { 70, 1460, }, + [21] = { 72, 1644, }, + [22] = { 74, 1850, }, + [23] = { 76, 2080, }, + [24] = { 78, 2338, }, + [25] = { 80, 2626, }, + [26] = { 82, 2949, }, + [27] = { 84, 3309, }, + [28] = { 86, 3712, }, + [29] = { 88, 4162, }, + [30] = { 90, 4665, }, }, } skills["SupportEfficacy"] = { @@ -616,14 +617,15 @@ skills["SupportEfficacy"] = { gemTags = { intelligence = true, support = true, + duration = true, }, - gemTagString = "Support", + gemTagString = "Support, Duration", gemStr = 0, gemDex = 0, gemInt = 100, color = 3, support = true, - requireSkillTypes = { 10, 1, 59, }, + requireSkillTypes = { 10, 1, 59, 12, 55, }, addSkillTypes = { }, excludeSkillTypes = { }, baseMods = { @@ -895,10 +897,11 @@ skills["SupportFasterCast"] = { skills["SupportIgniteProliferation"] = { name = "Ignite Proliferation", gemTags = { + fire = true, intelligence = true, support = true, }, - gemTagString = "Support", + gemTagString = "Fire, Support", gemStr = 40, gemDex = 0, gemInt = 60, @@ -915,7 +918,7 @@ skills["SupportIgniteProliferation"] = { }, levelMods = { [1] = nil, - --[2] = "base_ignite_proliferation_radius" + --[2] = "support_ignite_proliferation_radius" [3] = mod("FireDamage", "INC", nil), --"fire_damage_+%" }, levels = { @@ -954,10 +957,11 @@ skills["SupportIgniteProliferation"] = { skills["SupportImmolation"] = { name = "Immolate", gemTags = { + fire = true, intelligence = true, support = true, }, - gemTagString = "Support", + gemTagString = "Fire, Support", gemStr = 40, gemDex = 0, gemInt = 60, @@ -974,40 +978,40 @@ skills["SupportImmolation"] = { }, levelMods = { [1] = nil, - [2] = mod("FireMin", "BASE", nil, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }), --"support_minimum_added_fire_damage_vs_burning_enemies" - [3] = mod("FireMax", "BASE", nil, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }), --"support_maximum_added_fire_damage_vs_burning_enemies" + [2] = mod("FireMin", "BASE", nil, 0, 0, { type = "EnemyCondition", var = "Burning" }), --"support_minimum_added_fire_damage_vs_burning_enemies" + [3] = mod("FireMax", "BASE", nil, 0, 0, { type = "EnemyCondition", var = "Burning" }), --"support_maximum_added_fire_damage_vs_burning_enemies" }, levels = { - [1] = { 38, 47, 71, }, - [2] = { 40, 53, 80, }, - [3] = { 42, 60, 90, }, - [4] = { 44, 67, 100, }, - [5] = { 46, 75, 112, }, - [6] = { 48, 84, 126, }, - [7] = { 50, 94, 140, }, - [8] = { 52, 104, 157, }, - [9] = { 54, 116, 175, }, - [10] = { 56, 130, 194, }, - [11] = { 58, 144, 216, }, - [12] = { 60, 160, 240, }, - [13] = { 62, 178, 267, }, - [14] = { 64, 197, 296, }, - [15] = { 65, 208, 312, }, - [16] = { 66, 219, 328, }, - [17] = { 67, 230, 346, }, - [18] = { 68, 242, 364, }, - [19] = { 69, 255, 383, }, - [20] = { 70, 268, 403, }, - [21] = { 72, 297, 446, }, - [22] = { 74, 329, 493, }, - [23] = { 76, 363, 545, }, - [24] = { 78, 401, 602, }, - [25] = { 80, 443, 664, }, - [26] = { 82, 489, 733, }, - [27] = { 84, 539, 809, }, - [28] = { 86, 594, 892, }, - [29] = { 88, 655, 983, }, - [30] = { 90, 722, 1083, }, + [1] = { 38, 42, 63, }, + [2] = { 40, 47, 70, }, + [3] = { 42, 52, 78, }, + [4] = { 44, 58, 87, }, + [5] = { 46, 64, 97, }, + [6] = { 48, 71, 107, }, + [7] = { 50, 79, 118, }, + [8] = { 52, 87, 131, }, + [9] = { 54, 96, 144, }, + [10] = { 56, 106, 159, }, + [11] = { 58, 117, 175, }, + [12] = { 60, 129, 193, }, + [13] = { 62, 141, 212, }, + [14] = { 64, 155, 233, }, + [15] = { 65, 163, 244, }, + [16] = { 66, 171, 256, }, + [17] = { 67, 179, 268, }, + [18] = { 68, 187, 281, }, + [19] = { 69, 196, 294, }, + [20] = { 70, 205, 308, }, + [21] = { 72, 225, 337, }, + [22] = { 74, 246, 370, }, + [23] = { 76, 270, 405, }, + [24] = { 78, 295, 443, }, + [25] = { 80, 323, 484, }, + [26] = { 82, 353, 529, }, + [27] = { 84, 385, 578, }, + [28] = { 86, 421, 631, }, + [29] = { 88, 459, 689, }, + [30] = { 90, 501, 752, }, }, } skills["SupportIncreasedAreaOfEffect"] = { @@ -1920,14 +1924,14 @@ skills["SupportMulticast"] = { skills["SupportAilments"] = { name = "Unbound Ailments", gemTags = { - dexterity = true, + intelligence = true, support = true, }, gemTagString = "Support", gemStr = 0, - gemDex = 60, - gemInt = 40, - color = 2, + gemDex = 40, + gemInt = 60, + color = 3, support = true, requireSkillTypes = { 10, 1, }, addSkillTypes = { }, @@ -1941,7 +1945,7 @@ skills["SupportAilments"] = { levelMods = { [1] = nil, [2] = { mod("EnemyBleedDuration", "INC", nil), mod("EnemyPoisonDuration", "INC", nil), mod("EnemyIgniteDuration", "INC", nil), mod("EnemyShockDuration", "INC", nil), mod("EnemyChillDuration", "INC", nil), mod("EnemyFreezeDuration", "INC", nil) }, --"base_all_ailment_duration_+%" - [3] = mod("Damage", "INC", nil, 0, bit.bor(KeywordFlag.Bleed, KeywordFlag.Poison, KeywordFlag.Ignite)), --"support_ailments_effect_+%" + [3] = mod("AilmentEffect", "INC", nil), --"support_ailments_effect_+%" }, levels = { [1] = { 8, 30, 20, }, diff --git a/Data/3_0/Skills/sup_str.lua b/Data/3_0/Skills/sup_str.lua index fa2726da..5747781f 100644 --- a/Data/3_0/Skills/sup_str.lua +++ b/Data/3_0/Skills/sup_str.lua @@ -446,7 +446,7 @@ skills["SupportChanceToBleed"] = { support = true, requireSkillTypes = { 1, }, addSkillTypes = { }, - excludeSkillTypes = { }, + excludeSkillTypes = { 9, }, baseMods = { mod("ManaCost", "MORE", 20), mod("BleedChance", "BASE", 25, ModFlag.Attack), --"bleed_on_hit_with_attacks_%" = 25 @@ -456,8 +456,8 @@ skills["SupportChanceToBleed"] = { }, levelMods = { [1] = nil, - [2] = mod("PhysicalMin", "BASE", nil, 0, KeywordFlag.Attack, nil), --"attack_minimum_added_physical_damage" - [3] = mod("PhysicalMax", "BASE", nil, 0, KeywordFlag.Attack, nil), --"attack_maximum_added_physical_damage" + [2] = mod("PhysicalMin", "BASE", nil, ModFlag.Weapon, KeywordFlag.Attack, nil), --"attack_minimum_added_physical_damage_with_weapons" + [3] = mod("PhysicalMax", "BASE", nil, ModFlag.Weapon, KeywordFlag.Attack, nil), --"attack_maximum_added_physical_damage_with_weapons" }, levels = { [1] = { 8, 1, 2, }, @@ -1387,7 +1387,7 @@ skills["SupportMaim"] = { }, levelMods = { [1] = nil, - [2] = mod("PhysicalDamageTaken", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }, { type = "Condition", var = "Maimed" }), --"support_maimed_enemies_physical_damage_taken_+%" + [2] = mod("PhysicalDamageTaken", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff", effectName = "Maim" }, { type = "Condition", var = "Maimed" }), --"support_maimed_enemies_physical_damage_taken_+%" [3] = mod("PhysicalDamage", "MORE", nil), --"support_maim_chance_physical_damage_+%_final" }, levels = { diff --git a/Data/Global.lua b/Data/Global.lua index 8e2cec5f..48e7a931 100644 --- a/Data/Global.lua +++ b/Data/Global.lua @@ -86,6 +86,8 @@ KeywordFlag.Totem = 0x004000 KeywordFlag.Minion = 0x008000 KeywordFlag.Attack = 0x010000 KeywordFlag.Spell = 0x020000 +KeywordFlag.Hit = 0x040000 +KeywordFlag.Ailment = 0x080000 -- Other effects KeywordFlag.Poison = 0x100000 KeywordFlag.Bleed = 0x200000 diff --git a/Export/Skills/act_dex.txt b/Export/Skills/act_dex.txt index cf40a694..128c1a4b 100644 --- a/Export/Skills/act_dex.txt +++ b/Export/Skills/act_dex.txt @@ -50,7 +50,7 @@ local skills, mod, flag, skill = ... }, #setMod base_skill_show_average_damage_instead_of_dps==nil #baseMod skill("radius", 14) -#baseMod mod("Damage", "MORE", 120, 0, 0, { type = "SkillPart", skillPart = 2 }) +#baseMod mod("Damage", "MORE", 120, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }) #baseMod skill("dpsMultiplier", 3, { type = "SkillPart", skillPart = 3 }) #mods @@ -71,9 +71,9 @@ local skills, mod, flag, skill = ... }, }, #baseMod skill("radius", 15) -#baseMod mod("Damage", "MORE", 150, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 2 }) -#baseMod mod("Damage", "MORE", 300, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 3 }) -#baseMod mod("Damage", "MORE", 600, ModFlag.Spell, 0, { type = "SkillPart", skillPart = 4 }) +#baseMod mod("Damage", "MORE", 150, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }) +#baseMod mod("Damage", "MORE", 300, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 3 }) +#baseMod mod("Damage", "MORE", 600, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 4 }) #baseMod skill("hitTimeOverride", 0.6, { type = "SkillPart", skillPart = 1 }) #baseMod skill("hitTimeOverride", 0.4, { type = "SkillPart", skillPart = 2 }) #baseMod skill("hitTimeOverride", 0.3, { type = "SkillPart", skillPart = 3 }) @@ -342,6 +342,7 @@ local skills, mod, flag, skill = ... projectile = true, }, }, +#setMod active_skill_damage_over_time_from_projectile_hits_+%_final==mod("Damage", "MORE", {val}, ModFlag.Dot, 0, { type = "SkillPart", skillPart = 2 }) #mods #skill VaalLightningStrike diff --git a/Export/Skills/act_int.txt b/Export/Skills/act_int.txt index 1e35fca9..90eab641 100644 --- a/Export/Skills/act_int.txt +++ b/Export/Skills/act_int.txt @@ -175,7 +175,7 @@ local skills, mod, flag, skill = ... }, }, #setMod base_skill_show_average_damage_instead_of_dps==nil -#baseMod mod("Damage", "MORE", 990, 0, 0, { type = "SkillPart", skillPart = 2 }) +#baseMod mod("Damage", "MORE", 990, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }) #baseMod skill("dpsMultiplier", 0.1, { type = "SkillPart", skillPart = 2 }) #mods @@ -265,7 +265,7 @@ local skills, mod, flag, skill = ... name = "Fully charged", }, }, -#baseMod mod("Damage", "MORE", 150, 0, 0, { type = "SkillPart", skillPart = 2 }) +#baseMod mod("Damage", "MORE", 150, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "SkillPart", skillPart = 2 }) #mods #skill ClusterBurst diff --git a/Export/Skills/act_str.txt b/Export/Skills/act_str.txt index 410c8159..aea855ae 100644 --- a/Export/Skills/act_str.txt +++ b/Export/Skills/act_str.txt @@ -160,6 +160,7 @@ local skills, mod, flag, skill = ... area = true, }, }, +#setMod active_skill_damage_over_time_from_projectile_hits_+%_final==mod("Damage", "MORE", {val}, ModFlag.Dot, 0, { type = "SkillPart", skillPart = 2 }) #mods #skill Punishment diff --git a/Export/Skills/statmap.ini b/Export/Skills/statmap.ini index 823b25e8..8d789cbf 100644 --- a/Export/Skills/statmap.ini +++ b/Export/Skills/statmap.ini @@ -65,6 +65,8 @@ mod = skill("showAverage", true) mod = skill("castTimeOverridesAttackTime", true) [global_always_hit] mod = skill("cannotBeEvaded", true) +[bleed_duration_is_skill_duration] +mod = skill("bleedDurationIsSkillDuration", true) [poison_duration_is_skill_duration] mod = skill("poisonDurationIsSkillDuration", true) [spell_damage_modifiers_apply_to_skill_dot] @@ -137,6 +139,8 @@ div = 60 [base_mana_regeneration_rate_per_minute] mod = mod("ManaRegen", "BASE", {val}, 0, 0, {global}) div = 60 +[energy_shield_recharge_rate_+%] +mod = mod("EnergyShieldRecharge", "INC", {val}, 0, 0, {global}) [base_mana_cost_-%] mod = mod("ManaCost", "INC", {val}) mult = -1 @@ -237,9 +241,9 @@ mod = mod("ColdPenetration", "BASE", {val}) [base_reduce_enemy_lightning_resistance_%] mod = mod("LightningPenetration", "BASE", {val}) [support_minimum_added_fire_damage_vs_burning_enemies] -mod = mod("FireMin", "BASE", {val}, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }) +mod = mod("FireMin", "BASE", {val}, 0, 0, { type = "EnemyCondition", var = "Burning" }) [support_maximum_added_fire_damage_vs_burning_enemies] -mod = mod("FireMax", "BASE", {val}, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }) +mod = mod("FireMax", "BASE", {val}, 0, 0, { type = "EnemyCondition", var = "Burning" }) [global_minimum_added_cold_damage] mod = mod("ColdMin", "BASE", {val}) [global_maximum_added_cold_damage] @@ -319,7 +323,7 @@ mod = mod("Damage", "INC", {val}, 0, KeywordFlag.Bleed) [base_poison_damage_+%] mod = mod("Damage", "INC", {val}, 0, KeywordFlag.Poison) [support_ailments_effect_+%] -mod = mod("Damage", "INC", {val}, 0, bit.bor(KeywordFlag.Bleed, KeywordFlag.Poison, KeywordFlag.Ignite)) +mod = mod("AilmentEffect", "INC", {val}) # Global flags [never_ignite] mod = flag("CannotIgnite") @@ -436,6 +440,10 @@ mod = mod("ElementalDamage", "INC", {val}, 0, KeywordFlag.Attack) mod = mod("PhysicalMin", "BASE", {val}, 0, KeywordFlag.Attack, {global}) [attack_maximum_added_physical_damage] mod = mod("PhysicalMax", "BASE", {val}, 0, KeywordFlag.Attack, {global}) +[attack_minimum_added_physical_damage_with_weapons] +mod = mod("PhysicalMin", "BASE", {val}, ModFlag.Weapon, KeywordFlag.Attack, {global}) +[attack_maximum_added_physical_damage_with_weapons] +mod = mod("PhysicalMax", "BASE", {val}, ModFlag.Weapon, KeywordFlag.Attack, {global}) [attack_minimum_added_lightning_damage] mod = mod("LightningMin", "BASE", {val}, 0, KeywordFlag.Attack, {global}) [attack_maximum_added_lightning_damage] @@ -616,7 +624,7 @@ mod = skill("FireMax", {val}, { type = "Multiplier", var = "ExplosiveArrowFuse" mod = skill("radiusExtra", {val}, { type = "Multiplier", var = "ExplosiveArrowFuse" }) # Flame Surge [flame_whip_damage_+%_final_vs_burning_enemies] -mod = mod("Damage", "MORE", {val}, bit.bor(ModFlag.Spell, ModFlag.Hit), 0, { type = "EnemyCondition", var = "Burning" }) +mod = mod("Damage", "MORE", {val}, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Burning" }) # Flicker Strike [flicker_strike_more_attack_speed_+%_final] mod = mod("Speed", "MORE", {val}, ModFlag.Attack) @@ -648,12 +656,12 @@ mod = mod("Damage", "MORE", {val}, 0, 0, { type = "SkillPart", skillPart = 2 }) mod = mod("PhysicalDamage", "MORE", {val}, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "Buff" }) # Poacher's Mark [evasion_rating_+%_final_from_poachers_mark] -mod = mod("Evasion", "MORE", {val}, 0, 0, { type = "GlobalEffect", effectType = "Curse"}) +mod = mod("Evasion", "MORE", {val}, 0, 0, { type = "GlobalEffect", effectType = "Curse" }) # Punishment [newpunishment_attack_speed_+%] -mod = mod("Speed", "INC", {val}, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "Buff"}) +mod = mod("Speed", "INC", {val}, ModFlag.Attack, 0, { type = "GlobalEffect", effectType = "CurseBuff" }) [newpunishment_melee_damage_+%_final] -mod = mod("Damage", "MORE", {val}, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "Buff"}) +mod = mod("Damage", "MORE", {val}, ModFlag.Melee, 0, { type = "GlobalEffect", effectType = "CurseBuff" }) # Righteous Fire [righteous_fire_spell_damage_+%_final] mod = mod("Damage", "MORE", {val}, ModFlag.Spell, 0, {global}) @@ -773,7 +781,7 @@ mod = skill("auraCannotAffectSelf", true) mod = mod("Damage", "MORE", {val}, ModFlag.Projectile) # Hypothermia [support_hypothermia_damage_+%_vs_chilled_enemies_final] -mod = mod("Damage", "MORE", {val}, ModFlag.Hit, 0, { type = "EnemyCondition", var = "Chilled" }) +mod = mod("Damage", "MORE", {val}, 0, bit.bor(KeywordFlag.Hit, KeywordFlag.Ailment), { type = "EnemyCondition", var = "Chilled" }) # Lesser Multiple Projectiles [support_lesser_multiple_projectile_damage_+%_final] mod = mod("Damage", "MORE", {val}, ModFlag.Projectile) @@ -786,7 +794,7 @@ mod = mod("Damage", "MORE", {val}) [support_maim_chance_physical_damage_+%_final] mod = mod("PhysicalDamage", "MORE", {val}) [support_maimed_enemies_physical_damage_taken_+%] -mod = mod("PhysicalDamageTaken", "INC", {val}, 0, 0, { type = "GlobalEffect", effectType = "Debuff" }, { type = "Condition", var = "Maimed" }) +mod = mod("PhysicalDamageTaken", "INC", {val}, 0, 0, { type = "GlobalEffect", effectType = "Debuff", effectName = "Maim" }, { type = "Condition", var = "Maimed" }) # Melee Physical on Full Life [support_melee_physical_damage_+%_final_while_on_full_life] mod = mod("PhysicalDamage", "MORE", {val}, ModFlag.Melee, 0, { type = "Condition", var = "FullLife" }) diff --git a/Modules/Build.lua b/Modules/Build.lua index de09c868..484b5be3 100644 --- a/Modules/Build.lua +++ b/Modules/Build.lua @@ -265,7 +265,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, targetVersion) { stat = "EnergyShieldLeechGainPerHit", label = "ES Leech/Gain per Hit", fmt = ".1f", compPercent = true }, { stat = "Evasion", label = "Evasion rating", fmt = "d", compPercent = true }, { stat = "Spec:EvasionInc", label = "%Inc Evasion from Tree", fmt = "d%%" }, - { stat = "EvadeChance", label = "Evade Chance", fmt = "d%%", condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance == o.ProjectileEvadeChance end }, + { stat = "MeleeEvadeChance", label = "Evade Chance", fmt = "d%%", condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance == o.ProjectileEvadeChance end }, { stat = "MeleeEvadeChance", label = "Melee Evade Chance", fmt = "d%%", condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance ~= o.ProjectileEvadeChance end }, { stat = "ProjectileEvadeChance", label = "Projectile Evade Chance", fmt = "d%%", condFunc = function(v,o) return v > 0 and o.MeleeEvadeChance ~= o.ProjectileEvadeChance end }, { stat = "Armour", label = "Armour", fmt = "d", compPercent = true }, @@ -293,6 +293,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, targetVersion) { stat = "TotalDPS", label = "Total DPS", fmt = ".1f", compPercent = true }, { stat = "TotalDot", label = "DoT DPS", fmt = ".1f", compPercent = true }, { stat = "WithPoisonDPS", label = "DPS inc. Poison", fmt = ".1f", compPercent = true }, + { stat = "DecayDPS", label = "Decay DPS", fmt = ".1f", compPercent = true }, { stat = "Cooldown", label = "Skill Cooldown", fmt = ".2fs", lowerIsBetter = true }, { stat = "Life", label = "Total Life", fmt = ".1f", compPercent = true }, { stat = "LifeRegen", label = "Life Regen", fmt = ".1f" }, diff --git a/Modules/CalcActiveSkill.lua b/Modules/CalcActiveSkill.lua index d91ee3eb..f23e942c 100644 --- a/Modules/CalcActiveSkill.lua +++ b/Modules/CalcActiveSkill.lua @@ -90,6 +90,7 @@ function calcs.createActiveSkill(activeGem, supportList, summonSkill) supportList = supportList, summonSkill = summonSkill, skillData = { }, + buffList = { }, } -- Initialise skill types @@ -268,6 +269,9 @@ function calcs.buildActiveSkillModList(env, actor, activeSkill) -- Build skill keyword flag set local skillKeywordFlags = 0 + if skillFlags.hit then + skillKeywordFlags = bor(skillKeywordFlags, KeywordFlag.Hit) + end if skillFlags.aura then skillKeywordFlags = bor(skillKeywordFlags, KeywordFlag.Aura) end @@ -432,38 +436,43 @@ function calcs.buildActiveSkillModList(env, actor, activeSkill) -- Separate global effect modifiers (mods that can affect defensive stats or other skills) local i = 1 while skillModList[i] do - local destList + local effectType, effectName for _, tag in ipairs(skillModList[i].tagList) do if tag.type == "GlobalEffect" then - if tag.effectType == "Buff" then - destList = "buffModList" - elseif tag.effectType == "Aura" then - destList = "auraModList" - elseif tag.effectType == "Debuff" then - destList = "debuffModList" - elseif tag.effectType == "Curse" then - destList = "curseModList" - end + effectType = tag.effectType + effectName = tag.effectName or activeSkill.activeGem.grantedEffect.name break end end - if destList then - if not activeSkill[destList] then - activeSkill[destList] = { } + if effectType then + local buff + for _, skillBuff in ipairs(activeSkill.buffList) do + if skillBuff.type == effectType and skillBuff.name == effectName then + buff = skillBuff + break + end + end + if not buff then + buff = { + type = effectType, + name = effectName, + modList = { }, + } + t_insert(activeSkill.buffList, buff) end local sig = modLib.formatModParams(skillModList[i]) - for d = 1, #activeSkill[destList] do - local destMod = activeSkill[destList][d] + for d = 1, #buff.modList do + local destMod = buff.modList[d] if sig == modLib.formatModParams(destMod) and (destMod.type == "BASE" or destMod.type == "INC") then destMod = copyTable(destMod) destMod.value = destMod.value + skillModList[i].value - activeSkill[destList][d] = destMod + buff.modList[d] = destMod sig = nil break end end if sig then - t_insert(activeSkill[destList], skillModList[i]) + t_insert(buff.modList, skillModList[i]) end t_remove(skillModList, i) else @@ -471,7 +480,7 @@ function calcs.buildActiveSkillModList(env, actor, activeSkill) end end - if activeSkill.buffModList or activeSkill.auraModList or activeSkill.debuffModList or activeSkill.curseModList then + if activeSkill.buffList[1] then -- Add to auxillary skill list t_insert(env.auxSkillList, activeSkill) end diff --git a/Modules/CalcDefence-2_6.lua b/Modules/CalcDefence-2_6.lua index 8c33f4e4..5e9a48f5 100644 --- a/Modules/CalcDefence-2_6.lua +++ b/Modules/CalcDefence-2_6.lua @@ -200,8 +200,8 @@ function calcs.defence(env, actor) s_format("Approximate evade chance: %d%%", output.EvadeChance), } end - output.MeleeEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "MeleeEvadeChance"))) - output.ProjectileEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "ProjectileEvadeChance"))) + output.MeleeEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "EvadeChance", "MeleeEvadeChance"))) + output.ProjectileEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "EvadeChance", "ProjectileEvadeChance"))) end end diff --git a/Modules/CalcDefence-3_0.lua b/Modules/CalcDefence-3_0.lua index dbdf8ad8..bd02266c 100644 --- a/Modules/CalcDefence-3_0.lua +++ b/Modules/CalcDefence-3_0.lua @@ -200,8 +200,8 @@ function calcs.defence(env, actor) s_format("Approximate evade chance: %d%%", output.EvadeChance), } end - output.MeleeEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "MeleeEvadeChance"))) - output.ProjectileEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "ProjectileEvadeChance"))) + output.MeleeEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "EvadeChance", "MeleeEvadeChance"))) + output.ProjectileEvadeChance = m_max(5, m_min(95, output.EvadeChance * calcLib.mod(modDB, nil, "EvadeChance", "ProjectileEvadeChance"))) end end diff --git a/Modules/CalcOffence-3_0.lua b/Modules/CalcOffence-3_0.lua index fbc7fed7..78055ab7 100644 --- a/Modules/CalcOffence-3_0.lua +++ b/Modules/CalcOffence-3_0.lua @@ -1245,7 +1245,7 @@ function calcs.offence(env, actor) skillPart = skillCfg.skillPart, slotName = skillCfg.slotName, flags = ModFlag.Dot, - keywordFlags = bor(skillCfg.keywordFlags, KeywordFlag.Bleed), + keywordFlags = bor(band(skillCfg.keywordFlags, bnot(KeywordFlag.Hit)), KeywordFlag.Bleed, KeywordFlag.Ailment), skillCond = { }, } end @@ -1277,14 +1277,23 @@ function calcs.offence(env, actor) globalBreakdown.BleedEffMult = breakdown.effMult("Physical", resist, 0, taken, effMult) end end - output.BleedDPS = baseVal * effMult + local effectMod = calcLib.mod(modDB, dotCfg, "AilmentEffect") + output.BleedDPS = baseVal * effectMod * effMult local durationMod = calcLib.mod(modDB, dotCfg, "EnemyBleedDuration", "SkillAndDamagingAilmentDuration", skillData.bleedIsSkillEffect and "Duration" or nil) * calcLib.mod(enemyDB, nil, "SelfBleedDuration") globalOutput.BleedDuration = 5 * durationMod * debuffDurationMult if breakdown then t_insert(breakdown.BleedDPS, s_format("x %.2f ^8(bleed deals %d%% per second)", basePercent/100, basePercent)) + if effectMod ~= 1 then + t_insert(breakdown.BleedDPS, s_format("x %.2f ^8(ailment effect modifier)", effectMod)) + end t_insert(breakdown.BleedDPS, s_format("= %.1f", baseVal)) - t_insert(breakdown.BleedDPS, "Bleed DPS:") - breakdown.dot(breakdown.BleedDPS, baseVal, 0, 1, nil, effMult, output.BleedDPS) + breakdown.multiChain(breakdown.BleedDPS, { + label = "Bleed DPS:", + base = s_format("%.1f ^8(base damage per second)", baseVal), + { "%.2f ^8(ailment effect modifier)", effectMod }, + { "%.3f ^8(effective DPS modifier)", effMult }, + total = s_format("= %.1f ^8per second", output.BleedDPS), + }) if globalOutput.BleedDuration ~= 5 then globalBreakdown.BleedDuration = { "5.00s ^8(base duration)" @@ -1309,7 +1318,7 @@ function calcs.offence(env, actor) skillPart = skillCfg.skillPart, slotName = skillCfg.slotName, flags = ModFlag.Dot, - keywordFlags = bor(skillCfg.keywordFlags, KeywordFlag.Poison), + keywordFlags = bor(band(skillCfg.keywordFlags, bnot(KeywordFlag.Hit)), KeywordFlag.Poison, KeywordFlag.Ailment), skillCond = { }, } end @@ -1348,7 +1357,8 @@ function calcs.offence(env, actor) globalBreakdown.PoisonEffMult = breakdown.effMult("Chaos", resist, 0, taken, effMult) end end - output.PoisonDPS = baseVal * effMult + local effectMod = calcLib.mod(modDB, dotCfg, "AilmentEffect") + output.PoisonDPS = baseVal * effectMod * effMult local durationBase if skillData.poisonDurationIsSkillDuration then durationBase = skillData.duration @@ -1367,8 +1377,13 @@ function calcs.offence(env, actor) if breakdown then t_insert(breakdown.PoisonDPS, "x 0.16 ^8(poison deals 16% per second)") t_insert(breakdown.PoisonDPS, s_format("= %.1f", baseVal, 1)) - t_insert(breakdown.PoisonDPS, "Poison DPS:") - breakdown.dot(breakdown.PoisonDPS, baseVal, 0, 1, nil, effMult, output.PoisonDPS) + breakdown.multiChain(breakdown.PoisonDPS, { + label = "Poison DPS:", + base = s_format("%.1f ^8(base damage per second)", baseVal), + { "%.2f ^8(ailment effect modifier)", effectMod }, + { "%.3f ^8(effective DPS modifier)", effMult }, + total = s_format("= %.1f ^8per second", output.PoisonDPS), + }) if globalOutput.PoisonDuration ~= 2 then globalBreakdown.PoisonDuration = { s_format("%.2fs ^8(base duration)", durationBase) @@ -1414,7 +1429,7 @@ function calcs.offence(env, actor) skillPart = skillCfg.skillPart, slotName = skillCfg.slotName, flags = ModFlag.Dot, - keywordFlags = bor(skillCfg.keywordFlags, KeywordFlag.Ignite), + keywordFlags = bor(band(skillCfg.keywordFlags, bnot(KeywordFlag.Hit)), KeywordFlag.Ignite, KeywordFlag.Ailment), skillCond = { }, } end @@ -1461,8 +1476,9 @@ function calcs.offence(env, actor) globalBreakdown.IgniteEffMult = breakdown.effMult("Fire", resist, 0, taken, effMult) end end + local effectMod = calcLib.mod(modDB, dotCfg, "AilmentEffect") local burnRateMod = calcLib.mod(modDB, cfg, "IgniteBurnRate") - output.IgniteDPS = baseVal * burnRateMod * effMult + output.IgniteDPS = baseVal * effectMod * burnRateMod * effMult local incDur = modDB:Sum("INC", dotCfg, "EnemyIgniteDuration", "SkillAndDamagingAilmentDuration") + enemyDB:Sum("INC", nil, "SelfIgniteDuration") local moreDur = enemyDB:Sum("MORE", nil, "SelfIgniteDuration") globalOutput.IgniteDuration = 4 * (1 + incDur / 100) * moreDur / burnRateMod * debuffDurationMult @@ -1478,8 +1494,14 @@ function calcs.offence(env, actor) if breakdown then t_insert(breakdown.IgniteDPS, "x 0.4 ^8(ignite deals 40% per second)") t_insert(breakdown.IgniteDPS, s_format("= %.1f", baseVal, 1)) - t_insert(breakdown.IgniteDPS, "Ignite DPS:") - breakdown.dot(breakdown.IgniteDPS, baseVal, 0, 1, burnRateMod, effMult, output.IgniteDPS) + breakdown.multiChain(breakdown.IgniteDPS, { + label = "Ignite DPS:", + base = s_format("%.1f ^8(base damage per second)", baseVal), + { "%.2f ^8(ailment effect modifier)", effectMod }, + { "%.2f ^8(burn rate modifier)", burnRateMod }, + { "%.3f ^8(effective DPS modifier)", effMult }, + total = s_format("= %.1f ^8per second", output.IgniteDPS), + }) if skillFlags.igniteCanStack then breakdown.IgniteDamage = { } if isAttack then @@ -1641,7 +1663,7 @@ function calcs.offence(env, actor) skillPart = skillCfg.skillPart, slotName = skillCfg.slotName, flags = ModFlag.Dot, - keywordFlags = skillCfg.keywordFlags, + keywordFlags = band(skillCfg.keywordFlags, bnot(KeywordFlag.Hit)), } local dotCfg = mainSkill.decayCfg local effMult = 1 diff --git a/Modules/CalcPerform.lua b/Modules/CalcPerform.lua index 925345e0..31c129f7 100644 --- a/Modules/CalcPerform.lua +++ b/Modules/CalcPerform.lua @@ -511,8 +511,11 @@ function calcs.perform(env) -- Combine buffs/debuffs output.EnemyCurseLimit = modDB:Sum("BASE", nil, "EnemyCurseLimit") local buffs = { } + env.buffs = buffs local minionBuffs = { } + env.minionBuffs = minionBuffs local debuffs = { } + env.debuffs = debuffs local curses = { limit = output.EnemyCurseLimit, } @@ -523,123 +526,121 @@ function calcs.perform(env) for _, activeSkill in ipairs(env.activeSkillList) do local skillModList = activeSkill.skillModList local skillCfg = activeSkill.skillCfg - if env.mode_buffs then - if activeSkill.buffModList and - not activeSkill.skillFlags.curse and - (not activeSkill.skillFlags.totem or activeSkill.skillData.allowTotemBuff) then - if not activeSkill.skillData.buffNotPlayer then - activeSkill.buffSkill = true - local srcList = common.New("ModList") - local inc = modDB:Sum("INC", skillCfg, "BuffEffect", "BuffEffectOnSelf") - local more = modDB:Sum("MORE", skillCfg, "BuffEffect", "BuffEffectOnSelf") - srcList:ScaleAddList(activeSkill.buffModList, (1 + inc / 100) * more) - mergeBuff(srcList, buffs, activeSkill.activeGem.grantedEffect.name) + for _, buff in ipairs(activeSkill.buffList) do + if buff.type == "Buff" then + if env.mode_buffs and (not activeSkill.skillFlags.totem or activeSkill.skillData.allowTotemBuff) then + if not activeSkill.skillData.buffNotPlayer then + activeSkill.buffSkill = true + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "BuffEffect", "BuffEffectOnSelf") + local more = modDB:Sum("MORE", skillCfg, "BuffEffect", "BuffEffectOnSelf") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + mergeBuff(srcList, buffs, buff.name) + end + if env.minion and (activeSkill.skillData.buffMinions or activeSkill.skillData.buffAllies) then + activeSkill.minionBuffSkill = true + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "BuffEffect") + env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf") + local more = modDB:Sum("MORE", skillCfg, "BuffEffect") * env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + mergeBuff(srcList, minionBuffs, buff.name) + end end - if env.minion and (activeSkill.skillData.buffMinions or activeSkill.skillData.buffAllies) then - activeSkill.minionBuffSkill = true - local srcList = common.New("ModList") - local inc = modDB:Sum("INC", skillCfg, "BuffEffect") + env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf") - local more = modDB:Sum("MORE", skillCfg, "BuffEffect") * env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf") - srcList:ScaleAddList(activeSkill.buffModList, (1 + inc / 100) * more) - mergeBuff(srcList, minionBuffs, activeSkill.activeGem.grantedEffect.name) + elseif buff.type == "Aura" then + if env.mode_buffs then + if not activeSkill.skillData.auraCannotAffectSelf then + activeSkill.buffSkill = true + affectedByAura[env.player] = true + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "AuraEffect", "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") + local more = modDB:Sum("MORE", skillCfg, "AuraEffect", "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + srcList:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) + mergeBuff(srcList, buffs, buff.name) + end + if env.minion and not modDB:Sum("FLAG", nil, "YourAurasCannotAffectAllies") then + activeSkill.minionBuffSkill = true + affectedByAura[env.minion] = true + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "AuraEffect") + env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") + local more = modDB:Sum("MORE", skillCfg, "AuraEffect") * env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + srcList:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) + mergeBuff(srcList, minionBuffs, buff.name) + end end - end - if activeSkill.auraModList then - if not activeSkill.skillData.auraCannotAffectSelf then - activeSkill.buffSkill = true - affectedByAura[env.player] = true + elseif buff.type == "Debuff" then + if env.mode_effective then + activeSkill.debuffSkill = true local srcList = common.New("ModList") - local inc = modDB:Sum("INC", skillCfg, "AuraEffect", "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") - local more = modDB:Sum("MORE", skillCfg, "AuraEffect", "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") - srcList:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) - srcList:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) - mergeBuff(srcList, buffs, activeSkill.activeGem.grantedEffect.name) + srcList:ScaleAddList(buff.modList, activeSkill.skillData.stackCount or 1) + mergeBuff(srcList, debuffs, buff.name) end - if env.minion and not modDB:Sum("FLAG", nil, "YourAurasCannotAffectAllies") then - activeSkill.minionBuffSkill = true - affectedByAura[env.minion] = true - local srcList = common.New("ModList") - local inc = modDB:Sum("INC", skillCfg, "AuraEffect") + env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") - local more = modDB:Sum("MORE", skillCfg, "AuraEffect") * env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") - srcList:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) - srcList:ScaleAddList(extraAuraModList, (1 + inc / 100) * more) - mergeBuff(srcList, minionBuffs, activeSkill.activeGem.grantedEffect.name) - end - end - if activeSkill.minion then - for _, activeSkill in ipairs(activeSkill.minion.activeSkillList) do - local skillModList = activeSkill.skillModList - local skillCfg = activeSkill.skillCfg - if activeSkill.auraModList and activeSkill.skillData.enable then - if not modDB:Sum("FLAG", nil, "AlliesAurasCannotAffectSelf") then - local srcList = common.New("ModList") - local inc = modDB:Sum("INC", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") - local more = modDB:Sum("MORE", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") - srcList:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) - mergeBuff(srcList, buffs, activeSkill.activeGem.grantedEffect.id) - end - if env.minion and (env.minion ~= activeSkill.minion or not activeSkill.skillData.auraCannotAffectSelf) then - local srcList = common.New("ModList") - local inc = env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") - local more = env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") - srcList:ScaleAddList(activeSkill.auraModList, (1 + inc / 100) * more) - mergeBuff(srcList, minionBuffs, activeSkill.activeGem.grantedEffect.id) + elseif buff.type == "Curse" or buff.type == "CurseBuff" then + if env.mode_effective and (not enemyDB:Sum("FLAG", nil, "Hexproof") or modDB:Sum("FLAG", nil, "CursesIgnoreHexproof")) then + local curse = { + name = buff.name, + fromPlayer = true, + priority = activeSkill.skillTypes[SkillType.Aura] and 3 or 1, + } + local inc = modDB:Sum("INC", skillCfg, "CurseEffect") + enemyDB:Sum("INC", nil, "CurseEffectOnSelf") + skillModList:Sum("INC", skillCfg, "CurseEffect") + local more = modDB:Sum("MORE", skillCfg, "CurseEffect") * enemyDB:Sum("MORE", nil, "CurseEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "CurseEffect") + if buff.type == "Curse" then + curse.modList = common.New("ModList") + curse.modList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + else + -- Curse applies a buff; scale by curse effect, then buff effect + local temp = common.New("ModList") + temp:ScaleAddList(buff.modList, (1 + inc / 100) * more) + curse.buffModList = common.New("ModList") + local buffInc = modDB:Sum("INC", skillCfg, "BuffEffectOnSelf") + local buffMore = modDB:Sum("MORE", skillCfg, "BuffEffectOnSelf") + curse.buffModList:ScaleAddList(temp, (1 + buffInc / 100) * buffMore) + if env.minion then + curse.minionBuffModList = common.New("ModList") + local buffInc = env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf") + local buffMore = env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf") + curse.minionBuffModList:ScaleAddList(temp, (1 + buffInc / 100) * buffMore) end end + t_insert(curses, curse) end end end - if env.mode_effective then - if activeSkill.debuffModList then - activeSkill.debuffSkill = true - local srcList = common.New("ModList") - srcList:ScaleAddList(activeSkill.debuffModList, activeSkill.skillData.stackCount or 1) - mergeBuff(srcList, debuffs, activeSkill.activeGem.grantedEffect.name) - end - if (activeSkill.curseModList or (activeSkill.skillFlags.curse and activeSkill.buffModList)) - and (not enemyDB:Sum("FLAG", nil, "Hexproof") or modDB:Sum("FLAG", nil, "CursesIgnoreHexproof")) then - local curse = { - name = activeSkill.activeGem.grantedEffect.name, - fromPlayer = true, - priority = activeSkill.skillTypes[SkillType.Aura] and 3 or 1, - } - local inc = modDB:Sum("INC", skillCfg, "CurseEffect") + enemyDB:Sum("INC", nil, "CurseEffectOnSelf") + skillModList:Sum("INC", skillCfg, "CurseEffect") - local more = modDB:Sum("MORE", skillCfg, "CurseEffect") * enemyDB:Sum("MORE", nil, "CurseEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "CurseEffect") - 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, "BuffEffectOnSelf") - local buffMore = modDB:Sum("MORE", skillCfg, "BuffEffectOnSelf") - curse.buffModList:ScaleAddList(temp, (1 + buffInc / 100) * buffMore) - if env.minion then - curse.minionBuffModList = common.New("ModList") - local buffInc = env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf") - local buffMore = env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf") - curse.minionBuffModList:ScaleAddList(temp, (1 + buffInc / 100) * buffMore) - end - end - t_insert(curses, curse) - end - if activeSkill.minion then - for _, activeSkill in ipairs(activeSkill.minion.activeSkillList) do - local skillModList = activeSkill.skillModList - local skillCfg = activeSkill.skillCfg - if activeSkill.curseModList and activeSkill.skillData.enable and not enemyDB:Sum("FLAG", nil, "Hexproof") then - local curse = { - name = activeSkill.activeGem.grantedEffect.name, - priority = 1, - } - local inc = enemyDB:Sum("INC", nil, "CurseEffectOnSelf") + skillModList:Sum("INC", skillCfg, "CurseEffect") - local more = enemyDB:Sum("MORE", nil, "CurseEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "CurseEffect") - curse.modList = common.New("ModList") - curse.modList:ScaleAddList(activeSkill.curseModList, (1 + inc / 100) * more) - t_insert(minionCurses, curse) + if activeSkill.minion then + for _, activeSkill in ipairs(activeSkill.minion.activeSkillList) do + local skillModList = activeSkill.skillModList + local skillCfg = activeSkill.skillCfg + for _, buff in ipairs(activeSkill.buffList) do + if buff.type == "Aura" then + if env.mode_buffs and activeSkill.skillData.enable then + if not modDB:Sum("FLAG", nil, "AlliesAurasCannotAffectSelf") then + local srcList = common.New("ModList") + local inc = modDB:Sum("INC", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") + local more = modDB:Sum("MORE", skillCfg, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + mergeBuff(srcList, buffs, buff.name) + end + if env.minion and (env.minion ~= activeSkill.minion or not activeSkill.skillData.auraCannotAffectSelf) then + local srcList = common.New("ModList") + local inc = env.minion.modDB:Sum("INC", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") + skillModList:Sum("INC", skillCfg, "AuraEffect") + local more = env.minion.modDB:Sum("MORE", nil, "BuffEffectOnSelf", "AuraEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "AuraEffect") + srcList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + mergeBuff(srcList, minionBuffs, buff.name) + end + end + elseif buff.type == "Curse" then + if env.mode_effective and activeSkill.skillData.enable and not enemyDB:Sum("FLAG", nil, "Hexproof") then + local curse = { + name = buff.name, + priority = 1, + } + local inc = enemyDB:Sum("INC", nil, "CurseEffectOnSelf") + skillModList:Sum("INC", skillCfg, "CurseEffect") + local more = enemyDB:Sum("MORE", nil, "CurseEffectOnSelf") * skillModList:Sum("MORE", skillCfg, "CurseEffect") + curse.modList = common.New("ModList") + curse.modList:ScaleAddList(buff.modList, (1 + inc / 100) * more) + t_insert(minionCurses, curse) + end end end end diff --git a/Modules/CalcTools.lua b/Modules/CalcTools.lua index 42356650..fb33c9fc 100644 --- a/Modules/CalcTools.lua +++ b/Modules/CalcTools.lua @@ -40,14 +40,18 @@ end -- Validate the level of the given gem function calcLib.validateGemLevel(gem) if not gem.grantedEffect.levels[gem.level] then - -- Try limiting to the level range of the gem - gem.level = m_max(1, gem.level) - if #gem.grantedEffect.levels > 0 then - gem.level = m_min(#gem.grantedEffect.levels, gem.level) - end - if not gem.grantedEffect.levels[gem.level] then - -- That failed, so just grab any level - gem.level = next(gem.grantedEffect.levels) + if gem.grantedEffect.defaultLevel then + gem.level = gem.grantedEffect.defaultLevel + else + -- Try limiting to the level range of the gem + gem.level = m_max(1, gem.level) + if #gem.grantedEffect.levels > 0 then + gem.level = m_min(#gem.grantedEffect.levels, gem.level) + end + if not gem.grantedEffect.levels[gem.level] then + -- That failed, so just grab any level + gem.level = next(gem.grantedEffect.levels) + end end end end diff --git a/Modules/Calcs.lua b/Modules/Calcs.lua index 8e0a6f39..40f41535 100644 --- a/Modules/Calcs.lua +++ b/Modules/Calcs.lua @@ -219,24 +219,49 @@ function calcs.buildOutput(build, mode) if env.modDB:Sum("FLAG", nil, "UnholyMight") then t_insert(combatList, "Unholy Might") end - for _, activeSkill in ipairs(env.activeSkillList) do - if activeSkill.buffSkill then - if activeSkill.skillFlags.multiPart then - t_insert(buffList, activeSkill.activeGem.grantedEffect.name .. " (" .. activeSkill.skillPartName .. ")") - else - t_insert(buffList, activeSkill.activeGem.grantedEffect.name) + for name in pairs(env.buffs) do + t_insert(buffList, name) + end + table.sort(buffList) + env.player.breakdown.SkillBuffs = { modList = { } } + for _, name in ipairs(buffList) do + for _, mod in ipairs(env.buffs[name]) do + local value = env.modDB:EvalMod(mod) + if value and value ~= 0 then + t_insert(env.player.breakdown.SkillBuffs.modList, { + mod = mod, + value = value, + }) end end - if activeSkill.debuffSkill then - if activeSkill.skillFlags.multiPart then - t_insert(curseList, activeSkill.activeGem.grantedEffect.name .. " (" .. activeSkill.skillPartName .. ")") - else - t_insert(curseList, activeSkill.activeGem.grantedEffect.name) + end + env.player.breakdown.SkillDebuffs = { modList = { } } + for name in pairs(env.debuffs) do + t_insert(curseList, name) + end + table.sort(curseList) + for _, name in ipairs(curseList) do + for _, mod in ipairs(env.debuffs[name]) do + local value = env.enemy.modDB:EvalMod(mod) + if value and value ~= 0 then + t_insert(env.player.breakdown.SkillDebuffs.modList, { + mod = mod, + value = value, + }) end end end for _, slot in ipairs(env.curseSlots) do t_insert(curseList, slot.name) + for _, mod in ipairs(slot.modList) do + local value = env.enemy.modDB:EvalMod(mod) + if value and value ~= 0 then + t_insert(env.player.breakdown.SkillDebuffs.modList, { + mod = mod, + value = value, + }) + end + end end output.BuffList = table.concat(buffList, ", ") output.CombatList = table.concat(combatList, ", ") @@ -262,15 +287,23 @@ function calcs.buildOutput(build, mode) if env.minion.modDB:Sum("FLAG", nil, "UnholyMight") then t_insert(combatList, "Unholy Might") end - for _, activeSkill in ipairs(env.activeSkillList) do - if activeSkill.minionBuffSkill then - if activeSkill.skillFlags.multiPart then - t_insert(buffList, activeSkill.activeGem.grantedEffect.name .. " (" .. activeSkill.skillPartName .. ")") - else - t_insert(buffList, activeSkill.activeGem.grantedEffect.name) + for name in pairs(env.minionBuffs) do + t_insert(buffList, name) + end + table.sort(buffList) + env.minion.breakdown.SkillBuffs = { modList = { } } + for _, name in ipairs(buffList) do + for _, mod in ipairs(env.minionBuffs[name]) do + local value = env.minion.modDB:EvalMod(mod) + if value and value ~= 0 then + t_insert(env.minion.breakdown.SkillBuffs.modList, { + mod = mod, + value = value, + }) end end end + env.minion.breakdown.SkillDebuffs = env.player.breakdown.SkillDebuffs output.Minion.BuffList = table.concat(buffList, ", ") output.Minion.CombatList = table.concat(combatList, ", ") output.Minion.CurseList = output.CurseList diff --git a/Modules/ModParser-2_6.lua b/Modules/ModParser-2_6.lua index c2617388..8b859e6f 100644 --- a/Modules/ModParser-2_6.lua +++ b/Modules/ModParser-2_6.lua @@ -88,6 +88,8 @@ local modNameList = { ["evasion and energy shield"] = "EvasionAndEnergyShield", ["armour, evasion and energy shield"] = "Defences", ["defences"] = "Defences", + ["chance to evade"] = "EvadeChance", + ["chance to evade attacks"] = "EvadeChance", ["chance to evade projectile attacks"] = "ProjectileEvadeChance", ["chance to evade melee attacks"] = "MeleeEvadeChance", -- Resistances @@ -488,6 +490,7 @@ local modTagList = { ["wh[ie][ln]e? not on full life"] = { tag = { type = "Condition", var = "FullLife", neg = true } }, ["wh[ie][ln]e? no mana is reserved"] = { tag = { type = "Condition", var = "NoManaReserved" } }, ["wh[ie][ln]e? on full energy shield"] = { tag = { type = "Condition", var = "FullEnergyShield" } }, + ["wh[ie][ln]e? not on full energy shield"] = { tag = { type = "Condition", var = "FullEnergyShield", neg = true } }, ["while you have no power charges"] = { tag = { type = "Condition", var = "HaveNoPowerCharges" } }, ["while you have no frenzy charges"] = { tag = { type = "Condition", var = "HaveNoFrenzyCharges" } }, ["while you have no endurance charges"] = { tag = { type = "Condition", var = "HaveNoEnduranceCharges" } }, diff --git a/Modules/ModParser-3_0.lua b/Modules/ModParser-3_0.lua index 6e6223ce..99549cba 100644 --- a/Modules/ModParser-3_0.lua +++ b/Modules/ModParser-3_0.lua @@ -88,6 +88,8 @@ local modNameList = { ["evasion and energy shield"] = "EvasionAndEnergyShield", ["armour, evasion and energy shield"] = "Defences", ["defences"] = "Defences", + ["chance to evade"] = "EvadeChance", + ["chance to evade attacks"] = "EvadeChance", ["chance to evade projectile attacks"] = "ProjectileEvadeChance", ["chance to evade melee attacks"] = "MeleeEvadeChance", -- Resistances @@ -492,6 +494,7 @@ local modTagList = { ["wh[ie][ln]e? not on full life"] = { tag = { type = "Condition", var = "FullLife", neg = true } }, ["wh[ie][ln]e? no mana is reserved"] = { tag = { type = "Condition", var = "NoManaReserved" } }, ["wh[ie][ln]e? on full energy shield"] = { tag = { type = "Condition", var = "FullEnergyShield" } }, + ["wh[ie][ln]e? not on full energy shield"] = { tag = { type = "Condition", var = "FullEnergyShield", neg = true } }, ["while you have no power charges"] = { tag = { type = "Condition", var = "HaveNoPowerCharges" } }, ["while you have no frenzy charges"] = { tag = { type = "Condition", var = "HaveNoFrenzyCharges" } }, ["while you have no endurance charges"] = { tag = { type = "Condition", var = "HaveNoEnduranceCharges" } }, diff --git a/README.md b/README.md index 8d3fef57..6fd56bf4 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,23 @@ If you'd like to help support the development of Path of Building, I have a [Pat ![ss3](https://cloud.githubusercontent.com/assets/19189971/18089780/f0ff234a-6f04-11e6-8c88-6193fe59a5c4.png) ## Changelog +### 1.4.31 - 2017/06/16 + * The Buff/Debuff Skill lists in the Calcs tab now have breakdowns that list all the modifiers granted by those skills + * Added an option to the Configuration tab for "Are you always on full Energy Shield?" + * Fixed issue causing gems with a low maximum level to sometimes be assigned the wrong default level + * Fixed issue causing the slot dropdown in the Skills tab to fail to update correctly under some conditions +For 3.0 builds: + * The new support gems have been updated with the new data from the beta patch + * Applied the following changes from the beta patch: + * Blade Vortex's per-blade damage multiplier now applies to Ailments + * Flameblast's per-stage damage multiplier no longer applies to Decay + * Incinerate's per-stage damage multiplier no longer applies to Decay + * Blade Flurry's per-stage damage multiplier no longer applies to Decay + * Minion's Decay DPS is now shown in the sidebar + * Immolate and Hypothermia's conditional modifiers now apply to Ailments + * Unbound Ailments's modifier to Effect of Ailments should now function correctly + * Fixed issue causing the "increased Physical Damage taken" stat from Maim Support to sometimes apply multiple times + ### 1.4.30 - 2017/06/16 * Mind over Matter is now displayed in the Damage Taken section of the Calcs tab, instead of Other Defences For 3.0 builds: diff --git a/changelog.txt b/changelog.txt index abe0c2cd..e10f29e6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,19 @@ +VERSION[1.4.31][2017/06/16] + * The Buff/Debuff Skill lists in the Calcs tab now have breakdowns that list all the modifiers granted by those skills + * Added an option to the Configuration tab for "Are you always on full Energy Shield?" + * Fixed issue causing gems with a low maximum level to sometimes be assigned the wrong default level + * Fixed issue causing the slot dropdown in the Skills tab to fail to update correctly under some conditions +For 3.0 builds: + * The new support gems have been updated with the new data from the beta patch + * Applied the following changes from the beta patch: + * Blade Vortex's per-blade damage multiplier now applies to Ailments + * Flameblast's per-stage damage multiplier no longer applies to Decay + * Incinerate's per-stage damage multiplier no longer applies to Decay + * Blade Flurry's per-stage damage multiplier no longer applies to Decay + * Minion's Decay DPS is now shown in the sidebar + * Immolate and Hypothermia's conditional modifiers now apply to Ailments + * Unbound Ailments's modifier to Effect of Ailments should now function correctly + * Fixed issue causing the "increased Physical Damage taken" stat from Maim Support to sometimes apply multiple times VERSION[1.4.30][2017/06/16] * Mind over Matter is now displayed in the Damage Taken section of the Calcs tab, instead of Other Defences For 3.0 builds: diff --git a/manifest.xml b/manifest.xml index 3cfecdf8..75e603c1 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,20 +1,20 @@ - + - + - + - + - + @@ -29,8 +29,8 @@ - - + + @@ -42,38 +42,38 @@ - + - + - + - - + + - - - + + + - + - - + + - + @@ -164,15 +164,15 @@ - - - + + + - - - + + +