diff --git a/src/Classes/ConfigTab.lua b/src/Classes/ConfigTab.lua index 619de6d4c5..43049b1ce0 100644 --- a/src/Classes/ConfigTab.lua +++ b/src/Classes/ConfigTab.lua @@ -151,7 +151,7 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont local height = 20 for _, varControl in pairs(self.varControlList) do if varControl:IsShown() then - height = height + m_max(varControl.height, 16) + 4 + height = height + m_max((type(varControl.height) == "function" and varControl.height() or varControl.height), 16) + 4 end end return m_max(height, 32) @@ -185,6 +185,170 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont self:BuildModList() self.build.buildFlag = true end) + elseif varData.type == "multiList" then + control = new("Control", {"TOPLEFT",lastSection,"TOPLEFT"}, 234, 0, 16, 16) + control.varControlList = { {}, {} } + control.varData = varData + control.height = function() + local height = 20 + for i, varControl in ipairs(control.varControlList[1]) do + if varControl:IsShown() then + if varData.extraTypes and control.varControlList[2][i * (#varData.extraTypes)]:IsShown() then + height = varControl.y + control.varControlList[2][i * (#varData.extraTypes)].y + m_max(control.varControlList[2][i * (#varData.extraTypes)].height, 18) + 4 + else + height = varControl.y + m_max(varControl.height, 18) + 4 + end + end + end + return height + end + control.newLists = function() + local input = self.configSets[self.activeConfigSetId].input + local excludeValue = {} + local newValues = {} + for i, varControl in ipairs(control.varControlList[1]) do + excludeValue[input[varData.var.."_"..i] or varControl:GetSelValue().val] = true + newValues[i] = input[varData.var.."_"..i] or varControl:GetSelValue().val + end + if not varData.showAll then + for i, varControl in ipairs(control.varControlList[1]) do + if newValues[i] == "NONE" and self.configSets[self.activeConfigSetId].input[varData.var.."_"..i] == "NONE" then + if i < #control.varControlList[1] and newValues[i+1] ~= "NONE" then + newValues[i] = newValues[i+1] + newValues[i+1] = "NONE" + local index1, index2 = varData.var.."_"..i, varData.var.."_"..(i+1) + input[index1] = input[index2] + input[index2] = "NONE" + for j, varExtra in ipairs(varData.extraTypes or {}) do + local index1, index2 = index1.."_"..j, index2.."_"..j + local old = input[index1] + input[index1] = input[index2] + input[index2] = old + if varExtra[1] == "integer" then + control.varControlList[2][i*(#varData.extraTypes)+j-1]:SetText(tostring(input[index1] or "")) + control.varControlList[2][(i+1)*(#varData.extraTypes)+j-1]:SetText(tostring(input[index2] or "")) + elseif varExtra[1] == "slider" then + control.varControlList[2][i*(#varData.extraTypes)+j-1].val = input[index1] / 100 + control.varControlList[2][(i+1)*(#varData.extraTypes)+j-1].val = input[index1] / 100 + end + end + else + break + end + end + end + end + local firstNone = false + for i, varControl in ipairs(control.varControlList[1]) do + varControl.selIndex = 1 + varControl.list = { { val = "NONE", label = "None" } } + if i == 1 and not varData.showAll then + t_insert(varControl.list, { val = "ALL", label = "All Options" }) + end + varControl.shown = true + for j, element in ipairs(varData.list) do + if not excludeValue[element.val] or element.val == newValues[i] then + t_insert(varControl.list, element) + end + if element.val == newValues[i] then + varControl.selIndex = #varControl.list + end + end + if not varData.showAll then + if i == 1 and newValues[i] == "ALL" then + varControl.selIndex = 2 + for j, varControl2 in ipairs(control.varControlList[1]) do + if j ~= i then + varControl2.shown = false + end + end + break + elseif newValues[i] == "NONE" then + if firstNone then + varControl.shown = false + else + firstNone = true + end + end + end + end + for i, varControl in ipairs(control.varControlList[1]) do + if i ~= #control.varControlList[1] and varControl:IsShown() then + if varData.extraTypes and control.varControlList[2][i * (#varData.extraTypes)]:IsShown() then + control.varControlList[1][i+1].y = varControl.y + control.varControlList[2][i * (#varData.extraTypes)].y + m_max(control.varControlList[2][i * (#varData.extraTypes)].height, 18) + 4 + else + control.varControlList[1][i+1].y = varControl.y + m_max(varControl.height, 18) + 4 + end + else + break + end + end + end + local extraHeight = 20 + if varData.listFunc then + varData.list = varData.listFunc(self.build) + end + for i=1,(varData.maxElements or #varData.list) do + local dropDownControl = new("DropDownControl", {"TOPLEFT",control,"TOPLEFT"}, -225, extraHeight, 343, 18, { { val = "NONE", label = "None" } }, function(index, value) + self.configSets[self.activeConfigSetId].input[varData.var.."_"..i] = value.val + control.newLists() + self:AddUndoState() + self:BuildModList() + self.build.buildFlag = true + end) + dropDownControl.shown = varData.showAll or i == 1 + dropDownControl.newLists = control.newLists + self.varControls[varData.var.."_"..i] = dropDownControl + t_insert(control.varControlList[1], dropDownControl) + local extraTypesExtraHeight = 0 + for j, varExtra in ipairs(varData.extraTypes or {}) do + if varExtra[1] == "integer" then + local editControl = new("EditControl", {"TOPLEFT",dropDownControl,"TOPLEFT"}, 225, 0, 90, 18, "", nil, "^%-%d", 7, function(buf, placeholder) + if placeholder then + self.configSets[self.activeConfigSetId].placeholder[varData.var.."_"..i.."_"..j] = tonumber(buf) + else + self.configSets[self.activeConfigSetId].input[varData.var.."_"..i.."_"..j] = tonumber(buf) + self:AddUndoState() + self:BuildModList() + end + self.build.buildFlag = true + end) + if #varData.extraTypes == 1 then -- sameLine + dropDownControl.width = function() return 220 + ((not editControl:IsShown()) and 123 or 0) end + else + local xs = { 0, 112, 225 } + editControl.x = xs[(j-1)%3 + 1] + editControl.y = 22 * (1 + m_floor((j-1)/3)) + editControl.height = 16 + extraTypesExtraHeight = 20 * (1 + m_floor((j-1)/3)) + end + editControl.tooltipText = varExtra[2] + if varExtra[3] then + editControl.shown = function() return dropDownControl:GetSelValue()[varExtra[3]] end + end + editControl.placeholder = varExtra[4] + self.varControls[varData.var.."_"..i.."_"..j] = editControl + t_insert(control.varControlList[2], editControl) + elseif varExtra[1] == "slider" then + extraTypesExtraHeight = extraTypesExtraHeight + 22 + slider = new("SliderControl", {"TOPLEFT",dropDownControl,"TOPLEFT"}, 0, extraTypesExtraHeight, 118 + 225, 18, function(val) + self.configSets[self.activeConfigSetId].input[varData.var.."_"..i.."_"..j] = m_floor(val * 100) + self:AddUndoState() + self:BuildModList() + self.build.buildFlag = true + end) + slider.tooltipText = varExtra[2] + if varExtra[3] then + slider.shown = function() return dropDownControl:GetSelValue()[varExtra[3]] end + end + slider.val = varExtra[4] / 100 + self.varControls[varData.var.."_"..i.."_"..j] = slider + t_insert(control.varControlList[2], slider) + end + end + extraHeight = extraHeight + 22 + end + control.newLists() elseif varData.type == "text" and not varData.resizable then control = new("EditControl", {"TOPLEFT",lastSection,"TOPLEFT"}, 8, 0, 344, 118, "", nil, "^%C\t\n", nil, function(buf, placeholder) if placeholder then @@ -517,10 +681,15 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont if varData.tooltipFunc then control.tooltipFunc = varData.tooltipFunc + if control.varControlList then + for _, varControl in ipairs(control.varControlList[1]) do + varControl.tooltipFunc = varData.tooltipFunc + end + end end local labelControl = control if varData.label and varData.type ~= "check" then - labelControl = new("LabelControl", {"RIGHT",control,"LEFT"}, -4, 0, 0, DrawStringWidth(14, "VAR", varData.label) > 228 and 12 or 14, "^7"..varData.label) + labelControl = new("LabelControl", {"TOPRIGHT",control,"TOPLEFT"}, -4, 0, 0, DrawStringWidth(14, "VAR", varData.label) > 228 and 12 or 14, "^7"..varData.label) t_insert(self.controls, labelControl) end if varData.var then @@ -539,6 +708,10 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont self.defaultState[varData.var] = varData.defaultState or 0 elseif varData.type == "list" then self.defaultState[varData.var] = varData.list[varData.defaultIndex or 1].val + elseif varData.type == "multiList" then + for i, _ in ipairs(control.varControlList[1]) do + self.defaultState[varData.var.."_"..i] = "NONE" + end elseif varData.type == "text" then self.defaultState[varData.var] = varData.defaultState or "" else @@ -606,6 +779,13 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont t_insert(self.controls, control) t_insert(lastSection.varControlList, control) + if control.varControlList then + for _, varControlList in pairs(control.varControlList) do + for _, varControl in pairs(varControlList) do + t_insert(self.controls, varControl) + end + end + end end end self.controls.scrollBar = new("ScrollBarControl", {"TOPRIGHT",self,"TOPRIGHT"}, 0, 0, 18, 0, 50, "VERTICAL", true) @@ -745,6 +925,9 @@ function ConfigTabClass:UpdateControls() control.state = self.configSets[self.activeConfigSetId].input[var] elseif control._className == "DropDownControl" then control:SelByValue(self.configSets[self.activeConfigSetId].input[var] or self:GetDefaultState(var), "val") + if control.newLists then + control.newLists() + end end end end @@ -874,6 +1057,22 @@ function ConfigTabClass:BuildModList() if input[varData.var] then varData.apply(input[varData.var], modList, enemyModList, self.build) end + elseif varData.type == "multiList" then + for i, varControl in ipairs(self.varControls[varData.var].varControlList[1]) do + if not varControl:IsShown() then + break + elseif input[varData.var.."_"..i] then + local extraData = {} + for j, _ in ipairs(varData.extraTypes or {}) do + if not input[varData.var.."_"..i.."_"..j] and placeholder[varData.var.."_"..i.."_"..j] then + extraData[j] = placeholder[varData.var.."_"..i.."_"..j] + else + extraData[j] = input[varData.var.."_"..i.."_"..j] + end + end + varData.apply(input[varData.var.."_"..i], extraData, modList, enemyModList, self.build) + end + end elseif varData.type == "text" then if input[varData.var] then varData.apply(input[varData.var], modList, enemyModList, self.build) diff --git a/src/Data/ModMap.lua b/src/Data/ModMap.lua index 363ce29247..c14c1dea2e 100644 --- a/src/Data/ModMap.lua +++ b/src/Data/ModMap.lua @@ -1,442 +1,1429 @@ -- This is currently made by hand but should be auto generated -- Item data (c) Grinding Gear Games +local t_insert = table.insert +local s_format = string.format + + +local mapTierCache = { } +local mapTiers = {"Low", "Med", "High", "T17"} +local tooltipGenerator = function(affixData, tier) + local tooltip = {} + if #affixData.tooltipLines > 0 then + if affixData.type == "check" then + for _, line in ipairs(affixData.tooltipLines) do + t_insert(tooltip, {14, '^7'..line}) + end + elseif affixData.type == "list" then + if affixData.values[tier] then + t_insert(tooltip, {16, '^7'..mapTiers[tier]..": "}) + for i, line in ipairs(affixData.tooltipLines) do + local modValue = (#affixData.tooltipLines > 1) and affixData.values[tier][i] or affixData.values[tier] + if modValue == nil then + t_insert(tooltip, {14, ' ^7'..line}) + elseif modValue ~= 0 then + t_insert(tooltip, {14, ' ^7'..s_format(line, modValue)}) + end + end + end + elseif affixData.type == "count" then + if affixData.values[tier] then + t_insert(tooltip, {16, '^7'..mapTiers[tier]..": "}) + for i, line in ipairs(affixData.tooltipLines) do + local modValue = {(#affixData.tooltipLines > 1) and (affixData.values[tier][i] and affixData.values[tier][i][1] or nil) or affixData.values[tier][1], (#affixData.tooltipLines > 1) and (affixData.values[tier][i] and affixData.values[tier][i][2] or nil) or affixData.values[tier][2]} + if modValue[2] == nil then + t_insert(tooltip, {14, ' ^7'..line}) + elseif modValue[2] ~= 0 then + t_insert(tooltip, {14, ' ^7'..s_format(line, modValue[1], modValue[2])}) + end + end + end + end + end + return (#tooltip > 0) and tooltip +end + + return { AffixData = { -- defensive prefixes ["Armoured"] = { + order = 1, + modType= "Prefix", type = "list", - label = "Enemy Physical Damage reduction:", + label = "Enemy Physical Damage reduction Monster Armoured", tooltipLines = { "+%d%% Monster Physical Damage Reduction" }, - values = { 20, 30, 40 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("PhysicalDamageReduction", "BASE", values[val] * mapModEffect, "Map mod Armoured") - end + end, + values = { + [1] = 20, + [2] = 30, + [3] = 40, + [4] = 40, + }, + }, + ["Cycling UBER"] = { + order = 2, + modType= "Prefix", + type = "check", + label = "Players Deal no Damage 3 out of 10 seconds and their Minions for every Cycling UBER", + tooltipLines = { "Players and their Minions deal no damage for 3 out of every 10 seconds" }, + apply = function(val, mapModEffect, modList, enemyModList) + modList:NewMod("DPS", "MORE", -30, "Map mod Cycling") + end, }, ["Hexproof"] = { + order = 3, + modType= "Prefix", type = "check", - label = "Enemy is Hexproof?", + label = "Enemy is Hexproof? Monsters are Hexproof", tooltipLines = { "Monsters are Hexproof" }, apply = function(val, mapModEffect, modList, enemyModList) enemyModList:NewMod("Hexproof", "FLAG", true, "Map mod Hexproof") - end + end, }, ["Hexwarded"] = { + order = 4, + modType= "Prefix", type = "list", - label = "Less effect of Curses on enemy:", + label = "Less effect of Curses on enemy Monsters Hexwarded", tooltipLines = { "%d%% less effect of Curses on Monsters" }, - values = { 25, 40, 60 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("CurseEffectOnSelf", "MORE", -values[val] * mapModEffect, "Map mod Hexwarded") - end + end, + values = { + [1] = 25, + [2] = 40, + [3] = 60, + [4] = 60, + }, }, ["Resistant"] = { + order = 5, + modType= "Prefix", type = "list", - label = "Enemy has Elemental / ^xD02090Chaos ^7Resist:", - tooltipLines = { "+%d%% Monster Elemental Resistances", "+%d%% Monster Chaos Resistance" }, - values = { { 20, 15 }, { 30, 20 }, { 40, 25 } }, + label = "Enemy has Elemental / ^xD02090Chaos ^7Resist Monster Resistance Resistances Resistant", + tooltipLines = { "+%d%% Monster Chaos Resistance", "+%d%% Monster Elemental Resistances" }, apply = function(val, mapModEffect, values, modList, enemyModList) - enemyModList:NewMod("ElementalResist", "BASE", values[val][1] * mapModEffect, "Map mod Resistant") - enemyModList:NewMod("ChaosResist", "BASE", values[val][2] * mapModEffect, "Map mod Resistant") - end + enemyModList:NewMod("ElementalResist", "BASE", values[val][2] * mapModEffect, "Map mod Resistant") + enemyModList:NewMod("ChaosResist", "BASE", values[val][1] * mapModEffect, "Map mod Resistant") + end, + values = { + [1] = { 15, 20 }, + [2] = { 20, 30 }, + [3] = { 25, 40 }, + [4] = { 25, 40 }, + }, }, ["Unwavering"] = { + order = 6, + modType= "Prefix", type = "count", tooltipLines = { "(%d to %d)%% more Monster Life", "Monsters cannot be Stunned" }, - values = { { { 15, 19 } }, { { 20, 24 } }, { { 25, 30 } }, }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("AvoidStun", "BASE", 100, "Map mod Unwavering") - enemyModList:NewMod("Life", "MORE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100) * mapModEffect, "Map mod Unwavering") - end + enemyModList:NewMod("Life", "MORE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Unwavering") + end, + values = { + [1] = { 15, 19 }, + [2] = { 20, 24 }, + [3] = { 25, 30 }, + [4] = { 25, 30 }, + }, }, ["Fecund"] = { + order = 7, + modType= "Prefix", type = "count", tooltipLines = { "(%d to %d)%% more Monster Life" }, - values = { { 20, 29 }, { 30, 39 }, { 40, 49 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("Life", "MORE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Fecund") - end + end, + values = { + [1] = { 20, 29 }, + [2] = { 30, 39 }, + [3] = { 40, 49 }, + [4] = { 40, 49 }, + }, + }, + ["Fecund UBER"] = { + order = 8, + modType= "Prefix", + type = "count", + tooltipLines = { "(%d to %d)%% more Monster Life" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("Life", "MORE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Fecund") + end, + values = { + [4] = { 90, 100 }, + }, }, ["Unstoppable"] = { + order = 9, + modType= "Prefix", type = "check", + label = "Enemy Cannot Be Slowed Monsters Taunted Monsters' Action Speed modified below Base Value Movement Unstoppable", tooltipLines = { "Monsters cannot be Taunted", "Monsters' Action Speed cannot be modified to below Base Value", "Monsters' Movement Speed cannot be modified to below Base Value" }, - values = { { 0 } }, apply = function(val, mapModEffect, modList, enemyModList) -- MISSING: Monsters cannot be Taunted enemyModList:NewMod("MinimumActionSpeed", "MAX", 100, "Map mod Unstoppable") - end + end, }, ["Impervious"] = { + order = 10, + modType= "Prefix", type = "list", + label = "Enemy chance to avoid Poison and Bleed Monsters have Poison, Impale, Bleeding Impervious", tooltipLines = { "Monsters have a %d%% chance to avoid Poison, Impale, and Bleeding" }, - values = { 20, 35, 50 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("AvoidPoison", "BASE", values[val] * mapModEffect, "Map mod Impervious") enemyModList:NewMod("AvoidImpale", "BASE", values[val] * mapModEffect, "Map mod Impervious") enemyModList:NewMod("AvoidBleed", "BASE", values[val] * mapModEffect, "Map mod Impervious") - end + end, + values = { + [1] = 20, + [2] = 35, + [3] = 50, + [4] = 50, + }, }, ["Oppressive"] = { + order = 11, + modType= "Prefix", type = "list", + label = "Enemy chance to Suppress Spell Damage Monsters have Oppressive", tooltipLines = { "Monsters have +%d%% chance to Suppress Spell Damage" }, - values = { 30, 45, 60 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("SpellSuppressionChance", "BASE", values[val] * mapModEffect, "Map mod Oppressive") - end + end, + values = { + [1] = 30, + [2] = 45, + [3] = 60, + [4] = 60, + }, + }, + ["Oppressive UBER"] = { + order = 12, + modType= "Prefix", + type = "list", + label = "Enemy chance to Suppress Spell Damage Monsters have Oppressive UBER", + tooltipLines = { "Monsters have +%d%% chance to Suppress Spell Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("SpellSuppressionChance", "BASE", values[val] * mapModEffect, "Map mod Oppressive") + end, + values = { + [4] = 100, + }, }, ["Buffered"] = { + order = 13, + modType= "Prefix", type = "count", tooltipLines = { "Monsters gain (%d to %d)%% of Maximum Life as Extra Maximum Energy Shield" }, - values = { { 20, 29 }, { 30, 39 }, { 40, 49 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("LifeGainAsEnergyShield", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Buffered") - end + end, + values = { + [1] = { 20, 29 }, + [2] = { 30, 39 }, + [3] = { 40, 49 }, + [4] = { 40, 49 }, + }, + }, + ["Buffered UBER"] = { + order = 14, + modType= "Prefix", + type = "count", + tooltipLines = { "Monsters gain (%d to %d)%% of Maximum Life as Extra Maximum Energy Shield" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("LifeGainAsEnergyShield", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Buffered") + end, + values = { + [4] = { 70, 80 }, + }, + }, + ["Stalwart UBER"] = { + order = 15, + modType= "Prefix", + type = "list", + label = "Enemy Block Chance Monsters have to Attack Damage Stalwart UBER", + tooltipLines = { "Monsters have +%d%% Chance to Block Attack Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("BlockChance", "BASE", values[val] * mapModEffect, "Map mod Stalwart", ModFlag.Attack) + end, + values = { + [4] = 50, + }, }, ["Titan's"] = { + order = 16, + modType= "Prefix", type = "list", tooltipLines = { "Unique Boss has %d%% increased Life", "Unique Boss has %d%% increased Area of Effect" }, - values = { { 25, 45 }, { 30, 55 }, { 35, 70 } }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("Life", "MORE", values[val][1] * mapModEffect, "Map mod Titan's", { type = "Condition", var = "RareOrUnique" }) enemyModList:NewMod("AreaOfEffect", "INC", values[val][2] * mapModEffect, "Map mod Titan's", { type = "Condition", var = "RareOrUnique" }) - end + end, + values = { + [1] = { 25, 45 }, + [2] = { 30, 55 }, + [3] = { 35, 70 }, + [4] = { 35, 70 }, + }, }, -- offensive prefixes ["Savage"] = { + order = 17, + modType= "Prefix", type = "count", + label = "Enemy Increased Damage to Monster Savage", tooltipLines = { "(%d to %d)%% increased Monster Damage" }, - values = { { 14, 17 }, { 18, 21 }, { 22, 25 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("Damage", "INC", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Savage") - end + end, + values = { + [1] = { 14, 17 }, + [2] = { 18, 21 }, + [3] = { 22, 25 }, + [4] = { 22, 25 }, + }, + }, + ["Savage UBER"] = { + order = 18, + modType= "Prefix", + type = "count", + label = "Enemy Increased Damage to Monster Savage UBER", + tooltipLines = { "(%d to %d)%% increased Monster Damage" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("Damage", "INC", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Savage") + end, + values = { + [4] = { 30, 40 }, + }, }, ["Burning"] = { + order = 19, + modType= "Prefix", type = "count", + label = "Enemy Physical As Extra Fire Monsters deal to Damage Burning", tooltipLines = { "Monsters deal (%d to %d)%% extra Physical Damage as Fire" }, - values = { { 50, 69 }, { 70, 89 }, { 90, 110 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("PhysicalDamageGainAsFire", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Burning") - end + end, + values = { + [1] = { 50, 69 }, + [2] = { 70, 89 }, + [3] = { 90, 110 }, + [4] = { 90, 110 }, + }, }, ["Freezing"] = { + order = 20, + modType= "Prefix", type = "count", + label = "Enemy Physical As Extra Cold Monsters deal to Damage Freezing", tooltipLines = { "Monsters deal (%d to %d)%% extra Physical Damage as Cold" }, - values = { { 50, 69 }, { 70, 89 }, { 90, 110 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("PhysicalDamageGainAsCold", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Freezing") - end + end, + values = { + [1] = { 50, 69 }, + [2] = { 70, 89 }, + [3] = { 90, 110 }, + [4] = { 90, 110 }, + }, }, ["Shocking"] = { + order = 21, + modType= "Prefix", type = "count", + label = "Enemy Physical As Extra Lightning Monsters deal to Damage Shocking", tooltipLines = { "Monsters deal (%d to %d)%% extra Physical Damage as Lightning" }, - values = { { 50, 69 }, { 70, 89 }, { 90, 110 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("PhysicalDamageGainAsLightning", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Shocking") - end + end, + values = { + [1] = { 50, 69 }, + [2] = { 70, 89 }, + [3] = { 90, 110 }, + [4] = { 90, 110 }, + }, }, ["Profane"] = { + order = 22, + modType= "Prefix", type = "count", - tooltipLines = { "Monsters gain (%d to %d)%% of their Physical Damage as Extra Chaos Damage", "Monsters Inflict Withered for %d seconds on Hit" }, - values = { { { 0, 0 }, { 0, 0 } }, { { 21, 25 }, { 100 } }, { { 31, 35 }, { 100 } }, }, + label = "Enemy Physical As Extra Chaos Monsters gain to their Damage Inflict Withered for seconds Hit Profane", + tooltipLines = { "Monsters gain (%d to %d)%% of their Physical Damage as Extra Chaos Damage", "Monsters Inflict Withered for 10 seconds on Hit" }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) - enemyModList:NewMod("PhysicalDamageGainAsChaos", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100) * mapModEffect, "Map mod Profane") - modList:NewMod("Condition:CanBeWithered", "FLAG", true, "Map mod Profane") - end + if values[val] then + enemyModList:NewMod("PhysicalDamageGainAsChaos", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100) * mapModEffect, "Map mod Profane") + modList:NewMod("Condition:CanBeWithered", "FLAG", true, "Map mod Profane") + end + end, + values = { + [2] = { { 21, 25 }, { 100 } }, + [3] = { { 31, 35 }, { 100 } }, + [4] = { { 31, 35 }, { 100 } }, + }, + }, + ["Profane UBER"] = { + order = 23, + modType= "Prefix", + type = "count", + label = "Enemy Physical As Extra Chaos Monsters gain to their Damage Profane UBER", + tooltipLines = { "Monsters gain (%d to %d)%% of their Physical Damage as Extra Chaos Damage" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + if values[val] then + enemyModList:NewMod("PhysicalDamageGainAsChaos", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Profane") + end + end, + values = { + [4] = { 80, 100 }, + }, + }, + ["Prismatic UBER"] = { + order = 24, + modType= "Prefix", + type = "count", + label = "Enemy Physical As Extra Random Monsters gain to of their Damage Element Prismatic UBER", + tooltipLines = { "Monsters gain (%d to %d)%% of their Physical Damage as Extra Damage of a random Element" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + if values[val] then + enemyModList:NewMod("PhysicalDamageGainAsRandom", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod Prismatic") + end + end, + values = { + [4] = { 180, 200 }, + }, }, ["Fleet"] = { + order = 25, + modType= "Prefix", type = "count", + label = "Enemy Increased Speed to Monster Movement Attack Cast Fleet", tooltipLines = { "(%d to %d)%% increased Monster Movement Speed", "(%d to %d)%% increased Monster Attack Speed", "(%d to %d)%% increased Monster Cast Speed" }, - values = { { { 15, 20 }, { 20, 25 }, { 20, 25 } }, { { 20, 25 }, { 25, 35 }, { 25, 35 } }, { { 25, 30 }, { 35, 45 }, { 35, 45 } }, }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) -- attack and cast is the same so applying it once, movespeed does not matter enemyModList:NewMod("Speed", "INC", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100) * mapModEffect, "Map mod Fleet") - end + end, + values = { + [1] = { { 15, 20 }, { 20, 25 }, { 20, 25 } }, + [2] = { { 20, 25 }, { 25, 35 }, { 25, 35 } }, + [3] = { { 25, 30 }, { 35, 45 }, { 35, 45 } }, + [4] = { { 25, 30 }, { 35, 45 }, { 35, 45 } }, + }, + }, + ["Equalising UBER"] = { + order = 27, + modType= "Prefix", + type = "list", + tooltipLines = { "Rare and Unique Monsters remove %d%% of Life, Mana and Energy Shield from Players or their Minions on Hit" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + end, + values = { + [4] = 5, + }, + }, + ["Afflicting UBER"] = { + order = 28, + modType= "Prefix", + type = "check", + label = "Enemy Hits always Ignites, Freezes and Shocks All Monster Damage can Ignite, Monsters Afflicting UBER", + tooltipLines = { "All Monster Damage can Ignite, Freeze and Shock", "Monsters Ignite, Freeze and Shock on Hit" }, + apply = function(val, mapModEffect, modList, enemyModList) + enemyModList:NewMod("IgniteChance", "BASE", 100, "Map mod Afflicting") + enemyModList:NewMod("AllDamageIgnites", "FLAG", true, "Map mod Afflicting") + end, }, ["Conflagrating"] = { + order = 29, + modType= "Prefix", type = "check", + label = "Enemy Hits always Ignites All Monster Damage from Conflagrating", tooltipLines = { "All Monster Damage from Hits always Ignites" }, apply = function(val, mapModEffect, modList, enemyModList) enemyModList:NewMod("IgniteChance", "BASE", 100, "Map mod Conflagrating") enemyModList:NewMod("AllDamageIgnites", "FLAG", true, "Map mod Conflagrating") - end + end, }, ["Impaling"] = { + order = 30, + modType= "Prefix", type = "list", + label = "Enemy chance to Impale Monsters' Attacks have Hit Impaling", tooltipLines = { "Monsters' Attacks have %d%% chance to Impale on Hit" }, - values = { 25, 40, 60 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("ImpaleChance", "BASE", values[val] * mapModEffect, "Map mod Impaling", ModFlag.Attack) - end + end, + values = { + [1] = 25, + [2] = 40, + [3] = 60, + [4] = 60, + }, + }, + ["Impaling UBER"] = { + order = 31, + modType= "Prefix", + type = "list", + label = "Enemy chance to Impale Monsters' Attacks Hit When fifth is inflicted Player, Impales are removed Reflect their Physical Damage multiplied by remaining Hits that and Allies within metres Impaling UBER", + tooltipLines = { "Monsters' Attacks Impale on Hit", "When a fifth Impale is inflicted on a Player, Impales are removed to Reflect their Physical Damage multiplied by their remaining Hits to that Player and their Allies within X metres" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + if val == 4 then + enemyModList:NewMod("ImpaleChance", "BASE", values[val][2] * mapModEffect, "Map mod Impaling", ModFlag.Attack) + end + end, + values = { + [4] = { 5, 100 }, + }, }, ["Empowered"] = { + order = 32, + modType= "Prefix", type = "list", + label = "Enemy Elemental Ailments chance on Hit Monsters have to Ignite, Freeze and Shock Empowered", tooltipLines = { "Monsters have a %d%% chance to Ignite, Freeze and Shock on Hit" }, - values = { 0, 15, 20 }, apply = function(val, mapModEffect, values, modList, enemyModList) - enemyModList:NewMod("ElementalAilmentChance", "BASE", values[val] * mapModEffect, "Map mod Empowered") - end + if values[val] then + enemyModList:NewMod("ElementalAilmentChance", "BASE", values[val] * mapModEffect, "Map mod Empowered") + end + end, + values = { + [2] = 15, + [3] = 20, + [4] = 20, + }, }, ["Overlord's"] = { + order = 33, + modType= "Prefix", type = "list", + label = "Boss Increased Damage / Speed Unique deals has Attack and Cast Overlord's", tooltipLines = { "Unique Boss deals %d%% increased Damage", "Unique Boss has %d%% increased Attack and Cast Speed" }, - values = { { 15, 20 }, { 20, 25 }, { 25, 30 } }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("Damage", "INC", values[val][1] * mapModEffect, "Map mod Overlord's", { type = "Condition", var = "RareOrUnique" }) enemyModList:NewMod("Speed", "INC", values[val][2] * mapModEffect, "Map mod Overlord's", { type = "Condition", var = "RareOrUnique" }) - end + end, + values = { + [1] = { 15, 20 }, + [2] = { 20, 25 }, + [3] = { 25, 30 }, + [4] = { 25, 30 }, + }, }, -- reflect prefixes ["Punishing"] = { + order = 34, + modType= "Prefix", type = "list", tooltipLines = { "Monsters reflect %d%% of Physical Damage" }, - values = { 13, 15, 18 }, apply = function(val, mapModEffect, values, modList, enemyModList) - end + end, + values = { + [1] = 13, + [2] = 15, + [3] = 18, + [4] = 18, + }, + }, + ["Punishing UBER"] = { + order = 35, + modType= "Prefix", + type = "list", + tooltipLines = { "Monsters reflect %d%% of Physical Damage", "Monsters reflect %d%% of Elemental Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + end, + values = { + [4] = { 20, 20 }, + }, }, ["Mirrored"] = { + order = 36, + modType= "Prefix", type = "list", tooltipLines = { "Monsters reflect %d%% of Elemental Damage" }, - values = { 13, 15, 18 }, apply = function(val, mapModEffect, values, modList, enemyModList) - end + end, + values = { + [1] = 13, + [2] = 15, + [3] = 18, + [4] = 18, + }, }, -- suffixes ["of Balance"] = { + order = 37, + modType= "Suffix", type = "check", - label = "Player has Elemental Equilibrium?", + OldLabel = "Player has Elemental Equilibrium?", tooltipLines = { "Players cannot inflict Exposure" }, apply = function(val, mapModEffect, modList, enemyModList) -- Players cannot inflict Exposure -- modList:NewMod("Keystone", "LIST", "Elemental Equilibrium", "Map mod of Balance") -- OLD MOD - end + end, }, ["of Congealment"] = { + order = 38, + modType= "Suffix", type = "check", - label = "Cannot Leech ^xE05030Life ^7/ ^x7070FFMana?", + label = "Cannot Leech ^xE05030Life ^7/ ^x7070FFMana Monsters be Leeched from of Congealment", tooltipLines = { "Monsters cannot be Leeched from" }, apply = function(val, mapModEffect, modList, enemyModList) enemyModList:NewMod("CannotLeechLifeFromSelf", "FLAG", true, "Map mod of Congealment") enemyModList:NewMod("CannotLeechManaFromSelf", "FLAG", true, "Map mod of Congealment") --missing cannot leech es? - end + end, }, ["of Drought"] = { + order = 39, + modType= "Suffix", type = "list", - label = "Gains reduced Flask Charges:", + label = "Gain reduced Flask Charges Players of Drought", tooltipLines = { "Players gain %d%% reduced Flask Charges" }, - values = { 30, 40, 50 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("FlaskChargesGained", "INC", -values[val] * mapModEffect, "Map mod of Drought") - end + end, + values = { + [1] = 30, + [2] = 40, + [3] = 50, + [4] = 50, + }, }, ["of Exposure"] = { + order = 40, + modType= "Suffix", type = "count", - label = "-X% maximum Resistances:", - tooltip = "Mid tier: 5-8%\nHigh tier: 9-12%", + label = "-X% maximum Resistances Players have minus to all of Exposure", tooltipLines = { "Players have minus (%d to %d)%% to all maximum Resistances" }, - values = { { 0, 0 }, { 5, 8 }, { 9, 12 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) - if values[val][2] ~= 0 then + if values[val] then local roll = (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect modList:NewMod("FireResistMax", "BASE", -roll, "Map mod of Exposure") modList:NewMod("ColdResistMax", "BASE", -roll, "Map mod of Exposure") modList:NewMod("LightningResistMax", "BASE", -roll, "Map mod of Exposure") modList:NewMod("ChaosResistMax", "BASE", -roll, "Map mod of Exposure") end - end + end, + values = { + [2] = { 5, 8 }, + [3] = { 9, 12 }, + [4] = { 9, 12 }, + }, + }, + ["of Exposure UBER"] = { + order = 41, + modType= "Suffix", + type = "list", + label = "-X% maximum Resistances Players have minus to all of Exposure UBER", + tooltipLines = { "Players have minus %d%% to all maximum Resistances" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + if val == 4 then + modList:NewMod("FireResistMax", "BASE", -values[val], "Map mod of Exposure") + modList:NewMod("ColdResistMax", "BASE", -values[val], "Map mod of Exposure") + modList:NewMod("LightningResistMax", "BASE", -values[val], "Map mod of Exposure") + modList:NewMod("ChaosResistMax", "BASE", -values[val], "Map mod of Exposure") + end + end, + values = { + [4] = 20, + }, + }, + ["of Penetration UBER"] = { + order = 42, + modType= "Suffix", + type = "list", + label = "Enemy Penetrates Elemental Resistances Monster Damage of Penetration UBER", + tooltipLines = { "Monster Damage Penetrates %d%% Elemental Resistances" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("ElementalPenetration", "BASE", values[val] * mapModEffect, "Map mod Penetration") + end, + values = { + [4] = 15, + }, }, ["of Impotence"] = { + order = 43, + modType= "Suffix", type = "list", - label = "Less Area of Effect:", + label = "Less Area of Effect: Players have of Impotence", tooltipLines = { "Players have %d%% less Area of Effect" }, - values = { 15, 20, 25 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("AreaOfEffect", "MORE", -values[val] * mapModEffect, "Map mod of Impotence") - end + end, + values = { + [1] = 15, + [2] = 20, + [3] = 25, + [4] = 25, + }, + }, + ["of Impotence UBER"] = { + order = 44, + modType= "Suffix", + type = "count", + label = "Less Area of Effect: Players have to of Impotence UBER", + tooltipLines = { "Players have (%d to %d)%% less Area of Effect" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + if val == 4 then + modList:NewMod("AreaOfEffect", "MORE", -(values[val][1] + (values[val][2] - values[val][1]) * 100 / 100) * mapModEffect, "Map mod of Impotence") + end + end, + values = { + [4] = { 25, 30 }, + }, }, ["of Insulation"] = { + order = 45, + modType= "Suffix", type = "list", - label = "Enemy avoid Elemental Ailments:", + label = "Enemy chance to avoid Elemental Ailments Monsters have of Insulation", tooltipLines = { "Monsters have %d%% chance to Avoid Elemental Ailments" }, - values = { 30, 50, 70 }, apply = function(val, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("AvoidElementalAilments", "BASE", values[val] * mapModEffect, "Map mod of Insulation") - end + end, + values = { + [1] = 30, + [2] = 50, + [3] = 70, + [4] = 70, + }, }, ["of Miring"] = { + order = 46, + modType= "Suffix", type = "list", - label = "Unlucky Dodge / Enemy has inc. Accuracy:", - tooltipLines = { "Monsters have %d%% increased Accuracy Rating", "Players have minus %d%% to amount of Suppressed Spell Damage Prevented" }, - values = { { 10, 30 }, { 15, 40 }, { 20, 50 } }, + label = "Enemy has inc. Accuracy: / Players have to amount of Suppressed Spell Damage Prevented Monsters increased Rating minus of Miring", + tooltipLines = { "Players have minus %d%% to amount of Suppressed Spell Damage Prevented", "Monsters have %d%% increased Accuracy Rating" }, apply = function(val, mapModEffect, values, modList, enemyModList) - -- modList:NewMod("DodgeChanceIsUnlucky", "FLAG", true, "Map mod of Miring") -- OLD MOD modList:NewMod("SpellSuppressionEffect", "BASE", -values[val][1] * mapModEffect, "Map mod of Miring") enemyModList:NewMod("Accuracy", "INC", values[val][2] * mapModEffect, "Map mod of Miring") - end + end, + values = { + [1] = { 10, 30 }, + [2] = { 15, 40 }, + [3] = { 20, 50 }, + [4] = { 20, 50 }, + }, + }, + ["of Miring UBER"] = { + order = 47, + modType= "Suffix", + type = "count", + label = "Less Global Defences Players have to of Miring UBER", + tooltipLines = { "Players have (%d to %d)%% less Defences" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + modList:NewMod("Defences", "MORE", -(values[val][1] + (values[val][2] - values[val][1]) * 100 / 100) * mapModEffect, "Map mod of Miring") + end, + values = { + [4] = { 25, 30 }, + }, }, ["of Rust"] = { + order = 48, + modType= "Suffix", type = "list", - label = "Reduced Block Chance / less Armour:", - tooltipLines = { "Players have %d%% less Armour", "Players have %d%% reduced Chance to Block" }, - values = { { 20, 20 }, { 30, 25 }, { 40, 30 } }, + label = "Reduced Block Chance / less Armour Players have to of Rust", + tooltipLines = { "Players have %d%% reduced Chance to Block", "Players have %d%% less Armour" }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("BlockChance", "INC", -values[val][1] * mapModEffect, "Map mod of Rust") modList:NewMod("Armour", "MORE", -values[val][2] * mapModEffect, "Map mod of Rust") - end + end, + values = { + [1] = { 20, 20 }, + [2] = { 30, 25 }, + [3] = { 40, 30 }, + [4] = { 40, 30 }, + }, }, ["of Smothering"] = { + order = 49, + modType= "Suffix", type = "list", - label = "Less Recovery Rate of ^xE05030Life ^7and ^x88FFFFEnergy Shield:", + label = "Less Recovery Rate of ^xE05030Life ^7and ^x88FFFFEnergy Shield Players have of Smothering", tooltipLines = { "Players have %d%% less Recovery Rate of Life and Energy Shield" }, - values = { 20, 40, 60 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("LifeRecoveryRate", "MORE", -values[val] * mapModEffect, "Map mod of Smothering") modList:NewMod("EnergyShieldRecoveryRate", "MORE", -values[val] * mapModEffect, "Map mod of Smothering") - end + end, + values = { + [1] = 20, + [2] = 40, + [3] = 60, + [4] = 60, + }, }, ["of Stasis"] = { + order = 50, + modType= "Suffix", type = "check", - label = "Cannot Regen ^xE05030Life^7, ^x7070FFMana ^7or ^x88FFFFES?", + label = "Cannot Regenerate ^xE05030Life^7, ^x7070FFMana ^7or ^x88FFFFES Players Life, Energy Shield of Stasis", tooltipLines = { "Players cannot Regenerate Life, Mana or Energy Shield" }, apply = function(val, mapModEffect, modList, enemyModList) modList:NewMod("NoLifeRegen", "FLAG", true, "Map mod of Stasis") modList:NewMod("NoEnergyShieldRegen", "FLAG", true, "Map mod of Stasis") modList:NewMod("NoManaRegen", "FLAG", true, "Map mod of Stasis") - end + end, }, ["of Toughness"] = { + order = 51, + modType= "Suffix", type = "count", + label = "Enemy takes reduced Extra Crit Damage Monsters from Critical Strikes of Toughness", tooltipLines = { "Monsters take (%d to %d)%% reduced Extra Damage from Critical Strikes" }, - values = { { 25, 30 }, { 31, 35 }, { 36, 40 } }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("SelfCritMultiplier", "INC", -(values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod of Toughness") - end + end, + values = { + [1] = { 25, 30 }, + [2] = { 31, 35 }, + [3] = { 36, 40 }, + [4] = { 36, 40 }, + }, + }, + ["of Toughness UBER"] = { + order = 52, + modType= "Suffix", + type = "count", + label = "Enemy takes reduced Extra Crit Damage Monsters from Critical Strikes of Toughness UBER", + tooltipLines = { "Monsters take (%d to %d)%% reduced Extra Damage from Critical Strikes" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("SelfCritMultiplier", "INC", -(values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100) * mapModEffect, "Map mod of Toughness") + end, + values = { + [4] = { 35, 45 }, + }, }, ["of Fatigue"] = { + order = 53, + modType= "Suffix", type = "list", + label = "Less Cooldown Recovery Rate Players have of Fatigue", tooltipLines = { "Players have %d%% less Cooldown Recovery Rate" }, - values = { 20, 30, 40 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("CooldownRecovery", "MORE", -values[val] * mapModEffect, "Map mod of Fatigue") - end + end, + values = { + [1] = 20, + [2] = 30, + [3] = 40, + [4] = 40, + }, + }, + ["of Deceleration UBER"] = { + order = 54, + modType= "Suffix", + type = "list", + label = "Reduced Action Speed for each Skill used Recently Players have time they've of Deceleration UBER", + tooltipLines = { "Players have %d%% reduced Action Speed for each time they've used a Skill Recently" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + modList:NewMod("ActionSpeed", "INC", -values[val] * mapModEffect, "Map mod of Deceleration", { type = "Multiplier", var = "SkillUsedRecently" }) + end, + values = { + [4] = 3, + }, + }, + ["of Revolt UBER"] = { + order = 55, + modType= "Suffix", + type = "list", + label = "Less Minion Speed Players' Minions have less Attack Cast Movement of Revolt UBER", + tooltipLines = { "Players' Minions have %d%% less Attack Speed", "Players' Minions have %d%% less Cast Speed", "Players' Minions have %d%% less Movement Speed" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + modList:NewMod("MinionModifier", "LIST", { mod = modLib.createMod("Speed", "MORE", -values[val][1] * mapModEffect, "Map mod of Revolt", ModFlag.Attack) }, "Map mod of Revolt") + modList:NewMod("MinionModifier", "LIST", { mod = modLib.createMod("Speed", "MORE", -values[val][2] * mapModEffect, "Map mod of Revolt", ModFlag.Cast) }, "Map mod of Revolt") + modList:NewMod("MinionModifier", "LIST", { mod = modLib.createMod("MovementSpeed", "MORE", -values[val][3] * mapModEffect, "Map mod of Revolt") }, "Map mod of Revolt") + end, + values = { + [4] = { 50, 50, 50 }, + }, + }, + ["of Defiance UBER"] = { + order = 56, + modType= "Suffix", + type = "list", + label = "Debuffs on Enemies Expire Faster Monsters of Defiance UBER", + tooltipLines = { "Debuffs on Monsters expire %d%% faster" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("DebuffExpireFaster", "MORE", values[val] * mapModEffect, "Map mod of Defiance") + end, + values = { + [4] = 100, + }, }, ["of Transience"] = { + order = 57, + modType= "Suffix", type = "list", tooltipLines = { "Buffs on Players expire %d%% faster" }, - values = { 30, 50, 70 }, apply = function(val, mapModEffect, values, modList, enemyModList) - end + end, + values = { + [1] = 30, + [2] = 50, + [3] = 70, + [4] = 70, + }, + }, + ["of Transience UBER"] = { + order = 58, + modType= "Suffix", + type = "list", + tooltipLines = { "Buffs on Players expire %d%% faster" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + end, + values = { + [4] = 100, + }, }, ["of Doubt"] = { + order = 59, + modType= "Suffix", type = "list", + label = "Reduced Non-Curse Aura Effect Players have Auras from Skills of Doubt", tooltipLines = { "Players have %d%% reduced effect of Non-Curse Auras from Skills" }, - values = { 25, 40, 60 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("AuraEffect", "INC", -values[val] * mapModEffect, "Map mod of Doubt", { type = "SkillType", skillType = SkillType.Aura }, { type = "SkillType", skillType = SkillType.AppliesCurse, neg = true }) - end + end, + values = { + [1] = 25, + [2] = 40, + [3] = 60, + [4] = 60, + }, }, ["of Imprecision"] = { + order = 60, + modType= "Suffix", type = "list", + label = "Less Accuracy Rating Players have of Imprecision", tooltipLines = { "Players have %d%% less Accuracy Rating" }, - values = { 15, 20, 25 }, apply = function(val, mapModEffect, values, modList, enemyModList) modList:NewMod("Accuracy", "MORE", -values[val] * mapModEffect, "Map mod of Imprecision") - end + end, + values = { + [1] = 15, + [2] = 20, + [3] = 25, + [4] = 25, + }, }, ["of Blinding"] = { + order = 61, + modType= "Suffix", type = "check", tooltipLines = { "Monsters Blind on Hit" }, apply = function(val, mapModEffect, modList, enemyModList) --SHOULD THIS BE SUPPORTED? (as a flag to make "are you blinded" show on config?) - end + end, }, ["of Venom"] = { + order = 62, + modType= "Suffix", type = "check", + label = "Enemy chance to Poison on Hit Monsters of Venom", tooltipLines = { "Monsters Poison on Hit" }, apply = function(val, mapModEffect, modList, enemyModList) enemyModList:NewMod("PoisonChance", "BASE", 100, "Map mod of Venom") - end + end, }, ["of Deadliness"] = { + order = 63, + modType= "Suffix", type = "count", + label = "Enemy Critical Strike Monsters have to increased Chance Multiplier of Deadliness", tooltipLines = { "Monsters have (%d to %d)%% increased Critical Strike Chance", "+(%d to %d)%% to Monster Critical Strike Multiplier" }, - values = { { { 160, 200 }, { 30, 35 } }, { { 260, 300 }, { 36, 40 } }, { { 360, 400 }, { 41, 45 } }, }, apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) enemyModList:NewMod("CritChance", "INC", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100) * mapModEffect, "Map mod of Deadliness") enemyModList:NewMod("CritMultiplier", "BASE", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100) * mapModEffect, "Map mod of Deadliness") - end + end, + values = { + [1] = { { 160, 200 }, { 30, 35 } }, + [2] = { { 260, 300 }, { 36, 40 } }, + [3] = { { 360, 400 }, { 41, 45 } }, + [4] = { { 360, 400 }, { 41, 45 } }, + }, + }, + ["of Deadliness UBER"] = { + order = 64, + modType= "Suffix", + type = "count", + label = "Enemy Critical Strike Monsters have to increased Chance Multiplier of Deadliness UBER", + tooltipLines = { "Monsters have (%d to %d)%% increased Critical Strike Chance", "+(%d to %d)%% to Monster Critical Strike Multiplier" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("CritChance", "INC", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100) * mapModEffect, "Map mod of Deadliness") + enemyModList:NewMod("CritMultiplier", "BASE", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100) * mapModEffect, "Map mod of Deadliness") + end, + values = { + [4] = { { 650, 700 }, { 70, 75 } }, + }, + }, + -- Cleansing Altar + -- Cleansing Altar Boss + ["CleansingAltarDownsideBossArmour"] = { + type = "list", + tooltipLines = { "+%d to Armour" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("Armour", "BASE", values[val], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = 50000, + }, + }, + ["CleansingAltarDownsideBossIncreasedArmourAndEvasion"] = { + type = "count", + tooltipLines = { "(%d to %d)%% increased Armour", "(%d to %d)%% increased Evasion Rating" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("Armour", "INC", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("Evasion", "INC", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 100, 200 }, { 100, 200 } }, + }, + }, + ["CleansingAltarDownsideBossFireAndChaosResist"] = { + type = "list", + tooltipLines = { "+%d%% to Fire Resistance", "+%d%% to maximum Fire Resistance", "+%d%% to Chaos Resistance", "+%d%% to maximum Chaos Resistance" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("FireResist", "BASE", values[val][1], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("FireResistMax", "BASE", values[val][2], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("ChaosResist", "BASE", values[val][3], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("ChaosResistMax", "BASE", values[val][4], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { 80, 10, 80, 10 }, + }, + }, + ["CleansingAltarDownsideBossPenetrateElementalResist"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Physical Damage as Extra Damage of a random Element", "Damage Penetrates (%d to %d)%% of Enemy Elemental Resistances" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsRandom", "BASE", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("ElementalPenetration", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 15, 25 }, { 50, 80 } }, + }, + }, + ["CleansingAltarDownsideBossPhysToAddAsChaos"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Physical Damage as Extra Chaos Damage", "Poison on Hit", "All Damage from Hits can Poison" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsChaos", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("PoisonChance", "BASE", 100, "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("AllDamagePoisons", "FLAG", true, "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 70, 130 } }, + }, + }, + ["CleansingAltarDownsideBossPhysToAddAsFire"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Physical Damage as Extra Fire Damage", "Hits always Ignite", "All Damage can Ignite" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsFire", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("IgniteChance", "BASE", 100, "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("AllDamageIgnites", "FLAG", true, "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 70, 130 } }, + }, + }, + -- Cleansing Altar Monster + -- Cleansing Altar Player + ["CleansingAltarDownsidePlayerIncreasedFlaskChargesUsed"] = { + type = "count", + tooltipLines = { "(%d to %d)%% increased Flask Charges used", "(%d to %d)%% reduced Flask Effect Duration" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + modList:NewMod("FlaskChargesUsed", "INC", (values[val][1][2] + (values[val][1][1] - values[val][1][2]) * rollRange / 100), "Altar Player Downside") + modList:NewMod("FlaskDuration", "INC", -(values[val][2][2] + (values[val][2][1] - values[val][2][2]) * rollRange / 100), "Altar Player Downside") + end, + values = { + [1] = { { 20, 40 }, { 60, 40 } }, + }, + }, + ["CleansingAltarDownsidePlayerChaosDegenDuringFlaskDuration"] = { + type = "list", + tooltipLines = { "Take %d Chaos Damage per second during any Flask Effect" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + modList:NewMod("ChaosDegen", "BASE", values[val], "Altar Player Downside", { type = "Condition", var = "UsingFlask" }) + end, + values = { + [1] = 600, + }, + }, + ["CleansingAltarDownsidePlayerChaosMonsterAura"] = { + type = "list", + tooltipLines = { "Nearby Enemies Gain %d%% of their Physical Damage as Extra Chaos Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsChaos", "BASE", values[val], "Altar Player Downside") + end, + values = { + [1] = 100, + }, + }, + ["CleansingAltarDownsidePlayerFireMonsterAura"] = { + type = "list", + tooltipLines = { "Nearby Enemies Gain %d%% of their Physical Damage as Extra Fire Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsFire", "BASE", values[val], "Altar Player Downside") + end, + values = { + [1] = 100, + }, + }, + ["CleansingAltarDownsidePlayerReducedArmourAndEvasion"] = { + type = "list", + tooltipLines = { "minus %d to Armour", "minus %d to Evasion Rating" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + modList:NewMod("Armour", "BASE", -values[val][1], "Altar Player Downside") + modList:NewMod("Evasion", "BASE", -values[val][2], "Altar Player Downside") + end, + values = { + [1] = { 3000, 3000 }, + }, + }, + ["CleansingAltarDownsidePlayerReducedFireAndChaosResist"] = { + type = "count", + tooltipLines = { "-(%d to %d)%% to Fire Resistance", "-(%d to %d)%% to Chaos Resistance" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + local roll = (values[val][1][2] + (values[val][1][1] - values[val][1][2]) * rollRange / 100) + modList:NewMod("FireResist", "BASE", -roll, "Altar Player Downside") + modList:NewMod("ChaosResist", "BASE", -roll, "Altar Player Downside") + end, + values = { + [1] = { { 60, 40 }, { 60, 40 } }, + }, + }, + ["CleansingAltarDownsidePlayerScorched"] = { + type = "count", + tooltipLines = { "All Damage taken from Hits can Scorch you", "(%d to %d)%% chance to be Scorched when Hit" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + end, + values = { + [1] = { 25, 35 }, + }, + }, + -- Tangled Altar + -- Tangled Altar Boss + ["TangledAltarDownsideBossMaxLifeAsEnergyShield"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Maximum Life as Extra Maximum Energy Shield" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("LifeGainAsEnergyShield", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { 50, 70 }, + }, + }, + ["TangledAltarDownsideBossPhysicalDamageReduction"] = { + type = "count", + tooltipLines = { "(%d to %d)%% additional Physical Damage Reduction" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageReduction", "BASE", (values[val][1] + (values[val][2] - values[val][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { 50, 70 }, + }, + }, + ["TangledAltarDownsideBossSuppressSpells"] = { + type = "count", + tooltipLines = { "+%d%% chance to Suppress Spell Damage", "Prevent +(%d to %d)%% of Suppressed Spell Damage" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("SpellSuppressionChance", "BASE", values[val][1][1], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("SpellSuppressionEffect", "BASE", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 100 }, { 20, 30 } }, + }, + }, + ["TangledAltarDownsideBossColdAndLightningResist"] = { + type = "list", + tooltipLines = { "+%d%% to Cold Resistance", "+%d%% to maximum Cold Resistance", "+%d%% to Lightning Resistance", "+%d%% to maximum Lightning Resistance" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("ColdResist", "BASE", values[val][1], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("ColdResistMax", "BASE", values[val][2], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("LightningResist", "BASE", values[val][3], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("LightningResistMax", "BASE", values[val][4], "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { 80, 10, 80, 10 }, + }, + }, + ["TangledAltarDownsideBossPenetrateElementalResistances"] = { + type = "count", + tooltipLines = { "Damage Penetrates (%d to %d)%% of Enemy Elemental Resistances", "Gain (%d to %d)%% of Physical Damage as Extra Damage of a random Element" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsRandom", "BASE", (values[val][2][1] + (values[val][2][2] - values[val][2][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + enemyModList:NewMod("ElementalPenetration", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 15, 25 }, { 50, 80 } }, + }, + }, + ["TangledAltarDownsideBossPhysToAddAsCold"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Physical Damage as Extra Cold Damage", "All Damage with Hits can Chill" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsCold", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 70, 130 } }, + }, + }, + ["TangledAltarDownsideBossPhysToAddAsLightning"] = { + type = "count", + tooltipLines = { "Gain (%d to %d)%% of Physical Damage as Extra Lightning Damage", "Hits always Shock", "All Damage can Shock" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsLightning", "BASE", (values[val][1][1] + (values[val][1][2] - values[val][1][1]) * rollRange / 100), "Altar Boss Downside", { type = "Condition", var = "RareOrUnique" }) + end, + values = { + [1] = { { 70, 130 } }, + }, + }, + -- Tangled Altar Monster + -- Tangled Altar Player + ["TangledAltarDownsidePlayerReducedPhysicalDamageReduction"] = { + type = "count", + tooltipLines = { "minus (%d to %d)%% additional Physical Damage Reduction" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + modList:NewMod("PhysicalDamageReduction", "BASE", -(values[val][2] + (values[val][1] - values[val][2]) * rollRange / 100), "Altar Player Downside") + end, + values = { + [1] = { 60, 40 }, + }, + }, + ["TangledAltarDownsidePlayerReducedColdAndLightningResist"] = { + type = "count", + tooltipLines = { "-(%d to %d)%% to Cold Resistance", "-(%d to %d)%% to Lightning Resistance" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + local roll = (values[val][1][2] + (values[val][1][1] - values[val][1][2]) * rollRange / 100) + modList:NewMod("ColdResist", "BASE", -roll, "Altar Player Downside") + modList:NewMod("LightningResist", "BASE", -roll, "Altar Player Downside") + end, + values = { + [1] = { { 60, 40 }, { 60, 40 } }, + }, + }, + ["TangledAltarDownsidePlayerTaintedEndurance"] = { + type = "count", + tooltipLines = { "(%d to %d)%% reduced Recovery Rate of Life, Mana and Energy Shield per Endurance Charge" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + local roll = (values[val][2] + (values[val][1] - values[val][2]) * rollRange / 100) + modList:NewMod("LifeRecoveryRate", "INC", -roll, "Altar Player Downside", { type = "Multiplier", var = "EnduranceCharge" }) + modList:NewMod("ManaRecoveryRate", "INC", -roll, "Altar Player Downside", { type = "Multiplier", var = "EnduranceCharge" }) + modList:NewMod("EnergyShieldRecoveryRate", "INC", -roll, "Altar Player Downside", { type = "Multiplier", var = "EnduranceCharge" }) + end, + values = { + [1] = { 20, 10 }, + }, + }, + ["TangledAltarDownsidePlayerTaintedFrenzy"] = { + type = "count", + tooltipLines = { "(%d to %d)%% reduced Defences per Frenzy Charge" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + modList:NewMod("Defences", "INC", -(values[val][2] + (values[val][1] - values[val][2]) * rollRange / 100), "Altar Player Downside", { type = "Multiplier", var = "FrenzyCharge" }) + end, + values = { + [1] = { 50, 30 }, + }, + }, + ["TangledAltarDownsidePlayerTaintedPower"] = { + type = "count", + tooltipLines = { "-(%d to %d)%% to Critical Strike Multiplier per Power Charge" }, + apply = function(val, rollRange, mapModEffect, values, modList, enemyModList) + modList:NewMod("CritMultiplier", "BASE", -(values[val][2] + (values[val][1] - values[val][2]) * rollRange / 100), "Altar Player Downside", { type = "Multiplier", var = "PowerCharge" }) + end, + values = { + [1] = { 40, 20 }, + }, + }, + ["TangledAltarDownsidePlayerColdMonsterAura"] = { + type = "list", + tooltipLines = { "Nearby Enemies Gain %d%% of their Physical Damage as Extra Cold Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsCold", "BASE", values[val], "Altar Player Downside") + end, + values = { + [1] = 100, + }, + }, + ["TangledAltarDownsidePlayerLightningMonsterAura"] = { + type = "list", + tooltipLines = { "Nearby Enemies Gain %d%% of their Physical Damage as Extra Lightning Damage" }, + apply = function(val, mapModEffect, values, modList, enemyModList) + enemyModList:NewMod("PhysicalDamageGainAsLightning", "BASE", values[val], "Altar Player Downside") + end, + values = { + [1] = 100, + }, }, -- other Prefixes ["Abhorrent"] = { }, -- Area is inhabited by Abominations + ["Afflicting"] = { }, -- All Monster Damage can Ignite, Freeze and Shock", "Monsters Ignite, Freeze and Shock on Hit ["Antagonist's"] = { }, -- (20-30)% increased number of Rare Monsters ["Bipedal"] = { }, -- Area is inhabited by Humanoids ["Capricious"] = { }, -- Area is inhabited by Goatmen ["Ceremonial"] = { }, -- Area contains many Totems ["Chaining"] = { }, -- Monsters' skills Chain 2 additional times + ["Cycling"] = { }, -- Players and their Minions deal no damage for 3 out of every 10 seconds ["Demonic"] = { }, -- Area is inhabited by Demons ["Emanant"] = { }, -- Area is inhabited by ranged monsters ["Enthralled"] = { }, -- Unique Bosses are Possessed + ["Equalising"] = { }, -- Rare and Unique Monsters remove 5% of Life, Mana and Energy Shield from Players or their Minions on Hit ["Feasting"] = { }, -- Area is inhabited by Cultists of Kitava ["Feral"] = { }, -- Area is inhabited by Animals + ["Grasping"] = { }, -- Monsters inflict 2 Grasping Vines on Hit ["Haunting"] = { }, -- Area is inhabited by Ghosts + ["Hungering"] = { }, -- Area contains Drowning Orbs ["Lunar"] = { }, -- Area is inhabited by Lunaris fanatics + ["Magnifying"] = { }, -- Monsters have 100% increased Area of Effect", "Monsters fire 2 additional Projectiles ["Multifarious"] = { }, -- Area has increased monster variety + ["Parasitic"] = { }, -- 15% of Damage Players' Totems take from Hits is taken from their Summoner's Life instead + ["Prismatic"] = { }, -- Monsters gain (180-200)% of their Physical Damage as Extra Damage of a random Element + ["Protected"] = { }, -- +50% Monster Physical Damage Reduction", "+35% Monster Chaos Resistance", "+55% Monster Elemental Resistances + ["Retributive"] = { }, -- Players are Marked for Death for 10 seconds", "after killing a Rare or Unique monster + ["Sabotaging"] = { }, -- Player Skills which Throw Mines throw 1 fewer Mine", "Player Skills which Throw Traps throw 1 fewer Trap + ["Searing"] = { }, -- Area contains Runes of the Searing Exarch ["Skeletal"] = { }, -- Area is inhabited by Skeletons ["Slithering"] = { }, -- Area is inhabited by Sea Witches and their Spawn ["Solar"] = { }, -- Area is inhabited by Solaris fanatics ["Splitting"] = { }, -- Monsters fire 2 additional Projectiles + ["Stalwart"] = { }, -- Monsters have +50% Chance to Block Attack Damage + ["Synthetic"] = { }, -- Map Boss is accompanied by a Synthesis Boss ["Twinned"] = { }, -- Area contains two Unique Bosses + ["Ultimate"] = { }, -- Players are assaulted by Bloodstained Sawblades ["Undead"] = { }, -- Area is inhabited by Undead + ["Valdo's"] = { }, -- Rare monsters in area are Shaper-Touched + ["Volatile"] = { }, -- Rare Monsters have Volatile Cores -- other Suffixes - ["of Bloodlines"] = { }, -- (20-30)% more Magic Monsters + ["Decaying"] = { }, -- Area contains Unstable Tentacle Fiends + ["of Bloodlines"] = { }, -- (20-30)% increased Magic Monsters ["of Carnage"] = { }, -- Monsters Maim on Hit with Attacks + ["of Collection"] = { }, -- The Maven interferes with Players ["of Consecration"] = { }, -- Area has patches of Consecrated Ground + ["of Deceleration"] = { }, -- Players have 3% reduced Action Speed for each time they've used a Skill Recently + ["of Defiance"] = { }, -- Debuffs on Monsters expire 100% faster ["of Desecration"] = { }, -- Area has patches of desecrated ground + ["of Desolation"] = { }, -- Area has patches of Awakeners' Desolation + ["of Domination"] = { }, -- Unique Monsters have a random Shrine Buff ["of Endurance"] = { }, -- Monsters gain an Endurance Charge on Hit ["of Enervation"] = { }, -- Monsters steal Power, Frenzy and Endurance charges on Hit ["of Flames"] = { }, -- Area has patches of Burning Ground ["of Frenzy"] = { }, -- Monsters gain a Frenzy Charge on Hit ["of Giants"] = { }, -- Monsters have 45% increased Area of Effect ["of Ice"] = { }, -- Area has patches of Chilled Ground + ["of Imbibing"] = { }, -- Players are targeted by a Meteor when they use a Flask ["of Impedance"] = { }, -- Monsters Hinder on Hit with Spells ["of Lightning"] = { }, -- Area has patches of Shocked Ground which increase Damage taken by 20% + ["of Penetration"] = { }, -- Monster Damage Penetrates 15% Elemental Resistances + ["of Petrification"] = { }, -- Area contains Petrification Statues ["of Power"] = { }, -- Monsters gain a Power Charge on Hit + ["of Revolt"] = { }, -- Players' Minions have 50% less Attack Speed", "Players' Minions have 50% less Cast Speed", "Players' Minions have 50% less Movement Speed + ["of Splinters"] = { }, -- 25% chance for Rare Monsters to Fracture on death + ["of the Juggernaut"] = { }, -- Monsters cannot be Stunned", "Monsters' Action Speed cannot be modified to below Base Value", "Monsters' Movement Speed cannot be modified to below Base Value + -- other CleansingAltares + ["CleansingAltarDownsideBossConsecrateOnHit"] = { }, -- Create Consecrated Ground on Hit, lasting 6 seconds + ["CleansingAltarDownsideBossCoveredInAshOnHit"] = { }, -- Gain (50-80)% of Physical Damage as Extra Fire Damage", "Cover Enemies in Ash on Hit + ["CleansingAltarDownsideBossHinderAura"] = { }, -- Nearby Enemies are Hindered, with 40% reduced Movement Speed + ["CleansingAltarDownsideBossRemoveFlaskChargeOnHit"] = { }, -- Enemies lose 6 Flask Charges every 3 seconds and cannot gain Flask Charges for 6 seconds after being Hit + ["CleansingAltarDownsideMonsterArmour"] = { }, -- +50000 to Armour + ["CleansingAltarDownsideMonsterBurningGroundOnDeath"] = { }, -- Drops Burning Ground on Death, lasting 3 seconds + ["CleansingAltarDownsideMonsterChaosDamage"] = { }, -- Gain (70-130)% of Physical Damage as Extra Chaos Damage + ["CleansingAltarDownsideMonsterConsecratedGroundOnDeath"] = { }, -- Create Consecrated Ground on Death, lasting 6 seconds + ["CleansingAltarDownsideMonsterExposureOnHit"] = { }, -- Gain (70-130)% of Physical Damage as Extra Damage of a random Element", "Inflict Fire, Cold, and Lightning Exposure on Hit + ["CleansingAltarDownsideMonsterFireAndChaosResist"] = { }, -- +10% to maximum Fire Resistance", "+80% to Fire Resistance", "+10% to maximum Chaos Resistance", "+80% to Chaos Resistance + ["CleansingAltarDownsideMonsterFireDamage"] = { }, -- Gain (70-130)% of Physical Damage as Extra Fire Damage + ["CleansingAltarDownsideMonsterFlaskDegenOnHit"] = { }, -- Enemies lose 6 Flask Charges every 3 seconds and cannot gain Flask Charges for 6 seconds after being Hit + ["CleansingAltarDownsideMonsterIncreasedArea"] = { }, -- (70-130)% increased Area of Effect + ["CleansingAltarDownsideMonsterIncreasedEvasion"] = { }, -- (250-500)% increased Evasion Rating + ["CleansingAltarDownsidePlayerBurningGroundWhenHit"] = { }, -- (15-20)% chance for Enemies to drop Burning Ground when Hitting you, no more than once every 2 seconds + ["CleansingAltarDownsidePlayerCurseReflect"] = { }, -- Curses you inflict are reflected back to you + ["CleansingAltarDownsidePlayerMeteorOnFlaskUse"] = { }, -- 30% chance to be targeted by a Meteor when you use a Flask + -- other TangledAltares + ["TangledAltarDownsideBossBlindOnHit"] = { }, -- 100% Global chance to Blind Enemies on hit", "(100-200)% increased Blind Effect + ["TangledAltarDownsideBossCoveredInFrostOnHit"] = { }, -- Gain (50-80)% of Physical Damage as Extra Cold Damage", "Cover Enemies in Frost on Hit + ["TangledAltarDownsideMonsterChilledGroundOnDeath"] = { }, -- Drops Chilled Ground on Death, lasting 3 seconds + ["TangledAltarDownsideMonsterColdAndLightningResist"] = { }, -- +10% to maximum Cold Resistance", "+80% to Cold Resistance", "+10% to maximum Lightning Resistance", "+80% to Lightning Resistance + ["TangledAltarDownsideMonsterColdDamage"] = { }, -- Gain (70-130)% of Physical Damage as Extra Cold Damage + ["TangledAltarDownsideMonsterExtraProjectiles"] = { }, -- Skills fire (3-5) additional Projectiles + ["TangledAltarDownsideMonsterGraspingVineStackOnHit"] = { }, -- Inflict 1 Grasping Vine on Hit + ["TangledAltarDownsideMonsterLightningDamage"] = { }, -- Gain (70-130)% of Physical Damage as Extra Lightning Damage + ["TangledAltarDownsideMonsterOverwhelm"] = { }, -- Hits have (50-80)% chance to ignore Enemy Physical Damage Reduction + ["TangledAltarDownsideMonsterPhysicalDamageReduction"] = { }, -- (50-80)% additional Physical Damage Reduction + ["TangledAltarDownsideMonsterRemoveChargeOnHit"] = { }, -- 100% chance to remove a random Charge from Enemy on Hit + ["TangledAltarDownsideMonsterShockedGroundOnDeath"] = { }, -- 100% chance to create Shocked Ground on Death, lasting 3 seconds + ["TangledAltarDownsideMonsterSpeed"] = { }, -- (30-50)% increased Attack Speed", "(30-50)% increased Cast Speed", "(30-50)% increased Movement Speed + ["TangledAltarDownsideMonsterSupressSpells"] = { }, -- Prevent +(20-30)% of Suppressed Spell Damage", "+100% chance to Suppress Spell Damage + ["TangledAltarDownsidePlayerChilledGroundWhenHit"] = { }, -- (25-35)% chance for Enemies to drop Chilled Ground when Hitting you, no more than once every 2 seconds + ["TangledAltarDownsidePlayerNonDamagingAilmentsReflectedToSelf"] = { }, -- Non-Damaging Ailments you inflict are reflected back to you + ["TangledAltarDownsidePlayerRandomProjectileDirection"] = { }, -- Projectiles are fired in random directions + ["TangledAltarDownsidePlayerSapped"] = { }, -- All Damage taken from Hits can Sap you", "(25-35)% chance to be Sapped when Hit + ["TangledAltarDownsidePlayerShockedGroundWhenHit"] = { }, -- (25-35)% chance for Enemies to drop Shocked Ground when Hitting you, no more than once every 2 seconds }, - Prefix = { - { val = "NONE", label = "None" }, - { val = "Armoured", label = "Enemy Phys D R" .. " Physical Damage reduction".."Armoured" }, - { val = "Hexproof", label = "Enemy is Hexproof?" .. " ".."Hexproof" }, - { val = "Hexwarded", label = "Less Curse effect" .. " of Curses on enemy".."Hexwarded" }, - { val = "Resistant", label = "Enemy Resist" .. " has Elemental / Chaos".."Resistant" }, - { val = "Unstoppable", label = "Enemy Cannot Be Slowed Monsters Taunted Action Speed modified below base value".."Unstoppable" }, - { val = "Impervious", label = "avoid Poison and Bleed:" .. " Enemy ".."Impervious" }, - { val = "Savage", label = "Enemy Inc Damage" .. " has increased Damage".."Savage" }, - { val = "Burning", label = "Enemy Phys As Fire Monsters deal to extra Physical Damage".."Burning" }, - { val = "Freezing", label = "Enemy Phys As Cold Monsters deal to extra Physical Damage".."Freezing" }, - { val = "Shocking", label = "Enemy Phys As Lightning Monsters deal to extra Physical Damage".."Shocking" }, - { val = "Profane", label = "Enemy Phys As Chaos Monsters deal to extra Physical Damage Inflict Withered for seconds on Hit Profane" }, - { val = "Fleet", label = "Enemy Inc Speed to increased Monster Movement Attack Cast".."Fleet" }, - { val = "Impaling", label = "Enemy Impale Monsters have chance to with Attacks Impaling" }, - { val = "Conflagrating", label = "Hits always Ignites All Monster Damage from Conflagrating" }, - { val = "Empowered", label = "Elemental Ailments on Hit Monsters have chance to cause Empowered" }, - { val = "Overlord's", label = "Boss Inc Damage / Speed Unique deals increased has Attack and Cast".."Overlord's" }, + Prefix = function(build) + local List = {} + local tier = (build.configTab and build.configTab.varControls["multiplierMapModTier"].selIndex or 4) + if mapTierCache["Prefix"..tier] then + return mapTierCache["Prefix"..tier] + end + for affixName, affix in pairs(data.mapMods.AffixData) do + if affix.modType == "Prefix" and (affix.type == "check" or affix.values and affix.values[tier]) and affix.label then + t_insert(List, { val = affixName, label = affix.label, tooltip = tooltipGenerator(affix, tier), range = (affix.type == "count") or nil}) + end + end + table.sort(List, function(a, b) return data.mapMods.AffixData[a.val].order < data.mapMods.AffixData[b.val].order end) + mapTierCache["Prefix"..tier] = List + return List + end, + Suffix = function(build) + local List = {} + local tier = (build.configTab and build.configTab.varControls["multiplierMapModTier"].selIndex or 4) + if mapTierCache["Suffix"..tier] then + return mapTierCache["Suffix"..tier] + end + for affixName, affix in pairs(data.mapMods.AffixData) do + if affix.modType == "Suffix" and (affix.type == "check" or affix.values and affix.values[tier]) and affix.label then + t_insert(List, { val = affixName, label = affix.label, tooltip = tooltipGenerator(affix, tier), range = (affix.type == "count") or nil}) + end + end + table.sort(List, function(a, b) return data.mapMods.AffixData[a.val].order < data.mapMods.AffixData[b.val].order end) + mapTierCache["Suffix"..tier] = List + return List + end, + CleansingAltar = { + { val = "ALLPLAYER", label = "All Player Downsides" }, + { val = "CleansingAltarDownsideBossArmour", label = "Boss Armour to CleansingAltarDownsideBossArmour" }, + { val = "CleansingAltarDownsideBossIncreasedArmourAndEvasion", label = "Boss Increased Armour And Evasion Rating to CleansingAltarDownsideBossIncreasedArmourAndEvasion", range = true }, + { val = "CleansingAltarDownsideBossFireAndChaosResist", label = "Boss Fire and Chaos Resistances to maximum CleansingAltarDownsideBossFireAndChaosResist" }, + { val = "CleansingAltarDownsideBossPenetrateElementalResist", label = "Boss Phys as Random and Penetration Gain to of Physical Damage Extra Penetrates Enemy Resistances CleansingAltarDownsideBossPenetrateElementalResist", range = true }, + { val = "CleansingAltarDownsideBossPhysToAddAsChaos", label = "Boss Physical As Chaos Gain of Damage Extra Poison Hit All from Hits can CleansingAltarDownsideBossPhysToAddAsChaos", range = true }, + { val = "CleansingAltarDownsideBossPhysToAddAsFire", label = "Boss Physical As Fire Hits always Ignite Gain of Damage Extra All can CleansingAltarDownsideBossPhysToAddAsFire", range = true }, + { val = "CleansingAltarDownsidePlayerIncreasedFlaskChargesUsed", label = "Reduced Flask Sustain to Effect Duration CleansingAltarDownsidePlayerIncreasedFlaskChargesUsed", range = true }, + { val = "CleansingAltarDownsidePlayerChaosDegenDuringFlaskDuration", label = "Chaos Degen During Flask Take Damage per second any Effect CleansingAltarDownsidePlayerChaosDegenDuringFlaskDuration" }, + { val = "CleansingAltarDownsidePlayerChaosMonsterAura", label = "Physical As Chaos Aura Nearby Enemies Gain of their Damage Extra CleansingAltarDownsidePlayerChaosMonsterAura" }, + { val = "CleansingAltarDownsidePlayerFireMonsterAura", label = "Physical As Fire Aura Nearby Enemies Gain of their Damage Extra CleansingAltarDownsidePlayerFireMonsterAura" }, + { val = "CleansingAltarDownsidePlayerReducedArmourAndEvasion", label = "Minus Armour and Evasion Rating to CleansingAltarDownsidePlayerReducedArmourAndEvasion" }, + { val = "CleansingAltarDownsidePlayerReducedFireAndChaosResist", label = "Minus Fire and Chaos Resistances - to CleansingAltarDownsidePlayerReducedFireAndChaosResist", range = true }, }, - Suffix = { - { val = "NONE", label = "None" }, - { val = "of Congealment", label = "Cannot Leech" .." Life / Mana".."of Congealment" }, - { val = "of Drought", label = "reduced Flask Charges" .. " Gains".."of Drought" }, - { val = "of Exposure", label = "-X% maximum Res" .. " Resistances".."of Exposure" }, - { val = "of Impotence", label = "Less Area of Effect:" .. " ".."of Impotence" }, - { val = "of Insulation", label = "avoid Elemental Ailments:" .. " Enemy".."of Impotence" }, - { val = "of Miring", label = "Enemy has inc. Accuracy: / Players have to amount of Suppressed Spell Damage Prevented" .. " ".."of Miring" }, - { val = "of Rust", label = "Reduced Block Chance / less Armour:" .. " ".."of Rust" }, - { val = "of Smothering", label = "Less Recovery Rate of ^xE05030Life ^7and ^x88FFFFEnergy Shield:" .. " ".."of Smothering" }, - { val = "of Stasis", label = "Cannot Regen" .. " Life, Mana or ES".."of Stasis" }, - { val = "of Toughness", label = "Enemy takes red. Extra Crit Damage:" .. " ".."of Toughness" }, - { val = "of Fatigue", label = "Less Cooldown Recovery Players have Rate".."of Fatigue" }, - { val = "of Doubt", label = "Reduced Aura Effect Players have Non-Curse Auras from Skills".."of Doubt" }, - { val = "of Imprecision", label = "Less Accuracy Players have Rating".."of Imprecision" }, - { val = "of Venom", label = "Poison On Hit Monsters of Venom" }, - { val = "of Deadliness", label = "Enemy Critical Strike Monsters have to increased Chance Monster Multiplier".."of Deadliness" }, + TangledAltar = { + { val = "ALLPLAYER", label = "All Player Downsides" }, + { val = "TangledAltarDownsideBossPhysicalDamageReduction", label = "Boss Physical Damage Reduction to additional TangledAltarDownsideBossPhysicalDamageReduction", range = true }, + { val = "TangledAltarDownsideBossSuppressSpells", label = "Boss Spell Suppression Prevent to of Suppressed Damage chance TangledAltarDownsideBossSuppressSpells", range = true }, + { val = "TangledAltarDownsideBossColdAndLightningResist", label = "Boss Cold and Lightning Resistances to maximum TangledAltarDownsideBossColdAndLightningResist" }, + { val = "TangledAltarDownsideBossPenetrateElementalResistances", label = "Boss Phys as Random and Penetration Gain to of Physical Damage Extra Penetrates Enemy TangledAltarDownsideBossPenetrateElementalResistances", range = true }, + { val = "TangledAltarDownsideBossPhysToAddAsCold", label = "Boss Physical As Cold Gain of Damage Extra All with Hits can Chill TangledAltarDownsideBossPhysToAddAsCold", range = true }, + { val = "TangledAltarDownsideBossPhysToAddAsLightning", label = "Boss Physical As Lightning Hits always Shock Gain of Damage Extra All can TangledAltarDownsideBossPhysToAddAsLightning", range = true }, + { val = "TangledAltarDownsidePlayerReducedPhysicalDamageReduction", label = "Minus Physical Damage Reduction to additional TangledAltarDownsidePlayerReducedPhysicalDamageReduction", range = true }, + { val = "TangledAltarDownsidePlayerReducedColdAndLightningResist", label = "Minus Cold and Lightning Resistances - to TangledAltarDownsidePlayerReducedColdAndLightningResist", range = true }, + { val = "TangledAltarDownsidePlayerTaintedEndurance", label = "Minus Recovery Rate Per Endurance Charge to reduced of Life, Mana and Energy Shield TangledAltarDownsidePlayerTaintedEndurance", range = true }, + { val = "TangledAltarDownsidePlayerTaintedFrenzy", label = "Minus Defences Per Frenzy Charge to reduced TangledAltarDownsidePlayerTaintedFrenzy", range = true }, + { val = "TangledAltarDownsidePlayerTaintedPower", label = "Minus Crit Multi Per Power Charge - to Critical Strike Multiplier TangledAltarDownsidePlayerTaintedPower", range = true }, + { val = "TangledAltarDownsidePlayerColdMonsterAura", label = "Physical As Cold Aura Nearby Enemies Gain of their Damage Extra TangledAltarDownsidePlayerColdMonsterAura" }, + { val = "TangledAltarDownsidePlayerLightningMonsterAura", label = "Physical As Lightning Aura Nearby Enemies Gain of their Damage Extra TangledAltarDownsidePlayerLightningMonsterAura" }, }, } \ No newline at end of file diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index ec3b60e203..60e12e643f 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -1500,6 +1500,7 @@ function calcs.buildDefenceEstimations(env, actor) if enemyOverwhelm == nil then enemyOverwhelm = tonumber(env.configPlaceholder["enemy"..damageType.."enemyOverwhelm"]) or 0 end + enemyPen = enemyPen + enemyDB:Sum("BASE", enemyCfg, damageType.."Penetration", isElemental[damageType] and "ElementalPenetration" or nil ) -- Add min-max enemy damage from mods enemyDamage = enemyDamage + (enemyDB:Sum("BASE", enemyCfg, (damageType.."Min")) + enemyDB:Sum("BASE", enemyCfg, (damageType.."Max"))) / 2 @@ -1533,7 +1534,7 @@ function calcs.buildDefenceEstimations(env, actor) conversionTotal = conversions["total"] + conversions["totalSkill"] -- Calculate the amount converted/gained as for _, damageTypeTo in ipairs(dmgTypeList) do - local gainAsPercent = (enemyDB:Sum("BASE", enemyCfg, (damageType.."DamageGainAs"..damageTypeTo)) + conversions[damageTypeTo.."skill"] + conversions[damageTypeTo]) / 100 + local gainAsPercent = (enemyDB:Sum("BASE", enemyCfg, (damageType.."DamageGainAs"..damageTypeTo)) + (isElemental[damageTypeTo] and enemyDB:Sum("BASE", enemyCfg, (damageType.."DamageGainAsRandom")) or 0)/3 + conversions[damageTypeTo.."skill"] + conversions[damageTypeTo]) / 100 if gainAsPercent > 0 then enemyDamageConversion[damageTypeTo] = enemyDamageConversion[damageTypeTo] or { } enemyDamageConversion[damageTypeTo][damageType] = enemyDamage * gainAsPercent @@ -3388,7 +3389,7 @@ function calcs.buildDefenceEstimations(env, actor) ailmentList["Ignite"] = { damageType = "Fire", sourceTypes = enemyDB:Flag(nil, "AllDamageIgnites") and dmgTypeList or { "Fire" } } end if enemyPoisonChance > 0 then - ailmentList["Poison"] = { damageType = "Chaos", sourceTypes = { "Physical", "Chaos" } } + ailmentList["Poison"] = { damageType = "Chaos", sourceTypes = enemyDB:Flag(nil, "AllDamagePoisons") and dmgTypeList or{ "Physical", "Chaos" } } end for source, ailment in pairs(ailmentList) do local baseVal = 0 diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index fc430b091d..0998d495a6 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -295,7 +295,7 @@ function calcSkillDuration(skillModList, skillCfg, skillData, env, enemyDB) local duration = durationBase * durationMod local debuffDurationMult = 1 if env.mode_effective then - debuffDurationMult = 1 / m_max(data.misc.BuffExpirationSlowCap, calcLib.mod(enemyDB, skillCfg, "BuffExpireFaster")) + debuffDurationMult = 1 / m_max(data.misc.BuffExpirationSlowCap, calcLib.mod(enemyDB, skillCfg, "BuffExpireFaster", "DebuffExpireFaster")) end if skillData.debuff then duration = duration * debuffDurationMult @@ -1375,7 +1375,7 @@ function calcs.offence(env, actor, activeSkill) -- Skill duration local debuffDurationMult = 1 if env.mode_effective then - debuffDurationMult = 1 / m_max(data.misc.BuffExpirationSlowCap, calcLib.mod(enemyDB, skillCfg, "BuffExpireFaster")) + debuffDurationMult = 1 / m_max(data.misc.BuffExpirationSlowCap, calcLib.mod(enemyDB, skillCfg, "BuffExpireFaster", "DebuffExpireFaster")) end do output.DurationMod = calcLib.mod(skillModList, skillCfg, "Duration", "PrimaryDuration", "SkillAndDamagingAilmentDuration", skillData.mineDurationAppliesToSkill and "MineDuration" or nil) @@ -2332,6 +2332,15 @@ function calcs.offence(env, actor, activeSkill) if quantityMultiplier > 1 then output.QuantityMultiplier = quantityMultiplier end + + -- enemy spell suppress + do + local enemySuppressChance = m_min((enemyDB:Sum("BASE", cfg, "SpellSuppressionChance") or 0), 100) + if enemySuppressChance > 0 then + local effect = m_min(data.misc.SuppressionEffect + enemyDB:Sum("BASE", cfg, "SpellSuppressionEffect"), 100) + enemyDB:NewMod("DamageTaken", "MORE", -m_floor(effect * enemySuppressChance / 100), "Enemy Spell Suppression", ModFlag.Spell) + end + end --Calculate damage (exerts, crits, ruthless, DPS, etc) for _, pass in ipairs(passList) do diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index af359bcb5e..a12f856fdf 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -1782,7 +1782,8 @@ return { "PhysicalDamageGainAsLightning", "PhysicalDamageSkillConvertToLightning", "PhysicalDamageConvertToLightning", "PhysicalDamageGainAsCold", "PhysicalDamageSkillConvertToCold", "PhysicalDamageConvertToCold", "PhysicalDamageGainAsFire", "PhysicalDamageSkillConvertToFire", "PhysicalDamageConvertToFire", - "PhysicalDamageGainAsChaos", "PhysicalDamageSkillConvertToChaos", "PhysicalDamageConvertToChaos" + "PhysicalDamageGainAsChaos", "PhysicalDamageSkillConvertToChaos", "PhysicalDamageConvertToChaos", + "PhysicalDamageGainAsRandom" }, enemy = true }, }, { format = "{2:output:PhysicalEnemyDamage}", @@ -1792,23 +1793,24 @@ return { "PhysicalDamageGainAsLightning", "PhysicalDamageSkillConvertToLightning", "PhysicalDamageConvertToLightning", "PhysicalDamageGainAsCold", "PhysicalDamageSkillConvertToCold", "PhysicalDamageConvertToCold", "PhysicalDamageGainAsFire", "PhysicalDamageSkillConvertToFire", "PhysicalDamageConvertToFire", - "PhysicalDamageGainAsChaos", "PhysicalDamageSkillConvertToChaos", "PhysicalDamageConvertToChaos" + "PhysicalDamageGainAsChaos", "PhysicalDamageSkillConvertToChaos", "PhysicalDamageConvertToChaos", + "PhysicalDamageGainAsRandom" }, enemy = true }, }, { format = "{2:output:LightningEnemyDamage}", { breakdown = "LightningEnemyDamage" }, { label = "Enemy modifiers", modName = {"Damage", "LightningDamage", "ElementalDamage", "CritChance", "CritMultiplier"}, enemy = true }, - { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsLightning", "PhysicalDamageSkillConvertToLightning", "PhysicalDamageConvertToLightning"}, enemy = true }, + { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsLightning", "PhysicalDamageGainAsRandom", "PhysicalDamageSkillConvertToLightning", "PhysicalDamageConvertToLightning"}, enemy = true }, }, { format = "{2:output:ColdEnemyDamage}", { breakdown = "ColdEnemyDamage" }, { label = "Enemy modifiers", modName = {"Damage", "ColdDamage", "ElementalDamage", "CritChance", "CritMultiplier"}, enemy = true }, - { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsCold", "PhysicalDamageSkillConvertToCold", "PhysicalDamageConvertToCold"}, enemy = true }, + { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsCold", "PhysicalDamageGainAsRandom", "PhysicalDamageSkillConvertToCold", "PhysicalDamageConvertToCold"}, enemy = true }, }, { format = "{2:output:FireEnemyDamage}", { breakdown = "FireEnemyDamage" }, { label = "Enemy modifiers", modName = {"Damage", "FireDamage", "ElementalDamage", "CritChance", "CritMultiplier"}, enemy = true }, - { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsFire", "PhysicalDamageSkillConvertToFire", "PhysicalDamageConvertToFire"}, enemy = true }, + { label = "Enemy Conversion modifiers", modName = {"PhysicalDamageGainAsFire", "PhysicalDamageGainAsRandom", "PhysicalDamageSkillConvertToFire", "PhysicalDamageConvertToFire"}, enemy = true }, }, { format = "{2:output:ChaosEnemyDamage}", { breakdown = "ChaosEnemyDamage" }, @@ -1907,23 +1909,27 @@ return { { format = "" }, { format = "x {3:output:PhysicalTakenHitMult}", { breakdown = "PhysicalTakenHitMult" }, - { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "PhysicalDamageTaken", "PhysicalDamageTakenWhenHit", "PhysicalDamageTakenAsFire", "PhysicalDamageTakenAsCold", "PhysicalDamageTakenAsLightning", "PhysicalDamageTakenAsChaos" } } + { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "PhysicalDamageTaken", "PhysicalDamageTakenWhenHit", "PhysicalDamageTakenAsFire", "PhysicalDamageTakenAsCold", "PhysicalDamageTakenAsLightning", "PhysicalDamageTakenAsChaos" } } }, { format = "x {3:output:LightningTakenHitMult}", { breakdown = "LightningTakenHitMult" }, - { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "LightningDamageTaken", "LightningDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "LightningDamageTakenAsPhysical", "LightningDamageTakenAsFire", "LightningDamageTakenAsCold", "LightningDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreLightningResistance" } } + { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "LightningDamageTaken", "LightningDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "LightningDamageTakenAsPhysical", "LightningDamageTakenAsFire", "LightningDamageTakenAsCold", "LightningDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreLightningResistance" } }, + { label = "Enemy modifiers", modName = { "LightningPenetration", "ElementalPenetration" }, enemy = true }, }, { format = "x {3:output:ColdTakenHitMult}", { breakdown = "ColdTakenHitMult" }, - { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "ColdDamageTaken", "ColdDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "ColdDamageTakenAsPhysical", "ColdDamageTakenAsFire", "ColdDamageTakenAsLightning", "ColdDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreColdResistance" } } + { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "ColdDamageTaken", "ColdDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "ColdDamageTakenAsPhysical", "ColdDamageTakenAsFire", "ColdDamageTakenAsLightning", "ColdDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreColdResistance" } }, + { label = "Enemy modifiers", modName = { "ColdPenetration", "ElementalPenetration" }, enemy = true }, }, { format = "x {3:output:FireTakenHitMult}", { breakdown = "FireTakenHitMult" }, - { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "FireDamageTaken", "FireDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "FireDamageTakenAsPhysical", "FireDamageTakenAsCold", "FireDamageTakenAsLightning", "FireDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreFireResistance" } } + { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "FireDamageTaken", "FireDamageTakenWhenHit", "ElementalDamageTaken", "ElementalDamageTakenWhenHit", "FireDamageTakenAsPhysical", "FireDamageTakenAsCold", "FireDamageTakenAsLightning", "FireDamageTakenAsChaos", "ElementalDamageTakenAsPhysical", "ElementalDamageTakenAsChaos", "SelfIgnoreFireResistance" } }, + { label = "Enemy modifiers", modName = { "FirePenetration", "ElementalPenetration" }, enemy = true }, }, { format = "x {3:output:ChaosTakenHitMult}", { breakdown = "ChaosTakenHitMult" }, - { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "ChaosDamageTaken", "ChaosDamageTakenWhenHit", "ChaosDamageTakenAsPhysical", "ChaosDamageTakenAsFire", "ChaosDamageTakenAsCold", "ChaosDamageTakenAsLightning", "SelfIgnoreChaosResistance" } } + { modName = { "DamageTaken", "DamageTakenWhenHit", "AttackDamageTaken", "SpellDamageTaken", "ChaosDamageTaken", "ChaosDamageTakenWhenHit", "ChaosDamageTakenAsPhysical", "ChaosDamageTakenAsFire", "ChaosDamageTakenAsCold", "ChaosDamageTakenAsLightning", "SelfIgnoreChaosResistance" } }, + { label = "Enemy modifiers", modName = { "ChaosPenetration" }, enemy = true }, }, }, { label = "Reflect taken", haveOutput = "AnyTakenReflect", diff --git a/src/Modules/ConfigOptions.lua b/src/Modules/ConfigOptions.lua index 902dabc18f..700831ae0a 100644 --- a/src/Modules/ConfigOptions.lua +++ b/src/Modules/ConfigOptions.lua @@ -78,34 +78,72 @@ local function mapAffixTooltip(tooltip, mode, index, value) end local applyModes = { BODY = true, HOVER = true } if applyModes[mode] then - tooltip:AddLine(14, '^7'..value.val) - local affixData = data.mapMods.AffixData[value.val] or {} - if #affixData.tooltipLines > 0 then + tooltip:AddLine(20, '^7'..value.val) + if value.tooltip then + for _, line in ipairs(value.tooltip) do + tooltip:AddLine(line[1], line[2]) + end + return + end + end +end + +local function mapAffixDropDownFunction(val, extraData, modList, enemyModList, build) + if val ~= "NONE" then + local effect = (1 + (build.configTab.input['multiplierMapModEffect'] or 0)/100) + local tier = (build.configTab.varControls['multiplierMapModTier'].selIndex or 1) + local affixData = data.mapMods.AffixData[val] or {} + if affixData.apply then if affixData.type == "check" then - for _, line in ipairs(affixData.tooltipLines) do - tooltip:AddLine(14, '^7'..line) - end + affixData.apply(var, effect, modList, enemyModList) elseif affixData.type == "list" then - for i, tier in ipairs({"Low", "Med", "High"}) do - tooltip:AddLine(16, '^7'..tier..": ") - for j, line in ipairs(affixData.tooltipLines) do - local modValue = (#affixData.tooltipLines > 1) and affixData.values[i][j] or affixData.values[i] - if modValue == nil then - tooltip:AddLine(14, ' ^7'..line) - elseif modValue ~= 0 then - tooltip:AddLine(14, ' ^7'..s_format(line, modValue)) + affixData.apply(tier, effect, affixData.values, modList, enemyModList) + elseif affixData.type == "count" then + affixData.apply(tier, extraData[1] or 100, effect, affixData.values, modList, enemyModList) + end + end + end +end + +local function eldrtichAltarTooltip(tooltip, mode, index, value) + tooltip:Clear() + if value.val == "NONE" then + return + end + local applyModes = { BODY = true, HOVER = true } + if applyModes[mode] then + if value.val == "ALL" then + tooltip:AddLine(16, '^7Adds All Eldritch Altar Mods of This Kind') + elseif value.val == "ALLPLAYER" then + tooltip:AddLine(16, '^7Adds All Player Eldritch Altar Mods of This Kind') + else + tooltip:AddLine(20, '^7'..value.val) + local affixData = data.mapMods.AffixData[value.val] + if #affixData.tooltipLines > 0 then + if affixData.type == "check" then + for _, line in ipairs(affixData.tooltipLines) do + tooltip:AddLine(14, '^7'..line) + end + elseif affixData.type == "list" then + if affixData.values[1] then + for i, line in ipairs(affixData.tooltipLines) do + local modValue = (#affixData.tooltipLines > 1) and affixData.values[1][i] or affixData.values[1] + if modValue == nil then + tooltip:AddLine(14, ' ^7'..line) + elseif modValue ~= 0 then + tooltip:AddLine(14, ' ^7'..s_format(line, modValue)) + end end end - end - elseif affixData.type == "count" then - for i, tier in ipairs({"Low", "Med", "High"}) do - tooltip:AddLine(16, '^7'..tier..": ") - for j, line in ipairs(affixData.tooltipLines) do - local modValue = {(#affixData.tooltipLines > 1) and (affixData.values[i][j] and affixData.values[i][j][1] or nil) or affixData.values[i][1], (#affixData.tooltipLines > 1) and (affixData.values[i][j] and affixData.values[i][j][2] or nil) or affixData.values[i][2]} - if modValue[2] == nil then - tooltip:AddLine(14, ' ^7'..line) - elseif modValue[2] ~= 0 then - tooltip:AddLine(14, ' ^7'..s_format(line, modValue[1], modValue[2])) + elseif affixData.type == "count" then + if affixData.values[1] then + for i, line in ipairs(affixData.tooltipLines) do + local modValue = {(#affixData.tooltipLines > 1) and (affixData.values[1][i] and affixData.values[1][i][1] or nil) or affixData.values[1][1], (#affixData.tooltipLines > 1) and (affixData.values[1][i] and affixData.values[1][i][2] or nil) or affixData.values[1][2]} + if modValue[2] == nil then + tooltip:AddLine(14, ' ^7'..line) + elseif modValue[2] ~= 0 then + tooltip:AddLine(14, ' ^7'..s_format(line, modValue[1], modValue[2])) + end end end end @@ -114,16 +152,31 @@ local function mapAffixTooltip(tooltip, mode, index, value) end end -local function mapAffixDropDownFunction(val, modList, enemyModList, build) - if val ~= "NONE" then +local function eldritchAltarFunction(val, extraData, modList, enemyModList, altarList) + if val == "ALL" or val == "ALLPLAYER" then + for _, altar in ipairs(altarList) do + if altar.val ~= "ALLPLAYER" and (val == "ALL" or altar.val:match("DownsidePlayer")) then + local affixData = data.mapMods.AffixData[altar.val] or {} + if affixData.apply then + if affixData.type == "check" then + affixData.apply(var, 1, modList, enemyModList) + elseif affixData.type == "list" then + affixData.apply(1, 1, affixData.values, modList, enemyModList) + elseif affixData.type == "count" then + affixData.apply(1, extraData[1] or 100, 1, affixData.values, modList, enemyModList) + end + end + end + end + elseif val ~= "NONE" then local affixData = data.mapMods.AffixData[val] or {} if affixData.apply then if affixData.type == "check" then - affixData.apply(var, (1 + (build.configTab.input['multiplierMapModEffect'] or 0)/100), modList, enemyModList) + affixData.apply(var, 1, modList, enemyModList) elseif affixData.type == "list" then - affixData.apply(4 - (build.configTab.varControls['multiplierMapModTier'].selIndex or 1), (1 + (build.configTab.input['multiplierMapModEffect'] or 0)/100), affixData.values, modList, enemyModList) + affixData.apply(1, 1, affixData.values, modList, enemyModList) elseif affixData.type == "count" then - affixData.apply(4 - (build.configTab.varControls['multiplierMapModTier'].selIndex or 1), 100, (1 + (build.configTab.input['multiplierMapModEffect'] or 0)/100), affixData.values, modList, enemyModList) + affixData.apply(1, extraData[1] or 100, 1, affixData.values, modList, enemyModList) end end end @@ -704,22 +757,102 @@ Huge sets the radius to 11. { var = "multiplierSextant", type = "count", label = "# of Sextants affecting the area", ifMult = "Sextant", apply = function(val, modList, enemyModList) modList:NewMod("Multiplier:Sextant", "BASE", m_min(val, 5), "Config") end }, + --{ subsection = "Map Mods", { var = "multiplierMapModEffect", type = "count", label = "% increased effect of map mods" }, - { var = "multiplierMapModTier", type = "list", label = "Map Tier", list = { {val = "HIGH", label = "Red"}, {val = "MED", label = "Yellow"}, {val = "LOW", label = "White"} } }, - { label = "Map Prefix Modifiers:" }, - { var = "MapPrefix1", type = "list", label = "Prefix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Prefix, apply = mapAffixDropDownFunction }, - { var = "MapPrefix2", type = "list", label = "Prefix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Prefix, apply = mapAffixDropDownFunction }, - { var = "MapPrefix3", type = "list", label = "Prefix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Prefix, apply = mapAffixDropDownFunction }, - { var = "MapPrefix4", type = "list", label = "Prefix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Prefix, apply = mapAffixDropDownFunction }, - { label = "Map Suffix Modifiers:" }, - { var = "MapSuffix1", type = "list", label = "Suffix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Suffix, apply = mapAffixDropDownFunction }, - { var = "MapSuffix2", type = "list", label = "Suffix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Suffix, apply = mapAffixDropDownFunction }, - { var = "MapSuffix3", type = "list", label = "Suffix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Suffix, apply = mapAffixDropDownFunction }, - { var = "MapSuffix4", type = "list", label = "Suffix", tooltipFunc = mapAffixTooltip, list = data.mapMods.Suffix, apply = mapAffixDropDownFunction }, + { var = "multiplierMapModTier", type = "list", defaultIndex = 3, label = "Map Tier", list = { {val = "LOW", label = "White"}, {val = "MED", label = "Yellow"}, {val = "HIGH", label = "Red"}, {val = "UBER", label = "T17"} }, apply = function(val, modList, enemyModList, build) + local configTab = build.configTab + local input = configTab.configSets[configTab.activeConfigSetId].input + local varControls = configTab.varControls + if (varControls['multiplierMapModTier'].lastBuild or "HIGH") ~= val.val then + varControls['MapPrefixes'].varData.list = varControls['MapPrefixes'].varData.listFunc(build) + local modsFound = { true, true, true, true } or { false, false, false, false } + for _, mapMod in ipairs(build.configTab.varControls['MapPrefixes'].varData.list) do + if input['MapPrefixes_1'] == mapMod.val then + modsFound[1] = true + elseif input['MapPrefixes_2'] == mapMod.val then + modsFound[2] = true + elseif input['MapPrefixes_3'] == mapMod.val then + modsFound[3] = true + elseif input['MapPrefixes_4'] == mapMod.val then + modsFound[4] = true + end + end + if not modsFound[1] then + input['MapPrefixes_1'] = "NONE" + varControls['MapPrefixes_1']:SelByValue(input['MapPrefixes_1'], "val") + end + if not modsFound[2] then + input['MapPrefixes_2'] = "NONE" + varControls['MapPrefixes_2']:SelByValue(input['MapPrefixes_2'], "val") + end + if not modsFound[3] then + input['MapPrefixes_3'] = "NONE" + varControls['MapPrefixes_3']:SelByValue(input['MapPrefixes_3'], "val") + end + if not modsFound[4] then + input['MapPrefixes_4'] = "NONE" + varControls['MapPrefixes_4']:SelByValue(input['MapPrefixes_4'], "val") + end + build.configTab.varControls['MapPrefixes'].newLists() + build.configTab.varControls['MapSuffixes'].varData.list = build.configTab.varControls['MapSuffixes'].varData.listFunc(build) + local modsFound = { false, false, false, false } + for _, mapMod in ipairs(build.configTab.varControls['MapSuffixes'].varData.list) do + if input['MapSuffixes_1'] == mapMod.val then + modsFound[1] = true + elseif input['MapSuffixes_2'] == mapMod.val then + modsFound[2] = true + elseif input['MapSuffixes_3'] == mapMod.val then + modsFound[3] = true + elseif input['MapSuffixes_4'] == mapMod.val then + modsFound[4] = true + end + end + if not modsFound[1] then + input['MapSuffixes_1'] = "NONE" + varControls['MapSuffixes_1']:SelByValue(input['MapSuffixes_1'], "val") + end + if not modsFound[2] then + input['MapSuffixes_2'] = "NONE" + varControls['MapSuffixes_2']:SelByValue(input['MapSuffixes_2'], "val") + end + if not modsFound[3] then + input['MapSuffixes_3'] = "NONE" + varControls['MapSuffixes_3']:SelByValue(input['MapSuffixes_3'], "val") + end + if not modsFound[4] then + input['MapSuffixes_4'] = "NONE" + varControls['MapSuffixes_4']:SelByValue(input['MapSuffixes_4'], "val") + end + build.configTab.varControls['MapSuffixes'].newLists() + build.configTab.varControls['multiplierMapModTier'].lastBuild = val.val + end + end}, + { var = "MapPrefixes", type = "multiList", maxElements = 4, extraTypes = { { "slider", "range of the map mod", "range", 100 } }, showAll = true, label = "Map Prefix Modifiers:" , tooltipFunc = mapAffixTooltip, listFunc = data.mapMods.Prefix, apply = mapAffixDropDownFunction }, + { var = "MapSuffixes", type = "multiList", maxElements = 4, extraTypes = { { "slider", "range of the map mod", "range", 100 } }, showAll = true, label = "Map Suffix Modifiers:" , tooltipFunc = mapAffixTooltip, listFunc = data.mapMods.Suffix, apply = mapAffixDropDownFunction }, + + { var = "EldritchAltarDownsides", type = "list", defaultIndex = 2, label = "Eldritch Altar Type:" , tooltip = "Selects the stype of Eldritch Altar", list = { { val = "NONE", label = "None" }, { val = "CLEANSING", label = "Exarch" }, { val = "TANGLED", label = "Eater" } }, apply = function(val, modList, enemyModList, build) + if val == "NONE" then + build.configTab.varControls['CleansingAltarDownsides'].shown = false + build.configTab.varControls['TangledAltarDownsides'].shown = false + elseif val == "CLEANSING" then + build.configTab.varControls['CleansingAltarDownsides'].shown = true + build.configTab.varControls['TangledAltarDownsides'].shown = false + elseif val == "TANGLED" then + build.configTab.varControls['CleansingAltarDownsides'].shown = false + build.configTab.varControls['TangledAltarDownsides'].shown = true + end + end }, + { var = "CleansingAltarDownsides", type = "multiList", extraTypes = { { "slider", "range of the eldritch altar", "range", 100 } }, label = "EXARCH Eldritch Altar Downsides:" , tooltipFunc = eldrtichAltarTooltip, list = data.mapMods.CleansingAltar, apply = function(val, extraData, modList, enemyModList) + eldritchAltarFunction(val, extraData, modList, enemyModList, data.mapMods.CleansingAltar) + end }, + { var = "TangledAltarDownsides", type = "multiList", extraTypes = { { "slider", "range of the eldritch altar", "range", 100 } }, label = "EATER Eldritch Altar Downsides:" , tooltipFunc = eldrtichAltarTooltip, list = data.mapMods.TangledAltar, apply = function(val, extraData, modList, enemyModList) + eldritchAltarFunction(val, extraData, modList, enemyModList, data.mapMods.TangledAltar) + end }, { label = "Unique Map Modifiers:" }, { var = "PvpScaling", type = "check", label = "PvP damage scaling in effect", tooltip = "'Hall of Grandmasters'", apply = function(val, modList, enemyModList) modList:NewMod("HasPvpScaling", "FLAG", true, "Config") end }, + --} { label = "Player is cursed by:" }, { var = "playerCursedWithAssassinsMark", type = "count", label = "Assassin's Mark:", tooltip = "Sets the level of Assassin's Mark to apply to the player.", apply = function(val, modList, enemyModList) modList:NewMod("ExtraCurse", "LIST", { skillId = "AssassinsMark", level = val, applyToPlayer = true })